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
This commit is contained in:
2017-02-28 00:22:56 +03:00
parent 8ab4eb155c
commit 58787dc543
19 changed files with 637 additions and 249 deletions

View File

@ -30,6 +30,7 @@
#include "QueuedDatabase.h" #include "QueuedDatabase.h"
#include "QueuedDebug.h" #include "QueuedDebug.h"
#include "QueuedEnums.h" #include "QueuedEnums.h"
#include "QueuedExceptions.h"
#include "QueuedLimits.h" #include "QueuedLimits.h"
#include "QueuedProcess.h" #include "QueuedProcess.h"
#include "QueuedProcessManager.h" #include "QueuedProcessManager.h"

View File

@ -38,7 +38,8 @@ class QueuedAdvancedSettings : public QObject
public: public:
/** /**
* @brief QueuedAdvancedSettings class constructor * @brief QueuedAdvancedSettings class constructor
* @param parent pointer to parent item * @param parent
* pointer to parent item
*/ */
explicit QueuedAdvancedSettings(QObject *parent); explicit QueuedAdvancedSettings(QObject *parent);
/** /**
@ -47,29 +48,41 @@ public:
virtual ~QueuedAdvancedSettings(); virtual ~QueuedAdvancedSettings();
/** /**
* @brief get value * @brief get value
* @param _key key to search in * @param _key
* key to search in
* @return value by key if found * @return value by key if found
*/ */
QVariant get(const QString &_key) const; QVariant get(const QString &_key) const;
/** /**
* @brief get database value ID * @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 * @return database id or -1 if not found
*/ */
long long id(const QString &_key) const; long long id(const QString &_key) const;
/** /**
* @brief set value * @brief set value
* @param _key key to change * @param _key
* @param _value value to change * key to change
* @param _value
* value to change
*/ */
void set(const QString &_key, const QVariant &_value); void set(const QString &_key, const QVariant &_value);
/** /**
* @brief upload configuration from database in to internal format * @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<QVariantHash> &_values); void set(const QList<QVariantHash> &_values);
signals: signals:
/**
* @brief emits on each value update
* @param _key
* changed key
* @param _value
* changed value
*/
void valueUpdated(const QString &_key, const QVariant &_value); void valueUpdated(const QString &_key, const QVariant &_value);
private: private:

View File

@ -57,12 +57,18 @@ public:
virtual ~QueuedCore(); virtual ~QueuedCore();
/** /**
* @brief add new task * @brief add new task
* @param _command command line * @param _command
* @param _arguments command arguments * command line
* @param _workingDirectory working directory * @param _arguments
* @param _nice nice level * command arguments
* @param _userId task owner user ID * @param _workingDirectory
* @param _limits task defined limits * working directory
* @param _nice
* nice level
* @param _userId
* task owner user ID
* @param _limits
* task defined limits
* @return true on successfully addition * @return true on successfully addition
*/ */
bool addTask(const QString &_command, const QStringList &_arguments, bool addTask(const QString &_command, const QStringList &_arguments,
@ -70,31 +76,36 @@ public:
const long long _userId, const QueuedLimits::Limits &_limits); const long long _userId, const QueuedLimits::Limits &_limits);
/** /**
* @brief add new user * @brief add new user
* @param _name user name * @param _name
* @param _email user email * user name
* @param _password user password * @param _email
* @param _permissions user permissions * user email
* @param _limits user limits * @param _password
* user password
* @param _permissions
* user permissions
* @param _limits
* user limits
* @return true on successfully addition * @return true on successfully addition
*/ */
bool addUser(const QString &_name, const QString &_email, bool addUser(const QString &_name, const QString &_email,
const QString &_password, const unsigned int _permissions, const QString &_password, const unsigned int _permissions,
const QueuedLimits::Limits &_limits); const QueuedLimits::Limits &_limits);
/**
* @brief deinit subclasses
*/
void deinit();
/** /**
* @brief edit advanced settings * @brief edit advanced settings
* @param _key advanced settings key * @param _key
* @param _value advanced settings value * advanced settings key
* @param _value
* advanced settings value
* @return true on successful option edition * @return true on successful option edition
*/ */
bool editOption(const QString &_key, const QVariant &_value); bool editOption(const QString &_key, const QVariant &_value);
/** /**
* @brief edit task * @brief edit task
* @param _id task ID to edit * @param _id
* @param _taskData task data to edit * task ID to edit
* @param _taskData
* task data to edit
* @remark _taskData should contain only fields defined in schema, any other * @remark _taskData should contain only fields defined in schema, any other
* fields will be ignored. No need to pass all properties here * fields will be ignored. No need to pass all properties here
* @return true on successful task edition * @return true on successful task edition
@ -102,8 +113,10 @@ public:
bool editTask(const long long _id, const QVariantHash &_taskData); bool editTask(const long long _id, const QVariantHash &_taskData);
/** /**
* @brief edit user * @brief edit user
* @param _id user ID to edit * @param _id
* @param _userData user data to edit * user ID to edit
* @param _userData
* user data to edit
* @remark _userData should contain only fields defined in schema, any other * @remark _userData should contain only fields defined in schema, any other
* fields will be ignored. No need to pass all properties here * fields will be ignored. No need to pass all properties here
* @return true on successful user edition * @return true on successful user edition
@ -111,39 +124,56 @@ public:
bool editUser(const long long _id, const QVariantHash &_userData); bool editUser(const long long _id, const QVariantHash &_userData);
/** /**
* @brief edit user permissions * @brief edit user permissions
* @param _id user ID to edit * @param _id
* @param _permission permission to add or remove * user ID to edit
* @param _add indicates whether it should be added or removed * @param _permission
* permission to add or remove
* @param _add
* indicates whether it should be added or removed
* @return true on successful user permission edition * @return true on successful user permission edition
*/ */
bool editUserPermission(const long long _id, bool editUserPermission(const long long _id,
const QueuedEnums::Permission &_permission, const QueuedEnums::Permission &_permission,
const bool _add); const bool _add);
// control methods
/**
* @brief deinit subclasses
*/
void deinit();
/** /**
* @brief init subclasses * @brief init subclasses
* @param _configuration path to configuration file * @param _configuration
* path to configuration file
* @throws QueuedDatabaseException
*/ */
void init(const QString &_configuration); void init(const QString &_configuration);
private slots: private slots:
/** /**
* @brief notify clients about settings update * @brief notify clients about settings update
* @param _key updated key * @param _key
* @param _value new value * updated key
* @param _value
* new value
*/ */
void updateSettings(const QString &_key, const QVariant &_value); void updateSettings(const QString &_key, const QVariant &_value);
/** /**
* @brief update process time * @brief update process time
* @param _id task id * @param _id
* @param _startTime task start time or empty * task id
* @param _endTime task end time or empty * @param _startTime
* task start time or empty
* @param _endTime
* task end time or empty
*/ */
void updateTaskTime(const long long _id, const QDateTime &_startTime, void updateTaskTime(const long long _id, const QDateTime &_startTime,
const QDateTime &_endTime); const QDateTime &_endTime);
/** /**
* @brief update user login time * @brief update user login time
* @param _id user ID * @param _id
* @param _time user login time * user ID
* @param _time
* user login time
*/ */
void updateUserLoginTime(const long long _id, const QDateTime &_time); void updateUserLoginTime(const long long _id, const QDateTime &_time);
@ -177,6 +207,20 @@ private:
* @brief connection list * @brief connection list
*/ */
QList<QMetaObject::Connection> m_connections; QList<QMetaObject::Connection> 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();
}; };

View File

@ -40,9 +40,12 @@ class QueuedDatabase : public QObject
public: public:
/** /**
* @brief QueuedDatabase class constructor * @brief QueuedDatabase class constructor
* @param parent pointer to parent item * @param parent
* @param path path to database * pointer to parent item
* @param driver database driver * @param path
* path to database
* @param driver
* database driver
*/ */
explicit QueuedDatabase(QObject *parent, const QString path, explicit QueuedDatabase(QObject *parent, const QString path,
const QString driver); const QString driver);
@ -56,34 +59,44 @@ public:
void checkDatabase(); void checkDatabase();
/** /**
* @brief check and create queued administrator if missing * @brief check and create queued administrator if missing
* @param _user administrator username * @param _user
* @param _password administrator password SHA512 * administrator username
* @param _password
* administrator password SHA512
*/ */
void createAdministrator(const QString &_user, const QString &_password); void createAdministrator(const QString &_user, const QString &_password);
/** /**
* @brief get all records from table * @brief get all records from table
* @param _table table name * @param _table
* @param _condition optional condition string * table name
* @param _condition
* optional condition string
* @return list of records from table * @return list of records from table
*/ */
QList<QVariantHash> get(const QString &_table, QList<QVariantHash> get(const QString &_table,
const QString &_condition = QString()); const QString &_condition = QString());
/** /**
* @brief get record from table with given id * @brief get record from table with given id
* @param _table table name * @param _table
* @param _id record id * table name
* @param _id
* record id
* @return variant map from table * @return variant map from table
*/ */
QVariantHash get(const QString &_table, const long long _id); QVariantHash get(const QString &_table, const long long _id);
/** /**
* @brief open database * @brief open database
* @param _hostname hostname to connect, may be empty * @param _hostname
* @param _port port to connect, may be 0 * hostname to connect, may be empty
* @param _username username to connect, may be empty * @param _port
* @param _password password to connect, will be ignored if _username * port to connect, may be 0
* is empty * @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); const QString &_username, const QString &_password);
/** /**
* @brief path to database * @brief path to database
@ -94,20 +107,50 @@ public:
public slots: public slots:
/** /**
* @brief add record to database * @brief add record to database
* @param _table table name * @param _table
* @param _value value to insert * table name
* @param _value
* value to insert
* @return index of inserted record or -1 if no insertion * @return index of inserted record or -1 if no insertion
*/ */
long long add(const QString &_table, const QVariantHash &_value); long long add(const QString &_table, const QVariantHash &_value);
/** /**
* @brief modify record in table * @brief modify record in table
* @param _table table name * @param _table
* @param _id id for search * table name
* @param _value value to update * @param _id
* id for search
* @param _value
* value to update
* @return true on successfully modification * @return true on successfully modification
*/ */
bool modify(const QString &_table, const long long _id, bool modify(const QString &_table, const long long _id,
const QVariantHash &_value); 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: private:
/** /**
@ -120,32 +163,39 @@ private:
QString m_path; QString m_path;
/** /**
* @brief create or update actual schema in table * @brief create or update actual schema in table
* @param _table table name * @param _table
* table name
*/ */
void createSchema(const QString &_table); void createSchema(const QString &_table);
/** /**
* @brief create given table * @brief create given table
* @param _table table name * @param _table
* table name
*/ */
void createTable(const QString &_table); void createTable(const QString &_table);
/** /**
* @brief additional function to get column numbers from table * @brief additional function to get column numbers from table
* @param _columns columns mapping * @param _columns
* @param _record SQL record from query * columns mapping
* @param _record
* SQL record from query
* @return map of column names to their numbers * @return map of column names to their numbers
*/ */
QHash<QString, int> getColumnsInRecord(const QStringList &_columns, QHash<QString, int> getColumnsInRecord(const QStringList &_columns,
const QSqlRecord &_record) const; const QSqlRecord &_record) const;
/** /**
* @brief last insertion ID * @brief last insertion ID
* @param _table table name * @param _table
* table name
* @return last insertion id from table * @return last insertion id from table
*/ */
long long lastInsertionId(const QString &_table) const; long long lastInsertionId(const QString &_table) const;
/** /**
* @brief additional function to get payload for query * @brief additional function to get payload for query
* @param _table table name for search * @param _table
* @param _value value to build payload * table name for search
* @param _value
* value to build payload
* @return list of keys and list of values * @return list of keys and list of values
*/ */
QPair<QStringList, QStringList> QPair<QStringList, QStringList>

View File

@ -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 <QException>
/**
* @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 */

View File

@ -82,7 +82,8 @@ struct Limits {
, valid(false){}; , valid(false){};
/** /**
* @brief structure constructor from string representation * @brief structure constructor from string representation
* @param _stringLimits limits string representation * @param _stringLimits
* limits string representation
*/ */
Limits(const QString &_stringLimits) Limits(const QString &_stringLimits)
{ {
@ -101,25 +102,32 @@ struct Limits {
/** /**
* @ingroup QueuedLimits * @ingroup QueuedLimits
* @brief convert QString memory value to integer * @brief convert QString memory value to integer
* @param _value value to convert * @param _value
* @param _status conversion status * value to convert
* @param _status
* conversion status
* @return converted integer * @return converted integer
*/ */
long long convertMemory(QString _value, bool *_status); long long convertMemory(QString _value, bool *_status);
/** /**
* @ingroup QueuedLimits * @ingroup QueuedLimits
* @brief compare two limits * @brief compare two limits
* @param _first first limit * @param _first
* @param _second second limit * first limit
* @param _second
* second limit
* @return true if first limit is less than second * @return true if first limit is less than second
*/ */
bool limitCompare(const long long _first, const long long _second); bool limitCompare(const long long _first, const long long _second);
/** /**
* @ingroup QueuedLimits * @ingroup QueuedLimits
* @brief get minimal limits from given * @brief get minimal limits from given
* @param _task task defined limits * @param _task
* @param _user user defined limit * task defined limits
* @param _default default limits if anu * @param _user
* user defined limit
* @param _default
* default limits if anu
* @return minimal limits from given * @return minimal limits from given
*/ */
Limits minimalLimits(const Limits &_task, const Limits &_user, Limits minimalLimits(const Limits &_task, const Limits &_user,

View File

@ -96,12 +96,15 @@ public:
/** /**
* @brief QueuedProcess class constructor * @brief QueuedProcess class constructor
* @param parent pointer to parent item * @param parent
* @param definitions definitions of process * pointer to parent item
* @param index index of process * @param definitions
* definitions of process
* @param index
* index of process
*/ */
explicit QueuedProcess(QObject *parent, explicit QueuedProcess(QObject *parent,
const QueuedProcessDefinitions definitions, const QueuedProcessDefinitions &definitions,
const long long index); const long long index);
/** /**
* @brief QueuedProcess class destructor * @brief QueuedProcess class destructor
@ -180,57 +183,68 @@ public:
void setCommand(const QString &_command); void setCommand(const QString &_command);
/** /**
* @brief set command line arguments * @brief set command line arguments
* @param _commandArguments new command line arguments * @param _commandArguments
* new command line arguments
*/ */
void setCommandArguments(const QStringList &_commandArguments); void setCommandArguments(const QStringList &_commandArguments);
/** /**
* @brief set end time * @brief set end time
* @param _time process end time * @param _time
* process end time
*/ */
void setEndTime(const QDateTime &_time); void setEndTime(const QDateTime &_time);
/** /**
* @brief set process GID * @brief set process GID
* @param _gid new process GID * @param _gid
* new process GID
*/ */
void setGid(const unsigned int _gid); void setGid(const unsigned int _gid);
/** /**
* @brief set process limits * @brief set process limits
* @param _limits new process limits * @param _limits
* new process limits
*/ */
void setLimits(const QueuedLimits::Limits &_limits); void setLimits(const QueuedLimits::Limits &_limits);
/** /**
* @brief set process nice * @brief set process nice
* @param _nice new process nice * @param _nice
* new process nice
*/ */
void setNice(const unsigned int _nice); void setNice(const unsigned int _nice);
/** /**
* @brief set process state * @brief set process state
* @param _limits new process state * @param _limits
* new process state
*/ */
void setPState(const QueuedEnums::ProcessState _state); void setPState(const QueuedEnums::ProcessState _state);
/** /**
* @brief set start time * @brief set start time
* @param _time process start time * @param _time
* process start time
*/ */
void setStartTime(const QDateTime &_time); void setStartTime(const QDateTime &_time);
/** /**
* @brief set process UID * @brief set process UID
* @param _uid new process UID * @param _uid
* new process UID
*/ */
void setUid(const unsigned int _uid); void setUid(const unsigned int _uid);
/** /**
* @brief set user ID * @brief set user ID
* @param _user new user ID * @param _user
* new user ID
*/ */
void setUser(const long long _user); void setUser(const long long _user);
/** /**
* @brief set working directory * @brief set working directory
* @param _workDirectory new process working directory * @param _workDirectory
* new process working directory
*/ */
void setWorkDirectory(const QString &_workDirectory); void setWorkDirectory(const QString &_workDirectory);
/** /**
* @brief equal operator implementation * @brief equal operator implementation
* @param _other other object * @param _other
* other object
* @return true if objects are equal * @return true if objects are equal
*/ */
bool operator==(const QueuedProcess &_other); bool operator==(const QueuedProcess &_other);

View File

@ -64,8 +64,10 @@ public:
/** /**
* @brief QueuedProcessManager class constructor * @brief QueuedProcessManager class constructor
* @param parent pointer to parent item * @param parent
* @param onExit default action on exit * pointer to parent item
* @param onExit
* default action on exit
*/ */
explicit QueuedProcessManager(QObject *parent, const OnExitAction onExit); explicit QueuedProcessManager(QObject *parent, const OnExitAction onExit);
/** /**
@ -74,28 +76,34 @@ public:
virtual ~QueuedProcessManager(); virtual ~QueuedProcessManager();
/** /**
* @brief add task * @brief add task
* @param _properties task properties from database * @param _properties
* @param _index task index * task properties from database
* @param _index
* task index
* @return pointer to created task * @return pointer to created task
*/ */
QueuedProcess *add(const QVariantHash &_properties, const long long _index); QueuedProcess *add(const QVariantHash &_properties, const long long _index);
/** /**
* @brief add task * @brief add task
* @param _definitions process definitions * @param _definitions
* @param _index task index * process definitions
* @param _index
* task index
* @return pointer to created task * @return pointer to created task
*/ */
QueuedProcess * QueuedProcess *
add(const QueuedProcess::QueuedProcessDefinitions _definitions, add(const QueuedProcess::QueuedProcessDefinitions &_definitions,
const long long _index); const long long _index);
/** /**
* @brief add tasks from database * @brief add tasks from database
* @param _processes database stored tasks * @param _processes
* database stored tasks
*/ */
void loadProcesses(const QList<QVariantHash> &_processes); void loadProcesses(const QList<QVariantHash> &_processes);
/** /**
* @brief task * @brief task
* @param _index task index * @param _index
* task index
* @return task found by index or nullptr * @return task found by index or nullptr
*/ */
QueuedProcess *process(const long long _index); QueuedProcess *process(const long long _index);
@ -106,17 +114,20 @@ public:
QueuedProcessMap processes(); QueuedProcessMap processes();
/** /**
* @brief remove task from list * @brief remove task from list
* @param _index task index * @param _index
* task index
*/ */
void remove(const long long _index); void remove(const long long _index);
/** /**
* @brief force start task * @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 * @brief force stop task
* @param _index task index * @param _index
* task index
*/ */
void stop(const long long _index); void stop(const long long _index);
// properties // properties
@ -127,30 +138,38 @@ public:
OnExitAction onExit() const; OnExitAction onExit() const;
/** /**
* @brief set on exit action * @brief set on exit action
* @param _action new on exit action * @param _action
* new on exit action
*/ */
void setOnExitAction(const OnExitAction _action); void setOnExitAction(const OnExitAction _action);
signals: signals:
/** /**
* @brief signal which will be called on task start * @brief signal which will be called on task start
* @param _index task index * @param _index
* @param _time task start time * task index
* @param _time
* task start time
*/ */
void taskStartTimeReceived(const long long _index, const QDateTime &_time); void taskStartTimeReceived(const long long _index, const QDateTime &_time);
/** /**
* @brief signal which will be called on task end * @brief signal which will be called on task end
* @param _index task index * @param _index
* @param _time task stop time * task index
* @param _time
* task stop time
*/ */
void taskStopTimeReceived(const long long _index, const QDateTime &_time); void taskStopTimeReceived(const long long _index, const QDateTime &_time);
private slots: private slots:
/** /**
* @brief slot for catching finished tasks * @brief slot for catching finished tasks
* @param _exitCode exit code of finished task * @param _exitCode
* @param _exitStatus exit status of finished task * exit code of finished task
* @param _index index of finished task * @param _exitStatus
* exit status of finished task
* @param _index
* index of finished task
*/ */
void taskFinished(const int _exitCode, void taskFinished(const int _exitCode,
const QProcess::ExitStatus _exitStatus, const QProcess::ExitStatus _exitStatus,

View File

@ -39,8 +39,10 @@ class QueuedReportManager : public QObject
public: public:
/** /**
* @brief QueuedReportManager class constructor * @brief QueuedReportManager class constructor
* @param parent pointer to parent item * @param parent
* @param database pointer to database object * pointer to parent item
* @param database
* pointer to database object
*/ */
explicit QueuedReportManager(QObject *parent, QueuedDatabase *database); explicit QueuedReportManager(QObject *parent, QueuedDatabase *database);
/** /**

View File

@ -42,8 +42,10 @@ class QueuedSettings : public QObject
public: public:
/** /**
* @brief QueuedSettings class constructor * @brief QueuedSettings class constructor
* @param parent pointer to parent item * @param parent
* @param path path to configuration file * pointer to parent item
* @param path
* path to configuration file
*/ */
explicit QueuedSettings(QObject *parent, const QString path); explicit QueuedSettings(QObject *parent, const QString path);
/** /**

View File

@ -38,7 +38,8 @@ class QueuedTokenManager : public QObject
public: public:
/** /**
* @brief QueuedTokenManager class constructor * @brief QueuedTokenManager class constructor
* @param parent pointer to parent item * @param parent
* pointer to parent item
*/ */
explicit QueuedTokenManager(QObject *parent); explicit QueuedTokenManager(QObject *parent);
/** /**
@ -47,18 +48,21 @@ public:
virtual ~QueuedTokenManager(); virtual ~QueuedTokenManager();
/** /**
* @brief check if token is valid * @brief check if token is valid
* @param _token token ID * @param _token
* token ID
* @return true if token is valid otherwise return false * @return true if token is valid otherwise return false
*/ */
bool isTokenValid(const QString &_token); bool isTokenValid(const QString &_token);
/** /**
* @brief upload tokens from database * @brief upload tokens from database
* @param _value tokens from database * @param _value
* tokens from database
*/ */
void loadTokens(const QList<QVariantHash> &_values); void loadTokens(const QList<QVariantHash> &_values);
/** /**
* @brief register new token * @brief register new token
* @param _validUntil token valid until * @param _validUntil
* token valid until
* @return new generated token * @return new generated token
*/ */
QString registerToken(const QDateTime _validUntil); QString registerToken(const QDateTime _validUntil);
@ -66,20 +70,24 @@ public:
public slots: public slots:
/** /**
* @brief method which will be called on token expiring * @brief method which will be called on token expiring
* @param _token expired token ID * @param _token
* expired token ID
*/ */
void expireToken(const QString &_token); void expireToken(const QString &_token);
signals: signals:
/** /**
* @brief signal which will be emitted on token expiration * @brief signal which will be emitted on token expiration
* @param _token token ID * @param _token
* token ID
*/ */
void tokenExpired(const QString &_token); void tokenExpired(const QString &_token);
/** /**
* @brief signal which will be emitted on newly created token * @brief signal which will be emitted on newly created token
* @param _token token ID * @param _token
* @param _validUntil token valid until * token ID
* @param _validUntil
* token valid until
*/ */
void tokenRegistered(const QString &_token, const QDateTime &_validUntil); void tokenRegistered(const QString &_token, const QDateTime &_validUntil);

View File

@ -71,9 +71,12 @@ public:
/** /**
* @brief QueuedUser class constructor * @brief QueuedUser class constructor
* @param parent pointer to parent item * @param parent
* @param definitions definitions of user * pointer to parent item
* @param index index of process * @param definitions
* definitions of user
* @param index
* index of process
*/ */
explicit QueuedUser(QObject *parent, explicit QueuedUser(QObject *parent,
const QueuedUserDefinitions &definitions, const QueuedUserDefinitions &definitions,
@ -85,20 +88,23 @@ public:
// methods // methods
/** /**
* @brief add permissions to user * @brief add permissions to user
* @param _permissions new user permissions * @param _permissions
* new user permissions
* @return current user permissions * @return current user permissions
*/ */
QueuedEnums::Permissions QueuedEnums::Permissions
addPermissions(const QueuedEnums::Permissions _permissions); addPermissions(const QueuedEnums::Permissions _permissions);
/** /**
* @brief generates SHA512 hash from given password * @brief generates SHA512 hash from given password
* @param _password password as string * @param _password
* password as string
* @return SHA512 of password * @return SHA512 of password
*/ */
static QString hashFromPassword(const QString &_password); static QString hashFromPassword(const QString &_password);
/** /**
* @brief test user permissions * @brief test user permissions
* @param _permission permission to test * @param _permission
* permission to test
* @return true if user has permission otherwise return false * @return true if user has permission otherwise return false
*/ */
bool hasPermission(const QueuedEnums::Permission _permission); bool hasPermission(const QueuedEnums::Permission _permission);
@ -109,13 +115,15 @@ public:
QPair<unsigned int, unsigned int> ids(); QPair<unsigned int, unsigned int> ids();
/** /**
* @brief check if password is valid * @brief check if password is valid
* @param _password password as string * @param _password
* password as string
* @return true if password matches stored hash * @return true if password matches stored hash
*/ */
bool isPasswordValid(const QString &_password) const; bool isPasswordValid(const QString &_password) const;
/** /**
* @brief remove permissions from user * @brief remove permissions from user
* @param _permissions permissions to remove * @param _permissions
* permissions to remove
* @return current user permissions * @return current user permissions
*/ */
QueuedEnums::Permissions QueuedEnums::Permissions
@ -155,33 +163,39 @@ public:
// main properties // main properties
/** /**
* @brief set user email * @brief set user email
* @param _email new user email * @param _email
* new user email
*/ */
void setEmail(const QString _email); void setEmail(const QString _email);
/** /**
* @brief set username * @brief set username
* @param _name new user name * @param _name
* new user name
*/ */
void setName(const QString _name); void setName(const QString _name);
/** /**
* @brief set user password * @brief set user password
* @param _password new user password * @param _password
* new user password
*/ */
void setPassword(const QString _password); void setPassword(const QString _password);
/** /**
* @brief set user permissions * @brief set user permissions
* @param _permissions new user permissions * @param _permissions
* new user permissions
*/ */
void setPermissions(const unsigned int _permissions); void setPermissions(const unsigned int _permissions);
// permissions // permissions
/** /**
* @brief set limits * @brief set limits
* @param _limit new user limits * @param _limit
* new user limits
*/ */
void setLimits(const QueuedLimits::Limits &_limits); void setLimits(const QueuedLimits::Limits &_limits);
/** /**
* @brief equal operator implementation * @brief equal operator implementation
* @param _other other object * @param _other
* other object
* @return true if objects are equal * @return true if objects are equal
*/ */
bool operator==(const QueuedUser &_other); bool operator==(const QueuedUser &_other);

View File

@ -43,9 +43,24 @@ class QueuedUserManager : public QObject
long long tokenExpiration READ tokenExpiration WRITE setTokenExpiration) long long tokenExpiration READ tokenExpiration WRITE setTokenExpiration)
public: 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 * @brief QueuedUserManager class constructor
* @param parent pointer to parent item * @param parent
* pointer to parent item
*/ */
explicit QueuedUserManager(QObject *parent); explicit QueuedUserManager(QObject *parent);
/** /**
@ -54,60 +69,72 @@ public:
virtual ~QueuedUserManager(); virtual ~QueuedUserManager();
/** /**
* @brief add user * @brief add user
* @param _properties user properties from database * @param _properties
* @param _id user ID * user properties from database
* @param _id
* user ID
* @return pointer to created user * @return pointer to created user
*/ */
QueuedUser *add(const QVariantHash &_properties, const long long _id); QueuedUser *add(const QVariantHash &_properties, const long long _id);
/** /**
* @brief add user * @brief add user
* @param _definitions user definitions * @param _definitions
* @param _id user ID * user definitions
* @param _id
* user ID
* @return pointer to created user * @return pointer to created user
*/ */
QueuedUser *add(const QueuedUser::QueuedUserDefinitions &_definitions, QueuedUser *add(const QueuedUser::QueuedUserDefinitions &_definitions,
const long long _id); const long long _id);
/** /**
* @brief authorize user * @brief authorize user
* @param _user user name * @param _user
* @param _password user password * user name
* @return generated tokens 0r empty string if it is not valid * @param _password
* user password
* @return generated tokens or empty string if it is not valid
*/ */
QString authorize(const QString &_user, const QString &_password); QString authorize(const QString &_user, const QString &_password);
/** /**
* @brief authorize user for service * @brief authorize user for service
* @param _user user name * @param _auth
* @param _token token ID * user authorization structure
* @param _service service to authorize * @param _service
* service to authorize
* @return true if user allowed to do it otherwise return false * @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); const QueuedEnums::Permission _service);
/** /**
* @brief get UID and GID from user ID * @brief get UID and GID from user ID
* @param _id user id * @param _id
* user id
* @return pair of {uid, gid} * @return pair of {uid, gid}
*/ */
QPair<unsigned int, unsigned int> ids(const long long _id); QPair<unsigned int, unsigned int> ids(const long long _id);
/** /**
* @brief load tokens * @brief load tokens
* @param _tokens tokens list from database * @param _tokens
* tokens list from database
*/ */
void loadTokens(const QList<QVariantHash> &_tokens); void loadTokens(const QList<QVariantHash> &_tokens);
/** /**
* @brief load users * @brief load users
* @param _users users list from database * @param _users
* users list from database
*/ */
void loadUsers(const QList<QVariantHash> &_users); void loadUsers(const QList<QVariantHash> &_users);
/** /**
* @brief user by ID * @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 * @return user by id or nullptr if no user found
*/ */
QueuedUser *user(const long long _id); QueuedUser *user(const long long _id);
/** /**
* @brief user by name * @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 * @return user by name or nullptr if no user found
*/ */
QueuedUser *user(const QString &_name); QueuedUser *user(const QString &_name);
@ -119,15 +146,18 @@ public:
long long tokenExpiration() const; long long tokenExpiration() const;
/** /**
* @brief set token expiration * @brief set token expiration
* @param _expiry token expiration in days * @param _expiry
* token expiration in days
*/ */
void setTokenExpiration(const long long &_expiry); void setTokenExpiration(const long long &_expiry);
signals: signals:
/** /**
* @brief signal which emits on each user successfully login * @brief signal which emits on each user successfully login
* @param _id user ID * @param _id
* @param _time user login time * user ID
* @param _time
* user login time
*/ */
void userLoggedIn(const long long _id, const QDateTime &_time); void userLoggedIn(const long long _id, const QDateTime &_time);

View File

@ -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 * @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 * @fn init
*/ */
@ -279,49 +279,10 @@ void QueuedCore::init(const QString &_configuration)
// deinit objects if any // deinit objects if any
deinit(); deinit();
// read configuration first // init parts
m_settings = new QueuedSettings(this, _configuration); initSettings(_configuration);
// init database now initUsers();
auto dbSetup = m_settings->db(); initProcesses();
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<QueuedProcessManager::OnExitAction>(
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);
});
// settings update notifier // settings update notifier
m_connections += connect( m_connections += connect(
@ -388,3 +349,85 @@ void QueuedCore::updateUserLoginTime(const long long _id,
if (!status) if (!status)
qCWarning(LOG_LIB) << "Could not modify user record" << _id; qCWarning(LOG_LIB) << "Could not modify user record" << _id;
} }
/**
* @fn initProcesses
*/
void QueuedCore::initProcesses()
{
// init processes
auto onExitAction = static_cast<QueuedProcessManager::OnExitAction>(
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<int>(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 &)));
}

View File

@ -161,7 +161,7 @@ QVariantHash QueuedDatabase::get(const QString &_table, const long long _id)
/** /**
* @fn open * @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) const QString &_username, const QString &_password)
{ {
qCDebug(LOG_LIB) << "Open database at" << _hostname << _port << "as user" 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; qCDebug(LOG_LIB) << "Open database status" << status;
if (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 * @fn createSchema
*/ */

View File

@ -37,7 +37,7 @@ extern "C" {
* @fn QueuedProcess * @fn QueuedProcess
*/ */
QueuedProcess::QueuedProcess(QObject *parent, QueuedProcess::QueuedProcess(QObject *parent,
const QueuedProcessDefinitions definitions, const QueuedProcessDefinitions &definitions,
const long long index) const long long index)
: QProcess(parent) : QProcess(parent)
, m_definitions(definitions) , m_definitions(definitions)

View File

@ -87,7 +87,7 @@ QueuedProcess *QueuedProcessManager::add(const QVariantHash &_properties,
* @fn add * @fn add
*/ */
QueuedProcess *QueuedProcessManager::add( QueuedProcess *QueuedProcessManager::add(
const QueuedProcess::QueuedProcessDefinitions _definitions, const QueuedProcess::QueuedProcessDefinitions &_definitions,
const long long _index) const long long _index)
{ {
qCDebug(LOG_LIB) << "Add new process" << _definitions.command qCDebug(LOG_LIB) << "Add new process" << _definitions.command
@ -117,13 +117,8 @@ void QueuedProcessManager::loadProcesses(const QList<QVariantHash> &_processes)
{ {
qCDebug(LOG_LIB) << "Add tasks from" << _processes; qCDebug(LOG_LIB) << "Add tasks from" << _processes;
for (auto &processData : _processes) { for (auto &processData : _processes)
if (static_cast<QueuedEnums::ProcessState>(
processData[QString("state")].toUInt())
== QueuedEnums::ProcessState::Exited)
continue;
add(processData, processData[QString("_id")].toLongLong()); add(processData, processData[QString("_id")].toLongLong());
}
} }
@ -178,7 +173,7 @@ void QueuedProcessManager::remove(const long long _index)
/** /**
* @fn start * @fn start
*/ */
void QueuedProcessManager::start(const long long _index) void QueuedProcessManager::start(const long long _index)
{ {
qCDebug(LOG_LIB) << "Start task" << _index; qCDebug(LOG_LIB) << "Start task" << _index;

View File

@ -67,16 +67,14 @@ void QueuedTokenManager::loadTokens(const QList<QVariantHash> &_values)
{ {
qCDebug(LOG_LIB) << "Set values from" << _values; qCDebug(LOG_LIB) << "Set values from" << _values;
QDateTime now = QDateTime::currentDateTimeUtc();
for (auto &token : _values) { for (auto &token : _values) {
QDateTime validUntil = QDateTime::fromString( QDateTime validUntil = QDateTime::fromString(
token[QString("validUntil")].toString(), Qt::ISODate); token[QString("validUntil")].toString(), Qt::ISODate);
if (validUntil <= now)
continue;
QString tokenId = token[QString("token")].toString(); QString tokenId = token[QString("token")].toString();
m_tokens[tokenId] = validUntil; m_tokens[tokenId] = validUntil;
QTimer::singleShot(validUntil.toMSecsSinceEpoch() QTimer::singleShot(
- now.toMSecsSinceEpoch(), validUntil.toMSecsSinceEpoch()
- QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(),
Qt::VeryCoarseTimer, Qt::VeryCoarseTimer,
[this, tokenId]() { return expireToken(tokenId); }); [this, tokenId]() { return expireToken(tokenId); });
} }

View File

@ -124,24 +124,25 @@ QString QueuedUserManager::authorize(const QString &_user,
/** /**
* @fn authorize * @fn authorize
*/ */
bool QueuedUserManager::authorize(const QString &_user, const QString &_token, bool QueuedUserManager::authorize(const UserAuthorization &_auth,
const QueuedEnums::Permission _service) const QueuedEnums::Permission _service)
{ {
qCDebug(LOG_LIB) << "Authorize user" << _user << "for" qCDebug(LOG_LIB) << "Authorize user" << _auth.user << "for"
<< static_cast<int>(_service); << static_cast<int>(_service);
bool status = m_tokens->isTokenValid(_token); bool status = m_tokens->isTokenValid(_auth.token);
if (!status) { if (!status) {
qCInfo(LOG_LIB) << "Token invalid for user" << _user; qCInfo(LOG_LIB) << "Token invalid for user" << _auth.user;
return false; return false;
} }
if (!m_users.contains(_user)) { auto userObj = user(_auth.user);
qCInfo(LOG_LIB) << "No user found" << _user; if (!userObj) {
qCInfo(LOG_LIB) << "No user found" << _auth.user;
return false; return false;
} }
return m_users[_user]->hasPermission(_service); return userObj->hasPermission(_service);
} }