add demo application

This commit is contained in:
Evgenii Alekseev 2017-03-05 03:20:09 +03:00
parent 6646400027
commit 84b8632ae8
30 changed files with 906 additions and 123 deletions

View File

@ -72,9 +72,10 @@ include(cppcheck.cmake)
include(paths.cmake) include(paths.cmake)
get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS) get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS)
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h) configure_file("${CMAKE_SOURCE_DIR}/version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/version.h")
add_subdirectory(queued) add_subdirectory("queued")
add_subdirectory("queued-daemon")
if (BUILD_TESTING) if (BUILD_TESTING)
enable_testing() enable_testing()
add_subdirectory(test) add_subdirectory("test")
endif () endif ()

View File

@ -0,0 +1,13 @@
# set project name
set (SUBPROJECT "queued-daemon")
message (STATUS "Subproject ${SUBPROJECT}")
add_subdirectory ("src")
# build man
file (GLOB SUBPROJECT_MAN_IN "*.1")
file (RELATIVE_PATH SUBPROJECT_MAN "${CMAKE_SOURCE_DIR}" "${SUBPROJECT_MAN_IN}")
configure_file ("${SUBPROJECT_MAN_IN}" "${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_MAN}")
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_MAN}" DESTINATION "${DATA_INSTALL_DIR}/man/man1")
install (FILES "bash-completions" DESTINATION "${DATA_INSTALL_DIR}/bash-completion/completions" RENAME "${SUBPROJECT}")
install (FILES "zsh-completions" DESTINATION "${DATA_INSTALL_DIR}/zsh/site-functions" RENAME "_${SUBPROJECT}")

View File

View File

View File

@ -0,0 +1,11 @@
[Administrator]
Username = root
Password = 0dd3e512642c97ca3f747f9a76e374fbda73f9292823c0313be9d78add7cdd8f72235af0c553dd26797e78e1854edee0ae002f8aba074b066dfce1af114e32f8
[Database]
Driver = QSQLITE
Hostname =
Password =
Path = /tmp/queued.db
Port =
Username =

View File

@ -0,0 +1,18 @@
# set files
file (GLOB_RECURSE SUBPROJECT_SOURCES "*.cpp")
file (GLOB_RECURSE SUBPROJECT_HEADERS "*.h")
# include_path
include_directories ("${PROJECT_LIBRARY_DIR}/include"
"${CMAKE_CURRENT_BINARY_DIR}"
"${CMAKE_BINARY_DIR}"
"${PROJECT_TRDPARTY_DIR}"
"${Qt_INCLUDE}")
qt5_wrap_cpp (SUBPROJECT_MOC_SOURCES "${SUBPROJECT_HEADERS}")
add_executable ("${SUBPROJECT}" "${SUBPROJECT_HEADERS}" "${SUBPROJECT_SOURCES}"
"${SUBPROJECT_MOC_SOURCES}")
target_link_libraries ("${SUBPROJECT}" "${PROJECT_LIBRARY}" "${Qt_LIBRARIES}")
# install properties
install (TARGETS "${SUBPROJECT}" DESTINATION "${BIN_INSTALL_DIR}")

View File

@ -0,0 +1,87 @@
/*
* 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.
*/
#include "QueuedApplication.h"
#include <QDBusConnection>
#include <QDBusMessage>
#include "queued/Queued.h"
#include "QueuedApplicationInterface.h"
QueuedApplication::QueuedApplication(QObject *parent, const QVariantHash &args)
: QObject(parent)
, m_configuration(args)
{
qSetMessagePattern(QueuedDebug::LOG_FORMAT);
qCDebug(LOG_APP) << __PRETTY_FUNCTION__;
for (auto &metadata : QueuedDebug::getBuildData())
qCDebug(LOG_APP) << metadata;
init();
}
QueuedApplication::~QueuedApplication()
{
qCDebug(LOG_APP) << __PRETTY_FUNCTION__;
deinit();
}
void QueuedApplication::deinit()
{
QDBusConnection::sessionBus().unregisterObject(
QueuedConfig::DBUS_APPLICATION_PATH);
if (m_core)
delete m_core;
}
void QueuedApplication::init()
{
deinit();
initCore();
initDBus();
}
void QueuedApplication::initCore()
{
m_core = new QueuedCore(this);
// init objects
m_core->init(m_configuration[QString("config")].toString());
}
void QueuedApplication::initDBus()
{
QDBusConnection bus = QDBusConnection::systemBus();
if (!bus.registerObject(QueuedConfig::DBUS_APPLICATION_PATH,
new QueuedApplicationInterface(this),
QDBusConnection::ExportAllContents)) {
QString message = QString("Could not register application object %1")
.arg(bus.lastError().message());
qCCritical(LOG_DBUS) << message;
throw QueuedDBusException(message);
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.
*/
#ifndef QUEUEDAPPLICATION_H
#define QUEUEDAPPLICATION_H
#include <QObject>
#include <QVariant>
class QueuedCore;
class QueuedApplication : public QObject
{
Q_OBJECT
public:
explicit QueuedApplication(QObject *parent, const QVariantHash &args);
virtual ~QueuedApplication();
void deinit();
void init();
private:
// backend
void initDBus();
void initCore();
// library
QueuedCore *m_core = nullptr;
// configuration
QVariantHash m_configuration;
};
#endif /* QUEUEDAPPLICATION_H */

View File

@ -0,0 +1,61 @@
/*
* 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.
*/
#include "QueuedApplicationInterface.h"
#include <QCoreApplication>
#include <unistd.h>
#include "queued/Queued.h"
#include "QueuedApplication.h"
QueuedApplicationInterface::QueuedApplicationInterface(
QueuedApplication *parent)
: QDBusAbstractAdaptor(parent)
, m_application(parent)
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
QueuedApplicationInterface::~QueuedApplicationInterface()
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
bool QueuedApplicationInterface::Active() const
{
return true;
}
void QueuedApplicationInterface::Close() const
{
return QCoreApplication::exit(0);
}
QStringList QueuedApplicationInterface::UIDs() const
{
QStringList uids;
uids.append(QString::number(getuid()));
uids.append(QString::number(geteuid()));
return uids;
}

View File

@ -0,0 +1,46 @@
/*
* 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.
*/
#ifndef QUEUEDAPPLICATIONINTERFACE_H
#define QUEUEDAPPLICATIONINTERFACE_H
#include <QDBusAbstractAdaptor>
#include "QueuedConfig.h"
class QueuedApplication;
class QueuedApplicationInterface : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", DBUS_SERVICE_NAME)
public:
explicit QueuedApplicationInterface(QueuedApplication *parent);
virtual ~QueuedApplicationInterface();
public slots:
bool Active() const;
Q_NOREPLY void Close() const;
QStringList UIDs() const;
private:
QueuedApplication *m_application = nullptr;
};
#endif /* QUEUEDAPPLICATIONINTERFACE_H */

View File

@ -0,0 +1,85 @@
/*
* 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.
*/
#include <QCommandLineParser>
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
#include <queued/Queued.h>
#include "QueuedApplication.h"
#include "version.h"
bool existingSessionOperation(const QString &operation)
{
QVariantList arguments = QueuedCoreAdaptor::sendRequest(
QueuedConfig::DBUS_SERVICE, QueuedConfig::DBUS_APPLICATION_PATH,
QueuedConfig::DBUS_SERVICE, operation, QVariantList());
return (!arguments.isEmpty() && arguments.at(0).type() == QVariant::Bool
&& arguments[0].toBool());
}
int main(int argc, char *argv[])
{
// daemon(0, 0);
QCoreApplication app(argc, argv);
app.setApplicationName(NAME);
app.setApplicationVersion(VERSION);
// parser
QCommandLineParser parser;
parser.setApplicationDescription(
"Daemon for starting jobs to queue of calculations");
parser.addHelpOption();
parser.addVersionOption();
// configuration option
QCommandLineOption configOption(QStringList() << "c"
<< "config",
"Read initial configuration from file",
"config", QueuedSettings::defaultPath());
parser.addOption(configOption);
// debug mode
QCommandLineOption debugOption(QStringList() << "d"
<< "debug",
"Print debug information");
parser.addOption(debugOption);
parser.process(app);
// check if exists
if (existingSessionOperation(QString("Active"))) {
qCWarning(LOG_APP) << "Another session is active";
return 1;
}
// enable debug
if (parser.isSet(debugOption))
QueuedDebug::enableDebug();
// build initial options hash
QVariantHash arguments = {{"config", parser.value(configOption)}};
// start application
QueuedApplication instance(nullptr, arguments);
return app.exec();
}

View File

View File

@ -35,17 +35,27 @@ namespace QueuedConfig
* @brief DBus service name for library and application * @brief DBus service name for library and application
* @remark required by Qt macro * @remark required by Qt macro
*/ */
#define DBUS_SERVICE_NAME "org.quadro.core" #define DBUS_SERVICE_NAME "org.queued.core"
/** /**
* @ingroup QueuedConfig * @ingroup QueuedConfig
* @brief DBus service name for library and application * @brief DBus service name for library and application
*/ */
const char DBUS_SERVICE[] = DBUS_SERVICE_NAME; const char DBUS_SERVICE[] = DBUS_SERVICE_NAME;
/**
* @ingroup QueuedConfig
* @brief DBus object path for applicaiton
*/
const char DBUS_APPLICATION_PATH[] = "/application";
/** /**
* @ingroup QueuedConfig * @ingroup QueuedConfig
* @brief DBus object path for library * @brief DBus object path for library
*/ */
const char DBUS_OBJECT_PATH[] = "/queued"; const char DBUS_OBJECT_PATH[] = "/queued";
/**
* @ingroup QueuedConfig
* @brief DBus properties path for library
*/
const char DBUS_PROPERTY_PATH[] = "/property";
// path configuration // path configuration
// common paths // common paths

View File

@ -29,6 +29,7 @@
#include "QueuedCore.h" #include "QueuedCore.h"
#include "QueuedCoreAdaptor.h" #include "QueuedCoreAdaptor.h"
#include "QueuedCoreInterface.h" #include "QueuedCoreInterface.h"
#include "QueuedCorePropertiesInterface.h"
#include "QueuedDatabase.h" #include "QueuedDatabase.h"
#include "QueuedDebug.h" #include "QueuedDebug.h"
#include "QueuedEnums.h" #include "QueuedEnums.h"

View File

@ -33,6 +33,7 @@
class QueuedAdvancedSettings; class QueuedAdvancedSettings;
class QueuedDatabase; class QueuedDatabase;
class QueuedProcess;
class QueuedProcessManager; class QueuedProcessManager;
class QueuedReportManager; class QueuedReportManager;
class QueuedSettings; class QueuedSettings;
@ -185,6 +186,20 @@ public:
*/ */
bool stopTask(const long long _id, bool stopTask(const long long _id,
const QueuedUserManager::QueuedUserAuthorization &_auth); const QueuedUserManager::QueuedUserAuthorization &_auth);
/**
* @brief get task by ID
* @param _id
* task ID
* @return task object or nullptr if no task found
*/
const QueuedProcess *task(const long long _id);
/**
* @brief get user by ID
* @param _id
* user ID
* @return user object or nullptr if no user found
*/
const QueuedUser *user(const long long _id);
// control methods // control methods
/** /**
* @brief deinit subclasses * @brief deinit subclasses

View File

@ -24,30 +24,49 @@
#ifndef QUEUEDCOREADAPTOR_H #ifndef QUEUEDCOREADAPTOR_H
#define QUEUEDCOREADAPTOR_H #define QUEUEDCOREADAPTOR_H
#include <QObject> #include <QDBusArgument>
#include <QVariant>
/** /**
* @brief DBus adaptor for core interface * @defgroup QueuedCoreAdaptor
* @brief adaptor to DBus methods
*/ */
class QueuedCoreAdaptor : public QObject namespace QueuedCoreAdaptor
{ {
Q_OBJECT /**
* @ingroup QueuedCoreAdaptor
public: * @brief common DBus request
/** * @param _service
* @brief QueuedCoreAdaptor class constructor * DBus service name
* @param parent * @param _path
* pointer to parent item * DBus object path
* @param _interface
* DBus interface name
* @param _cmd
* command which will be sent to DBus
* @param _args
* command arguments
* @return reply object from DBus request
*/ */
explicit QueuedCoreAdaptor(QObject *parent); QVariantList sendRequest(const QString &_service, const QString &_path,
/** const QString &_interface, const QString &_cmd,
* @brief QueuedCoreAdaptor class destructor const QVariantList &_args);
/**
* @ingroup QueuedCoreAdaptor
* @brief additional method to avoid conversion from DBus type to native ones
* @tparam T
* type to which DBus data should be converted
* @param _data
* source data
* @return converted value
*/ */
virtual ~QueuedCoreAdaptor(); template <class T> T toNativeType(const QVariant &_data)
{
private: return qdbus_cast<T>(
_data.value<QDBusVariant>().variant().value<QDBusArgument>());
}; };
}
#endif /* QUEUEDCOREADAPTOR_H */ #endif /* QUEUEDCOREADAPTOR_H */

View File

@ -114,16 +114,45 @@ public slots:
* @brief edit task * @brief edit task
* @param id * @param id
* task ID * task ID
* @param data * @param command
* new task data * new command or empty
* @param arguments
* command line arguments or empty
* @param directory
* working directory or empty
* @param nice
* nice level or 0
* @param uid
* new uid or 0
* @param state
* new state or 0
* @param cpu
* new limit by CPU cores or -1
* @param gpu
* limit by GPU cores or -1
* @param memory
* new limit by memory or -1
* @param gpumemory
* new limit by GPU memory or -1
* @param storage
* new limit by storage or -1
* @param start
* new start time in ISO format or empty
* @param end
* new end time in ISO format or empty
* @param whoAmI * @param whoAmI
* auth user name * auth user name
* @param token * @param token
* auth user token * auth user token
* @return true on successful task edition * @return true on successful task edition
*/ */
bool TaskEdit(const qlonglong id, const QDBusVariant &data, bool TaskEdit(const qlonglong id, const QString &command,
const QString &whoAmI, const QString &token); const QStringList &arguments, const QString &directory,
const uint nice, const uint uid, const uint gid,
const uint state, const long long cpu, const long long gpu,
const QString &memory, const QString &gpumemory,
const QString &storage, const QString &whoAmI,
const QString &token);
/** /**
* @brief force start task * @brief force start task
* @param id * @param id
@ -184,16 +213,34 @@ public slots:
* @brief edit user * @brief edit user
* @param id * @param id
* user ID * user ID
* @param data * @param name
* new user data * new user name or empty
* @param password
* new user password or empty
* @param email
* new user email or empty
* @param cpu
* new limit by CPU cores or -1
* @param gpu
* limit by GPU cores or -1
* @param memory
* new limit by memory or -1
* @param gpumemory
* new limit by GPU memory or -1
* @param storage
* new limit by storage or -1
* @param whoAmI * @param whoAmI
* auth user name * auth user name
* @param token * @param token
* auth user token * auth user token
* @return true on successful user edition * @return true on successful user edition
*/ */
bool UserEdit(const qlonglong id, const QDBusVariant &data, bool UserEdit(const qlonglong id, const QString &name,
const QString &whoAmI, const QString &token); const QString &password, const QString &email,
const long long cpu, const long long gpu,
const QString &memory, const QString &gpumemory,
const QString &storage, const QString &whoAmI,
const QString &token);
/** /**
* @brief add permission to user * @brief add permission to user
* @param id * @param id

View File

@ -0,0 +1,83 @@
/*
* 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 QueuedCorePropertiesInterface.h
* Header of Queued library
* @author Evgeniy Alekseev
* @copyright MIT
* @bug https://github.com/arcan1s/queued/issues
*/
#ifndef QUEUEDCOREPROPERTIESINTERFACE_H
#define QUEUEDCOREPROPERTIESINTERFACE_H
#include <QDBusAbstractAdaptor>
#include <QDBusVariant>
#include "QueuedConfig.h"
class QueuedCore;
/**
* @brief DBus interface for QueuedCore class
*/
class QueuedCorePropertiesInterface : public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", DBUS_SERVICE_NAME)
public:
/**
* @brief QueuedCorePropertiesInterface class constructor
* @param parent
* pointer to QueuedCore object
*/
explicit QueuedCorePropertiesInterface(QueuedCore *parent);
/**
* @brief QueuedCorePropertiesInterface class destructor
*/
virtual ~QueuedCorePropertiesInterface();
public slots:
/**
* @brief get task property
* @param id
* task ID
* @param property
* property name
* @return property value or empty if task or property not found
*/
QDBusVariant TaskProperty(const long long id, const QString &property);
/**
* @brief get user property
* @param id
* user ID
* @param property
* property name
* @return property value or empty if user or property not found
*/
QDBusVariant UserProperty(const long long id, const QString &property);
private:
/**
* @brief pointer to database object
*/
QueuedCore *m_core = nullptr;
};
#endif /* QUEUEDCOREPROPERTIESINTERFACE_H */

View File

@ -88,8 +88,7 @@ const QueuedDBSchema DBSchema = {
{{"_id", {{"_id",
{"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong,
true}}, true}},
{"key", {"key", {"key", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"key", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String, true}},
{"value", {"value", "TEXT", QVariant::String, true}}}}, {"value", {"value", "TEXT", QVariant::String, true}}}},
{TASKS_TABLE, {TASKS_TABLE,
{{"_id", {{"_id",
@ -111,16 +110,14 @@ const QueuedDBSchema DBSchema = {
{{"_id", {{"_id",
{"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong,
true}}, true}},
{"token", {"token", {"token", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"token", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String, true}},
{"validUntil", {"validUntil",
{"validUntil", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}}}}, {"validUntil", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}}}},
{USERS_TABLE, {USERS_TABLE,
{{"_id", {{"_id",
{"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong, {"_id", "INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE", QVariant::LongLong,
true}}, true}},
{"name", {"name", {"name", "TEXT NOT NULL DEFAULT '0'", QVariant::String, true}},
{"name", "TEXT NOT NULL UNIQUE DEFAULT '0'", QVariant::String, true}},
{"password", {"password", "TEXT", QVariant::String, false}}, {"password", {"password", "TEXT", QVariant::String, false}},
{"email", {"email", "TEXT", QVariant::String, false}}, {"email", {"email", "TEXT", QVariant::String, false}},
{"lastLogin", {"lastLogin", "TEXT", QVariant::String, true}}, {"lastLogin", {"lastLogin", "TEXT", QVariant::String, true}},

View File

@ -27,6 +27,10 @@
#include <QLoggingCategory> #include <QLoggingCategory>
/**
* @brief daemon logging category
*/
Q_DECLARE_LOGGING_CATEGORY(LOG_APP)
/** /**
* @brief control application logging category * @brief control application logging category
*/ */
@ -63,7 +67,11 @@ const char LOG_FORMAT[] = "[%{time "
"{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-" "{if-warning}WW%{endif}%{if-critical}CC%{endif}%{if-"
"fatal}FF%{endif}][%{category}][%{function}] " "fatal}FF%{endif}][%{category}][%{function}] "
"%{message}"; "%{message}";
/**
* @ingroup QueuedDebug
* @brief method to enable debug messages
*/
void enableDebug();
/** /**
* @ingroup QueuedDebug * @ingroup QueuedDebug
* @brief additional method to get build details declared in version.h * @brief additional method to get build details declared in version.h

View File

@ -31,30 +31,6 @@
*/ */
namespace QueuedEnums namespace QueuedEnums
{ {
/**
* @ingroup QueuedEnums
* @enum LimitType
* @brief available limit types
* @var LimitType::CPUThreads
* limit on CPU threads count
* @var LimitType::GPUThreads
* limit on GPU threads count
* @var LimitType::Memory
* limit on physical memory
* @var LimitType::GPUMemory
* limit on GPU memory
* @var LimitType::Storage
* limit on storage
*/
enum LimitType {
CPUThreads = 1 << 0,
GPUThreads = 1 << 1,
Memory = 1 << 2,
GPUMemory = 1 << 3,
Storage = 1 << 4
};
Q_DECLARE_FLAGS(LimitTypes, LimitType)
Q_DECLARE_OPERATORS_FOR_FLAGS(LimitTypes)
/** /**
* @ingroup QueuedEnums * @ingroup QueuedEnums
* @enum Permissions * @enum Permissions
@ -71,10 +47,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(LimitTypes)
* access to reports * access to reports
*/ */
enum class Permission { enum class Permission {
SuperAdmin = 1 << 0, SuperAdmin = 1 << 1,
Admin = 1 << 1, Admin = 1 << 2,
JobOwner = 1 << 2, JobOwner = 1 << 3,
User = 1 << 3,
Web = 1 << 4, Web = 1 << 4,
Reports = 1 << 5 Reports = 1 << 5
}; };
@ -92,9 +67,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Permissions)
* process exit * process exit
*/ */
enum class ProcessState { enum class ProcessState {
NotRunning = 1 << 0, NotRunning = 1 << 1,
Running = 1 << 1, Running = 1 << 2,
Exited = 1 << 2 Exited = 1 << 3
}; };
}; };

View File

@ -88,7 +88,7 @@ struct Limits {
Limits(const QString &_stringLimits) Limits(const QString &_stringLimits)
{ {
QStringList limits = _stringLimits.split(QChar('\x01')); QStringList limits = _stringLimits.split(QChar('\x01'));
while (limits.count() < 4) while (limits.count() < 5)
limits.append(QString("0")); limits.append(QString("0"));
cpu = limits.at(0).toLongLong(); cpu = limits.at(0).toLongLong();

View File

@ -65,7 +65,12 @@ bool QueuedCore::addTask(
qCDebug(LOG_LIB) << "Add task" << _command << "with arguments" << _arguments qCDebug(LOG_LIB) << "Add task" << _command << "with arguments" << _arguments
<< "from user" << _userId; << "from user" << _userId;
long long userAuthId = m_users->user(_auth.user)->index(); auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
long long actualUserId = (_userId == -1) ? userAuthId : _userId; long long actualUserId = (_userId == -1) ? userAuthId : _userId;
// check permissions // check permissions
@ -89,8 +94,13 @@ bool QueuedCore::addTask(
// add to database // add to database
auto ids = m_users->ids(_userId); auto ids = m_users->ids(_userId);
auto user = m_users->user(_userId);
if (!user) {
qCWarning(LOG_LIB) << "Could not find task user" << _userId;
return false;
}
auto taskLimits = QueuedLimits::minimalLimits( auto taskLimits = QueuedLimits::minimalLimits(
_limits, m_users->user(_userId)->limits(), _limits, user->limits(),
QueuedLimits::Limits( QueuedLimits::Limits(
m_advancedSettings->get(QString("DefaultLimits")).toString())); m_advancedSettings->get(QString("DefaultLimits")).toString()));
QVariantHash properties = {{"user", _userId}, QVariantHash properties = {{"user", _userId},
@ -131,6 +141,13 @@ bool QueuedCore::addUser(
return false; return false;
} }
// check if already exists
auto user = m_users->user(_name);
if (user) {
qCWarning(LOG_LIB) << "User" << _name << "already exists";
return false;
}
// add to dababase // add to dababase
QVariantHash properties QVariantHash properties
= {{"name", _name}, = {{"name", _name},
@ -158,6 +175,7 @@ QueuedCore::authorization(const QString &_name, const QString &_password)
QString token = m_users->authorize(_name, _password); QString token = m_users->authorize(_name, _password);
QueuedUserManager::QueuedUserAuthorization auth; QueuedUserManager::QueuedUserAuthorization auth;
auth.user = _name; auth.user = _name;
auth.token = token;
if (!token.isEmpty()) { if (!token.isEmpty()) {
QVariantHash payload = { QVariantHash payload = {
@ -225,7 +243,12 @@ bool QueuedCore::editTask(
} }
// check permissions // check permissions
long long userAuthId = m_users->user(_auth.user)->index(); auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin); bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin);
bool isUser = m_users->authorize(_auth, QueuedEnums::Permission::JobOwner); bool isUser = m_users->authorize(_auth, QueuedEnums::Permission::JobOwner);
if (userAuthId == task->user()) { if (userAuthId == task->user()) {
@ -290,8 +313,13 @@ bool QueuedCore::editUser(
} }
// check permissions // check permissions
auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin); bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin);
long long userAuthId = m_users->user(_auth.user)->index();
if (userAuthId != _id) { if (userAuthId != _id) {
if (!isAdmin) { if (!isAdmin) {
qCInfo(LOG_LIB) << "User" << _auth.user qCInfo(LOG_LIB) << "User" << _auth.user
@ -339,8 +367,13 @@ bool QueuedCore::editUserPermission(
} }
// check permissions // check permissions
auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin); bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin);
long long userAuthId = m_users->user(_auth.user)->index();
if (userAuthId != _id) { if (userAuthId != _id) {
if (!isAdmin) { if (!isAdmin) {
qCInfo(LOG_LIB) << "User" << _auth.user qCInfo(LOG_LIB) << "User" << _auth.user
@ -385,8 +418,13 @@ bool QueuedCore::startTask(
qCDebug(LOG_LIB) << "Force start task with ID" << _id; qCDebug(LOG_LIB) << "Force start task with ID" << _id;
// check permissions // check permissions
auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin); bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin);
long long userAuthId = m_users->user(_auth.user)->index();
if (userAuthId != _id) { if (userAuthId != _id) {
if (!isAdmin) { if (!isAdmin) {
qCInfo(LOG_LIB) << "User" << _auth.user qCInfo(LOG_LIB) << "User" << _auth.user
@ -417,7 +455,12 @@ bool QueuedCore::stopTask(
} }
// check permissions // check permissions
long long userAuthId = m_users->user(_auth.user)->index(); auto authUser = m_users->user(_auth.user);
if (!authUser) {
qCWarning(LOG_LIB) << "Could not find auth user" << _auth.user;
return false;
}
long long userAuthId = authUser->index();
bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin); bool isAdmin = m_users->authorize(_auth, QueuedEnums::Permission::Admin);
bool isUser = m_users->authorize(_auth, QueuedEnums::Permission::JobOwner); bool isUser = m_users->authorize(_auth, QueuedEnums::Permission::JobOwner);
if (userAuthId == task->user()) { if (userAuthId == task->user()) {
@ -442,6 +485,28 @@ bool QueuedCore::stopTask(
} }
/**
* @fn task
*/
const QueuedProcess *QueuedCore::task(const long long _id)
{
qCDebug(LOG_LIB) << "Get task by ID" << _id;
return m_processes->process(_id);
}
/**
* @fn user
*/
const QueuedUser *QueuedCore::user(const long long _id)
{
qCDebug(LOG_LIB) << "Get user by ID" << _id;
return m_users->user(_id);
}
/** /**
* @fn deinit * @fn deinit
*/ */
@ -455,6 +520,8 @@ void QueuedCore::deinit()
// dbus cleanup // dbus cleanup
QDBusConnection::sessionBus().unregisterObject( QDBusConnection::sessionBus().unregisterObject(
QueuedConfig::DBUS_OBJECT_PATH); QueuedConfig::DBUS_OBJECT_PATH);
QDBusConnection::sessionBus().unregisterObject(
QueuedConfig::DBUS_PROPERTY_PATH);
QDBusConnection::sessionBus().unregisterService(QueuedConfig::DBUS_SERVICE); QDBusConnection::sessionBus().unregisterService(QueuedConfig::DBUS_SERVICE);
// delete objects now // delete objects now
@ -583,7 +650,7 @@ QVariantHash QueuedCore::dropAdminFields(const QString &_table,
*/ */
void QueuedCore::initDBus() void QueuedCore::initDBus()
{ {
QDBusConnection bus = QDBusConnection::sessionBus(); QDBusConnection bus = QDBusConnection::systemBus();
if (!bus.registerService(QueuedConfig::DBUS_SERVICE)) { if (!bus.registerService(QueuedConfig::DBUS_SERVICE)) {
QString message = QString("Could not register service %1") QString message = QString("Could not register service %1")
@ -600,6 +667,14 @@ void QueuedCore::initDBus()
qCCritical(LOG_DBUS) << message; qCCritical(LOG_DBUS) << message;
throw QueuedDBusException(message); throw QueuedDBusException(message);
} }
if (!bus.registerObject(QueuedConfig::DBUS_PROPERTY_PATH,
new QueuedCorePropertiesInterface(this),
QDBusConnection::ExportAllContents)) {
QString message = QString("Could not register properties object %1")
.arg(bus.lastError().message());
qCCritical(LOG_DBUS) << message;
throw QueuedDBusException(message);
}
} }
@ -677,7 +752,7 @@ void QueuedCore::initUsers()
QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate); QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
auto dbTokens = m_database->get( auto dbTokens = m_database->get(
QueuedDB::TOKENS_TABLE, QueuedDB::TOKENS_TABLE,
QString("WHERE datetime(validUntil) > datetime(%2)").arg(now)); QString("WHERE datetime(validUntil) > datetime('%1')").arg(now));
m_users->loadTokens(dbTokens); m_users->loadTokens(dbTokens);
auto dbUsers = m_database->get(QueuedDB::USERS_TABLE); auto dbUsers = m_database->get(QueuedDB::USERS_TABLE);
m_users->loadUsers(dbUsers); m_users->loadUsers(dbUsers);

View File

@ -23,24 +23,35 @@
#include "queued/Queued.h" #include "queued/Queued.h"
#include <QDBusConnection>
#include <QDBusMessage>
/** /**
* @class QueuedCoreAdaptor * @fn sendRequest
*/ */
/** QVariantList QueuedCoreAdaptor::sendRequest(const QString &_service,
* @fn QueuedCoreAdaptor const QString &_path,
*/ const QString &_interface,
QueuedCoreAdaptor::QueuedCoreAdaptor(QObject *parent) const QString &_cmd,
: QObject(parent) const QVariantList &_args)
{ {
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCDebug(LOG_DBUS) << "Send request to service" << _service << "by interface"
} << _interface << "to" << _path << "command" << _cmd
<< "with args" << _args;
QDBusConnection bus = QDBusConnection::systemBus();
QDBusMessage request
= QDBusMessage::createMethodCall(_service, _path, _interface, _cmd);
if (!_args.isEmpty())
request.setArguments(_args);
/** QDBusMessage response = bus.call(request, QDBus::BlockWithGui);
* @fn ~QueuedCoreAdaptor QVariantList arguments = response.arguments();
*/
QueuedCoreAdaptor::~QueuedCoreAdaptor() QString error = response.errorMessage();
{ if (!error.isEmpty())
qCDebug(LOG_LIB) << __PRETTY_FUNCTION__; qCWarning(LOG_DBUS) << "Error message" << error;
return arguments;
} }

View File

@ -100,14 +100,54 @@ bool QueuedCoreInterface::TaskAdd(
/** /**
* @fn TaskEdit * @fn TaskEdit
*/ */
bool QueuedCoreInterface::TaskEdit(const qlonglong id, const QDBusVariant &data, bool QueuedCoreInterface::TaskEdit(
const qlonglong id, const QString &command, const QStringList &arguments,
const QString &directory, const uint nice, const uint uid, const uint gid,
const uint state, const long long cpu, const long long gpu,
const QString &memory, const QString &gpumemory, const QString &storage,
const QString &whoAmI, const QString &token) const QString &whoAmI, const QString &token)
{ {
qCDebug(LOG_DBUS) << "Edit task" << id << data.variant() << "auth by" qCDebug(LOG_DBUS) << "Edit task" << id << command << arguments << directory
<< whoAmI; << nice << uid << gid << state << cpu << gpu << memory
<< gpumemory << storage << "auth by" << whoAmI;
return m_core->editTask(id, data.variant().toHash(), auto task = m_core->task(id);
QueuedUserManager::auth(whoAmI, token)); if (!task) {
qCWarning(LOG_DBUS) << "Could not find task" << id;
return false;
}
// build payload
QVariantHash data;
if (!command.isEmpty())
data[QString("command")] = command;
if (!arguments.isEmpty())
data[QString("arguments")] = arguments;
if (!directory.isEmpty())
data[QString("directory")] = directory;
if (nice > 0)
data[QString("nice")] = nice;
if (uid > 0)
data[QString("uid")] = uid;
if (gid > 0)
data[QString("gid")] = gid;
if (state > 0)
data[QString("state")] = state;
// append limits now
auto limits = task->limits();
if (cpu > -1)
limits.cpu = cpu;
if (gpu > -1)
limits.gpu = gpu;
if (memory > -1)
limits.memory = QueuedLimits::convertMemory(memory);
if (gpumemory > -1)
limits.gpumemory = QueuedLimits::convertMemory(gpumemory);
if (storage > -1)
limits.storage = QueuedLimits::convertMemory(storage);
data[QString("limits")] = limits.toString();
return m_core->editTask(id, data, QueuedUserManager::auth(whoAmI, token));
} }
@ -161,14 +201,47 @@ bool QueuedCoreInterface::UserAdd(const QString &name, const QString &email,
/** /**
* @fn UserEdit * @fn UserEdit
*/ */
bool QueuedCoreInterface::UserEdit(const qlonglong id, const QDBusVariant &data, bool QueuedCoreInterface::UserEdit(const qlonglong id, const QString &name,
const QString &password,
const QString &email, const long long cpu,
const long long gpu, const QString &memory,
const QString &gpumemory,
const QString &storage,
const QString &whoAmI, const QString &token) const QString &whoAmI, const QString &token)
{ {
qCDebug(LOG_DBUS) << "Edit user" << id << data.variant() << "auth by" qCDebug(LOG_DBUS) << "Edit user" << id << name << email << cpu << gpu
<< whoAmI; << memory << gpumemory << storage << "auth by" << whoAmI;
return m_core->editUser(id, data.variant().toHash(), // get user object first to match limits
QueuedUserManager::auth(whoAmI, token)); auto user = m_core->user(id);
if (!user) {
qCWarning(LOG_DBUS) << "Could not find user" << id;
return false;
}
// build payload
QVariantHash data;
if (!name.isEmpty())
data[QString("name")] = name;
if (!password.isEmpty())
data[QString("password")] = password;
if (!email.isEmpty())
data[QString("email")] = email;
// append limits now
auto limits = user->limits();
if (cpu > -1)
limits.cpu = cpu;
if (gpu > -1)
limits.gpu = gpu;
if (memory > -1)
limits.memory = QueuedLimits::convertMemory(memory);
if (gpumemory > -1)
limits.gpumemory = QueuedLimits::convertMemory(gpumemory);
if (storage > -1)
limits.storage = QueuedLimits::convertMemory(storage);
data[QString("limits")] = limits.toString();
return m_core->editUser(id, data, QueuedUserManager::auth(whoAmI, token));
} }

View File

@ -0,0 +1,85 @@
/*
* 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 QueuedCorePropertiesInterface.cpp
* Source code of queued library
* @author Evgeniy Alekseev
* @copyright GPLv3
* @bug https://github.com/arcan1s/queued/issues
*/
#include "queued/Queued.h"
/**
* @class QueuedCorePropertiesInterface
*/
/**
* @fn QueuedCorePropertiesInterface
*/
QueuedCorePropertiesInterface::QueuedCorePropertiesInterface(QueuedCore *parent)
: QDBusAbstractAdaptor(parent)
, m_core(parent)
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
/**
* @fn ~QueuedCorePropertiesInterface
*/
QueuedCorePropertiesInterface::~QueuedCorePropertiesInterface()
{
qCDebug(LOG_DBUS) << __PRETTY_FUNCTION__;
}
/**
* @fn TaskProperty
*/
QDBusVariant
QueuedCorePropertiesInterface::TaskProperty(const long long id,
const QString &property)
{
qCDebug(LOG_DBUS) << "Get property" << property << "from task" << id;
auto task = m_core->task(id);
if (!task) {
qCWarning(LOG_DBUS) << "Could not find task" << id;
return QDBusVariant();
}
return QDBusVariant(task->property(property.toLocal8Bit().constData()));
}
/**
* @fn UserProperty
*/
QDBusVariant
QueuedCorePropertiesInterface::UserProperty(const long long id,
const QString &property)
{
qCDebug(LOG_DBUS) << "Get property" << property << "from user" << id;
auto user = m_core->user(id);
if (!user) {
qCWarning(LOG_DBUS) << "Could not find user" << id;
return QDBusVariant();
}
return QDBusVariant(user->property(property.toLocal8Bit().constData()));
}

View File

@ -80,15 +80,17 @@ void QueuedDatabase::createAdministrator(const QString &_user,
const QString &_password) const QString &_password)
{ {
qCDebug(LOG_LIB) << "Check for user" << _user; qCDebug(LOG_LIB) << "Check for user" << _user;
QString table("users");
QSqlQuery query = m_database.exec( QSqlQuery query
QString("SELECT * FROM '%1' WHERE name='%2'").arg(table).arg(_user)); = m_database.exec(QString("SELECT * FROM '%1' WHERE name='%2'")
.arg(QueuedDB::USERS_TABLE)
.arg(_user));
QSqlError error = query.lastError(); QSqlError error = query.lastError();
if (error.isValid()) if (error.isValid())
qCWarning(LOG_LIB) << "Could not get record" << _user << "from" << table qCWarning(LOG_LIB) << "Could not get record" << _user << "from"
<< "message" << error.text(); << QueuedDB::USERS_TABLE << "message"
else if (query.size() > 0) << error.text();
else if (query.next())
return; return;
qCInfo(LOG_LIB) << "Create administrator user" << _user; qCInfo(LOG_LIB) << "Create administrator user" << _user;
@ -97,7 +99,7 @@ void QueuedDatabase::createAdministrator(const QString &_user,
{"password", _password}, {"password", _password},
{"permissions", static_cast<int>(QueuedEnums::Permission::SuperAdmin)}}; {"permissions", static_cast<int>(QueuedEnums::Permission::SuperAdmin)}};
if (!add(table, payload)) if (!add(QueuedDB::USERS_TABLE, payload))
qCCritical(LOG_LIB) << "Could not create administrator"; qCCritical(LOG_LIB) << "Could not create administrator";
} }
@ -113,7 +115,7 @@ QList<QVariantHash> QueuedDatabase::get(const QString &_table,
QList<QVariantHash> output; QList<QVariantHash> output;
QSqlQuery query QSqlQuery query
= m_database.exec(QString("SELECT * FROM '%1' ORDER BY _id DESC %1") = m_database.exec(QString("SELECT * FROM '%1' %2 ORDER BY _id DESC")
.arg(_table) .arg(_table)
.arg(_condition)); .arg(_condition));
@ -227,7 +229,7 @@ bool QueuedDatabase::modify(const QString &_table, const long long _id,
auto payload = getQueryPayload(_table, _value); auto payload = getQueryPayload(_table, _value);
QStringList stringPayload; QStringList stringPayload;
for (int i = 0; i < payload.first.count(); i++) for (int i = 0; i < payload.first.count(); i++)
stringPayload.append(QString("%1='%2'") stringPayload.append(QString("%1=%2")
.arg(payload.first.at(i)) .arg(payload.first.at(i))
.arg(payload.second.at(i))); .arg(payload.second.at(i)));
// build query // build query
@ -274,7 +276,7 @@ void QueuedDatabase::removeTasks(const QDateTime &_endTime)
qCDebug(LOG_LIB) << "Remove all tasks which are older than" << _endTime; qCDebug(LOG_LIB) << "Remove all tasks which are older than" << _endTime;
QSqlQuery query = m_database.exec( QSqlQuery query = m_database.exec(
QString("DELETE FROM %1 WHERE datetime(endTime) < datetime(%2)") QString("DELETE FROM %1 WHERE datetime(endTime) < datetime('%2')")
.arg(QueuedDB::TASKS_TABLE) .arg(QueuedDB::TASKS_TABLE)
.arg(_endTime.toString(Qt::ISODate))); .arg(_endTime.toString(Qt::ISODate)));
@ -292,7 +294,7 @@ void QueuedDatabase::removeTokens()
{ {
QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate); QString now = QDateTime::currentDateTimeUtc().toString(Qt::ISODate);
QSqlQuery query = m_database.exec( QSqlQuery query = m_database.exec(
QString("DELETE FROM %1 WHERE datetime(validUntil) > datetime(%2)") QString("DELETE FROM %1 WHERE datetime(validUntil) > datetime('%2')")
.arg(QueuedDB::TOKENS_TABLE) .arg(QueuedDB::TOKENS_TABLE)
.arg(now)); .arg(now));
@ -312,7 +314,7 @@ void QueuedDatabase::removeUsers(const QDateTime &_lastLogin)
<< _lastLogin; << _lastLogin;
QSqlQuery query = m_database.exec( QSqlQuery query = m_database.exec(
QString("DELETE FROM %1 WHERE datetime(lastLogin) < datetime(%2)") QString("DELETE FROM %1 WHERE datetime(lastLogin) < datetime('%2')")
.arg(QueuedDB::USERS_TABLE) .arg(QueuedDB::USERS_TABLE)
.arg(_lastLogin.toString(Qt::ISODate))); .arg(_lastLogin.toString(Qt::ISODate)));

View File

@ -26,6 +26,7 @@
#include "version.h" #include "version.h"
Q_LOGGING_CATEGORY(LOG_APP, "org.queued.application", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_CTL, "org.queued.control", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_CTL, "org.queued.control", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_DBUS, "org.queued.dbus", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_DBUS, "org.queued.dbus", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_LIB, "org.queued.library", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_LIB, "org.queued.library", QtMsgType::QtWarningMsg)
@ -33,6 +34,15 @@ Q_LOGGING_CATEGORY(LOG_PL, "org.queued.plugin", QtMsgType::QtWarningMsg)
Q_LOGGING_CATEGORY(LOG_SERV, "org.queued.server", QtMsgType::QtWarningMsg) Q_LOGGING_CATEGORY(LOG_SERV, "org.queued.server", QtMsgType::QtWarningMsg)
/**
* @fn enableDebug
*/
void QueuedDebug::enableDebug()
{
QLoggingCategory::setFilterRules(QString("org.queued.*=true"));
}
/** /**
* @fn getBuildData * @fn getBuildData
*/ */

View File

@ -73,10 +73,14 @@ void QueuedTokenManager::loadTokens(const QList<QVariantHash> &_values)
token[QString("validUntil")].toString(), Qt::ISODate); token[QString("validUntil")].toString(), Qt::ISODate);
QString tokenId = token[QString("token")].toString(); QString tokenId = token[QString("token")].toString();
m_tokens[tokenId] = validUntil; m_tokens[tokenId] = validUntil;
QTimer::singleShot( // create timer
std::chrono::milliseconds duration(
validUntil.toMSecsSinceEpoch() validUntil.toMSecsSinceEpoch()
- QDateTime::currentDateTimeUtc().toMSecsSinceEpoch(), - QDateTime::currentDateTimeUtc().toMSecsSinceEpoch());
Qt::VeryCoarseTimer, QTimer timer;
timer.setSingleShot(true);
timer.setInterval(duration);
connect(&timer, &QTimer::timeout,
[this, tokenId]() { return expireToken(tokenId); }); [this, tokenId]() { return expireToken(tokenId); });
} }
} }

View File

@ -79,7 +79,8 @@ QueuedUser::addPermissions(const QueuedEnums::Permissions _permissions)
QString QueuedUser::hashFromPassword(const QString &_password) QString QueuedUser::hashFromPassword(const QString &_password)
{ {
return QCryptographicHash::hash(_password.toUtf8(), return QCryptographicHash::hash(_password.toUtf8(),
QCryptographicHash::Sha512); QCryptographicHash::Sha512)
.toHex();
} }
@ -122,9 +123,7 @@ QPair<uint, uint> QueuedUser::ids()
*/ */
bool QueuedUser::isPasswordValid(const QString &_password) const bool QueuedUser::isPasswordValid(const QString &_password) const
{ {
return (m_definitions.password.toUtf8() return (m_definitions.password.toUtf8() == hashFromPassword(_password));
== QCryptographicHash::hash(_password.toUtf8(),
QCryptographicHash::Sha512));
} }