From 58787dc543f028a3cb809005a570237900872856 Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Tue, 28 Feb 2017 00:22:56 +0300 Subject: [PATCH] Library code changes * change documenting to better l&f * add custom exceptions header * QueuedCore::init will now throw exception on library opening error * add database cleanup functions * use sql query to filter data b4 upload to workers * add custom auth structure --- sources/queued/include/queued/Queued.h | 1 + .../include/queued/QueuedAdvancedSettings.h | 25 ++- sources/queued/include/queued/QueuedCore.h | 108 +++++++---- .../queued/include/queued/QueuedDatabase.h | 104 +++++++--- .../queued/include/queued/QueuedExceptions.h | 68 +++++++ sources/queued/include/queued/QueuedLimits.h | 24 ++- sources/queued/include/queued/QueuedProcess.h | 44 +++-- .../include/queued/QueuedProcessManager.h | 61 ++++-- .../include/queued/QueuedReportManager.h | 6 +- .../queued/include/queued/QueuedSettings.h | 6 +- .../include/queued/QueuedTokenManager.h | 24 ++- sources/queued/include/queued/QueuedUser.h | 42 ++-- .../queued/include/queued/QueuedUserManager.h | 70 +++++-- sources/queued/src/QueuedCore.cpp | 181 +++++++++++------- sources/queued/src/QueuedDatabase.cpp | 82 +++++++- sources/queued/src/QueuedProcess.cpp | 2 +- sources/queued/src/QueuedProcessManager.cpp | 11 +- sources/queued/src/QueuedTokenManager.cpp | 12 +- sources/queued/src/QueuedUserManager.cpp | 15 +- 19 files changed, 637 insertions(+), 249 deletions(-) create mode 100644 sources/queued/include/queued/QueuedExceptions.h diff --git a/sources/queued/include/queued/Queued.h b/sources/queued/include/queued/Queued.h index 197f1cc..9bb8600 100644 --- a/sources/queued/include/queued/Queued.h +++ b/sources/queued/include/queued/Queued.h @@ -30,6 +30,7 @@ #include "QueuedDatabase.h" #include "QueuedDebug.h" #include "QueuedEnums.h" +#include "QueuedExceptions.h" #include "QueuedLimits.h" #include "QueuedProcess.h" #include "QueuedProcessManager.h" diff --git a/sources/queued/include/queued/QueuedAdvancedSettings.h b/sources/queued/include/queued/QueuedAdvancedSettings.h index 7a3ef15..7d4cb82 100644 --- a/sources/queued/include/queued/QueuedAdvancedSettings.h +++ b/sources/queued/include/queued/QueuedAdvancedSettings.h @@ -38,7 +38,8 @@ class QueuedAdvancedSettings : public QObject public: /** * @brief QueuedAdvancedSettings class constructor - * @param parent pointer to parent item + * @param parent + * pointer to parent item */ explicit QueuedAdvancedSettings(QObject *parent); /** @@ -47,29 +48,41 @@ public: virtual ~QueuedAdvancedSettings(); /** * @brief get value - * @param _key key to search in + * @param _key + * key to search in * @return value by key if found */ QVariant get(const QString &_key) const; /** * @brief get database value ID - * @param _key key to search in + * @param _key + * key to search in * @return database id or -1 if not found */ long long id(const QString &_key) const; /** * @brief set value - * @param _key key to change - * @param _value value to change + * @param _key + * key to change + * @param _value + * value to change */ void set(const QString &_key, const QVariant &_value); /** * @brief upload configuration from database in to internal format - * @param _value configuration values from database + * @param _value + * configuration values from database */ void set(const QList &_values); signals: + /** + * @brief emits on each value update + * @param _key + * changed key + * @param _value + * changed value + */ void valueUpdated(const QString &_key, const QVariant &_value); private: diff --git a/sources/queued/include/queued/QueuedCore.h b/sources/queued/include/queued/QueuedCore.h index 387bbb4..49379c2 100644 --- a/sources/queued/include/queued/QueuedCore.h +++ b/sources/queued/include/queued/QueuedCore.h @@ -57,12 +57,18 @@ public: virtual ~QueuedCore(); /** * @brief add new task - * @param _command command line - * @param _arguments command arguments - * @param _workingDirectory working directory - * @param _nice nice level - * @param _userId task owner user ID - * @param _limits task defined limits + * @param _command + * command line + * @param _arguments + * command arguments + * @param _workingDirectory + * working directory + * @param _nice + * nice level + * @param _userId + * task owner user ID + * @param _limits + * task defined limits * @return true on successfully addition */ bool addTask(const QString &_command, const QStringList &_arguments, @@ -70,31 +76,36 @@ public: const long long _userId, const QueuedLimits::Limits &_limits); /** * @brief add new user - * @param _name user name - * @param _email user email - * @param _password user password - * @param _permissions user permissions - * @param _limits user limits + * @param _name + * user name + * @param _email + * user email + * @param _password + * user password + * @param _permissions + * user permissions + * @param _limits + * user limits * @return true on successfully addition */ bool addUser(const QString &_name, const QString &_email, const QString &_password, const unsigned int _permissions, const QueuedLimits::Limits &_limits); - /** - * @brief deinit subclasses - */ - void deinit(); /** * @brief edit advanced settings - * @param _key advanced settings key - * @param _value advanced settings value + * @param _key + * advanced settings key + * @param _value + * advanced settings value * @return true on successful option edition */ bool editOption(const QString &_key, const QVariant &_value); /** * @brief edit task - * @param _id task ID to edit - * @param _taskData task data to edit + * @param _id + * task ID to edit + * @param _taskData + * task data to edit * @remark _taskData should contain only fields defined in schema, any other * fields will be ignored. No need to pass all properties here * @return true on successful task edition @@ -102,8 +113,10 @@ public: bool editTask(const long long _id, const QVariantHash &_taskData); /** * @brief edit user - * @param _id user ID to edit - * @param _userData user data to edit + * @param _id + * user ID to edit + * @param _userData + * user data to edit * @remark _userData should contain only fields defined in schema, any other * fields will be ignored. No need to pass all properties here * @return true on successful user edition @@ -111,39 +124,56 @@ public: bool editUser(const long long _id, const QVariantHash &_userData); /** * @brief edit user permissions - * @param _id user ID to edit - * @param _permission permission to add or remove - * @param _add indicates whether it should be added or removed + * @param _id + * user ID to edit + * @param _permission + * permission to add or remove + * @param _add + * indicates whether it should be added or removed * @return true on successful user permission edition */ bool editUserPermission(const long long _id, const QueuedEnums::Permission &_permission, const bool _add); + // control methods + /** + * @brief deinit subclasses + */ + void deinit(); /** * @brief init subclasses - * @param _configuration path to configuration file + * @param _configuration + * path to configuration file + * @throws QueuedDatabaseException */ void init(const QString &_configuration); private slots: /** * @brief notify clients about settings update - * @param _key updated key - * @param _value new value + * @param _key + * updated key + * @param _value + * new value */ void updateSettings(const QString &_key, const QVariant &_value); /** * @brief update process time - * @param _id task id - * @param _startTime task start time or empty - * @param _endTime task end time or empty + * @param _id + * task id + * @param _startTime + * task start time or empty + * @param _endTime + * task end time or empty */ void updateTaskTime(const long long _id, const QDateTime &_startTime, const QDateTime &_endTime); /** * @brief update user login time - * @param _id user ID - * @param _time user login time + * @param _id + * user ID + * @param _time + * user login time */ void updateUserLoginTime(const long long _id, const QDateTime &_time); @@ -177,6 +207,20 @@ private: * @brief connection list */ QList m_connections; + /** + * @brief init processes + */ + void initProcesses(); + /** + * @brief init settings and database + * @param _configuration + * path to configuration file + */ + void initSettings(const QString &_configuration); + /** + * @brief init users + */ + void initUsers(); }; diff --git a/sources/queued/include/queued/QueuedDatabase.h b/sources/queued/include/queued/QueuedDatabase.h index 0310d54..237ff0a 100644 --- a/sources/queued/include/queued/QueuedDatabase.h +++ b/sources/queued/include/queued/QueuedDatabase.h @@ -40,9 +40,12 @@ class QueuedDatabase : public QObject public: /** * @brief QueuedDatabase class constructor - * @param parent pointer to parent item - * @param path path to database - * @param driver database driver + * @param parent + * pointer to parent item + * @param path + * path to database + * @param driver + * database driver */ explicit QueuedDatabase(QObject *parent, const QString path, const QString driver); @@ -56,34 +59,44 @@ public: void checkDatabase(); /** * @brief check and create queued administrator if missing - * @param _user administrator username - * @param _password administrator password SHA512 + * @param _user + * administrator username + * @param _password + * administrator password SHA512 */ void createAdministrator(const QString &_user, const QString &_password); /** * @brief get all records from table - * @param _table table name - * @param _condition optional condition string + * @param _table + * table name + * @param _condition + * optional condition string * @return list of records from table */ QList get(const QString &_table, const QString &_condition = QString()); /** * @brief get record from table with given id - * @param _table table name - * @param _id record id + * @param _table + * table name + * @param _id + * record id * @return variant map from table */ QVariantHash get(const QString &_table, const long long _id); /** * @brief open database - * @param _hostname hostname to connect, may be empty - * @param _port port to connect, may be 0 - * @param _username username to connect, may be empty - * @param _password password to connect, will be ignored if _username - * is empty + * @param _hostname + * hostname to connect, may be empty + * @param _port + * port to connect, may be 0 + * @param _username + * username to connect, may be empty + * @param _password + * password to connect, will be ignored if _username is empty + * @return true on successful opening */ - void open(const QString &_hostname, const int _port, + bool open(const QString &_hostname, const int _port, const QString &_username, const QString &_password); /** * @brief path to database @@ -94,20 +107,50 @@ public: public slots: /** * @brief add record to database - * @param _table table name - * @param _value value to insert + * @param _table + * table name + * @param _value + * value to insert * @return index of inserted record or -1 if no insertion */ long long add(const QString &_table, const QVariantHash &_value); /** * @brief modify record in table - * @param _table table name - * @param _id id for search - * @param _value value to update + * @param _table + * table name + * @param _id + * id for search + * @param _value + * value to update * @return true on successfully modification */ bool modify(const QString &_table, const long long _id, const QVariantHash &_value); + /** + * @brief remove record in table by ID + * @param _table + * table name + * @param _id + * id to remove + * @return true on successfully removal + */ + bool remove(const QString &_table, const long long _id); + /** + * @brief remove ended task + * @param _endTime + * last task end time + */ + void removeTasks(const QDateTime &_endTime); + /** + * @brief remove unused tokens + */ + void removeTokens(); + /** + * @brief remove user which where not logged into system + * @param _lastLogin + * last user login + */ + void removeUsers(const QDateTime &_lastLogin); private: /** @@ -120,32 +163,39 @@ private: QString m_path; /** * @brief create or update actual schema in table - * @param _table table name + * @param _table + * table name */ void createSchema(const QString &_table); /** * @brief create given table - * @param _table table name + * @param _table + * table name */ void createTable(const QString &_table); /** * @brief additional function to get column numbers from table - * @param _columns columns mapping - * @param _record SQL record from query + * @param _columns + * columns mapping + * @param _record + * SQL record from query * @return map of column names to their numbers */ QHash getColumnsInRecord(const QStringList &_columns, const QSqlRecord &_record) const; /** * @brief last insertion ID - * @param _table table name + * @param _table + * table name * @return last insertion id from table */ long long lastInsertionId(const QString &_table) const; /** * @brief additional function to get payload for query - * @param _table table name for search - * @param _value value to build payload + * @param _table + * table name for search + * @param _value + * value to build payload * @return list of keys and list of values */ QPair diff --git a/sources/queued/include/queued/QueuedExceptions.h b/sources/queued/include/queued/QueuedExceptions.h new file mode 100644 index 0000000..0082135 --- /dev/null +++ b/sources/queued/include/queued/QueuedExceptions.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016 Evgeniy Alekseev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + */ +/** + * @file QueuedExceptions.h + * Header of Queued library + * @author Evgeniy Alekseev + * @copyright MIT + * @bug https://github.com/arcan1s/queued/issues + */ + + +#ifndef QUEUEDEXCEPTIONS_H +#define QUEUEDEXCEPTIONS_H + +#include + + +/** + * @brief database operation exception + */ +class QueuedDatabaseException : public QException +{ +public: + /** + * @brief QueuedDatabaseException class constructor + * @param message + * exception message + */ + QueuedDatabaseException(const QString &message) + : m_message(message){}; + /** + * @brief clone QueuedDatabaseException + */ + QueuedDatabaseException *clone() const + { + return new QueuedDatabaseException(*this); + }; + /** + * @brief message of this exception + * @return message for logging, etc + */ + QString message() const { return m_message; }; + /** + * @brief raise QueuedDatabaseException + */ + void raise() const { throw * this; } + +private: + /** + * @brief exception message + */ + QString m_message; +}; + + +#endif /* QUEUEDEXCEPTIONS_H */ diff --git a/sources/queued/include/queued/QueuedLimits.h b/sources/queued/include/queued/QueuedLimits.h index 95f0ec7..29b0b6d 100644 --- a/sources/queued/include/queued/QueuedLimits.h +++ b/sources/queued/include/queued/QueuedLimits.h @@ -82,7 +82,8 @@ struct Limits { , valid(false){}; /** * @brief structure constructor from string representation - * @param _stringLimits limits string representation + * @param _stringLimits + * limits string representation */ Limits(const QString &_stringLimits) { @@ -101,25 +102,32 @@ struct Limits { /** * @ingroup QueuedLimits * @brief convert QString memory value to integer - * @param _value value to convert - * @param _status conversion status + * @param _value + * value to convert + * @param _status + * conversion status * @return converted integer */ long long convertMemory(QString _value, bool *_status); /** * @ingroup QueuedLimits * @brief compare two limits - * @param _first first limit - * @param _second second limit + * @param _first + * first limit + * @param _second + * second limit * @return true if first limit is less than second */ bool limitCompare(const long long _first, const long long _second); /** * @ingroup QueuedLimits * @brief get minimal limits from given - * @param _task task defined limits - * @param _user user defined limit - * @param _default default limits if anu + * @param _task + * task defined limits + * @param _user + * user defined limit + * @param _default + * default limits if anu * @return minimal limits from given */ Limits minimalLimits(const Limits &_task, const Limits &_user, diff --git a/sources/queued/include/queued/QueuedProcess.h b/sources/queued/include/queued/QueuedProcess.h index 886745d..d33c749 100644 --- a/sources/queued/include/queued/QueuedProcess.h +++ b/sources/queued/include/queued/QueuedProcess.h @@ -96,12 +96,15 @@ public: /** * @brief QueuedProcess class constructor - * @param parent pointer to parent item - * @param definitions definitions of process - * @param index index of process + * @param parent + * pointer to parent item + * @param definitions + * definitions of process + * @param index + * index of process */ explicit QueuedProcess(QObject *parent, - const QueuedProcessDefinitions definitions, + const QueuedProcessDefinitions &definitions, const long long index); /** * @brief QueuedProcess class destructor @@ -180,57 +183,68 @@ public: void setCommand(const QString &_command); /** * @brief set command line arguments - * @param _commandArguments new command line arguments + * @param _commandArguments + * new command line arguments */ void setCommandArguments(const QStringList &_commandArguments); /** * @brief set end time - * @param _time process end time + * @param _time + * process end time */ void setEndTime(const QDateTime &_time); /** * @brief set process GID - * @param _gid new process GID + * @param _gid + * new process GID */ void setGid(const unsigned int _gid); /** * @brief set process limits - * @param _limits new process limits + * @param _limits + * new process limits */ void setLimits(const QueuedLimits::Limits &_limits); /** * @brief set process nice - * @param _nice new process nice + * @param _nice + * new process nice */ void setNice(const unsigned int _nice); /** * @brief set process state - * @param _limits new process state + * @param _limits + * new process state */ void setPState(const QueuedEnums::ProcessState _state); /** * @brief set start time - * @param _time process start time + * @param _time + * process start time */ void setStartTime(const QDateTime &_time); /** * @brief set process UID - * @param _uid new process UID + * @param _uid + * new process UID */ void setUid(const unsigned int _uid); /** * @brief set user ID - * @param _user new user ID + * @param _user + * new user ID */ void setUser(const long long _user); /** * @brief set working directory - * @param _workDirectory new process working directory + * @param _workDirectory + * new process working directory */ void setWorkDirectory(const QString &_workDirectory); /** * @brief equal operator implementation - * @param _other other object + * @param _other + * other object * @return true if objects are equal */ bool operator==(const QueuedProcess &_other); diff --git a/sources/queued/include/queued/QueuedProcessManager.h b/sources/queued/include/queued/QueuedProcessManager.h index e08baaf..1497eb9 100644 --- a/sources/queued/include/queued/QueuedProcessManager.h +++ b/sources/queued/include/queued/QueuedProcessManager.h @@ -64,8 +64,10 @@ public: /** * @brief QueuedProcessManager class constructor - * @param parent pointer to parent item - * @param onExit default action on exit + * @param parent + * pointer to parent item + * @param onExit + * default action on exit */ explicit QueuedProcessManager(QObject *parent, const OnExitAction onExit); /** @@ -74,28 +76,34 @@ public: virtual ~QueuedProcessManager(); /** * @brief add task - * @param _properties task properties from database - * @param _index task index + * @param _properties + * task properties from database + * @param _index + * task index * @return pointer to created task */ QueuedProcess *add(const QVariantHash &_properties, const long long _index); /** * @brief add task - * @param _definitions process definitions - * @param _index task index + * @param _definitions + * process definitions + * @param _index + * task index * @return pointer to created task */ QueuedProcess * - add(const QueuedProcess::QueuedProcessDefinitions _definitions, + add(const QueuedProcess::QueuedProcessDefinitions &_definitions, const long long _index); /** * @brief add tasks from database - * @param _processes database stored tasks + * @param _processes + * database stored tasks */ void loadProcesses(const QList &_processes); /** * @brief task - * @param _index task index + * @param _index + * task index * @return task found by index or nullptr */ QueuedProcess *process(const long long _index); @@ -106,17 +114,20 @@ public: QueuedProcessMap processes(); /** * @brief remove task from list - * @param _index task index + * @param _index + * task index */ void remove(const long long _index); /** * @brief force start task - * @param _index task index + * @param _index + * task index */ - void start(const long long _index); + void start(const long long _index); /** * @brief force stop task - * @param _index task index + * @param _index + * task index */ void stop(const long long _index); // properties @@ -127,30 +138,38 @@ public: OnExitAction onExit() const; /** * @brief set on exit action - * @param _action new on exit action + * @param _action + * new on exit action */ void setOnExitAction(const OnExitAction _action); signals: /** * @brief signal which will be called on task start - * @param _index task index - * @param _time task start time + * @param _index + * task index + * @param _time + * task start time */ void taskStartTimeReceived(const long long _index, const QDateTime &_time); /** * @brief signal which will be called on task end - * @param _index task index - * @param _time task stop time + * @param _index + * task index + * @param _time + * task stop time */ void taskStopTimeReceived(const long long _index, const QDateTime &_time); private slots: /** * @brief slot for catching finished tasks - * @param _exitCode exit code of finished task - * @param _exitStatus exit status of finished task - * @param _index index of finished task + * @param _exitCode + * exit code of finished task + * @param _exitStatus + * exit status of finished task + * @param _index + * index of finished task */ void taskFinished(const int _exitCode, const QProcess::ExitStatus _exitStatus, diff --git a/sources/queued/include/queued/QueuedReportManager.h b/sources/queued/include/queued/QueuedReportManager.h index 6a1f06f..8999ecc 100644 --- a/sources/queued/include/queued/QueuedReportManager.h +++ b/sources/queued/include/queued/QueuedReportManager.h @@ -39,8 +39,10 @@ class QueuedReportManager : public QObject public: /** * @brief QueuedReportManager class constructor - * @param parent pointer to parent item - * @param database pointer to database object + * @param parent + * pointer to parent item + * @param database + * pointer to database object */ explicit QueuedReportManager(QObject *parent, QueuedDatabase *database); /** diff --git a/sources/queued/include/queued/QueuedSettings.h b/sources/queued/include/queued/QueuedSettings.h index 30a0063..a304cd8 100644 --- a/sources/queued/include/queued/QueuedSettings.h +++ b/sources/queued/include/queued/QueuedSettings.h @@ -42,8 +42,10 @@ class QueuedSettings : public QObject public: /** * @brief QueuedSettings class constructor - * @param parent pointer to parent item - * @param path path to configuration file + * @param parent + * pointer to parent item + * @param path + * path to configuration file */ explicit QueuedSettings(QObject *parent, const QString path); /** diff --git a/sources/queued/include/queued/QueuedTokenManager.h b/sources/queued/include/queued/QueuedTokenManager.h index 5d4f564..9b72437 100644 --- a/sources/queued/include/queued/QueuedTokenManager.h +++ b/sources/queued/include/queued/QueuedTokenManager.h @@ -38,7 +38,8 @@ class QueuedTokenManager : public QObject public: /** * @brief QueuedTokenManager class constructor - * @param parent pointer to parent item + * @param parent + * pointer to parent item */ explicit QueuedTokenManager(QObject *parent); /** @@ -47,18 +48,21 @@ public: virtual ~QueuedTokenManager(); /** * @brief check if token is valid - * @param _token token ID + * @param _token + * token ID * @return true if token is valid otherwise return false */ bool isTokenValid(const QString &_token); /** * @brief upload tokens from database - * @param _value tokens from database + * @param _value + * tokens from database */ void loadTokens(const QList &_values); /** * @brief register new token - * @param _validUntil token valid until + * @param _validUntil + * token valid until * @return new generated token */ QString registerToken(const QDateTime _validUntil); @@ -66,20 +70,24 @@ public: public slots: /** * @brief method which will be called on token expiring - * @param _token expired token ID + * @param _token + * expired token ID */ void expireToken(const QString &_token); signals: /** * @brief signal which will be emitted on token expiration - * @param _token token ID + * @param _token + * token ID */ void tokenExpired(const QString &_token); /** * @brief signal which will be emitted on newly created token - * @param _token token ID - * @param _validUntil token valid until + * @param _token + * token ID + * @param _validUntil + * token valid until */ void tokenRegistered(const QString &_token, const QDateTime &_validUntil); diff --git a/sources/queued/include/queued/QueuedUser.h b/sources/queued/include/queued/QueuedUser.h index 3d1bcdd..3dbd3b7 100644 --- a/sources/queued/include/queued/QueuedUser.h +++ b/sources/queued/include/queued/QueuedUser.h @@ -71,9 +71,12 @@ public: /** * @brief QueuedUser class constructor - * @param parent pointer to parent item - * @param definitions definitions of user - * @param index index of process + * @param parent + * pointer to parent item + * @param definitions + * definitions of user + * @param index + * index of process */ explicit QueuedUser(QObject *parent, const QueuedUserDefinitions &definitions, @@ -85,20 +88,23 @@ public: // methods /** * @brief add permissions to user - * @param _permissions new user permissions + * @param _permissions + * new user permissions * @return current user permissions */ QueuedEnums::Permissions addPermissions(const QueuedEnums::Permissions _permissions); /** * @brief generates SHA512 hash from given password - * @param _password password as string + * @param _password + * password as string * @return SHA512 of password */ static QString hashFromPassword(const QString &_password); /** * @brief test user permissions - * @param _permission permission to test + * @param _permission + * permission to test * @return true if user has permission otherwise return false */ bool hasPermission(const QueuedEnums::Permission _permission); @@ -109,13 +115,15 @@ public: QPair ids(); /** * @brief check if password is valid - * @param _password password as string + * @param _password + * password as string * @return true if password matches stored hash */ bool isPasswordValid(const QString &_password) const; /** * @brief remove permissions from user - * @param _permissions permissions to remove + * @param _permissions + * permissions to remove * @return current user permissions */ QueuedEnums::Permissions @@ -155,33 +163,39 @@ public: // main properties /** * @brief set user email - * @param _email new user email + * @param _email + * new user email */ void setEmail(const QString _email); /** * @brief set username - * @param _name new user name + * @param _name + * new user name */ void setName(const QString _name); /** * @brief set user password - * @param _password new user password + * @param _password + * new user password */ void setPassword(const QString _password); /** * @brief set user permissions - * @param _permissions new user permissions + * @param _permissions + * new user permissions */ void setPermissions(const unsigned int _permissions); // permissions /** * @brief set limits - * @param _limit new user limits + * @param _limit + * new user limits */ void setLimits(const QueuedLimits::Limits &_limits); /** * @brief equal operator implementation - * @param _other other object + * @param _other + * other object * @return true if objects are equal */ bool operator==(const QueuedUser &_other); diff --git a/sources/queued/include/queued/QueuedUserManager.h b/sources/queued/include/queued/QueuedUserManager.h index 25ef50a..aea9472 100644 --- a/sources/queued/include/queued/QueuedUserManager.h +++ b/sources/queued/include/queued/QueuedUserManager.h @@ -43,9 +43,24 @@ class QueuedUserManager : public QObject long long tokenExpiration READ tokenExpiration WRITE setTokenExpiration) public: + /** + * @struct UserAuthorization + * user authorization structure + * @remark only + * @var token + * authorization token + * @var user + * username, token owner + */ + typedef struct { + QString token; + QString user; + } UserAuthorization; + /** * @brief QueuedUserManager class constructor - * @param parent pointer to parent item + * @param parent + * pointer to parent item */ explicit QueuedUserManager(QObject *parent); /** @@ -54,60 +69,72 @@ public: virtual ~QueuedUserManager(); /** * @brief add user - * @param _properties user properties from database - * @param _id user ID + * @param _properties + * user properties from database + * @param _id + * user ID * @return pointer to created user */ QueuedUser *add(const QVariantHash &_properties, const long long _id); /** * @brief add user - * @param _definitions user definitions - * @param _id user ID + * @param _definitions + * user definitions + * @param _id + * user ID * @return pointer to created user */ QueuedUser *add(const QueuedUser::QueuedUserDefinitions &_definitions, const long long _id); /** * @brief authorize user - * @param _user user name - * @param _password user password - * @return generated tokens 0r empty string if it is not valid + * @param _user + * user name + * @param _password + * user password + * @return generated tokens or empty string if it is not valid */ QString authorize(const QString &_user, const QString &_password); /** * @brief authorize user for service - * @param _user user name - * @param _token token ID - * @param _service service to authorize + * @param _auth + * user authorization structure + * @param _service + * service to authorize * @return true if user allowed to do it otherwise return false */ - bool authorize(const QString &_user, const QString &_token, + bool authorize(const UserAuthorization &_auth, const QueuedEnums::Permission _service); /** * @brief get UID and GID from user ID - * @param _id user id + * @param _id + * user id * @return pair of {uid, gid} */ QPair ids(const long long _id); /** * @brief load tokens - * @param _tokens tokens list from database + * @param _tokens + * tokens list from database */ void loadTokens(const QList &_tokens); /** * @brief load users - * @param _users users list from database + * @param _users + * users list from database */ void loadUsers(const QList &_users); /** * @brief user by ID - * @param _id user id for search + * @param _id + * user id for search * @return user by id or nullptr if no user found */ QueuedUser *user(const long long _id); /** * @brief user by name - * @param _name user name for search + * @param _name + * user name for search * @return user by name or nullptr if no user found */ QueuedUser *user(const QString &_name); @@ -119,15 +146,18 @@ public: long long tokenExpiration() const; /** * @brief set token expiration - * @param _expiry token expiration in days + * @param _expiry + * token expiration in days */ void setTokenExpiration(const long long &_expiry); signals: /** * @brief signal which emits on each user successfully login - * @param _id user ID - * @param _time user login time + * @param _id + * user ID + * @param _time + * user login time */ void userLoggedIn(const long long _id, const QDateTime &_time); diff --git a/sources/queued/src/QueuedCore.cpp b/sources/queued/src/QueuedCore.cpp index 6993fab..7884fd8 100644 --- a/sources/queued/src/QueuedCore.cpp +++ b/sources/queued/src/QueuedCore.cpp @@ -113,32 +113,6 @@ bool QueuedCore::addUser(const QString &_name, const QString &_email, } -/** - * @fn deinit - */ -void QueuedCore::deinit() -{ - // clear connections first - for (auto &connection : m_connections) - disconnect(connection); - m_connections.clear(); - - // delete objects now - if (m_reports) - delete m_reports; - if (m_processes) - delete m_processes; - if (m_users) - delete m_users; - if (m_database) - delete m_database; - if (m_settings) - delete m_settings; - if (m_advancedSettings) - delete m_advancedSettings; -} - - /** * @fn editOption */ @@ -269,6 +243,32 @@ bool QueuedCore::editUserPermission(const long long _id, } +/** + * @fn deinit + */ +void QueuedCore::deinit() +{ + // clear connections first + for (auto &connection : m_connections) + disconnect(connection); + m_connections.clear(); + + // delete objects now + if (m_reports) + delete m_reports; + if (m_processes) + delete m_processes; + if (m_users) + delete m_users; + if (m_database) + delete m_database; + if (m_settings) + delete m_settings; + if (m_advancedSettings) + delete m_advancedSettings; +} + + /** * @fn init */ @@ -279,49 +279,10 @@ void QueuedCore::init(const QString &_configuration) // deinit objects if any deinit(); - // read configuration first - m_settings = new QueuedSettings(this, _configuration); - // init database now - auto dbSetup = m_settings->db(); - m_database = new QueuedDatabase(this, dbSetup.path, dbSetup.driver); - m_database->open(dbSetup.hostname, dbSetup.port, dbSetup.username, - dbSetup.password); - auto dbAdmin = m_settings->admin(); - m_database->createAdministrator(dbAdmin.name, dbAdmin.password); - - // and load advanced settings - m_advancedSettings = new QueuedAdvancedSettings(this); - m_advancedSettings->set(m_database->get(QueuedDB::SETTINGS_TABLE)); - - // report manager - m_reports = new QueuedReportManager(this, m_database); - - // load users and tokens - m_users = new QueuedUserManager(this); - auto expiry - = m_advancedSettings->get(QString("TokenExpiration")).toLongLong(); - m_users->setTokenExpiration(expiry); - m_users->loadTokens(m_database->get(QueuedDB::TOKENS_TABLE)); - m_users->loadUsers(m_database->get(QueuedDB::USERS_TABLE)); - m_connections += connect( - m_users, SIGNAL(userLoggedIn(const long long, const QDateTime &)), this, - SLOT(updateUserLoginTime(const long long, const QDateTime &))); - - // and processes finally - auto onExitAction = static_cast( - m_advancedSettings->get(QString("OnExitAction")).toInt()); - m_processes = new QueuedProcessManager(this, onExitAction); - m_processes->loadProcesses(m_database->get(QueuedDB::TASKS_TABLE)); - m_connections - += connect(m_processes, &QueuedProcessManager::taskStartTimeReceived, - [this](const long long _index, const QDateTime &_time) { - return updateTaskTime(_index, _time, QDateTime()); - }); - m_connections - += connect(m_processes, &QueuedProcessManager::taskStopTimeReceived, - [this](const long long _index, const QDateTime &_time) { - return updateTaskTime(_index, QDateTime(), _time); - }); + // init parts + initSettings(_configuration); + initUsers(); + initProcesses(); // settings update notifier m_connections += connect( @@ -388,3 +349,85 @@ void QueuedCore::updateUserLoginTime(const long long _id, if (!status) qCWarning(LOG_LIB) << "Could not modify user record" << _id; } + + +/** + * @fn initProcesses + */ +void QueuedCore::initProcesses() +{ + // init processes + auto onExitAction = static_cast( + m_advancedSettings->get(QString("OnExitAction")).toInt()); + + m_processes = new QueuedProcessManager(this, onExitAction); + auto dbProcesses = m_database->get( + QueuedDB::TASKS_TABLE, + QString("WHERE state != %1") + .arg(static_cast(QueuedEnums::ProcessState::Exited))); + m_processes->loadProcesses(dbProcesses); + + m_connections + += connect(m_processes, &QueuedProcessManager::taskStartTimeReceived, + [this](const long long _index, const QDateTime &_time) { + return updateTaskTime(_index, _time, QDateTime()); + }); + m_connections + += connect(m_processes, &QueuedProcessManager::taskStopTimeReceived, + [this](const long long _index, const QDateTime &_time) { + return updateTaskTime(_index, QDateTime(), _time); + }); +} + + +/** + * @fn initSettings + */ +void QueuedCore::initSettings(const QString &_configuration) +{ + // read configuration first + m_settings = new QueuedSettings(this, _configuration); + // init database now + auto dbSetup = m_settings->db(); + m_database = new QueuedDatabase(this, dbSetup.path, dbSetup.driver); + bool status = m_database->open(dbSetup.hostname, dbSetup.port, + dbSetup.username, dbSetup.password); + if (!status) + throw QueuedDatabaseException("Could not open database"); + + // create administrator if required + auto dbAdmin = m_settings->admin(); + m_database->createAdministrator(dbAdmin.name, dbAdmin.password); + + // and load advanced settings + m_advancedSettings = new QueuedAdvancedSettings(this); + m_advancedSettings->set(m_database->get(QueuedDB::SETTINGS_TABLE)); + + // report manager + m_reports = new QueuedReportManager(this, m_database); +} + + +/** + * @fn initUsers + */ +void QueuedCore::initUsers() +{ + // load users and tokens + auto expiry + = m_advancedSettings->get(QString("TokenExpiration")).toLongLong(); + + m_users = new QueuedUserManager(this); + m_users->setTokenExpiration(expiry); + QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate); + auto dbTokens = m_database->get( + QueuedDB::TOKENS_TABLE, + QString("WHERE datetime(validUntil) > datetime(%2)").arg(now)); + m_users->loadTokens(dbTokens); + auto dbUsers = m_database->get(QueuedDB::USERS_TABLE); + m_users->loadUsers(dbUsers); + + m_connections += connect( + m_users, SIGNAL(userLoggedIn(const long long, const QDateTime &)), this, + SLOT(updateUserLoginTime(const long long, const QDateTime &))); +} diff --git a/sources/queued/src/QueuedDatabase.cpp b/sources/queued/src/QueuedDatabase.cpp index 5799f92..edadade 100644 --- a/sources/queued/src/QueuedDatabase.cpp +++ b/sources/queued/src/QueuedDatabase.cpp @@ -161,7 +161,7 @@ QVariantHash QueuedDatabase::get(const QString &_table, const long long _id) /** * @fn open */ -void QueuedDatabase::open(const QString &_hostname, const int _port, +bool QueuedDatabase::open(const QString &_hostname, const int _port, const QString &_username, const QString &_password) { qCDebug(LOG_LIB) << "Open database at" << _hostname << _port << "as user" @@ -176,7 +176,8 @@ void QueuedDatabase::open(const QString &_hostname, const int _port, qCDebug(LOG_LIB) << "Open database status" << status; if (status) - return checkDatabase(); + checkDatabase(); + return status; } @@ -245,6 +246,83 @@ bool QueuedDatabase::modify(const QString &_table, const long long _id, } +/** + * @fn remove + */ +bool QueuedDatabase::remove(const QString &_table, const long long _id) +{ + qCDebug(LOG_LIB) << "Remove row" << _id << "from" << _table; + + QSqlQuery query = m_database.exec( + QString("DELETE FROM %1 WHERE _id=%2").arg(_table).arg(_id)); + QSqlError error = query.lastError(); + if (error.isValid()) { + qCCritical(LOG_LIB) << "Could not remove record" << _id << "in table" + << _table << "message" << error.text(); + return false; + } + + return true; +} + + +/** + * @fn removeTasks + */ +void QueuedDatabase::removeTasks(const QDateTime &_endTime) +{ + qCDebug(LOG_LIB) << "Remove all tasks which are older than" << _endTime; + + QSqlQuery query = m_database.exec( + QString("DELETE FROM %1 WHERE datetime(endTime) < datetime(%2)") + .arg(QueuedDB::TASKS_TABLE) + .arg(_endTime.toString(Qt::ISODate))); + + QSqlError error = query.lastError(); + if (error.isValid()) + qCCritical(LOG_LIB) << "Could not remove tasks in table" + << "message" << error.text(); +} + + +/** + * @fn removeTokens + */ +void QueuedDatabase::removeTokens() +{ + QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate); + QSqlQuery query = m_database.exec( + QString("DELETE FROM %1 WHERE datetime(validUntil) > datetime(%2)") + .arg(QueuedDB::TOKENS_TABLE) + .arg(now)); + + QSqlError error = query.lastError(); + if (error.isValid()) + qCCritical(LOG_LIB) << "Could not remove tokens in table" + << "message" << error.text(); +} + + +/** + * @fn removeUsers + */ +void QueuedDatabase::removeUsers(const QDateTime &_lastLogin) +{ + qCDebug(LOG_LIB) << "Remove all users which logged older than" + << _lastLogin; + + QSqlQuery query = m_database.exec( + QString("DELETE FROM %1 WHERE datetime(lastLogin) < datetime(%2)") + .arg(QueuedDB::USERS_TABLE) + .arg(_lastLogin.toString(Qt::ISODate))); + + QSqlError error = query.lastError(); + if (error.isValid()) + qCCritical(LOG_LIB) << "Could not remove users in table" + << "message" << error.text(); +} + + /** * @fn createSchema */ diff --git a/sources/queued/src/QueuedProcess.cpp b/sources/queued/src/QueuedProcess.cpp index 14a9427..89c3678 100644 --- a/sources/queued/src/QueuedProcess.cpp +++ b/sources/queued/src/QueuedProcess.cpp @@ -37,7 +37,7 @@ extern "C" { * @fn QueuedProcess */ QueuedProcess::QueuedProcess(QObject *parent, - const QueuedProcessDefinitions definitions, + const QueuedProcessDefinitions &definitions, const long long index) : QProcess(parent) , m_definitions(definitions) diff --git a/sources/queued/src/QueuedProcessManager.cpp b/sources/queued/src/QueuedProcessManager.cpp index 9f5e291..b27ac4b 100644 --- a/sources/queued/src/QueuedProcessManager.cpp +++ b/sources/queued/src/QueuedProcessManager.cpp @@ -87,7 +87,7 @@ QueuedProcess *QueuedProcessManager::add(const QVariantHash &_properties, * @fn add */ QueuedProcess *QueuedProcessManager::add( - const QueuedProcess::QueuedProcessDefinitions _definitions, + const QueuedProcess::QueuedProcessDefinitions &_definitions, const long long _index) { qCDebug(LOG_LIB) << "Add new process" << _definitions.command @@ -117,13 +117,8 @@ void QueuedProcessManager::loadProcesses(const QList &_processes) { qCDebug(LOG_LIB) << "Add tasks from" << _processes; - for (auto &processData : _processes) { - if (static_cast( - processData[QString("state")].toUInt()) - == QueuedEnums::ProcessState::Exited) - continue; + for (auto &processData : _processes) add(processData, processData[QString("_id")].toLongLong()); - } } @@ -178,7 +173,7 @@ void QueuedProcessManager::remove(const long long _index) /** * @fn start */ - void QueuedProcessManager::start(const long long _index) +void QueuedProcessManager::start(const long long _index) { qCDebug(LOG_LIB) << "Start task" << _index; diff --git a/sources/queued/src/QueuedTokenManager.cpp b/sources/queued/src/QueuedTokenManager.cpp index 8be4061..ad27916 100644 --- a/sources/queued/src/QueuedTokenManager.cpp +++ b/sources/queued/src/QueuedTokenManager.cpp @@ -67,18 +67,16 @@ void QueuedTokenManager::loadTokens(const QList &_values) { qCDebug(LOG_LIB) << "Set values from" << _values; - QDateTime now = QDateTime::currentDateTimeUtc(); for (auto &token : _values) { QDateTime validUntil = QDateTime::fromString( token[QString("validUntil")].toString(), Qt::ISODate); - if (validUntil <= now) - continue; QString tokenId = token[QString("token")].toString(); m_tokens[tokenId] = validUntil; - QTimer::singleShot(validUntil.toMSecsSinceEpoch() - - now.toMSecsSinceEpoch(), - Qt::VeryCoarseTimer, - [this, tokenId]() { return expireToken(tokenId); }); + QTimer::singleShot( + validUntil.toMSecsSinceEpoch() + - QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(), + Qt::VeryCoarseTimer, + [this, tokenId]() { return expireToken(tokenId); }); } } diff --git a/sources/queued/src/QueuedUserManager.cpp b/sources/queued/src/QueuedUserManager.cpp index 3081ddc..6e890d3 100644 --- a/sources/queued/src/QueuedUserManager.cpp +++ b/sources/queued/src/QueuedUserManager.cpp @@ -124,24 +124,25 @@ QString QueuedUserManager::authorize(const QString &_user, /** * @fn authorize */ -bool QueuedUserManager::authorize(const QString &_user, const QString &_token, +bool QueuedUserManager::authorize(const UserAuthorization &_auth, const QueuedEnums::Permission _service) { - qCDebug(LOG_LIB) << "Authorize user" << _user << "for" + qCDebug(LOG_LIB) << "Authorize user" << _auth.user << "for" << static_cast(_service); - bool status = m_tokens->isTokenValid(_token); + bool status = m_tokens->isTokenValid(_auth.token); if (!status) { - qCInfo(LOG_LIB) << "Token invalid for user" << _user; + qCInfo(LOG_LIB) << "Token invalid for user" << _auth.user; return false; } - if (!m_users.contains(_user)) { - qCInfo(LOG_LIB) << "No user found" << _user; + auto userObj = user(_auth.user); + if (!userObj) { + qCInfo(LOG_LIB) << "No user found" << _auth.user; return false; } - return m_users[_user]->hasPermission(_service); + return userObj->hasPermission(_service); }