mirror of
				https://gitlab.com/comunic/comunicmessages
				synced 2025-11-04 04:04:10 +00:00 
			
		
		
		
	Can perform user sign in.
This commit is contained in:
		@@ -1,14 +1,28 @@
 | 
			
		||||
QT += widgets
 | 
			
		||||
QT += widgets network
 | 
			
		||||
 | 
			
		||||
SOURCES += \
 | 
			
		||||
    main.cpp \
 | 
			
		||||
    helpers/accounthelper.cpp \
 | 
			
		||||
    widgets/loginwidget.cpp
 | 
			
		||||
    widgets/loginwidget.cpp \
 | 
			
		||||
    utils/accountutils.cpp \
 | 
			
		||||
    data/accountloginrequest.cpp \
 | 
			
		||||
    data/apirequest.cpp \
 | 
			
		||||
    data/apirequestparameter.cpp \
 | 
			
		||||
    helpers/apihelper.cpp \
 | 
			
		||||
    utils/jsonutils.cpp \
 | 
			
		||||
    data/apirequestslist.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    helpers/accounthelper.h \
 | 
			
		||||
    config.h \
 | 
			
		||||
    widgets/loginwidget.h
 | 
			
		||||
    widgets/loginwidget.h \
 | 
			
		||||
    utils/accountutils.h \
 | 
			
		||||
    data/accountloginrequest.h \
 | 
			
		||||
    data/apirequest.h \
 | 
			
		||||
    data/apirequestparameter.h \
 | 
			
		||||
    helpers/apihelper.h \
 | 
			
		||||
    utils/jsonutils.h \
 | 
			
		||||
    data/apirequestslist.h
 | 
			
		||||
 | 
			
		||||
FORMS += \
 | 
			
		||||
    widgets/loginwidget.ui
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								data/accountloginrequest.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								data/accountloginrequest.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
#include "accountloginrequest.h"
 | 
			
		||||
 | 
			
		||||
AccountLoginRequest::AccountLoginRequest()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AccountLoginRequest::emailAddress() const
 | 
			
		||||
{
 | 
			
		||||
    return mEmailAddress;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AccountLoginRequest::setEmailAddress(const QString &emailAddress)
 | 
			
		||||
{
 | 
			
		||||
    mEmailAddress = emailAddress;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AccountLoginRequest::password() const
 | 
			
		||||
{
 | 
			
		||||
    return mPassword;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AccountLoginRequest::setPassword(const QString &password)
 | 
			
		||||
{
 | 
			
		||||
    mPassword = password;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								data/accountloginrequest.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								data/accountloginrequest.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Account login request
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ACCOUNTLOGINREQUEST_H
 | 
			
		||||
#define ACCOUNTLOGINREQUEST_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Possible login results
 | 
			
		||||
 */
 | 
			
		||||
enum LoginResult {
 | 
			
		||||
    LOGIN_SUCCESS,
 | 
			
		||||
    INVALID_CREDENTIALS,
 | 
			
		||||
    TOO_MANY_REQUEST,
 | 
			
		||||
    NETWORK_ERROR,
 | 
			
		||||
    OTHER_ERROR
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Login request
 | 
			
		||||
 */
 | 
			
		||||
class AccountLoginRequest
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    AccountLoginRequest();
 | 
			
		||||
 | 
			
		||||
    QString emailAddress() const;
 | 
			
		||||
    void setEmailAddress(const QString &emailAddress);
 | 
			
		||||
 | 
			
		||||
    QString password() const;
 | 
			
		||||
    void setPassword(const QString &password);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString mEmailAddress;
 | 
			
		||||
    QString mPassword;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // ACCOUNTLOGINREQUEST_H
 | 
			
		||||
							
								
								
									
										54
									
								
								data/apirequest.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								data/apirequest.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
 | 
			
		||||
#include "apirequest.h"
 | 
			
		||||
 | 
			
		||||
APIRequest::APIRequest(QObject *parent) : QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
APIRequest::~APIRequest()
 | 
			
		||||
{
 | 
			
		||||
    if(mNetworkReply != nullptr)
 | 
			
		||||
        mNetworkReply->deleteLater();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString APIRequest::URI() const
 | 
			
		||||
{
 | 
			
		||||
    return mURI;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequest::setURI(const QString &uRI)
 | 
			
		||||
{
 | 
			
		||||
    mURI = uRI;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequest::addString(QString name, QString value)
 | 
			
		||||
{
 | 
			
		||||
    mArguments.append(APIRequestParameter(name, value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequest::addInt(QString name, int value)
 | 
			
		||||
{
 | 
			
		||||
    mArguments.append(APIRequestParameter(name, QString::number(value)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequest::addBool(QString name, bool value)
 | 
			
		||||
{
 | 
			
		||||
    mArguments.append(APIRequestParameter(name, value ? "true" : "false"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QList<APIRequestParameter> APIRequest::arguments() const
 | 
			
		||||
{
 | 
			
		||||
    return mArguments;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QNetworkReply *APIRequest::networkReply() const
 | 
			
		||||
{
 | 
			
		||||
    return mNetworkReply;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequest::setNetworkReply(QNetworkReply *networkReply)
 | 
			
		||||
{
 | 
			
		||||
    mNetworkReply = networkReply;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										88
									
								
								data/apirequest.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								data/apirequest.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
/**
 | 
			
		||||
 * This object contains information about a single
 | 
			
		||||
 * object.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APIREQUEST_H
 | 
			
		||||
#define APIREQUEST_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
 | 
			
		||||
#include "apirequestparameter.h"
 | 
			
		||||
 | 
			
		||||
class QNetworkReply;
 | 
			
		||||
 | 
			
		||||
class APIRequest : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit APIRequest(QObject *parent = nullptr);
 | 
			
		||||
    ~APIRequest();
 | 
			
		||||
 | 
			
		||||
    //Get and set URI target
 | 
			
		||||
    QString URI() const;
 | 
			
		||||
    void setURI(const QString &URI);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a string parameter to the request
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the field to add
 | 
			
		||||
     * @param value The value of the argument to add
 | 
			
		||||
     */
 | 
			
		||||
    void addString(QString name, QString value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add an integer parameter to the request
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the field to add
 | 
			
		||||
     * @param value The value of the argument to add
 | 
			
		||||
     */
 | 
			
		||||
    void addInt(QString name, int value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a boolean parameter to the request
 | 
			
		||||
     *
 | 
			
		||||
     * @param name The name of the field to add
 | 
			
		||||
     * @param value The value of the argument to add
 | 
			
		||||
     */
 | 
			
		||||
    void addBool(QString name, bool value);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the entire list of arguments of the request
 | 
			
		||||
     *
 | 
			
		||||
     * @return The list of arguments
 | 
			
		||||
     */
 | 
			
		||||
    QList<APIRequestParameter> arguments() const;
 | 
			
		||||
 | 
			
		||||
    //Get and set network reply associated with the request
 | 
			
		||||
    QNetworkReply *networkReply() const;
 | 
			
		||||
    void setNetworkReply(QNetworkReply *networkReply);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Signal emitted when an error occurred
 | 
			
		||||
     *
 | 
			
		||||
     * @param code The code of the error
 | 
			
		||||
     */
 | 
			
		||||
    void error(int code);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Signal emitted once we have got the response for our request
 | 
			
		||||
     *
 | 
			
		||||
     * @param document JSON Response
 | 
			
		||||
     */
 | 
			
		||||
    void success(const QJsonDocument &document);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString mURI;
 | 
			
		||||
    QList<APIRequestParameter> mArguments;
 | 
			
		||||
    QNetworkReply *mNetworkReply = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // APIREQUEST_H
 | 
			
		||||
							
								
								
									
										32
									
								
								data/apirequestparameter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								data/apirequestparameter.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
#include "apirequestparameter.h"
 | 
			
		||||
 | 
			
		||||
APIRequestParameter::APIRequestParameter()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
APIRequestParameter::APIRequestParameter(const QString &name, const QString &value) :
 | 
			
		||||
    mName(name), mValue(value)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString APIRequestParameter::name() const
 | 
			
		||||
{
 | 
			
		||||
    return mName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequestParameter::setName(const QString &name)
 | 
			
		||||
{
 | 
			
		||||
    mName = name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString APIRequestParameter::value() const
 | 
			
		||||
{
 | 
			
		||||
    return mValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIRequestParameter::setValue(const QString &value)
 | 
			
		||||
{
 | 
			
		||||
    mValue = value;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								data/apirequestparameter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								data/apirequestparameter.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Single API request parameter
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APIREQUESTPARAMETER_H
 | 
			
		||||
#define APIREQUESTPARAMETER_H
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
class APIRequestParameter
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    APIRequestParameter();
 | 
			
		||||
    APIRequestParameter(const QString &name, const QString &value);
 | 
			
		||||
 | 
			
		||||
    QString name() const;
 | 
			
		||||
    void setName(const QString &name);
 | 
			
		||||
 | 
			
		||||
    QString value() const;
 | 
			
		||||
    void setValue(const QString &value);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QString mName;
 | 
			
		||||
    QString mValue;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // APIREQUESTPARAMETER_H
 | 
			
		||||
							
								
								
									
										29
									
								
								data/apirequestslist.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								data/apirequestslist.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
#include "apirequest.h"
 | 
			
		||||
#include "apirequestslist.h"
 | 
			
		||||
 | 
			
		||||
APIRequestsList::APIRequestsList() : QList()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
APIRequest *APIRequestsList::findForReply(QNetworkReply *reply, bool delete_from_list)
 | 
			
		||||
{
 | 
			
		||||
    bool found = false;
 | 
			
		||||
    int i;
 | 
			
		||||
    for(i = 0; i < size(); i++){
 | 
			
		||||
        if(at(i)->networkReply() == reply){
 | 
			
		||||
            found = true;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    APIRequest *request = nullptr;
 | 
			
		||||
 | 
			
		||||
    if(found)
 | 
			
		||||
        request = at(i);
 | 
			
		||||
 | 
			
		||||
    if(found && delete_from_list)
 | 
			
		||||
        removeAt(i);
 | 
			
		||||
 | 
			
		||||
    return request;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								data/apirequestslist.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								data/apirequestslist.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
#ifndef APIREQUESTSLIST_H
 | 
			
		||||
#define APIREQUESTSLIST_H
 | 
			
		||||
 | 
			
		||||
#include <QList>
 | 
			
		||||
 | 
			
		||||
class APIRequest;
 | 
			
		||||
class QNetworkReply;
 | 
			
		||||
 | 
			
		||||
class APIRequestsList : public QList<APIRequest *>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    APIRequestsList();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Search and return the API Request that contains a specific NetworkReply
 | 
			
		||||
     *
 | 
			
		||||
     * @param reply The reply to search
 | 
			
		||||
     * @param delete_from_list Specify whether the entry should be removed
 | 
			
		||||
     * from the list or not
 | 
			
		||||
     * @return The request / null if none found
 | 
			
		||||
     */
 | 
			
		||||
    APIRequest *findForReply(QNetworkReply *reply, bool delete_from_list);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // APIREQUESTSLIST_H
 | 
			
		||||
@@ -1,12 +1,60 @@
 | 
			
		||||
 | 
			
		||||
#include "accounthelper.h"
 | 
			
		||||
#include "../data/apirequest.h"
 | 
			
		||||
#include "../helpers/apihelper.h"
 | 
			
		||||
 | 
			
		||||
AccountHelper::AccountHelper(QObject *parent) : QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    mAPIHelper = new APIHelper;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AccountHelper::signedIn()
 | 
			
		||||
{
 | 
			
		||||
    return false; //TODO : implement
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AccountHelper::login(const AccountLoginRequest &info)
 | 
			
		||||
{
 | 
			
		||||
    //Create API request
 | 
			
		||||
    APIRequest *request = new APIRequest;
 | 
			
		||||
    request->setURI("account/login");
 | 
			
		||||
    request->addString("userMail", info.emailAddress());
 | 
			
		||||
    request->addString("userPassword", info.password());
 | 
			
		||||
 | 
			
		||||
    //Make connections
 | 
			
		||||
    connect(request, &APIRequest::success, this, &AccountHelper::requestLoginResult);
 | 
			
		||||
    connect(request, &APIRequest::error, this, &AccountHelper::loginError);
 | 
			
		||||
 | 
			
		||||
    //Execute request
 | 
			
		||||
    mAPIHelper->execute(request);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AccountHelper::loginError(int code)
 | 
			
		||||
{
 | 
			
		||||
    //Delete API request
 | 
			
		||||
    qobject_cast<APIRequest *>(sender())->deleteLater();
 | 
			
		||||
 | 
			
		||||
    LoginResult result = LoginResult::OTHER_ERROR;
 | 
			
		||||
 | 
			
		||||
    if(code < 100)
 | 
			
		||||
        result = LoginResult::NETWORK_ERROR;
 | 
			
		||||
    if(code == 401)
 | 
			
		||||
        result = LoginResult::INVALID_CREDENTIALS;
 | 
			
		||||
    if(code == 429)
 | 
			
		||||
        result = LoginResult::TOO_MANY_REQUEST;
 | 
			
		||||
 | 
			
		||||
    //Inform about the result
 | 
			
		||||
    emit loginResult(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AccountHelper::requestLoginResult(const QJsonDocument &document)
 | 
			
		||||
{
 | 
			
		||||
    //Delete API request
 | 
			
		||||
    qobject_cast<APIRequest *>(sender())->deleteLater();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //Success
 | 
			
		||||
    emit loginResult(LoginResult::LOGIN_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,11 @@
 | 
			
		||||
#define ACCOUNTHELPER_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
 | 
			
		||||
class APIHelper;
 | 
			
		||||
 | 
			
		||||
#include "../data/accountloginrequest.h"
 | 
			
		||||
 | 
			
		||||
class AccountHelper : public QObject
 | 
			
		||||
{
 | 
			
		||||
@@ -22,9 +27,32 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    bool signedIn();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Perform login
 | 
			
		||||
     *
 | 
			
		||||
     * @param info Request data (user credentials)
 | 
			
		||||
     */
 | 
			
		||||
    void login(const AccountLoginRequest &info);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This signal is emitted once a login request has been completed
 | 
			
		||||
     *
 | 
			
		||||
     * @param result The state of the request
 | 
			
		||||
     */
 | 
			
		||||
    void loginResult(LoginResult result);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
 | 
			
		||||
    //Login request callbacks
 | 
			
		||||
    void loginError(int code);
 | 
			
		||||
    void requestLoginResult(const QJsonDocument &document);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    APIHelper *mAPIHelper;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // ACCOUNTHELPER_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										70
									
								
								helpers/apihelper.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								helpers/apihelper.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
#include <QUrlQuery>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
 | 
			
		||||
#include "apihelper.h"
 | 
			
		||||
#include "../config.h"
 | 
			
		||||
 | 
			
		||||
APIHelper::APIHelper(QObject *parent) : QObject(parent)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    //Make errors
 | 
			
		||||
    QObject::connect(&mNetworkManager, &QNetworkAccessManager::sslErrors, this, &APIHelper::sslErrors);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIHelper::execute(APIRequest *request)
 | 
			
		||||
{
 | 
			
		||||
    //Determine full request URL
 | 
			
		||||
    QString requestURL = API_URL + request->URI();
 | 
			
		||||
 | 
			
		||||
    //Add API credentials to parameters
 | 
			
		||||
    request->addString("serviceName", API_SERVICE_NAME);
 | 
			
		||||
    request->addString("serviceToken", API_SERVICE_TOKEN);
 | 
			
		||||
 | 
			
		||||
    //Prepare request
 | 
			
		||||
    //See this SO question to learn more : https://stackoverflow.com/questions/2599423
 | 
			
		||||
    QUrlQuery queryData;
 | 
			
		||||
    for(APIRequestParameter param : request->arguments())
 | 
			
		||||
        queryData.addQueryItem(param.name(), param.value());
 | 
			
		||||
 | 
			
		||||
    //Send request
 | 
			
		||||
    QNetworkRequest networkRequest((QUrl(requestURL)));
 | 
			
		||||
    networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
 | 
			
		||||
    QNetworkReply *reply = mNetworkManager.post(networkRequest, queryData.toString(QUrl::FullyEncoded).toUtf8());
 | 
			
		||||
 | 
			
		||||
    //Make connections
 | 
			
		||||
    connect(reply, &QNetworkReply::finished, this, &APIHelper::finished);
 | 
			
		||||
    connect(reply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), this, &APIHelper::error);
 | 
			
		||||
 | 
			
		||||
    //Add the request to the list
 | 
			
		||||
    request->setNetworkReply(reply);
 | 
			
		||||
    mRequestsList.append(request);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIHelper::finished()
 | 
			
		||||
{
 | 
			
		||||
    if(qobject_cast<QNetworkReply *>(sender())->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 200)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    //Get the API request related to this
 | 
			
		||||
    APIRequest *request = mRequestsList.findForReply(qobject_cast<QNetworkReply *>(sender()), true);
 | 
			
		||||
 | 
			
		||||
    //Process and return response
 | 
			
		||||
    emit request->success(QJsonDocument::fromJson(request->networkReply()->readAll()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIHelper::error()
 | 
			
		||||
{
 | 
			
		||||
    //Get the API request related to this
 | 
			
		||||
    APIRequest *request = mRequestsList.findForReply(qobject_cast<QNetworkReply *>(sender()), true);
 | 
			
		||||
 | 
			
		||||
    //Try to determine error code
 | 
			
		||||
    int response_code = request->networkReply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
 | 
			
		||||
    qWarning("An error occurred in an API request! (code: %d)", response_code);
 | 
			
		||||
 | 
			
		||||
    emit request->error(response_code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void APIHelper::sslErrors()
 | 
			
		||||
{
 | 
			
		||||
    qWarning("APIHelper: the SSL/TLS session encountered an error!");
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										45
									
								
								helpers/apihelper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								helpers/apihelper.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
/**
 | 
			
		||||
 * API Helper - handles the connections between
 | 
			
		||||
 * the server and this application
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef APIHELPER_H
 | 
			
		||||
#define APIHELPER_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QNetworkAccessManager>
 | 
			
		||||
#include <QNetworkReply>
 | 
			
		||||
 | 
			
		||||
#include "../data/apirequest.h"
 | 
			
		||||
#include "../data/apirequestslist.h"
 | 
			
		||||
 | 
			
		||||
class APIHelper : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit APIHelper(QObject *parent = nullptr);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Send a request to the server
 | 
			
		||||
     *
 | 
			
		||||
     * @param request The request to execute
 | 
			
		||||
     */
 | 
			
		||||
    void execute(APIRequest *request);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void finished();
 | 
			
		||||
    void error();
 | 
			
		||||
    void sslErrors();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QNetworkAccessManager mNetworkManager;
 | 
			
		||||
    APIRequestsList mRequestsList;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // APIHELPER_H
 | 
			
		||||
							
								
								
									
										16
									
								
								utils/accountutils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								utils/accountutils.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
#include <QRegularExpression>
 | 
			
		||||
 | 
			
		||||
#include "accountutils.h"
 | 
			
		||||
 | 
			
		||||
AccountUtils::AccountUtils()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AccountUtils::CheckEmailAddress(const QString &email)
 | 
			
		||||
{
 | 
			
		||||
    QRegExp regex("\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}\\b");
 | 
			
		||||
    regex.setCaseSensitivity(Qt::CaseInsensitive);
 | 
			
		||||
    regex.setPatternSyntax(QRegExp::RegExp);
 | 
			
		||||
    return regex.exactMatch(email);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								utils/accountutils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								utils/accountutils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Account utilities
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ACCOUNTUTILS_H
 | 
			
		||||
#define ACCOUNTUTILS_H
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
 | 
			
		||||
class AccountUtils
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    AccountUtils();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determine whether an email address is valid or not
 | 
			
		||||
     *
 | 
			
		||||
     * @param email The email address to check
 | 
			
		||||
     * @return TRUE if the email is valid / FALSE else
 | 
			
		||||
     */
 | 
			
		||||
    bool static CheckEmailAddress(const QString &email);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // ACCOUNTUTILS_H
 | 
			
		||||
							
								
								
									
										6
									
								
								utils/jsonutils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								utils/jsonutils.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
#include "jsonutils.h"
 | 
			
		||||
 | 
			
		||||
JSONUtils::JSONUtils()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								utils/jsonutils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								utils/jsonutils.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
/**
 | 
			
		||||
 * JSON utilities
 | 
			
		||||
 *
 | 
			
		||||
 * @author Pierre HUBERT
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef JSONUTILS_H
 | 
			
		||||
#define JSONUTILS_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JSONUtils
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    JSONUtils();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // JSONUTILS_H
 | 
			
		||||
@@ -1,14 +1,110 @@
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
#include "loginwidget.h"
 | 
			
		||||
#include "ui_loginwidget.h"
 | 
			
		||||
#include "../utils/accountutils.h"
 | 
			
		||||
#include "../helpers/accounthelper.h"
 | 
			
		||||
 | 
			
		||||
LoginWidget::LoginWidget(QWidget *parent) :
 | 
			
		||||
    QWidget(parent),
 | 
			
		||||
    ui(new Ui::LoginWidget)
 | 
			
		||||
{
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
    mAccountHelper = new AccountHelper(this);
 | 
			
		||||
    connect(mAccountHelper, &AccountHelper::loginResult, this, &LoginWidget::loginResult);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LoginWidget::~LoginWidget()
 | 
			
		||||
{
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LoginWidget::loginResult(LoginResult result)
 | 
			
		||||
{
 | 
			
		||||
    //Check if login is successfull
 | 
			
		||||
    if(result == LoginResult::LOGIN_SUCCESS){
 | 
			
		||||
        qDebug("User successfully signed in.");
 | 
			
		||||
 | 
			
		||||
        close();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Release login button
 | 
			
		||||
    ui->loginButton->setEnabled(true);
 | 
			
		||||
 | 
			
		||||
    //Display appropriate error
 | 
			
		||||
    switch (result) {
 | 
			
		||||
        case LoginResult::INVALID_CREDENTIALS:
 | 
			
		||||
            showError(tr("The email and / or the password was rejected by the server!"));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case LoginResult::NETWORK_ERROR:
 | 
			
		||||
            showError(tr("A network occurred. Please check your Internet connection..."));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case LoginResult::TOO_MANY_REQUEST:
 | 
			
		||||
            showError(tr("Too many login attempts from your computer. Please try again later..."));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case LoginResult::OTHER_ERROR:
 | 
			
		||||
        default:
 | 
			
		||||
            showError(tr("Login attempt did not succeed."));
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LoginWidget::on_loginButton_clicked()
 | 
			
		||||
{
 | 
			
		||||
    submitForm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LoginWidget::on_emailEdit_returnPressed()
 | 
			
		||||
{
 | 
			
		||||
    submitForm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LoginWidget::on_passwordEdit_returnPressed()
 | 
			
		||||
{
 | 
			
		||||
    submitForm();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void LoginWidget::submitForm()
 | 
			
		||||
{
 | 
			
		||||
    showError("");
 | 
			
		||||
 | 
			
		||||
    QString emailAddress = ui->emailEdit->text();
 | 
			
		||||
    QString password = ui->passwordEdit->text();
 | 
			
		||||
 | 
			
		||||
    //Check input
 | 
			
		||||
    if(emailAddress.length() < 5){
 | 
			
		||||
       showError(tr("Please specify an email address!"));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(password.length() < 3){
 | 
			
		||||
        showError(tr("Please specify a valid password!"));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!AccountUtils::CheckEmailAddress(emailAddress)){
 | 
			
		||||
        showError(("Please specify a valid email address!"));
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Block login button
 | 
			
		||||
    ui->loginButton->setEnabled(false);
 | 
			
		||||
 | 
			
		||||
    //Try to sign in user
 | 
			
		||||
    AccountLoginRequest request;
 | 
			
		||||
    request.setEmailAddress(emailAddress);
 | 
			
		||||
    request.setPassword(password);
 | 
			
		||||
    mAccountHelper->login(request);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LoginWidget::showError(const QString &msg)
 | 
			
		||||
{
 | 
			
		||||
    ui->errorLabel->setText(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,15 @@
 | 
			
		||||
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
 | 
			
		||||
#include "../data/accountloginrequest.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class LoginWidget;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class AccountHelper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class LoginWidget : public QWidget
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
@@ -15,8 +20,31 @@ public:
 | 
			
		||||
    explicit LoginWidget(QWidget *parent = nullptr);
 | 
			
		||||
    ~LoginWidget();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
 | 
			
		||||
    void loginResult(LoginResult result);
 | 
			
		||||
 | 
			
		||||
    //UI Slots
 | 
			
		||||
    void on_loginButton_clicked();
 | 
			
		||||
    void on_emailEdit_returnPressed();
 | 
			
		||||
    void on_passwordEdit_returnPressed();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Submit login form
 | 
			
		||||
     */
 | 
			
		||||
    void submitForm();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Display an error message on the widget
 | 
			
		||||
     *
 | 
			
		||||
     * @param msg The message to show
 | 
			
		||||
     */
 | 
			
		||||
    void showError(const QString &msg);
 | 
			
		||||
 | 
			
		||||
    Ui::LoginWidget *ui;
 | 
			
		||||
    AccountHelper *mAccountHelper;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // LOGINWIDGET_H
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,8 @@
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>402</width>
 | 
			
		||||
    <height>107</height>
 | 
			
		||||
    <width>274</width>
 | 
			
		||||
    <height>397</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
@@ -15,8 +15,35 @@
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
   <item>
 | 
			
		||||
    <layout class="QFormLayout" name="formLayout">
 | 
			
		||||
     <item row="0" column="1">
 | 
			
		||||
    <spacer name="verticalSpacer_2">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Vertical</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="sizeHint" stdset="0">
 | 
			
		||||
      <size>
 | 
			
		||||
       <width>20</width>
 | 
			
		||||
       <height>40</height>
 | 
			
		||||
      </size>
 | 
			
		||||
     </property>
 | 
			
		||||
    </spacer>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="errorLabel">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <weight>75</weight>
 | 
			
		||||
       <bold>true</bold>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string/>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="alignment">
 | 
			
		||||
      <set>Qt::AlignCenter</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLineEdit" name="emailEdit">
 | 
			
		||||
     <property name="inputMask">
 | 
			
		||||
      <string/>
 | 
			
		||||
@@ -26,36 +53,36 @@
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
     <item row="0" column="0">
 | 
			
		||||
      <widget class="QLabel" name="label">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Email address</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="0">
 | 
			
		||||
      <widget class="QLabel" name="label_2">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Password</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item row="1" column="1">
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLineEdit" name="passwordEdit">
 | 
			
		||||
     <property name="echoMode">
 | 
			
		||||
      <enum>QLineEdit::Password</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="placeholderText">
 | 
			
		||||
      <string>Your password</string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QPushButton" name="pushButton">
 | 
			
		||||
    <widget class="QPushButton" name="loginButton">
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>Login</string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <spacer name="verticalSpacer">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Vertical</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="sizeHint" stdset="0">
 | 
			
		||||
      <size>
 | 
			
		||||
       <width>20</width>
 | 
			
		||||
       <height>40</height>
 | 
			
		||||
      </size>
 | 
			
		||||
     </property>
 | 
			
		||||
    </spacer>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user