GCI2012: Google Issue Login
authorDrew Gottlieb
Sat, 08 Dec 2012 15:06:30 +0100
changeset 8268 fe4e94311585
parent 8266 927da572bcdc
child 8270 16a52ad5a362
GCI2012: Google Issue Login
QTfrontend/hwform.cpp
QTfrontend/hwform.h
QTfrontend/ui/page/pagefeedback.cpp
QTfrontend/ui/page/pagefeedback.h
--- a/QTfrontend/hwform.cpp	Fri Dec 07 16:03:53 2012 -0500
+++ b/QTfrontend/hwform.cpp	Sat Dec 08 15:06:30 2012 +0100
@@ -681,6 +681,11 @@
     {
         ui.pageOptions->setTeamOptionsEnabled(true);
     }
+
+    if (id == ID_PAGE_FEEDBACK)
+    {
+        ui.pageFeedback->LoadCaptchaImage();
+    }
 }
 
 void HWForm::GoToPage(int id)
@@ -1853,22 +1858,37 @@
         return;
     }
 
-    //Google login using fake account (feedback.hedgewars@gmail.com)
+    //Submit issue to PHP script
+    QString source = "HedgewarsFoundation-Hedgewars-";
+    source += (cVersionString?(*cVersionString):QString(""));
+    QString captchaCode = ui.pageFeedback->captcha_code->text();
+    QString captchaID = QString::number(ui.pageFeedback->captchaID);
+    
+    QByteArray body;
+    body.append("captcha=");
+    body.append(captchaID);
+    body.append("&code=");
+    body.append(captchaCode);
+    body.append("&source=");
+    body.append(source);
+    body.append("&issue=");
+    body.append(QUrl::toPercentEncoding(issueXml));
+    
     nam = new QNetworkAccessManager(this);
     connect(nam, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(finishedSlot(QNetworkReply*)));
-
-    QUrl url(QString("https://www.google.com/accounts/ClientLogin?"
-                     "accountType=GOOGLE&Email=feedback.hedgewars@gmail.com&Passwd=hwfeedback&service=code&source=HedgewarsFoundation-Hedgewars-")
-                    + (cVersionString?(*cVersionString):QString("")));
-    nam->get(QNetworkRequest(url));
-
+            
+    QNetworkRequest header(QUrl("http://hedgewars.org/feedback/?submit"));
+    header.setRawHeader("Content-Length", QString::number(body.size()).toAscii());
+    
+    nam->post(header, body);
 }
 
 bool HWForm::CreateIssueXml()
 {
     QString summary = ui.pageFeedback->summary->text();
     QString description = ui.pageFeedback->description->toPlainText();
+    QString email = ui.pageFeedback->email->text();
 
     //Check if all necessary information is entered
     if (summary.isEmpty() || description.isEmpty())
@@ -1881,7 +1901,19 @@
     issueXml.append(summary);
     issueXml.append("</title><content type='html'>");
     issueXml.append(description);
-    issueXml.append("</content><author><name>feedback.hedgewars</name></author></entry>");
+    issueXml.append("</content><author><name>feedback.hedgewars</name></author>");
+
+    if (!email.isEmpty())
+    {
+        issueXml.append("<issues:owner><issues:username>");
+        issueXml.append(email);
+        issueXml.append("</issues:username></issues:owner>");
+        issueXml.append("<issues:cc><issues:username>");
+        issueXml.append(email);
+        issueXml.append("</issues:username></issues:cc>");
+    }
+
+    issueXml.append("</entry>");
 
     return true;
 }
@@ -1890,12 +1922,6 @@
 {
     if (reply && reply->error() == QNetworkReply::NoError)
     {
-        QByteArray array = reply->readAll();
-        QString str(array);
-
-        if (authToken.length() != 0)
-        {
-
             QMessageBox infoMsg(this);
             infoMsg.setIcon(QMessageBox::Information);
             infoMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Success"));
@@ -1905,46 +1931,15 @@
 
             ui.pageFeedback->summary->clear();
             ui.pageFeedback->description->clear();
-            authToken = "";
-            return;
-        }
-
-        if (!getAuthToken(str))
-        {
-            ShowErrorMessage(QMessageBox::tr("Error during authentication at google.com"));
+            ui.pageFeedback->EmbedSystemInfo();
+            ui.pageFeedback->LoadCaptchaImage();
+            
             return;
-        }
-
-        QByteArray body(issueXml.toUtf8());
-        QNetworkRequest header(QUrl("https://code.google.com/feeds/issues/p/hedgewars/issues/full"));
-        header.setRawHeader("Content-Length", QString::number(issueXml.length()).toAscii());
-        header.setRawHeader("Content-Type", "application/atom+xml");
-        header.setRawHeader("Authorization", QString("GoogleLogin auth=%1").arg(authToken).toUtf8());
-        nam->post(header, body);
-
     }
-    else if (authToken.length() == 0)
-        ShowErrorMessage(QMessageBox::tr("Error during authentication at google.com"));
     else
     {
-        ShowErrorMessage(QMessageBox::tr("Error reporting the issue, please try again later (or visit hedgewars.googlecode.com directly)"));
-        authToken = "";
+        ShowErrorMessage(QString("Error: ") + reply->readAll());
+        ui.pageFeedback->LoadCaptchaImage();
     }
-
 }
 
-bool HWForm::getAuthToken(QString str)
-{
-    QRegExp ex("Auth=(.+)");
-
-    if (-1 == ex.indexIn(str))
-        return false;
-
-    authToken = ex.cap(1);
-    authToken.remove(QChar('\n'));
-
-    return true;
-}
-
-
-
--- a/QTfrontend/hwform.h	Fri Dec 07 16:03:53 2012 -0500
+++ b/QTfrontend/hwform.h	Sat Dec 08 15:06:30 2012 +0100
@@ -127,11 +127,8 @@
         void SendFeedback();
         //Make a xml representation of the issue to be created
         bool CreateIssueXml();
-        //Called the first time when receiving authorization token from google,
-        //second time when receiving the response after posting the issue
+        //Called after posting a new issue
         void finishedSlot(QNetworkReply* reply);
-        //Filter the auth token from the reply from google
-        bool getAuthToken(QString str);
 
         void NetGameChangeStatus(bool isMaster);
         void NetGameMaster();
@@ -194,7 +191,6 @@
         QByteArray m_lastDemo;
         QNetworkAccessManager * nam;
         QString issueXml;
-        QString authToken;
 
         QPropertyAnimation *animationNewSlide;
         QPropertyAnimation *animationOldSlide;
--- a/QTfrontend/ui/page/pagefeedback.cpp	Fri Dec 07 16:03:53 2012 -0500
+++ b/QTfrontend/ui/page/pagefeedback.cpp	Sat Dec 08 15:06:30 2012 +0100
@@ -20,10 +20,15 @@
 #include <QLineEdit>
 #include <QTextBrowser>
 #include <QLabel>
+#include <QHttp>
 #include <QSysInfo>
+#include <QDebug>
+#include <QBuffer>
 #include <QApplication>
 #include <QDesktopWidget>
+#include <QNetworkReply>
 #include <QProcess>
+#include <QMessageBox>
 
 #include <string>
 
@@ -48,6 +53,8 @@
 {
     QVBoxLayout * pageLayout = new QVBoxLayout();
     QHBoxLayout * summaryLayout = new QHBoxLayout();
+    QHBoxLayout * emailLayout = new QHBoxLayout();
+    QHBoxLayout * combinedTopLayout = new QHBoxLayout();
 
     info = new QLabel();
     info->setText(
@@ -57,22 +64,48 @@
         "<div align=\"center\"><h1>Please give us a feedback!</h1>"
         "<h3>We are always happy about suggestions, ideas or bug reports.<h3>"
         "<h4>The feedback will be posted as a new issue on our Google Code page.<h4>"
+        //"<h4>Your email is optional, but if given, you will be notified of responses.<h4>"
         "</div>"
     );
     pageLayout->addWidget(info);
 
     label_summary = new QLabel();
-    label_summary->setText(QLabel::tr("Summary   "));
+    label_summary->setText(QLabel::tr("Summary"));
     summaryLayout->addWidget(label_summary);
     summary = new QLineEdit();
     summaryLayout->addWidget(summary);
-    pageLayout->addLayout(summaryLayout);
+    combinedTopLayout->addLayout(summaryLayout);
+
+    label_email = new QLabel();
+    label_email->setText(QLabel::tr("Your Email"));
+    emailLayout->addWidget(label_email);
+    email = new QLineEdit();
+    emailLayout->addWidget(email);
+    
+    //  Email -- although implemented -- doesn't seem to work as intended.
+    //  It's sent in the XML as a <issues:cc> , the <entry>, but it doesn't seem
+    //  to actually do anything. If you figure out how to fix that, uncomment these lines
+    //  and the line above in the 'info' QLabel to re-enable this feature.
+    //combinedTopLayout->addLayout(emailLayout);
+    //combinedTopLayout->insertSpacing(1, 50);
+
+    pageLayout->addLayout(combinedTopLayout);
 
     label_description = new QLabel();
     label_description->setText(QLabel::tr("Description"));
     pageLayout->addWidget(label_description, 0, Qt::AlignHCenter);
     description = new QTextBrowser();
 
+    EmbedSystemInfo();
+    
+    description->setReadOnly(false);
+    pageLayout->addWidget(description);
+
+    return pageLayout;
+}
+
+void PageFeedback::EmbedSystemInfo()
+{
     // Gather some information about the system and embed it into the report
     QDesktopWidget* screen = QApplication::desktop();
     QString os_version = "Operating system: ";
@@ -223,20 +256,102 @@
         + compiler_bits
         + kernel_line
     );
-    description->setReadOnly(false);
-    pageLayout->addWidget(description);
+}
+
+QNetworkAccessManager * PageFeedback::GetNetManager()
+{
+    if (netManager) return netManager;
+    netManager = new QNetworkAccessManager(this);
+    connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(NetReply(QNetworkReply*)));
+    return netManager;
+}
+
+void PageFeedback::LoadCaptchaImage()
+{
+        QNetworkAccessManager *netManager = GetNetManager();
+        QUrl captchaURL("http://hedgewars.org/feedback/?gencaptcha");
+        QNetworkRequest req(captchaURL);
+        genCaptchaRequest = netManager->get(req);
+}
+
+void PageFeedback::NetReply(QNetworkReply *reply)
+{
+    if (reply == genCaptchaRequest)
+    {
+        if (reply->error() != QNetworkReply::NoError)
+        {
+            qDebug() << "Error generating captcha image: " << reply->errorString();
+            ShowErrorMessage(QMessageBox::tr("Failed to generate captcha"));
+            return;
+        }
 
-    return pageLayout;
+        bool okay;
+        QByteArray body = reply->readAll();
+        captchaID = QString(body).toInt(&okay);
+
+        if (!okay)
+        {
+            qDebug() << "Failed to get captcha ID: " << body;
+            ShowErrorMessage(QMessageBox::tr("Failed to generate captcha"));
+            return;
+        }
+
+        QString url = "http://hedgewars.org/feedback/?captcha&id=";
+        url += QString::number(captchaID);
+        
+        QNetworkAccessManager *netManager = GetNetManager();
+        QUrl captchaURL(url);
+        QNetworkRequest req(captchaURL);
+        captchaImageRequest = netManager->get(req);
+    }
+    else if (reply == captchaImageRequest)
+    {
+        if (reply->error() != QNetworkReply::NoError)
+        {
+            qDebug() << "Error loading captcha image: " << reply->errorString();
+            ShowErrorMessage(QMessageBox::tr("Failed to download captcha"));
+            return;
+        }
+
+        QByteArray imageData = reply->readAll();
+        QPixmap pixmap;
+        pixmap.loadFromData(imageData);
+        label_captcha->setPixmap(pixmap);
+        captcha_code->setText("");
+    }
 }
 
 QLayout * PageFeedback::footerLayoutDefinition()
 {
     QHBoxLayout * bottomLayout = new QHBoxLayout();
+    QHBoxLayout * captchaLayout = new QHBoxLayout();
+    QVBoxLayout * captchaInputLayout = new QVBoxLayout();
 
-    bottomLayout->setStretch(0,1);
+    label_captcha = new QLabel();
+    label_captcha->setStyleSheet("border: 3px solid #ffcc00; border-radius: 4px");
+    label_captcha->setText("<div style='width: 200px; height: 100px;'>loading<br>captcha</div>");
+    captchaLayout->addWidget(label_captcha);
+
+    label_captcha_input = new QLabel();
+    label_captcha_input->setText(QLabel::tr("Type the security code:"));
+    captchaInputLayout->addWidget(label_captcha_input);
+    captchaInputLayout->setAlignment(label_captcha, Qt::AlignBottom);
+    captcha_code = new QLineEdit();
+    captcha_code->setFixedSize(165, 30);
+    captchaInputLayout->addWidget(captcha_code);
+    captchaInputLayout->setAlignment(captcha_code, Qt::AlignTop);
+    captchaLayout->addLayout(captchaInputLayout);
+    captchaLayout->setAlignment(captchaInputLayout, Qt::AlignLeft);
+
+    captchaLayout->insertSpacing(-1, 40);
+    bottomLayout->addLayout(captchaLayout);
+    
     //TODO: create logo for send button
-    BtnSend = addButton("Send", bottomLayout, 0, false);
-    bottomLayout->insertStretch(0);
+    BtnSend = addButton("Send Feedback", bottomLayout, 0, false);
+    BtnSend->setFixedSize(120, 40);
+
+    bottomLayout->setStretchFactor(captchaLayout, 0);
+    bottomLayout->setStretchFactor(BtnSend, 1);
 
     return bottomLayout;
 }
@@ -246,8 +361,18 @@
     //TODO
 }
 
+void PageFeedback::ShowErrorMessage(const QString & msg)
+{
+    QMessageBox msgMsg(this);
+    msgMsg.setIcon(QMessageBox::Warning);
+    msgMsg.setWindowTitle(QMessageBox::tr("Hedgewars - Error"));
+    msgMsg.setText(msg);
+    msgMsg.setWindowModality(Qt::WindowModal);
+    msgMsg.exec();
+}
+
 PageFeedback::PageFeedback(QWidget* parent) : AbstractPage(parent)
 {
     initPage();
-
+    netManager = NULL;
 }
--- a/QTfrontend/ui/page/pagefeedback.h	Fri Dec 07 16:03:53 2012 -0500
+++ b/QTfrontend/ui/page/pagefeedback.h	Sat Dec 08 15:06:30 2012 +0100
@@ -21,12 +21,17 @@
 
 #include "AbstractPage.h"
 
+class QNetworkReply;
+class QNetworkAccessManager;
+
 class PageFeedback : public AbstractPage
 {
         Q_OBJECT
 
     public:
         PageFeedback(QWidget * parent = 0);
+        void EmbedSystemInfo();
+        void LoadCaptchaImage();
 
         QPushButton * BtnSend;
         QLineEdit * summary;
@@ -34,11 +39,27 @@
         QLabel * info;
         QLabel * label_summary;
         QLabel * label_description;
+        QLabel * label_captcha;
+        QLabel * label_email;
+        QLabel * label_captcha_input;
+        QLineEdit * captcha_code;
+        QLineEdit * email;
+        int captchaID;
+        
+    private slots:
+    
+        virtual void NetReply(QNetworkReply*);
 
     private:
         QLayout * bodyLayoutDefinition();
         QLayout * footerLayoutDefinition();
+        QNetworkAccessManager * GetNetManager();
+        void ShowErrorMessage(const QString & msg);
         void connectSignals();
+
+        QNetworkAccessManager * netManager;
+        QNetworkReply * captchaImageRequest;
+        QNetworkReply * genCaptchaRequest;
 };
 
 #endif