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 "QueuedDebug.h"
#include "QueuedEnums.h"
#include "QueuedExceptions.h"
#include "QueuedLimits.h"
#include "QueuedProcess.h"
#include "QueuedProcessManager.h"

View File

@ -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<QVariantHash> &_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:

View File

@ -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<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:
/**
* @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<QVariantHash> 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<QString, int> 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<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){};
/**
* @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,

View File

@ -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);

View File

@ -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<QVariantHash> &_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,

View File

@ -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);
/**

View File

@ -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);
/**

View File

@ -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<QVariantHash> &_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);

View File

@ -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<unsigned int, unsigned int> 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);

View File

@ -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<unsigned int, unsigned int> ids(const long long _id);
/**
* @brief load tokens
* @param _tokens tokens list from database
* @param _tokens
* tokens list from database
*/
void loadTokens(const QList<QVariantHash> &_tokens);
/**
* @brief load users
* @param _users users list from database
* @param _users
* users list from database
*/
void loadUsers(const QList<QVariantHash> &_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);

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
*/
@ -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<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);
});
// 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<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
*/
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
*/

View File

@ -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)

View File

@ -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<QVariantHash> &_processes)
{
qCDebug(LOG_LIB) << "Add tasks from" << _processes;
for (auto &processData : _processes) {
if (static_cast<QueuedEnums::ProcessState>(
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;

View File

@ -67,18 +67,16 @@ void QueuedTokenManager::loadTokens(const QList<QVariantHash> &_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); });
}
}

View File

@ -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<int>(_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);
}