mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
refactor: API split (#721)
* refactor: API split * refactor: cleanup hyperiond
This commit is contained in:
parent
c6c6453267
commit
2739aec1e3
21
.editorconfig
Normal file
21
.editorconfig
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
# Tab indentation (no size specified)
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
[*.{c,h,cpp,hpp}]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
# js and webui
|
||||||
|
[*.{ts,js,html}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
@ -49,6 +49,8 @@
|
|||||||
"general_btn_next": "Weiter",
|
"general_btn_next": "Weiter",
|
||||||
"general_btn_back": "Zurück",
|
"general_btn_back": "Zurück",
|
||||||
"general_btn_iswitch": "Switch",
|
"general_btn_iswitch": "Switch",
|
||||||
|
"general_btn_grantAccess": "Zugriff gewähren",
|
||||||
|
"general_btn_denyAccess": "Zugriff ablehnen",
|
||||||
"general_chars_needed": "weitere Zeichen benötigt",
|
"general_chars_needed": "weitere Zeichen benötigt",
|
||||||
"general_wiki_moreto": "Mehr Informationen zu \"$1\" findest du in unserem Wiki",
|
"general_wiki_moreto": "Mehr Informationen zu \"$1\" findest du in unserem Wiki",
|
||||||
"dashboard_label_intro": "Das Dashboard zeigt dir Informationen zum Systemstatus, ob Updates verfügbar sind, den Komponentenstatus sowie die letzten Blog-Posts vom Hyperion Team.",
|
"dashboard_label_intro": "Das Dashboard zeigt dir Informationen zum Systemstatus, ob Updates verfügbar sind, den Komponentenstatus sowie die letzten Blog-Posts vom Hyperion Team.",
|
||||||
@ -203,6 +205,8 @@
|
|||||||
"conf_network_tok_diaTitle" : "Neues Token erstellt!",
|
"conf_network_tok_diaTitle" : "Neues Token erstellt!",
|
||||||
"conf_network_tok_diaMsg" : "Hier ist dein neues Token, welches für den Zugriff auf die Hyperion API verwendet werden kann. Aus Sicherheitsgründen können Tokens nach der Erstellung nur einmalig eingesehen werden, notiere es dir daher jetzt.",
|
"conf_network_tok_diaMsg" : "Hier ist dein neues Token, welches für den Zugriff auf die Hyperion API verwendet werden kann. Aus Sicherheitsgründen können Tokens nach der Erstellung nur einmalig eingesehen werden, notiere es dir daher jetzt.",
|
||||||
"conf_network_tok_intro" : "Hier kannst du Token zur API Authentifizierung erstellen oder löschen. Neu erstellte Token werden einmalig angezeigt.",
|
"conf_network_tok_intro" : "Hier kannst du Token zur API Authentifizierung erstellen oder löschen. Neu erstellte Token werden einmalig angezeigt.",
|
||||||
|
"conf_network_tok_grantT": "App Token angefordert",
|
||||||
|
"conf_network_tok_grantMsg": "Eine App fordert Zugriff auf die Hyperion API durch ein Token. Möchtest du dies zulassen? Bitte überprüfe die angegebenen Informationen!",
|
||||||
"conf_logging_label_intro": "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.",
|
"conf_logging_label_intro": "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.",
|
||||||
"conf_logging_btn_pbupload": "Bericht für Supportanfrage hochladen",
|
"conf_logging_btn_pbupload": "Bericht für Supportanfrage hochladen",
|
||||||
"conf_logging_btn_autoscroll": "Automatisch scrollen",
|
"conf_logging_btn_autoscroll": "Automatisch scrollen",
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
"general_btn_next" : "Next",
|
"general_btn_next" : "Next",
|
||||||
"general_btn_back" : "Back",
|
"general_btn_back" : "Back",
|
||||||
"general_btn_iswitch" : "Switch",
|
"general_btn_iswitch" : "Switch",
|
||||||
|
"general_btn_grantAccess": "Grant Access",
|
||||||
|
"general_btn_denyAccess": "Deny Access",
|
||||||
"general_chars_needed": "more characters needed",
|
"general_chars_needed": "more characters needed",
|
||||||
"general_wiki_moreto" : "More information about \"$1\" is available at our",
|
"general_wiki_moreto" : "More information about \"$1\" is available at our",
|
||||||
"dashboard_label_intro" : "This dashboard gives you a quick overview of your Hyperion installation and shows you the latest news from the Hyperion Blog.",
|
"dashboard_label_intro" : "This dashboard gives you a quick overview of your Hyperion installation and shows you the latest news from the Hyperion Blog.",
|
||||||
@ -202,6 +204,8 @@
|
|||||||
"conf_network_tok_diaTitle" : "New Token created!",
|
"conf_network_tok_diaTitle" : "New Token created!",
|
||||||
"conf_network_tok_diaMsg" : "Here is your new token which can be used to grant an application access to the Hyperion API. For security reasons you can't view it again so use/note it down.",
|
"conf_network_tok_diaMsg" : "Here is your new token which can be used to grant an application access to the Hyperion API. For security reasons you can't view it again so use/note it down.",
|
||||||
"conf_network_tok_intro" : "Here you can create and delete tokens for API authentication. Created tokens will only be displayed once.",
|
"conf_network_tok_intro" : "Here you can create and delete tokens for API authentication. Created tokens will only be displayed once.",
|
||||||
|
"conf_network_tok_grantT": "App Requests Token",
|
||||||
|
"conf_network_tok_grantMsg": "An App requested a token to get access to the Hyperion API. Do you want to grant access? Please verify the provided information!",
|
||||||
"conf_logging_label_intro" : "Area to check log messages, you will see more or less information depending on the set logging level .",
|
"conf_logging_label_intro" : "Area to check log messages, you will see more or less information depending on the set logging level .",
|
||||||
"conf_logging_btn_pbupload" : "Upload a report for support requests",
|
"conf_logging_btn_pbupload" : "Upload a report for support requests",
|
||||||
"conf_logging_btn_autoscroll" : "Auto scrolling",
|
"conf_logging_btn_autoscroll" : "Auto scrolling",
|
||||||
|
@ -14,8 +14,7 @@ $(document).ready( function() {
|
|||||||
$(window.hyperion).trigger("ready");
|
$(window.hyperion).trigger("ready");
|
||||||
|
|
||||||
window.comps.forEach(function (obj) {
|
window.comps.forEach(function (obj) {
|
||||||
if (obj.name == "ALL")
|
if (obj.name == "ALL") {
|
||||||
{
|
|
||||||
if (obj.enabled)
|
if (obj.enabled)
|
||||||
$("#hyperion_disabled_notify").fadeOut("fast");
|
$("#hyperion_disabled_notify").fadeOut("fast");
|
||||||
else
|
else
|
||||||
@ -31,8 +30,7 @@ $(document).ready( function() {
|
|||||||
$('#btn_hypinstanceswitch').toggle(false)
|
$('#btn_hypinstanceswitch').toggle(false)
|
||||||
// update listing at button
|
// update listing at button
|
||||||
updateHyperionInstanceListing()
|
updateHyperionInstanceListing()
|
||||||
if(!instNameInit)
|
if (!instNameInit) {
|
||||||
{
|
|
||||||
window.currentHyperionInstanceName = getInstanceNameByIndex(0);
|
window.currentHyperionInstanceName = getInstanceNameByIndex(0);
|
||||||
instNameInit = true;
|
instNameInit = true;
|
||||||
}
|
}
|
||||||
@ -45,6 +43,29 @@ $(document).ready( function() {
|
|||||||
updateSessions();
|
updateSessions();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(window.hyperion).on("cmd-authorize-tokenRequest cmd-authorize-getPendingTokenRequests", function (event) {
|
||||||
|
var val = event.response.info;
|
||||||
|
if (Array.isArray(event.response.info)) {
|
||||||
|
if (event.response.info.length == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val = event.response.info[0]
|
||||||
|
if (val.comment == '')
|
||||||
|
$('#modal_dialog').modal('hide');
|
||||||
|
}
|
||||||
|
|
||||||
|
showInfoDialog("grantToken", $.i18n('conf_network_tok_grantT'), $.i18n('conf_network_tok_grantMsg') + '<br><span style="font-weight:bold">App: ' + val.comment + '</span><br><span style="font-weight:bold">Code: ' + val.id + '</span>')
|
||||||
|
$("#tok_grant_acc").off().on('click', function () {
|
||||||
|
tokenList.push(val)
|
||||||
|
// forward event, in case we need to rebuild the list now
|
||||||
|
$(window.hyperion).trigger({ type: "build-token-list" });
|
||||||
|
requestHandleTokenRequest(val.id, true)
|
||||||
|
});
|
||||||
|
$("#tok_deny_acc").off().on('click', function () {
|
||||||
|
requestHandleTokenRequest(val.id, false)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$(window.hyperion).one("cmd-authorize-getTokenList", function (event) {
|
$(window.hyperion).one("cmd-authorize-getTokenList", function (event) {
|
||||||
tokenList = event.response.info;
|
tokenList = event.response.info;
|
||||||
requestServerInfo();
|
requestServerInfo();
|
||||||
@ -62,6 +83,7 @@ $(document).ready( function() {
|
|||||||
window.serverSchema = event.response.info;
|
window.serverSchema = event.response.info;
|
||||||
requestServerConfig();
|
requestServerConfig();
|
||||||
requestTokenInfo();
|
requestTokenInfo();
|
||||||
|
requestGetPendingTokenRequests();
|
||||||
|
|
||||||
window.schema = window.serverSchema.properties;
|
window.schema = window.serverSchema.properties;
|
||||||
});
|
});
|
||||||
@ -107,8 +129,7 @@ $(document).ready( function() {
|
|||||||
$(window.hyperion).on("cmd-authorize-newPasswordRequired", function (event) {
|
$(window.hyperion).on("cmd-authorize-newPasswordRequired", function (event) {
|
||||||
var loginToken = getStorage("loginToken", true)
|
var loginToken = getStorage("loginToken", true)
|
||||||
|
|
||||||
if (event.response.info.newPasswordRequired == true)
|
if (event.response.info.newPasswordRequired == true) {
|
||||||
{
|
|
||||||
window.defaultPasswordIsSet = true;
|
window.defaultPasswordIsSet = true;
|
||||||
|
|
||||||
if (loginToken)
|
if (loginToken)
|
||||||
@ -116,8 +137,7 @@ $(document).ready( function() {
|
|||||||
else
|
else
|
||||||
requestAuthorization('hyperion');
|
requestAuthorization('hyperion');
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
$("#main-nav").attr('style', 'display:none')
|
$("#main-nav").attr('style', 'display:none')
|
||||||
$("#top-navbar").attr('style', 'display:none')
|
$("#top-navbar").attr('style', 'display:none')
|
||||||
|
|
||||||
@ -141,13 +161,11 @@ $(document).ready( function() {
|
|||||||
$(window.hyperion).on("error", function (event) {
|
$(window.hyperion).on("error", function (event) {
|
||||||
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
|
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
|
||||||
//e.g.: hyperiond was started new in the meantime)
|
//e.g.: hyperiond was started new in the meantime)
|
||||||
if (event.reason == "No Authorization" && getStorage("loginToken", true))
|
if (event.reason == "No Authorization" && getStorage("loginToken", true)) {
|
||||||
{
|
|
||||||
removeStorage("loginToken", true);
|
removeStorage("loginToken", true);
|
||||||
requestRequiresAdminAuth();
|
requestRequiresAdminAuth();
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
showInfoDialog("error", "Error", event.reason);
|
showInfoDialog("error", "Error", event.reason);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -172,8 +190,7 @@ $(document).ready( function() {
|
|||||||
let obj = event.response.data
|
let obj = event.response.data
|
||||||
|
|
||||||
// notfication in index
|
// notfication in index
|
||||||
if (obj.name == "ALL")
|
if (obj.name == "ALL") {
|
||||||
{
|
|
||||||
if (obj.enabled)
|
if (obj.enabled)
|
||||||
$("#hyperion_disabled_notify").fadeOut("fast");
|
$("#hyperion_disabled_notify").fadeOut("fast");
|
||||||
else
|
else
|
||||||
@ -197,16 +214,13 @@ $(document).ready( function() {
|
|||||||
|
|
||||||
// if our current instance is no longer available we are at instance 0 again.
|
// if our current instance is no longer available we are at instance 0 again.
|
||||||
var isInData = false;
|
var isInData = false;
|
||||||
for(var key in avail)
|
for (var key in avail) {
|
||||||
{
|
if (avail[key].instance == currentHyperionInstance && avail[key].running) {
|
||||||
if(avail[key].instance == currentHyperionInstance && avail[key].running)
|
|
||||||
{
|
|
||||||
isInData = true;
|
isInData = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isInData)
|
if (!isInData) {
|
||||||
{
|
|
||||||
//Delete Storage information about the last used but now stopped instance
|
//Delete Storage information about the last used but now stopped instance
|
||||||
if (getStorage('lastSelectedInstance', false))
|
if (getStorage('lastSelectedInstance', false))
|
||||||
removeStorage('lastSelectedInstance', false)
|
removeStorage('lastSelectedInstance', false)
|
||||||
|
@ -204,6 +204,10 @@ function requestTokenInfo()
|
|||||||
sendToHyperion("authorize","getTokenList","");
|
sendToHyperion("authorize","getTokenList","");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requestGetPendingTokenRequests (id, state) {
|
||||||
|
sendToHyperion("authorize", "getPendingTokenRequests", "");
|
||||||
|
}
|
||||||
|
|
||||||
function requestHandleTokenRequest(id, state)
|
function requestHandleTokenRequest(id, state)
|
||||||
{
|
{
|
||||||
sendToHyperion("authorize","answerRequest",'"id":"'+id+'", "accept":'+state);
|
sendToHyperion("authorize","answerRequest",'"id":"'+id+'", "accept":'+state);
|
||||||
|
409
include/api/API.h
Normal file
409
include/api/API.h
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// hyperion includes
|
||||||
|
#include <utils/Logger.h>
|
||||||
|
#include <utils/Components.h>
|
||||||
|
#include <hyperion/Hyperion.h>
|
||||||
|
#include <hyperion/HyperionIManager.h>
|
||||||
|
// auth manager
|
||||||
|
#include <hyperion/AuthManager.h>
|
||||||
|
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
#include <utils/ColorSys.h>
|
||||||
|
|
||||||
|
// qt includes
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
class JsonCB;
|
||||||
|
class HyperionIManager;
|
||||||
|
|
||||||
|
const QString NO_AUTH = "No Authorization";
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief API for Hyperion to be inherted from a child class with specific protocol implementations
|
||||||
|
/// Workflow:
|
||||||
|
/// 1. create the class
|
||||||
|
/// 2. connect the forceClose signal, as the api might to close the connection for security reasons
|
||||||
|
/// 3. call Initialize()
|
||||||
|
/// 4. proceed as usual
|
||||||
|
///
|
||||||
|
|
||||||
|
class API : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
#include <api/apiStructs.h>
|
||||||
|
// workaround Q_ARG std::map template issues
|
||||||
|
typedef std::map<int, registerData> MapRegister;
|
||||||
|
typedef QMap<QString, AuthManager::AuthDefinition> MapAuthDefs;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Constructor
|
||||||
|
///
|
||||||
|
///@ param The parent Logger
|
||||||
|
/// @param localConnection Is this a local network connection? Use utils/NetOrigin to check that
|
||||||
|
/// @param parent Parent QObject
|
||||||
|
///
|
||||||
|
API(Logger *log, const bool &localConnection, QObject *parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///
|
||||||
|
/// @brief Initialize the API
|
||||||
|
/// This call is REQUIRED!
|
||||||
|
///
|
||||||
|
void init(void);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set a single color
|
||||||
|
/// @param[in] priority The priority of the written color
|
||||||
|
/// @param[in] ledColor The color to write to the leds
|
||||||
|
/// @param[in] timeout_ms The time the leds are set to the given color [ms]
|
||||||
|
/// @param[in] origin The setter
|
||||||
|
///
|
||||||
|
void setColor(const int &priority, const std::vector<uint8_t> &ledColors, const int &timeout_ms = -1, const QString &origin = "API", const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set a image
|
||||||
|
/// @param[in] data The command data
|
||||||
|
/// @param[in] comp The component that should be used
|
||||||
|
/// @param[out] replyMsg The replyMsg on failure
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
/// @return True on success
|
||||||
|
///
|
||||||
|
bool setImage(ImageCmdData &data, hyperion::Components comp, QString &replyMsg, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Clear a priority in the Muxer, if -1 all priorities are cleared
|
||||||
|
/// @param priority The priority to clear
|
||||||
|
/// @param replyMsg the message on failure
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
/// @return True on success
|
||||||
|
///
|
||||||
|
bool clearPriority(const int &priority, QString &replyMsg, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set a new component state
|
||||||
|
/// @param comp The component name
|
||||||
|
/// @param compState The new state of the comp
|
||||||
|
/// @param replyMsg The reply on failure
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
/// @ return True on success
|
||||||
|
///
|
||||||
|
bool setComponentState(const QString &comp, bool &compState, QString &replyMsg, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set a ledToImageMapping type
|
||||||
|
/// @param type mapping type string
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
///
|
||||||
|
void setLedMappingType(const int &type, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set the 2D/3D modes type
|
||||||
|
/// @param mode The VideoMode
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
///
|
||||||
|
void setVideoMode(const VideoMode &mode, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set an effect
|
||||||
|
/// @param dat The effect data
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
/// REQUIRED dat fields: effectName, priority, duration, origin
|
||||||
|
///
|
||||||
|
void setEffect(const EffectCmdData &dat, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set source auto select enabled or disabled
|
||||||
|
/// @param sate The new state
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
///
|
||||||
|
void setSourceAutoSelect(const bool state, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set the visible priority to given priority
|
||||||
|
/// @param priority The priority to set
|
||||||
|
/// @param callerComp The HYPERION COMPONENT that calls this function! e.g. PROT/FLATBUF
|
||||||
|
///
|
||||||
|
void setVisiblePriority(const int &priority, const hyperion::Components &callerComp = hyperion::COMP_INVALID);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Register a input or update the meta data of a previous register call
|
||||||
|
/// ATTENTION: Check unregisterInput() method description !!!
|
||||||
|
/// @param[in] priority The priority of the channel
|
||||||
|
/// @param[in] component The component of the channel
|
||||||
|
/// @param[in] origin Who set the channel (CustomString@IP)
|
||||||
|
/// @param[in] owner Specific owner string, might be empty
|
||||||
|
/// @param[in] callerComp The component that call this (e.g. PROTO/FLAT)
|
||||||
|
///
|
||||||
|
void registerInput(const int &priority, const hyperion::Components &component, const QString &origin, const QString &owner, const hyperion::Components &callerComp);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Revoke a registerInput() call by priority. We maintain all registered priorities in this scope
|
||||||
|
/// ATTENTION: This is MANDATORY if you change (priority change) or stop(clear/timeout) DURING lifetime. If this class destructs it's not needed
|
||||||
|
/// @param priority The priority to unregister
|
||||||
|
///
|
||||||
|
void unregisterInput(const int &priority);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Handle the instance switching
|
||||||
|
/// @param inst The requested instance
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
bool setHyperionInstance(const quint8 &inst);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get all contrable components and their state
|
||||||
|
///
|
||||||
|
std::map<hyperion::Components, bool> getAllComponents();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if Hyperion ist enabled
|
||||||
|
/// @return True when enabled else false
|
||||||
|
///
|
||||||
|
bool isHyperionEnabled();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get all instances data
|
||||||
|
/// @return The instance data
|
||||||
|
///
|
||||||
|
QVector<QVariantMap> getAllInstanceData(void);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Start instance
|
||||||
|
/// @param index The instance index
|
||||||
|
///
|
||||||
|
void startInstance(const quint8 &index);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Stop instance
|
||||||
|
/// @param index The instance index
|
||||||
|
///
|
||||||
|
void stopInstance(const quint8 &index);
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
/// AUTH / ADMINISTRATION METHODS
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete instance. Requires ADMIN ACCESS
|
||||||
|
/// @param index The instance index
|
||||||
|
/// @param replyMsg The reply Msg
|
||||||
|
/// @return False with reply
|
||||||
|
///
|
||||||
|
bool deleteInstance(const quint8 &index, QString &replyMsg);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Create instance. Requires ADMIN ACCESS
|
||||||
|
/// @param name With given name
|
||||||
|
/// @return False with reply
|
||||||
|
///
|
||||||
|
QString createInstance(const QString &name);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Rename an instance. Requires ADMIN ACCESS
|
||||||
|
/// @param index The instance index
|
||||||
|
/// @param name With given name
|
||||||
|
/// @return False with reply
|
||||||
|
///
|
||||||
|
QString setInstanceName(const quint8 &index, const QString &name);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete an effect. Requires ADMIN ACCESS
|
||||||
|
/// @param name The effect name
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
QString deleteEffect(const QString &name);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete an effect. Requires ADMIN ACCESS
|
||||||
|
/// @param name The effect name
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
QString saveEffect(const QJsonObject &data);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Save settings object. Requires ADMIN ACCESS
|
||||||
|
/// @param data The data object
|
||||||
|
///
|
||||||
|
void saveSettings(const QJsonObject &data);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Test if we are authorized to use the interface
|
||||||
|
/// @return The result
|
||||||
|
///
|
||||||
|
bool isAuthorized() { return _authorized; };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Test if we are authorized to use the admin interface
|
||||||
|
/// @return The result
|
||||||
|
///
|
||||||
|
bool isAdminAuthorized() { return _adminAuthorized; };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Update the Password of Hyperion. Requires ADMIN ACCESS
|
||||||
|
/// @param password Old password
|
||||||
|
/// @param newPassword New password
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
bool updateHyperionPassword(const QString &password, const QString &newPassword);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get a new token from AuthManager. Requires ADMIN ACCESS
|
||||||
|
/// @param comment The comment of the request
|
||||||
|
/// @param def The final definition
|
||||||
|
/// @return Empty string on success else error message
|
||||||
|
///
|
||||||
|
QString createToken(const QString &comment, AuthManager::AuthDefinition &def);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Rename a token by given id. Requires ADMIN ACCESS
|
||||||
|
/// @param id The id of the token
|
||||||
|
/// @param comment The new comment
|
||||||
|
/// @return Empty string on success else error message
|
||||||
|
///
|
||||||
|
QString renameToken(const QString &id, const QString &comment);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete a token by given id. Requires ADMIN ACCESS
|
||||||
|
/// @param id The id of the token
|
||||||
|
/// @return Empty string on success else error message
|
||||||
|
///
|
||||||
|
QString deleteToken(const QString &id);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Set a new token request
|
||||||
|
/// @param comment The comment
|
||||||
|
/// @param id The id
|
||||||
|
///
|
||||||
|
void setNewTokenRequest(const QString &comment, const QString &id);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Cancel new token request
|
||||||
|
/// @param comment The comment
|
||||||
|
/// @param id The id
|
||||||
|
///
|
||||||
|
void cancelNewTokenRequest(const QString &comment, const QString &id);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Handle a pending token request. Requires ADMIN ACCESS
|
||||||
|
/// @param id The id fo the request
|
||||||
|
/// @param accept True when it should be accepted, else false
|
||||||
|
/// @return True on success
|
||||||
|
bool handlePendingTokenRequest(const QString &id, const bool accept);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get the current List of Tokens. Requires ADMIN ACCESS
|
||||||
|
/// @param def returns the defintions
|
||||||
|
/// @return True on success
|
||||||
|
///
|
||||||
|
bool getTokenList(QVector<AuthManager::AuthDefinition> &def);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get all current pending token requests. Requires ADMIN ACCESS
|
||||||
|
/// @return True on success
|
||||||
|
///
|
||||||
|
bool getPendingTokenRequests(QVector<AuthManager::AuthDefinition> &map);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Is User Token Authorized. On success this will grant acces to API and ADMIN API
|
||||||
|
/// @param userToken The user Token
|
||||||
|
/// @return True on succes
|
||||||
|
///
|
||||||
|
bool isUserTokenAuthorized(const QString &userToken);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get the current User Token (session token). Requires ADMIN ACCESS
|
||||||
|
/// @param userToken The user Token
|
||||||
|
/// @return True on success
|
||||||
|
///
|
||||||
|
bool getUserToken(QString &userToken);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Is a token authrized. On success this will grant acces to the API (NOT ADMIN API)
|
||||||
|
/// @param token The user Token
|
||||||
|
/// @return True on succes
|
||||||
|
///
|
||||||
|
bool isTokenAuthorized(const QString &token);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Is User authorized. On success this will grant acces to the API and ADMIN API
|
||||||
|
/// @param password The password of the User
|
||||||
|
/// @return True if authorized
|
||||||
|
///
|
||||||
|
bool isUserAuthorized(const QString &password);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Test if Hyperion has the default PW
|
||||||
|
/// @return The result
|
||||||
|
///
|
||||||
|
bool hasHyperionDefaultPw();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Logout revokes all authorizations
|
||||||
|
///
|
||||||
|
void logout();
|
||||||
|
|
||||||
|
/// Reflect auth status of this client
|
||||||
|
bool _authorized;
|
||||||
|
bool _adminAuthorized;
|
||||||
|
|
||||||
|
/// Is this a local connection
|
||||||
|
bool _localConnection;
|
||||||
|
|
||||||
|
AuthManager *_authManager;
|
||||||
|
HyperionIManager *_instanceManager;
|
||||||
|
|
||||||
|
Logger *_log;
|
||||||
|
Hyperion *_hyperion;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
///
|
||||||
|
/// @brief The API might decide to block connections for security reasons, this emitter should close the socket
|
||||||
|
///
|
||||||
|
void forceClose();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Emits whenever a new Token request is pending. This signal is just active when ADMIN ACCESS has been granted
|
||||||
|
/// @param id The id of the request
|
||||||
|
/// @param comment The comment of the request; If the commen is EMPTY the request has been revoked by the caller. So remove it from the pending list
|
||||||
|
///
|
||||||
|
void onPendingTokenRequest(const QString &id, const QString &comment);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Handle emits from AuthManager of accepted/denied/timeouts token request, just if QObject matches with this instance it will emit.
|
||||||
|
/// @param success If true the request was accepted else false and no token was created
|
||||||
|
/// @param token The new token that is now valid
|
||||||
|
/// @param comment The comment that was part of the request
|
||||||
|
/// @param id The id that was part of the request
|
||||||
|
///
|
||||||
|
void onTokenResponse(const bool &success, const QString &token, const QString &comment, const QString &id);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
///
|
||||||
|
/// @brief Is called whenever a Hyperion instance wants the current register list
|
||||||
|
/// @param callerInstance The instance should be returned in the answer call
|
||||||
|
///
|
||||||
|
void requestActiveRegister(QObject *callerInstance);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief See onTokenResponse(). Here we validate the caller instance and on success we will emit onTokenResponse()
|
||||||
|
/// @param success If true the request was accepted else false and no token was created
|
||||||
|
/// @param caller The origin caller instance who requested this token
|
||||||
|
/// @param token The new token that is now valid
|
||||||
|
/// @param comment The comment that was part of the request
|
||||||
|
/// @param id The id that was part of the request
|
||||||
|
///
|
||||||
|
void checkTokenResponse(const bool &success, QObject *caller, const QString &token, const QString &comment, const QString &id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void stopDataConnectionss();
|
||||||
|
|
||||||
|
// Contains all active register call data
|
||||||
|
std::map<int, registerData> _activeRegisters;
|
||||||
|
|
||||||
|
// current instance index
|
||||||
|
quint8 _currInstanceIndex;
|
||||||
|
};
|
@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// parent class
|
||||||
|
#include <api/API.h>
|
||||||
|
|
||||||
// hyperion includes
|
// hyperion includes
|
||||||
#include <utils/Logger.h>
|
|
||||||
#include <utils/Components.h>
|
#include <utils/Components.h>
|
||||||
#include <hyperion/Hyperion.h>
|
#include <hyperion/Hyperion.h>
|
||||||
#include <hyperion/HyperionIManager.h>
|
#include <hyperion/HyperionIManager.h>
|
||||||
@ -14,7 +16,7 @@ class QTimer;
|
|||||||
class JsonCB;
|
class JsonCB;
|
||||||
class AuthManager;
|
class AuthManager;
|
||||||
|
|
||||||
class JsonAPI : public QObject
|
class JsonAPI : public API
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@ -62,21 +64,20 @@ public slots:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
///
|
///
|
||||||
/// @brief Handle emits from AuthManager of new request, just _userAuthorized sessions are allowed to handle them
|
/// @brief Handle emits from API of a new Token request.
|
||||||
/// @param id The id of the request
|
/// @param id The id of the request
|
||||||
/// @param The comment which needs to be accepted
|
/// @param The comment which needs to be accepted
|
||||||
///
|
///
|
||||||
void handlePendingTokenRequest(const QString& id, const QString& comment);
|
void newPendingTokenRequest(const QString &id, const QString &comment);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Handle emits from AuthManager of accepted/denied/timeouts token request, just if QObject matches with this instance we are allowed to send response.
|
/// @brief Handle emits from AuthManager of accepted/denied/timeouts token request, just if QObject matches with this instance we are allowed to send response.
|
||||||
/// @param success If true the request was accepted else false and no token was created
|
/// @param success If true the request was accepted else false and no token was created
|
||||||
/// @param caller The origin caller instance who requested this token
|
|
||||||
/// @param token The new token that is now valid
|
/// @param token The new token that is now valid
|
||||||
/// @param comment The comment that was part of the request
|
/// @param comment The comment that was part of the request
|
||||||
/// @param id The id that was part of the request
|
/// @param id The id that was part of the request
|
||||||
///
|
///
|
||||||
void handleTokenResponse(const bool& success, QObject* caller, const QString& token, const QString& comment, const QString& id);
|
void handleTokenResponse(const bool &success, const QString &token, const QString &comment, const QString &id);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Handle whenever the state of a instance (HyperionIManager) changes according to enum instanceState
|
/// @brief Handle whenever the state of a instance (HyperionIManager) changes according to enum instanceState
|
||||||
@ -97,40 +98,13 @@ signals:
|
|||||||
///
|
///
|
||||||
void forwardJsonMessage(QJsonObject);
|
void forwardJsonMessage(QJsonObject);
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief The API might decide to block connections for security reasons, this emitter should close the socket
|
|
||||||
///
|
|
||||||
void forceClose();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Auth management pointer
|
|
||||||
AuthManager* _authManager;
|
|
||||||
|
|
||||||
/// Reflect auth status of this client
|
|
||||||
bool _authorized;
|
|
||||||
bool _userAuthorized;
|
|
||||||
|
|
||||||
/// Reflect auth required
|
|
||||||
bool _apiAuthRequired;
|
|
||||||
|
|
||||||
// true if further callbacks are forbidden (http)
|
// true if further callbacks are forbidden (http)
|
||||||
bool _noListener;
|
bool _noListener;
|
||||||
|
|
||||||
/// The peer address of the client
|
/// The peer address of the client
|
||||||
QString _peerAddress;
|
QString _peerAddress;
|
||||||
|
|
||||||
/// Log instance
|
|
||||||
Logger* _log;
|
|
||||||
|
|
||||||
/// Is this a local connection
|
|
||||||
bool _localConnection;
|
|
||||||
|
|
||||||
/// Hyperion instance manager
|
|
||||||
HyperionIManager* _instanceManager;
|
|
||||||
|
|
||||||
/// Hyperion instance
|
|
||||||
Hyperion* _hyperion;
|
|
||||||
|
|
||||||
// The JsonCB instance which handles data subscription/notifications
|
// The JsonCB instance which handles data subscription/notifications
|
||||||
JsonCB *_jsonCB;
|
JsonCB *_jsonCB;
|
||||||
|
|
||||||
@ -142,15 +116,6 @@ private:
|
|||||||
/// flag to determine state of log streaming
|
/// flag to determine state of log streaming
|
||||||
bool _streaming_logging_activated;
|
bool _streaming_logging_activated;
|
||||||
|
|
||||||
/// timer for live video refresh
|
|
||||||
QTimer* _imageStreamTimer;
|
|
||||||
|
|
||||||
/// image stream connection handle
|
|
||||||
QMetaObject::Connection _imageStreamConnection;
|
|
||||||
|
|
||||||
/// the current streaming image
|
|
||||||
Image<ColorRgb> _currentImage;
|
|
||||||
|
|
||||||
/// timer for led color refresh
|
/// timer for led color refresh
|
||||||
QTimer *_ledStreamTimer;
|
QTimer *_ledStreamTimer;
|
||||||
|
|
||||||
@ -300,15 +265,6 @@ private:
|
|||||||
///
|
///
|
||||||
void handleAuthorizeCommand(const QJsonObject &message, const QString &command, const int tan);
|
void handleAuthorizeCommand(const QJsonObject &message, const QString &command, const int tan);
|
||||||
|
|
||||||
///
|
|
||||||
/// Handle HTTP on-the-fly token authorization
|
|
||||||
/// @param command The command
|
|
||||||
/// @param tan The tan
|
|
||||||
/// @param token The token to verify
|
|
||||||
/// @return True on succcess else false (pushes failed client feedback)
|
|
||||||
///
|
|
||||||
bool handleHTTPAuth(const QString& command, const int& tan, const QString& token);
|
|
||||||
|
|
||||||
/// Handle an incoming JSON instance message
|
/// Handle an incoming JSON instance message
|
||||||
///
|
///
|
||||||
/// @param message the incoming message
|
/// @param message the incoming message
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
// settings
|
// settings
|
||||||
#include <utils/settings.h>
|
#include <utils/settings.h>
|
||||||
|
// AuthManager
|
||||||
|
#include <hyperion/AuthManager.h>
|
||||||
|
|
||||||
class Hyperion;
|
class Hyperion;
|
||||||
class ComponentRegister;
|
class ComponentRegister;
|
||||||
@ -119,6 +121,11 @@ private slots:
|
|||||||
///
|
///
|
||||||
void handleInstanceChange();
|
void handleInstanceChange();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Handle AuthManager token changes
|
||||||
|
///
|
||||||
|
void handleTokenChange(const QVector<AuthManager::AuthDefinition> &def);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// pointer of Hyperion instance
|
/// pointer of Hyperion instance
|
||||||
Hyperion* _hyperion;
|
Hyperion* _hyperion;
|
||||||
|
36
include/api/apiStructs.h
Normal file
36
include/api/apiStructs.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
struct ImageCmdData
|
||||||
|
{
|
||||||
|
int priority;
|
||||||
|
QString origin;
|
||||||
|
int64_t duration;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int scale;
|
||||||
|
QString format;
|
||||||
|
QString imgName;
|
||||||
|
QByteArray data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EffectCmdData
|
||||||
|
{
|
||||||
|
int priority;
|
||||||
|
int duration;
|
||||||
|
QString pythonScript;
|
||||||
|
QString origin;
|
||||||
|
QString effectName;
|
||||||
|
QString data;
|
||||||
|
QJsonObject args;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct registerData
|
||||||
|
{
|
||||||
|
const hyperion::Components component;
|
||||||
|
const QString origin;
|
||||||
|
const QString owner;
|
||||||
|
const hyperion::Components callerComp;
|
||||||
|
};
|
@ -222,6 +222,22 @@ public:
|
|||||||
return deleteRecord(cond);
|
return deleteRecord(cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Rename token record by id
|
||||||
|
/// @param[in] id The token id
|
||||||
|
/// @param[in] comment The new comment
|
||||||
|
/// @return true on success else false
|
||||||
|
///
|
||||||
|
inline bool renameToken(const QString &id, const QString &comment)
|
||||||
|
{
|
||||||
|
QVariantMap map;
|
||||||
|
map["comment"] = comment;
|
||||||
|
|
||||||
|
VectorPair cond;
|
||||||
|
cond.append(CPair("id", id));
|
||||||
|
return updateRecord(cond, map);
|
||||||
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Get all 'comment', 'last_use' and 'id' column entries
|
/// @brief Get all 'comment', 'last_use' and 'id' column entries
|
||||||
/// @return A vector of all lists
|
/// @return A vector of all lists
|
||||||
|
@ -42,18 +42,16 @@ public:
|
|||||||
///
|
///
|
||||||
/// @brief Save an effect with EffectFileHandler
|
/// @brief Save an effect with EffectFileHandler
|
||||||
/// @param obj The effect args
|
/// @param obj The effect args
|
||||||
/// @param[out] resultMsg The feedback message
|
/// @return If not empty, it contains the error
|
||||||
/// @return True on success else false
|
|
||||||
///
|
///
|
||||||
bool saveEffect(const QJsonObject& obj, QString& resultMsg);
|
QString saveEffect(const QJsonObject& obj);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Delete an effect by name.
|
/// @brief Delete an effect by name.
|
||||||
/// @param[in] effectName The effect name to delete
|
/// @param effectName The effect name to delete
|
||||||
/// @param[out] resultMsg The message on error
|
/// @return If not empty, it contains the error
|
||||||
/// @return True on success else false
|
|
||||||
///
|
///
|
||||||
bool deleteEffect(const QString& effectName, QString& resultMsg);
|
QString deleteEffect(const QString& effectName);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Get all init data of the running effects and stop them
|
/// @brief Get all init data of the running effects and stop them
|
||||||
|
@ -30,18 +30,16 @@ public:
|
|||||||
///
|
///
|
||||||
/// @brief Save an effect
|
/// @brief Save an effect
|
||||||
/// @param obj The effect args
|
/// @param obj The effect args
|
||||||
/// @param[out] resultMsg The feedback message
|
/// @return If not empty, it contains the error
|
||||||
/// @return True on success else false
|
|
||||||
///
|
///
|
||||||
bool saveEffect(const QJsonObject& obj, QString& resultMsg);
|
QString saveEffect(const QJsonObject& obj);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Delete an effect by name.
|
/// @brief Delete an effect by name.
|
||||||
/// @param[in] effectName The effect name to delete
|
/// @param effectName The effect name to delete
|
||||||
/// @param[out] resultMsg The message on error
|
/// @return If not empty, it contains the error
|
||||||
/// @return True on success else false
|
|
||||||
///
|
///
|
||||||
bool deleteEffect(const QString& effectName, QString& resultMsg);
|
QString deleteEffect(const QString& effectName);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
///
|
///
|
||||||
|
@ -23,7 +23,8 @@ private:
|
|||||||
AuthManager(QObject *parent = 0);
|
AuthManager(QObject *parent = 0);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct AuthDefinition{
|
struct AuthDefinition
|
||||||
|
{
|
||||||
QString id;
|
QString id;
|
||||||
QString comment;
|
QString comment;
|
||||||
QObject *caller;
|
QObject *caller;
|
||||||
@ -38,11 +39,6 @@ public:
|
|||||||
///
|
///
|
||||||
const QString &getID() { return _uuid; };
|
const QString &getID() { return _uuid; };
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get all available token entries
|
|
||||||
///
|
|
||||||
const QVector<AuthDefinition> getTokenList();
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Check authorization is required according to the user setting
|
/// @brief Check authorization is required according to the user setting
|
||||||
/// @return True if authorization required else false
|
/// @return True if authorization required else false
|
||||||
@ -61,19 +57,6 @@ public:
|
|||||||
///
|
///
|
||||||
const bool &isLocalAdminAuthRequired() { return _localAdminAuthRequired; };
|
const bool &isLocalAdminAuthRequired() { return _localAdminAuthRequired; };
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Check if Hyperion user has default password
|
|
||||||
/// @return True if so, else false
|
|
||||||
///
|
|
||||||
const bool hasHyperionDefaultPw() { return isUserAuthorized("Hyperion","hyperion"); };
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get the current valid token for user. Make sure this call is allowed!
|
|
||||||
/// @param For the defined user
|
|
||||||
/// @return The token
|
|
||||||
///
|
|
||||||
const QString getUserToken(const QString & usr = "Hyperion");
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Reset Hyperion user
|
/// @brief Reset Hyperion user
|
||||||
/// @return True on success else false
|
/// @return True on success else false
|
||||||
@ -81,11 +64,23 @@ public:
|
|||||||
bool resetHyperionUser();
|
bool resetHyperionUser();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Create a new token and skip the usual chain
|
/// @brief Check if user auth is temporary blocked due to failed attempts
|
||||||
/// @param comment The comment that should be used for
|
/// @return True on blocked and no further Auth requests will be accepted
|
||||||
/// @return The new Auth definition
|
|
||||||
///
|
///
|
||||||
const AuthDefinition createToken(const QString& comment);
|
bool isUserAuthBlocked() { return (_userAuthAttempts.length() >= 10); };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Check if token auth is temporary blocked due to failed attempts
|
||||||
|
/// @return True on blocked and no further Auth requests will be accepted
|
||||||
|
///
|
||||||
|
bool isTokenAuthBlocked() { return (_tokenAuthAttempts.length() >= 25); };
|
||||||
|
|
||||||
|
/// Pointer of this instance
|
||||||
|
static AuthManager *manager;
|
||||||
|
/// Get Pointer of this instance
|
||||||
|
static AuthManager *getInstance() { return manager; };
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Check if user is authorized
|
/// @brief Check if user is authorized
|
||||||
@ -111,16 +106,26 @@ public:
|
|||||||
bool isUserTokenAuthorized(const QString &usr, const QString &token);
|
bool isUserTokenAuthorized(const QString &usr, const QString &token);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Check if user auth is temporary blocked due to failed attempts
|
/// @brief Create a new token and skip the usual chain
|
||||||
/// @return True on blocked and no further Auth requests will be accepted
|
/// @param comment The comment that should be used for
|
||||||
|
/// @return The new Auth definition
|
||||||
///
|
///
|
||||||
bool isUserAuthBlocked(){ return (_userAuthAttempts.length() >= 10); };
|
AuthManager::AuthDefinition createToken(const QString &comment);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Check if token auth is temporary blocked due to failed attempts
|
/// @brief Rename a token by id
|
||||||
/// @return True on blocked and no further Auth requests will be accepted
|
/// @param id The token id
|
||||||
|
/// @param comment The new comment
|
||||||
|
/// @return True on success else false (or not found)
|
||||||
///
|
///
|
||||||
bool isTokenAuthBlocked(){ return (_tokenAuthAttempts.length() >= 25); };
|
bool renameToken(const QString &id, const QString &comment);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete a token by id
|
||||||
|
/// @param id The token id
|
||||||
|
/// @return True on success else false (or not found)
|
||||||
|
///
|
||||||
|
bool deleteToken(const QString &id);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Change password of user
|
/// @brief Change password of user
|
||||||
@ -140,38 +145,38 @@ public:
|
|||||||
void setNewTokenRequest(QObject *caller, const QString &comment, const QString &id);
|
void setNewTokenRequest(QObject *caller, const QString &comment, const QString &id);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Accept a token request by id, generate token and inform token caller
|
/// @brief Cancel a pending token request with the provided comment and id as identifier helper
|
||||||
/// @param id The id of the request
|
/// @param caller The QObject of the caller to deliver the reply
|
||||||
/// @return True on success, false if not found
|
/// @param comment The comment as ident helper
|
||||||
|
/// @param id The id created by the caller
|
||||||
///
|
///
|
||||||
bool acceptTokenRequest(const QString& id);
|
void cancelNewTokenRequest(QObject *caller, const QString &comment, const QString &id);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Deny a token request by id, inform the requester
|
/// @brief Handle a token request by id, generate token and inform token caller or deny
|
||||||
/// @param id The id of the request
|
/// @param id The id of the request
|
||||||
/// @return True on success, false if not found
|
/// @param accept The accept or deny the request
|
||||||
///
|
///
|
||||||
bool denyTokenRequest(const QString& id);
|
void handlePendingTokenRequest(const QString &id, const bool &accept);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Get pending requests
|
/// @brief Get pending requests
|
||||||
/// @return All pending requests
|
/// @return All pending requests
|
||||||
///
|
///
|
||||||
const QMap<QString, AuthDefinition> getPendingRequests();
|
QVector<AuthManager::AuthDefinition> getPendingRequests();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Delete a token by id
|
/// @brief Get the current valid token for user. Make sure this call is allowed!
|
||||||
/// @param id The token id
|
/// @param usr the defined user
|
||||||
/// @return True on success else false (or not found)
|
/// @return The token
|
||||||
///
|
///
|
||||||
bool deleteToken(const QString& id);
|
const QString getUserToken(const QString &usr = "Hyperion");
|
||||||
|
|
||||||
/// Pointer of this instance
|
///
|
||||||
static AuthManager* manager;
|
/// @brief Get all available token entries
|
||||||
/// Get Pointer of this instance
|
///
|
||||||
static AuthManager* getInstance() { return manager; };
|
QVector<AuthManager::AuthDefinition> getTokenList();
|
||||||
|
|
||||||
public slots:
|
|
||||||
///
|
///
|
||||||
/// @brief Handle settings update from Hyperion Settingsmanager emit
|
/// @brief Handle settings update from Hyperion Settingsmanager emit
|
||||||
/// @param type settings type from enum
|
/// @param type settings type from enum
|
||||||
@ -183,7 +188,7 @@ signals:
|
|||||||
///
|
///
|
||||||
/// @brief Emits whenever a new token Request has been created along with the id and comment
|
/// @brief Emits whenever a new token Request has been created along with the id and comment
|
||||||
/// @param id The id of the request
|
/// @param id The id of the request
|
||||||
/// @param comment The comment of the request
|
/// @param comment The comment of the request; If the comment is EMPTY, it's a revoke of the caller!
|
||||||
///
|
///
|
||||||
void newPendingTokenRequest(const QString &id, const QString &comment);
|
void newPendingTokenRequest(const QString &id, const QString &comment);
|
||||||
|
|
||||||
@ -197,6 +202,12 @@ signals:
|
|||||||
///
|
///
|
||||||
void tokenResponse(const bool &success, QObject *caller, const QString &token, const QString &comment, const QString &id);
|
void tokenResponse(const bool &success, QObject *caller, const QString &token, const QString &comment, const QString &id);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Emits whenever the token list changes
|
||||||
|
/// @param data The full list of tokens
|
||||||
|
///
|
||||||
|
void tokenChange(QVector<AuthManager::AuthDefinition>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
/// @brief Increment counter for token/user auth
|
/// @brief Increment counter for token/user auth
|
||||||
|
@ -78,35 +78,8 @@ public:
|
|||||||
///
|
///
|
||||||
void freeObjects(bool emitCloseSignal=false);
|
void freeObjects(bool emitCloseSignal=false);
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get a pointer to the effect engine
|
|
||||||
/// @return EffectEngine instance pointer
|
|
||||||
///
|
|
||||||
EffectEngine* getEffectEngineInstance() { return _effectEngine; };
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get a pointer to the priorityMuxer instance
|
|
||||||
/// @return PriorityMuxer instance pointer
|
|
||||||
///
|
|
||||||
PriorityMuxer* getMuxerInstance() { return &_muxer; };
|
|
||||||
|
|
||||||
ImageProcessor* getImageProcessor() { return _imageProcessor; };
|
ImageProcessor* getImageProcessor() { return _imageProcessor; };
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get a setting by settings::type from SettingsManager
|
|
||||||
/// @param type The settingsType from enum
|
|
||||||
/// @return Data Document
|
|
||||||
///
|
|
||||||
QJsonDocument getSetting(const settings::type& type);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Save a complete json config
|
|
||||||
/// @param config The entire config object
|
|
||||||
/// @param correct If true will correct json against schema before save
|
|
||||||
/// @return True on success else false
|
|
||||||
///
|
|
||||||
bool saveSettings(QJsonObject config, const bool& correct = false);
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Get instance index of this instance
|
/// @brief Get instance index of this instance
|
||||||
/// @return The index of this instance
|
/// @return The index of this instance
|
||||||
@ -123,103 +96,6 @@ public:
|
|||||||
///
|
///
|
||||||
QSize getLedGridSize() const { return _ledGridSize; };
|
QSize getLedGridSize() const { return _ledGridSize; };
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the current priority
|
|
||||||
///
|
|
||||||
/// @return The current priority
|
|
||||||
///
|
|
||||||
int getCurrentPriority() const;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns true if current priority is given priority
|
|
||||||
///
|
|
||||||
/// @return bool
|
|
||||||
///
|
|
||||||
bool isCurrentPriority(const int priority) const;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a list of all registered priorities
|
|
||||||
///
|
|
||||||
/// @return The list with priorities
|
|
||||||
///
|
|
||||||
QList<int> getActivePriorities() const;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns the information of a specific priorrity channel
|
|
||||||
///
|
|
||||||
/// @param[in] priority The priority channel
|
|
||||||
///
|
|
||||||
/// @return The information of the given, a not found priority will return lowest priority as fallback
|
|
||||||
///
|
|
||||||
const InputInfo getPriorityInfo(const int priority) const;
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Save an effect
|
|
||||||
/// @param obj The effect args
|
|
||||||
/// @param[out] resultMsg The feedback message
|
|
||||||
/// @return True on success else false
|
|
||||||
///
|
|
||||||
bool saveEffect(const QJsonObject& obj, QString& resultMsg);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Delete an effect by name.
|
|
||||||
/// @param[in] effectName The effect name to delete
|
|
||||||
/// @param[out] resultMsg The message on error
|
|
||||||
/// @return True on success else false
|
|
||||||
///
|
|
||||||
bool deleteEffect(const QString& effectName, QString& resultMsg);
|
|
||||||
|
|
||||||
/// Get the list of available effects
|
|
||||||
/// @return The list of available effects
|
|
||||||
const std::list<EffectDefinition> &getEffects() const;
|
|
||||||
|
|
||||||
/// Get the list of active effects
|
|
||||||
/// @return The list of active effects
|
|
||||||
const std::list<ActiveEffectDefinition> &getActiveEffects();
|
|
||||||
|
|
||||||
/// Get the list of available effect schema files
|
|
||||||
/// @return The list of available effect schema files
|
|
||||||
const std::list<EffectSchema> &getEffectSchemas();
|
|
||||||
|
|
||||||
/// gets the current json config object from SettingsManager
|
|
||||||
/// @return json config
|
|
||||||
const QJsonObject& getQJsonConfig();
|
|
||||||
|
|
||||||
/// enable/disable automatic/priorized source selection
|
|
||||||
/// @param enabled the state
|
|
||||||
void setSourceAutoSelectEnabled(bool enabled);
|
|
||||||
|
|
||||||
/// set current input source to visible
|
|
||||||
/// @param priority the priority channel which should be vidible
|
|
||||||
/// @return true if success, false on error
|
|
||||||
bool setCurrentSourcePriority(int priority );
|
|
||||||
|
|
||||||
/// gets current state of automatic/priorized source selection
|
|
||||||
/// @return the state
|
|
||||||
bool sourceAutoSelectEnabled();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Called from components to update their current state. DO NOT CALL FROM USERS
|
|
||||||
/// @param[in] component The component from enum
|
|
||||||
/// @param[in] state The state of the component [true | false]
|
|
||||||
///
|
|
||||||
void setNewComponentState(const hyperion::Components& component, const bool& state);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Get a list of all contrable components and their current state
|
|
||||||
/// @return list of components
|
|
||||||
///
|
|
||||||
std::map<hyperion::Components, bool> getAllComponents();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// @brief Test if a component is enabled
|
|
||||||
/// @param The component to test
|
|
||||||
/// @return Component state
|
|
||||||
///
|
|
||||||
int isComponentEnabled(const hyperion::Components& comp);
|
|
||||||
|
|
||||||
ComponentRegister& getComponentRegister() { return _componentRegister; };
|
|
||||||
|
|
||||||
/// gets the methode how image is maped to leds
|
/// gets the methode how image is maped to leds
|
||||||
const int & getLedMappingType();
|
const int & getLedMappingType();
|
||||||
|
|
||||||
@ -244,6 +120,7 @@ public:
|
|||||||
LedDevice * getActiveDevice() const;
|
LedDevice * getActiveDevice() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
|
/// @brief Register a new input by priority, the priority is not active (timeout -100 isn't muxer recognized) until you start to update the data with setInput()
|
||||||
/// A repeated call to update the base data of a known priority won't overwrite their current timeout
|
/// A repeated call to update the base data of a known priority won't overwrite their current timeout
|
||||||
@ -322,6 +199,28 @@ public slots:
|
|||||||
///
|
///
|
||||||
bool clear(const int priority, bool forceClearAll=false);
|
bool clear(const int priority, bool forceClearAll=false);
|
||||||
|
|
||||||
|
/// #############
|
||||||
|
// EFFECTENGINE
|
||||||
|
///
|
||||||
|
/// @brief Get a pointer to the effect engine
|
||||||
|
/// @return EffectEngine instance pointer
|
||||||
|
///
|
||||||
|
|
||||||
|
EffectEngine* getEffectEngineInstance() { return _effectEngine; };
|
||||||
|
///
|
||||||
|
/// @brief Save an effect
|
||||||
|
/// @param obj The effect args
|
||||||
|
/// @return Empty on success else error message
|
||||||
|
///
|
||||||
|
QString saveEffect(const QJsonObject& obj);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Delete an effect by name.
|
||||||
|
/// @param effectName The effect name to delete
|
||||||
|
/// @return Empty on success else error message
|
||||||
|
///
|
||||||
|
QString deleteEffect(const QString& effectName);
|
||||||
|
|
||||||
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
/// Run the specified effect on the given priority channel and optionally specify a timeout
|
||||||
/// @param effectName Name of the effec to run
|
/// @param effectName Name of the effec to run
|
||||||
/// @param priority The priority channel of the effect
|
/// @param priority The priority channel of the effect
|
||||||
@ -342,6 +241,122 @@ public slots:
|
|||||||
, const QString &imageData = ""
|
, const QString &imageData = ""
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Get the list of available effects
|
||||||
|
/// @return The list of available effects
|
||||||
|
const std::list<EffectDefinition> &getEffects() const;
|
||||||
|
|
||||||
|
/// Get the list of active effects
|
||||||
|
/// @return The list of active effects
|
||||||
|
const std::list<ActiveEffectDefinition> &getActiveEffects();
|
||||||
|
|
||||||
|
/// Get the list of available effect schema files
|
||||||
|
/// @return The list of available effect schema files
|
||||||
|
const std::list<EffectSchema> &getEffectSchemas();
|
||||||
|
|
||||||
|
/// #############
|
||||||
|
/// PRIORITYMUXER
|
||||||
|
///
|
||||||
|
/// @brief Get a pointer to the priorityMuxer instance
|
||||||
|
/// @return PriorityMuxer instance pointer
|
||||||
|
///
|
||||||
|
PriorityMuxer* getMuxerInstance() { return &_muxer; };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief enable/disable automatic/priorized source selection
|
||||||
|
/// @param state The new state
|
||||||
|
///
|
||||||
|
void setSourceAutoSelect(const bool state);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief set current input source to visible
|
||||||
|
/// @param priority the priority channel which should be vidible
|
||||||
|
/// @return true if success, false on error
|
||||||
|
///
|
||||||
|
bool setVisiblePriority(const int& priority);
|
||||||
|
|
||||||
|
/// gets current state of automatic/priorized source selection
|
||||||
|
/// @return the state
|
||||||
|
bool sourceAutoSelectEnabled();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the current priority
|
||||||
|
///
|
||||||
|
/// @return The current priority
|
||||||
|
///
|
||||||
|
int getCurrentPriority() const;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns true if current priority is given priority
|
||||||
|
///
|
||||||
|
/// @return bool
|
||||||
|
///
|
||||||
|
bool isCurrentPriority(const int priority) const;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns a list of all registered priorities
|
||||||
|
///
|
||||||
|
/// @return The list with priorities
|
||||||
|
///
|
||||||
|
QList<int> getActivePriorities() const;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// Returns the information of a specific priorrity channel
|
||||||
|
///
|
||||||
|
/// @param[in] priority The priority channel
|
||||||
|
///
|
||||||
|
/// @return The information of the given, a not found priority will return lowest priority as fallback
|
||||||
|
///
|
||||||
|
const InputInfo getPriorityInfo(const int priority) const;
|
||||||
|
|
||||||
|
/// #############
|
||||||
|
/// SETTINGSMANAGER
|
||||||
|
///
|
||||||
|
/// @brief Get a setting by settings::type from SettingsManager
|
||||||
|
/// @param type The settingsType from enum
|
||||||
|
/// @return Data Document
|
||||||
|
///
|
||||||
|
QJsonDocument getSetting(const settings::type& type);
|
||||||
|
|
||||||
|
/// gets the current json config object from SettingsManager
|
||||||
|
/// @return json config
|
||||||
|
const QJsonObject& getQJsonConfig();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Save a complete json config
|
||||||
|
/// @param config The entire config object
|
||||||
|
/// @param correct If true will correct json against schema before save
|
||||||
|
/// @return True on success else false
|
||||||
|
///
|
||||||
|
bool saveSettings(QJsonObject config, const bool& correct = false);
|
||||||
|
|
||||||
|
/// ############
|
||||||
|
/// COMPONENTREGISTER
|
||||||
|
///
|
||||||
|
/// @brief Get the component Register
|
||||||
|
/// return Component register pointer
|
||||||
|
///
|
||||||
|
ComponentRegister& getComponentRegister() { return _componentRegister; };
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Called from components to update their current state. DO NOT CALL FROM USERS
|
||||||
|
/// @param[in] component The component from enum
|
||||||
|
/// @param[in] state The state of the component [true | false]
|
||||||
|
///
|
||||||
|
void setNewComponentState(const hyperion::Components& component, const bool& state);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Get a list of all contrable components and their current state
|
||||||
|
/// @return list of components
|
||||||
|
///
|
||||||
|
std::map<hyperion::Components, bool> getAllComponents();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Test if a component is enabled
|
||||||
|
/// @param The component to test
|
||||||
|
/// @return Component state
|
||||||
|
///
|
||||||
|
int isComponentEnabled(const hyperion::Components& comp);
|
||||||
|
|
||||||
/// sets the methode how image is maped to leds at ImageProcessor
|
/// sets the methode how image is maped to leds at ImageProcessor
|
||||||
void setLedMappingType(const int& mappingType);
|
void setLedMappingType(const int& mappingType);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
static HyperionIManager* getInstance() { return HIMinstance; };
|
static HyperionIManager* getInstance() { return HIMinstance; };
|
||||||
static HyperionIManager* HIMinstance;
|
static HyperionIManager* HIMinstance;
|
||||||
|
|
||||||
|
public slots:
|
||||||
///
|
///
|
||||||
/// @brief Is given instance running?
|
/// @brief Is given instance running?
|
||||||
/// @param inst The instance to check
|
/// @param inst The instance to check
|
||||||
|
529
libsrc/api/API.cpp
Normal file
529
libsrc/api/API.cpp
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
// project includes
|
||||||
|
#include <api/API.h>
|
||||||
|
|
||||||
|
// stl includes
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
// Qt includes
|
||||||
|
#include <QResource>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
// hyperion includes
|
||||||
|
#include <leddevice/LedDeviceWrapper.h>
|
||||||
|
#include <hyperion/GrabberWrapper.h>
|
||||||
|
#include <utils/jsonschema/QJsonFactory.h>
|
||||||
|
#include <utils/jsonschema/QJsonSchemaChecker.h>
|
||||||
|
#include <HyperionConfig.h>
|
||||||
|
#include <utils/SysInfo.h>
|
||||||
|
#include <utils/ColorSys.h>
|
||||||
|
#include <utils/Process.h>
|
||||||
|
//#include <utils/ApiSync.h>
|
||||||
|
|
||||||
|
// bonjour wrapper
|
||||||
|
#include <bonjour/bonjourbrowserwrapper.h>
|
||||||
|
|
||||||
|
// ledmapping int <> string transform methods
|
||||||
|
#include <hyperion/ImageProcessor.h>
|
||||||
|
|
||||||
|
// api includes
|
||||||
|
#include <api/JsonCB.h>
|
||||||
|
|
||||||
|
using namespace hyperion;
|
||||||
|
|
||||||
|
API::API(Logger *log, const bool &localConnection, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
qRegisterMetaType<int64_t>("int64_t");
|
||||||
|
qRegisterMetaType<VideoMode>("VideoMode");
|
||||||
|
qRegisterMetaType<std::map<int, registerData>>("std::map<int,registerData>");
|
||||||
|
|
||||||
|
// Init
|
||||||
|
_log = log;
|
||||||
|
_authManager = AuthManager::getInstance();
|
||||||
|
_instanceManager = HyperionIManager::getInstance();
|
||||||
|
_localConnection = localConnection;
|
||||||
|
|
||||||
|
_authorized = false;
|
||||||
|
_adminAuthorized = false;
|
||||||
|
|
||||||
|
_hyperion = _instanceManager->getHyperionInstance(0);
|
||||||
|
_currInstanceIndex = 0;
|
||||||
|
// TODO FIXME
|
||||||
|
// report back current registers when a Hyperion instance request it
|
||||||
|
//connect(ApiSync::getInstance(), &ApiSync::requestActiveRegister, this, &API::requestActiveRegister, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
// connect to possible token responses that has been requested
|
||||||
|
connect(_authManager, &AuthManager::tokenResponse, this, &API::checkTokenResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::init(void)
|
||||||
|
{
|
||||||
|
bool apiAuthRequired = _authManager->isAuthRequired();
|
||||||
|
|
||||||
|
// For security we block external connections if default PW is set
|
||||||
|
if (!_localConnection && API::hasHyperionDefaultPw())
|
||||||
|
{
|
||||||
|
emit forceClose();
|
||||||
|
}
|
||||||
|
// if this is localConnection and network allows unauth locals, set authorized flag
|
||||||
|
if (apiAuthRequired && _localConnection)
|
||||||
|
_authorized = !_authManager->isLocalAuthRequired();
|
||||||
|
|
||||||
|
// admin access is allowed, when the connection is local and the option for local admin isn't set. Con: All local connections get full access
|
||||||
|
if (_localConnection)
|
||||||
|
{
|
||||||
|
_adminAuthorized = !_authManager->isLocalAdminAuthRequired();
|
||||||
|
// just in positive direction
|
||||||
|
if (_adminAuthorized)
|
||||||
|
_authorized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setColor(const int &priority, const std::vector<uint8_t> &ledColors, const int &timeout_ms, const QString &origin, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
std::vector<ColorRgb> fledColors;
|
||||||
|
if (ledColors.size() % 3 == 0)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < ledColors.size(); i += 3)
|
||||||
|
{
|
||||||
|
fledColors.emplace_back(ColorRgb{ledColors[i], ledColors[i + 1], ledColors[i + 2]});
|
||||||
|
}
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setColor", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(std::vector<ColorRgb>, fledColors), Q_ARG(int, timeout_ms), Q_ARG(QString, origin));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setColor", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(std::vector<ColorRgb>, fledColors), Q_ARG(int, timeout_ms), Q_ARG(QString, origin), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::setImage(ImageCmdData &data, hyperion::Components comp, QString &replyMsg, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
// truncate name length
|
||||||
|
data.imgName.truncate(16);
|
||||||
|
|
||||||
|
if (data.format == "auto")
|
||||||
|
{
|
||||||
|
QImage img = QImage::fromData(data.data);
|
||||||
|
if (img.isNull())
|
||||||
|
{
|
||||||
|
replyMsg = "Failed to parse picture, the file might be corrupted";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for requested scale
|
||||||
|
if (data.scale > 24)
|
||||||
|
{
|
||||||
|
if (img.height() > data.scale)
|
||||||
|
{
|
||||||
|
img = img.scaledToHeight(data.scale);
|
||||||
|
}
|
||||||
|
if (img.width() > data.scale)
|
||||||
|
{
|
||||||
|
img = img.scaledToWidth(data.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we need to force a scale
|
||||||
|
if (img.width() > 2000 || img.height() > 2000)
|
||||||
|
{
|
||||||
|
data.scale = 2000;
|
||||||
|
if (img.height() > data.scale)
|
||||||
|
{
|
||||||
|
img = img.scaledToHeight(data.scale);
|
||||||
|
}
|
||||||
|
if (img.width() > data.scale)
|
||||||
|
{
|
||||||
|
img = img.scaledToWidth(data.scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.width = img.width();
|
||||||
|
data.height = img.height();
|
||||||
|
|
||||||
|
// extract image
|
||||||
|
img = img.convertToFormat(QImage::Format_ARGB32_Premultiplied);
|
||||||
|
data.data.clear();
|
||||||
|
data.data.reserve(img.width() * img.height() * 3);
|
||||||
|
for (int i = 0; i < img.height(); ++i)
|
||||||
|
{
|
||||||
|
const QRgb *scanline = reinterpret_cast<const QRgb *>(img.scanLine(i));
|
||||||
|
for (int j = 0; j < img.width(); ++j)
|
||||||
|
{
|
||||||
|
data.data.append((char)qRed(scanline[j]));
|
||||||
|
data.data.append((char)qGreen(scanline[j]));
|
||||||
|
data.data.append((char)qBlue(scanline[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check consistency of the size of the received data
|
||||||
|
if (data.data.size() != data.width * data.height * 3)
|
||||||
|
{
|
||||||
|
replyMsg = "Size of image data does not match with the width and height";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy image
|
||||||
|
Image<ColorRgb> image(data.width, data.height);
|
||||||
|
memcpy(image.memptr(), data.data.data(), data.data.size());
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(hyperion::Components, comp), Q_ARG(QString, data.origin), Q_ARG(QString, data.imgName));
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setInputImage", Qt::QueuedConnection, Q_ARG(int, data.priority), Q_ARG(Image<ColorRgb>, image), Q_ARG(int64_t, data.duration));
|
||||||
|
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "registerInput", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, data.priority), Q_ARG(hyperion::Components, comp), Q_ARG(QString, data.origin), Q_ARG(QString, data.imgName), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setInputImage", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, data.priority), Q_ARG(Image<ColorRgb>, image), Q_ARG(int64_t, data.duration), Q_ARG(hyperion::Components, comp), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::clearPriority(const int &priority, QString &replyMsg, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
if (priority < 0 || (priority > 0 && priority < 254))
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "clear", Qt::QueuedConnection, Q_ARG(int, priority));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "clearPriority", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
replyMsg = QString("Priority %1 is not allowed to be cleared").arg(priority);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::setComponentState(const QString &comp, bool &compState, QString &replyMsg, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
Components component = stringToComponent(comp);
|
||||||
|
|
||||||
|
if (component != COMP_INVALID)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "compStateChangeRequest", Qt::QueuedConnection, Q_ARG(hyperion::Components, component), Q_ARG(bool, compState));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "compStateChangeRequest", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(hyperion::Components, component), Q_ARG(bool, compState), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
replyMsg = QString("Unknown component name: %1").arg(comp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setLedMappingType(const int &type, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setLedMappingType", Qt::QueuedConnection, Q_ARG(int, type));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setLedMappingType", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, type), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setVideoMode(const VideoMode &mode, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setVideoMode", Qt::QueuedConnection, Q_ARG(VideoMode, mode));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setVideoMode", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(VideoMode, mode), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setEffect(const EffectCmdData &dat, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
if (!dat.args.isEmpty())
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(QJsonObject, dat.args), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.pythonScript), Q_ARG(QString, dat.origin), Q_ARG(QString, dat.data));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setEffect", Qt::QueuedConnection, Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setEffect", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(QString, dat.effectName), Q_ARG(int, dat.priority), Q_ARG(int, dat.duration), Q_ARG(QString, dat.origin), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setSourceAutoSelect(const bool state, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setSourceAutoSelect", Qt::QueuedConnection, Q_ARG(bool, state));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setSourceAutoSelect", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(bool, state), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setVisiblePriority(const int &priority, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "setVisiblePriority", Qt::QueuedConnection, Q_ARG(int, priority));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "setVisiblePriority", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::registerInput(const int &priority, const hyperion::Components &component, const QString &origin, const QString &owner, const hyperion::Components &callerComp)
|
||||||
|
{
|
||||||
|
if (_activeRegisters.count(priority))
|
||||||
|
_activeRegisters.erase(priority);
|
||||||
|
|
||||||
|
_activeRegisters.insert({priority, registerData{component, origin, owner, callerComp}});
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "registerInput", Qt::QueuedConnection, Q_ARG(int, priority), Q_ARG(hyperion::Components, component), Q_ARG(QString, origin), Q_ARG(QString, owner));
|
||||||
|
//QMetaObject::invokeMethod(ApiSync::getInstance(), "registerInput", Qt::QueuedConnection, Q_ARG(QObject *, _hyperion), Q_ARG(int, priority), Q_ARG(hyperion::Components, component), Q_ARG(QString, origin), Q_ARG(QString, owner), Q_ARG(hyperion::Components, callerComp));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::unregisterInput(const int &priority)
|
||||||
|
{
|
||||||
|
if (_activeRegisters.count(priority))
|
||||||
|
_activeRegisters.erase(priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::setHyperionInstance(const quint8 &inst)
|
||||||
|
{
|
||||||
|
if (_currInstanceIndex == inst)
|
||||||
|
return true;
|
||||||
|
bool isRunning;
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "IsInstanceRunning", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, isRunning), Q_ARG(quint8, inst));
|
||||||
|
if (!isRunning)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
disconnect(_hyperion, 0, this, 0);
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "getHyperionInstance", Qt::BlockingQueuedConnection, Q_RETURN_ARG(Hyperion *, _hyperion), Q_ARG(quint8, inst));
|
||||||
|
_currInstanceIndex = inst;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<hyperion::Components, bool> API::getAllComponents()
|
||||||
|
{
|
||||||
|
std::map<hyperion::Components, bool> comps;
|
||||||
|
//QMetaObject::invokeMethod(_hyperion, "getAllComponents", Qt::BlockingQueuedConnection, Q_RETURN_ARG(std::map<hyperion::Components, bool>, comps));
|
||||||
|
return comps;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::isHyperionEnabled()
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "isComponentEnabled", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, res), Q_ARG(hyperion::Components, hyperion::COMP_ALL));
|
||||||
|
return res > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QVariantMap> API::getAllInstanceData(void)
|
||||||
|
{
|
||||||
|
QVector<QVariantMap> vec;
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "getInstanceData", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVector<QVariantMap>, vec));
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::startInstance(const quint8 &index)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "startInstance", Qt::QueuedConnection, Q_ARG(quint8, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::stopInstance(const quint8 &index)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "stopInstance", Qt::QueuedConnection, Q_ARG(quint8, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::requestActiveRegister(QObject *callerInstance)
|
||||||
|
{
|
||||||
|
// TODO FIXME
|
||||||
|
//if (_activeRegisters.size())
|
||||||
|
// QMetaObject::invokeMethod(ApiSync::getInstance(), "answerActiveRegister", Qt::QueuedConnection, Q_ARG(QObject *, callerInstance), Q_ARG(MapRegister, _activeRegisters));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::deleteInstance(const quint8 &index, QString &replyMsg)
|
||||||
|
{
|
||||||
|
if (_adminAuthorized)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "deleteInstance", Qt::QueuedConnection, Q_ARG(quint8, index));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
replyMsg = NO_AUTH;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::createInstance(const QString &name)
|
||||||
|
{
|
||||||
|
if (_adminAuthorized)
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "createInstance", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, success), Q_ARG(QString, name));
|
||||||
|
if (!success)
|
||||||
|
return QString("Instance name '%1' is already in use").arg(name);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return NO_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::setInstanceName(const quint8 &index, const QString &name)
|
||||||
|
{
|
||||||
|
if (_adminAuthorized)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_instanceManager, "saveName", Qt::QueuedConnection, Q_ARG(quint8, index), Q_ARG(QString, name));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return NO_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::deleteEffect(const QString &name)
|
||||||
|
{
|
||||||
|
if (_adminAuthorized)
|
||||||
|
{
|
||||||
|
QString res;
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "deleteEffect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, res), Q_ARG(QString, name));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return NO_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::saveEffect(const QJsonObject &data)
|
||||||
|
{
|
||||||
|
if (_adminAuthorized)
|
||||||
|
{
|
||||||
|
QString res;
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "saveEffect", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, res), Q_ARG(QJsonObject, data));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return NO_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::saveSettings(const QJsonObject &data)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return;
|
||||||
|
QMetaObject::invokeMethod(_hyperion, "saveSettings", Qt::QueuedConnection, Q_ARG(QJsonObject, data), Q_ARG(bool, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::updateHyperionPassword(const QString &password, const QString &newPassword)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return false;
|
||||||
|
bool res;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "updateUserPassword", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, "Hyperion"), Q_ARG(QString, password), Q_ARG(QString, newPassword));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::createToken(const QString &comment, AuthManager::AuthDefinition &def)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return NO_AUTH;
|
||||||
|
if (comment.isEmpty())
|
||||||
|
return "comment is empty";
|
||||||
|
QMetaObject::invokeMethod(_authManager, "createToken", Qt::BlockingQueuedConnection, Q_RETURN_ARG(AuthManager::AuthDefinition, def), Q_ARG(QString, comment));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::renameToken(const QString &id, const QString &comment)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return NO_AUTH;
|
||||||
|
if (comment.isEmpty() || id.isEmpty())
|
||||||
|
return "Empty comment or id";
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(_authManager, "renameToken", Qt::QueuedConnection, Q_ARG(QString, id), Q_ARG(QString, comment));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString API::deleteToken(const QString &id)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return NO_AUTH;
|
||||||
|
if (id.isEmpty())
|
||||||
|
return "Empty id";
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(_authManager, "deleteToken", Qt::QueuedConnection, Q_ARG(QString, id));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::setNewTokenRequest(const QString &comment, const QString &id)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_authManager, "setNewTokenRequest", Qt::QueuedConnection, Q_ARG(QObject *, this), Q_ARG(QString, comment), Q_ARG(QString, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::cancelNewTokenRequest(const QString &comment, const QString &id)
|
||||||
|
{
|
||||||
|
QMetaObject::invokeMethod(_authManager, "cancelNewTokenRequest", Qt::QueuedConnection, Q_ARG(QObject *, this), Q_ARG(QString, comment), Q_ARG(QString, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::handlePendingTokenRequest(const QString &id, const bool accept)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return false;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "handlePendingTokenRequest", Qt::QueuedConnection, Q_ARG(QString, id), Q_ARG(bool, accept));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::getTokenList(QVector<AuthManager::AuthDefinition> &def)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return false;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "getTokenList", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVector<AuthManager::AuthDefinition>, def));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::getPendingTokenRequests(QVector<AuthManager::AuthDefinition> &map)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return false;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "getPendingRequests", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QVector<AuthManager::AuthDefinition>, map));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::isUserTokenAuthorized(const QString &userToken)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "isUserTokenAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, "Hyperion"), Q_ARG(QString, userToken));
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
_authorized = true;
|
||||||
|
_adminAuthorized = true;
|
||||||
|
// Listen for ADMIN ACCESS protected signals
|
||||||
|
connect(_authManager, &AuthManager::newPendingTokenRequest, this, &API::onPendingTokenRequest, Qt::UniqueConnection);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::getUserToken(QString &userToken)
|
||||||
|
{
|
||||||
|
if (!_adminAuthorized)
|
||||||
|
return false;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "getUserToken", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, userToken));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::isTokenAuthorized(const QString &token)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "isTokenAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, token));
|
||||||
|
if (res)
|
||||||
|
_authorized = true;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::isUserAuthorized(const QString &password)
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "isUserAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, "Hyperion"), Q_ARG(QString, password));
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
_authorized = true;
|
||||||
|
_adminAuthorized = true;
|
||||||
|
// Listen for ADMIN ACCESS protected signals
|
||||||
|
connect(_authManager, &AuthManager::newPendingTokenRequest, this, &API::onPendingTokenRequest, Qt::UniqueConnection);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool API::hasHyperionDefaultPw()
|
||||||
|
{
|
||||||
|
bool res;
|
||||||
|
QMetaObject::invokeMethod(_authManager, "isUserAuthorized", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, res), Q_ARG(QString, "Hyperion"), Q_ARG(QString, "hyperion"));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::logout()
|
||||||
|
{
|
||||||
|
_authorized = false;
|
||||||
|
_adminAuthorized = false;
|
||||||
|
// Stop listenig for ADMIN ACCESS protected signals
|
||||||
|
disconnect(_authManager, &AuthManager::newPendingTokenRequest, this, &API::onPendingTokenRequest);
|
||||||
|
stopDataConnectionss();
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::checkTokenResponse(const bool &success, QObject *caller, const QString &token, const QString &comment, const QString &id)
|
||||||
|
{
|
||||||
|
if (this == caller)
|
||||||
|
emit onTokenResponse(success, token, comment, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void API::stopDataConnectionss()
|
||||||
|
{
|
||||||
|
}
|
@ -10,7 +10,7 @@
|
|||||||
"subcommand" : {
|
"subcommand" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"enum" : ["requestToken","createToken","deleteToken","getTokenList","logout","login","required","adminRequired","newPasswordRequired","newPassword","answerRequest","getPendingRequests"]
|
"enum" : ["requestToken","createToken","renameToken","deleteToken","getTokenList","logout","login","tokenRequired","adminRequired","newPasswordRequired","newPassword","answerRequest","getPendingTokenRequests"]
|
||||||
},
|
},
|
||||||
"tan" : {
|
"tan" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,7 +35,7 @@ JsonCB::JsonCB(QObject* parent)
|
|||||||
, _prioMuxer(nullptr)
|
, _prioMuxer(nullptr)
|
||||||
{
|
{
|
||||||
_availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update"
|
_availableCommands << "components-update" << "sessions-update" << "priorities-update" << "imageToLedMapping-update"
|
||||||
<< "adjustment-update" << "videomode-update" << "effects-update" << "settings-update" << "leds-update" << "instance-update";
|
<< "adjustment-update" << "videomode-update" << "effects-update" << "settings-update" << "leds-update" << "instance-update" << "token-update";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe)
|
bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe)
|
||||||
@ -131,6 +131,14 @@ bool JsonCB::subscribeFor(const QString& type, const bool & unsubscribe)
|
|||||||
connect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange, Qt::UniqueConnection);
|
connect(HyperionIManager::getInstance(), &HyperionIManager::change, this, &JsonCB::handleInstanceChange, Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == "token-update")
|
||||||
|
{
|
||||||
|
if (unsubscribe)
|
||||||
|
disconnect(AuthManager::getInstance(), &AuthManager::tokenChange, this, &JsonCB::handleTokenChange);
|
||||||
|
else
|
||||||
|
connect(AuthManager::getInstance(), &AuthManager::tokenChange, this, &JsonCB::handleTokenChange, Qt::UniqueConnection);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,3 +409,17 @@ void JsonCB::handleInstanceChange()
|
|||||||
}
|
}
|
||||||
doCallback("instance-update", QVariant(arr));
|
doCallback("instance-update", QVariant(arr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonCB::handleTokenChange(const QVector<AuthManager::AuthDefinition> &def)
|
||||||
|
{
|
||||||
|
QJsonArray arr;
|
||||||
|
for (const auto &entry : def)
|
||||||
|
{
|
||||||
|
QJsonObject sub;
|
||||||
|
sub["comment"] = entry.comment;
|
||||||
|
sub["id"] = entry.id;
|
||||||
|
sub["last_use"] = entry.lastUse;
|
||||||
|
arr.push_back(sub);
|
||||||
|
}
|
||||||
|
doCallback("token-update", QVariant(arr));
|
||||||
|
}
|
||||||
|
@ -47,14 +47,14 @@ EffectEngine::~EffectEngine()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectEngine::saveEffect(const QJsonObject& obj, QString& resultMsg)
|
QString EffectEngine::saveEffect(const QJsonObject& obj)
|
||||||
{
|
{
|
||||||
return _effectFileHandler->saveEffect(obj, resultMsg);
|
return _effectFileHandler->saveEffect(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectEngine::deleteEffect(const QString& effectName, QString& resultMsg)
|
QString EffectEngine::deleteEffect(const QString& effectName)
|
||||||
{
|
{
|
||||||
return _effectFileHandler->deleteEffect(effectName, resultMsg);
|
return _effectFileHandler->deleteEffect(effectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list<ActiveEffectDefinition> &EffectEngine::getActiveEffects()
|
const std::list<ActiveEffectDefinition> &EffectEngine::getActiveEffects()
|
||||||
|
@ -58,8 +58,9 @@ void EffectFileHandler::handleSettingsUpdate(const settings::type& type, const Q
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectFileHandler::deleteEffect(const QString& effectName, QString& resultMsg)
|
QString EffectFileHandler::deleteEffect(const QString& effectName)
|
||||||
{
|
{
|
||||||
|
QString resultMsg;
|
||||||
std::list<EffectDefinition> effectsDefinition = getEffects();
|
std::list<EffectDefinition> effectsDefinition = getEffects();
|
||||||
std::list<EffectDefinition>::iterator it = std::find_if(effectsDefinition.begin(), effectsDefinition.end(), find_effect(effectName));
|
std::list<EffectDefinition>::iterator it = std::find_if(effectsDefinition.begin(), effectsDefinition.end(), find_effect(effectName));
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ bool EffectFileHandler::deleteEffect(const QString& effectName, QString& resultM
|
|||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
updateEffects();
|
updateEffects();
|
||||||
return true;
|
return "";
|
||||||
} else
|
} else
|
||||||
resultMsg = "Can't delete effect configuration file: " + effectConfigurationFile.absoluteFilePath() + ". Please check permissions";
|
resultMsg = "Can't delete effect configuration file: " + effectConfigurationFile.absoluteFilePath() + ". Please check permissions";
|
||||||
} else
|
} else
|
||||||
@ -92,11 +93,12 @@ bool EffectFileHandler::deleteEffect(const QString& effectName, QString& resultM
|
|||||||
} else
|
} else
|
||||||
resultMsg = "Effect " + effectName + " not found";
|
resultMsg = "Effect " + effectName + " not found";
|
||||||
|
|
||||||
return false;
|
return resultMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMsg)
|
QString EffectFileHandler::saveEffect(const QJsonObject& message)
|
||||||
{
|
{
|
||||||
|
QString resultMsg;
|
||||||
if (!message["args"].toObject().isEmpty())
|
if (!message["args"].toObject().isEmpty())
|
||||||
{
|
{
|
||||||
QString scriptName;
|
QString scriptName;
|
||||||
@ -111,8 +113,7 @@ bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMs
|
|||||||
{
|
{
|
||||||
if(!JsonUtils::validate("EffectFileHandler", message["args"].toObject(), it->schemaFile, _log))
|
if(!JsonUtils::validate("EffectFileHandler", message["args"].toObject(), it->schemaFile, _log))
|
||||||
{
|
{
|
||||||
resultMsg = "Error during arg validation against schema, please consult the Hyperion Log";
|
return "Error during arg validation against schema, please consult the Hyperion Log";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject effectJson;
|
QJsonObject effectJson;
|
||||||
@ -123,8 +124,7 @@ bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMs
|
|||||||
{
|
{
|
||||||
if (message["name"].toString().trimmed().isEmpty() || message["name"].toString().trimmed().startsWith("."))
|
if (message["name"].toString().trimmed().isEmpty() || message["name"].toString().trimmed().startsWith("."))
|
||||||
{
|
{
|
||||||
resultMsg = "Can't save new effect. Effect name is empty or begins with a dot.";
|
return "Can't save new effect. Effect name is empty or begins with a dot.";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
effectJson["name"] = message["name"].toString();
|
effectJson["name"] = message["name"].toString();
|
||||||
@ -140,8 +140,7 @@ bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMs
|
|||||||
newFileName.setFile(iter->file);
|
newFileName.setFile(iter->file);
|
||||||
if (newFileName.absoluteFilePath().mid(0, 1) == ":")
|
if (newFileName.absoluteFilePath().mid(0, 1) == ":")
|
||||||
{
|
{
|
||||||
resultMsg = "The effect name '" + message["name"].toString() + "' is assigned to an internal effect. Please rename your effekt.";
|
return "The effect name '" + message["name"].toString() + "' is assigned to an internal effect. Please rename your effekt.";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
@ -156,21 +155,18 @@ bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMs
|
|||||||
QFileInfo imageFileName(effectArray[0].toString().replace("$ROOT",_rootPath) + "/" + message["args"].toObject().value("image").toString());
|
QFileInfo imageFileName(effectArray[0].toString().replace("$ROOT",_rootPath) + "/" + message["args"].toObject().value("image").toString());
|
||||||
if(!FileUtils::writeFile(imageFileName.absoluteFilePath(), QByteArray::fromBase64(message["imageData"].toString("").toUtf8()), _log))
|
if(!FileUtils::writeFile(imageFileName.absoluteFilePath(), QByteArray::fromBase64(message["imageData"].toString("").toUtf8()), _log))
|
||||||
{
|
{
|
||||||
resultMsg = "Error while saving image file '" + message["args"].toObject().value("image").toString() + ", please check the Hyperion Log";
|
return "Error while saving image file '" + message["args"].toObject().value("image").toString() + ", please check the Hyperion Log";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!JsonUtils::write(newFileName.absoluteFilePath(), effectJson, _log))
|
if(!JsonUtils::write(newFileName.absoluteFilePath(), effectJson, _log))
|
||||||
{
|
{
|
||||||
resultMsg = "Error while saving effect, please check the Hyperion Log";
|
return "Error while saving effect, please check the Hyperion Log";
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info(_log, "Reload effect list");
|
Info(_log, "Reload effect list");
|
||||||
updateEffects();
|
updateEffects();
|
||||||
resultMsg = "";
|
return "";
|
||||||
return true;
|
|
||||||
} else
|
} else
|
||||||
resultMsg = "Can't save new effect. Effect path empty";
|
resultMsg = "Can't save new effect. Effect path empty";
|
||||||
} else
|
} else
|
||||||
@ -178,7 +174,7 @@ bool EffectFileHandler::saveEffect(const QJsonObject& message, QString& resultMs
|
|||||||
} else
|
} else
|
||||||
resultMsg = "Missing or empty Object 'args'";
|
resultMsg = "Missing or empty Object 'args'";
|
||||||
|
|
||||||
return false;
|
return resultMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectFileHandler::updateEffects()
|
void EffectFileHandler::updateEffects()
|
||||||
|
@ -21,10 +21,12 @@ AuthManager::AuthManager(QObject* parent)
|
|||||||
{
|
{
|
||||||
AuthManager::manager = this;
|
AuthManager::manager = this;
|
||||||
|
|
||||||
|
|
||||||
// get uuid
|
// get uuid
|
||||||
_uuid = _metaTable->getUUID();
|
_uuid = _metaTable->getUUID();
|
||||||
|
|
||||||
|
// Register meta
|
||||||
|
qRegisterMetaType<QVector<AuthManager::AuthDefinition>>("QVector<AuthManager::AuthDefinition>");
|
||||||
|
|
||||||
// setup timer
|
// setup timer
|
||||||
_timer->setInterval(1000);
|
_timer->setInterval(1000);
|
||||||
connect(_timer, &QTimer::timeout, this, &AuthManager::checkTimeout);
|
connect(_timer, &QTimer::timeout, this, &AuthManager::checkTimeout);
|
||||||
@ -43,7 +45,7 @@ AuthManager::AuthManager(QObject* parent)
|
|||||||
_authTable->setUserToken("Hyperion");
|
_authTable->setUserToken("Hyperion");
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthManager::AuthDefinition AuthManager::createToken(const QString& comment)
|
AuthManager::AuthDefinition AuthManager::createToken(const QString &comment)
|
||||||
{
|
{
|
||||||
const QString token = QUuid::createUuid().toString().mid(1, 36);
|
const QString token = QUuid::createUuid().toString().mid(1, 36);
|
||||||
const QString id = QUuid::createUuid().toString().mid(1, 36).left(5);
|
const QString id = QUuid::createUuid().toString().mid(1, 36).left(5);
|
||||||
@ -55,10 +57,11 @@ const AuthManager::AuthDefinition AuthManager::createToken(const QString& commen
|
|||||||
def.token = token;
|
def.token = token;
|
||||||
def.id = id;
|
def.id = id;
|
||||||
|
|
||||||
|
emit tokenChange(getTokenList());
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<AuthManager::AuthDefinition> AuthManager::getTokenList()
|
QVector<AuthManager::AuthDefinition> AuthManager::getTokenList()
|
||||||
{
|
{
|
||||||
QVector<QVariantMap> vector = _authTable->getTokenList();
|
QVector<QVariantMap> vector = _authTable->getTokenList();
|
||||||
QVector<AuthManager::AuthDefinition> finalVec;
|
QVector<AuthManager::AuthDefinition> finalVec;
|
||||||
@ -78,6 +81,7 @@ const QVector<AuthManager::AuthDefinition> AuthManager::getTokenList()
|
|||||||
|
|
||||||
const QString AuthManager::getUserToken(const QString &usr)
|
const QString AuthManager::getUserToken(const QString &usr)
|
||||||
{
|
{
|
||||||
|
QString tok = _authTable->getUserToken(usr);
|
||||||
return QString(_authTable->getUserToken(usr));
|
return QString(_authTable->getUserToken(usr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ void AuthManager::setAuthBlock(const bool& user)
|
|||||||
else
|
else
|
||||||
_tokenAuthAttempts.append(QDateTime::currentMSecsSinceEpoch() + 600000);
|
_tokenAuthAttempts.append(QDateTime::currentMSecsSinceEpoch() + 600000);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(_authBlockTimer, "start", Qt::QueuedConnection);
|
_authBlockTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::isUserAuthorized(const QString &user, const QString &pw)
|
bool AuthManager::isUserAuthorized(const QString &user, const QString &pw)
|
||||||
@ -97,7 +101,8 @@ bool AuthManager::isUserAuthorized(const QString& user, const QString& pw)
|
|||||||
if (isUserAuthBlocked())
|
if (isUserAuthBlocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!_authTable->isUserAuthorized(user, pw)){
|
if (!_authTable->isUserAuthorized(user, pw))
|
||||||
|
{
|
||||||
setAuthBlock(true);
|
setAuthBlock(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -109,10 +114,13 @@ bool AuthManager::isTokenAuthorized(const QString& token)
|
|||||||
if (isTokenAuthBlocked())
|
if (isTokenAuthBlocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!_authTable->tokenExist(token)){
|
if (!_authTable->tokenExist(token))
|
||||||
|
{
|
||||||
setAuthBlock();
|
setAuthBlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// timestamp update
|
||||||
|
tokenChange(getTokenList());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +129,8 @@ bool AuthManager::isUserTokenAuthorized(const QString& usr, const QString& token
|
|||||||
if (isUserAuthBlocked())
|
if (isUserAuthBlocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!_authTable->isUserTokenAuthorized(usr, token)){
|
if (!_authTable->isUserTokenAuthorized(usr, token))
|
||||||
|
{
|
||||||
setAuthBlock(true);
|
setAuthBlock(true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -145,47 +154,73 @@ void AuthManager::setNewTokenRequest(QObject* caller, const QString& comment, co
|
|||||||
{
|
{
|
||||||
if (!_pendingRequests.contains(id))
|
if (!_pendingRequests.contains(id))
|
||||||
{
|
{
|
||||||
AuthDefinition newDef {id, comment, caller, uint64_t(QDateTime::currentMSecsSinceEpoch()+60000)};
|
AuthDefinition newDef{id, comment, caller, uint64_t(QDateTime::currentMSecsSinceEpoch() + 180000)};
|
||||||
_pendingRequests[id] = newDef;
|
_pendingRequests[id] = newDef;
|
||||||
_timer->start();
|
_timer->start();
|
||||||
emit newPendingTokenRequest(id, comment);
|
emit newPendingTokenRequest(id, comment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthManager::acceptTokenRequest(const QString& id)
|
void AuthManager::cancelNewTokenRequest(QObject *caller, const QString &comment, const QString &id)
|
||||||
{
|
{
|
||||||
if (_pendingRequests.contains(id))
|
if (_pendingRequests.contains(id))
|
||||||
|
{
|
||||||
|
AuthDefinition def = _pendingRequests.value(id);
|
||||||
|
if (def.caller == caller)
|
||||||
|
_pendingRequests.remove(id);
|
||||||
|
emit newPendingTokenRequest(id, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::handlePendingTokenRequest(const QString &id, const bool &accept)
|
||||||
|
{
|
||||||
|
if (_pendingRequests.contains(id))
|
||||||
|
{
|
||||||
|
AuthDefinition def = _pendingRequests.take(id);
|
||||||
|
|
||||||
|
if (accept)
|
||||||
{
|
{
|
||||||
const QString token = QUuid::createUuid().toString().remove("{").remove("}");
|
const QString token = QUuid::createUuid().toString().remove("{").remove("}");
|
||||||
AuthDefinition def = _pendingRequests.take(id);
|
|
||||||
_authTable->createToken(token, def.comment, id);
|
_authTable->createToken(token, def.comment, id);
|
||||||
emit tokenResponse(true, def.caller, token, def.comment, id);
|
emit tokenResponse(true, def.caller, token, def.comment, id);
|
||||||
return true;
|
emit tokenChange(getTokenList());
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthManager::denyTokenRequest(const QString& id)
|
|
||||||
{
|
{
|
||||||
if(_pendingRequests.contains(id))
|
|
||||||
{
|
|
||||||
AuthDefinition def = _pendingRequests.take(id);
|
|
||||||
emit tokenResponse(false, def.caller, QString(), def.comment, id);
|
emit tokenResponse(false, def.caller, QString(), def.comment, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<AuthManager::AuthDefinition> AuthManager::getPendingRequests()
|
||||||
|
{
|
||||||
|
QVector<AuthManager::AuthDefinition> finalVec;
|
||||||
|
for (const auto &entry : _pendingRequests)
|
||||||
|
{
|
||||||
|
AuthDefinition def;
|
||||||
|
def.comment = entry.comment;
|
||||||
|
def.id = entry.id;
|
||||||
|
def.timeoutTime = entry.timeoutTime - QDateTime::currentMSecsSinceEpoch();
|
||||||
|
finalVec.append(def);
|
||||||
|
}
|
||||||
|
return finalVec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthManager::renameToken(const QString &id, const QString &comment)
|
||||||
|
{
|
||||||
|
if (_authTable->renameToken(id, comment))
|
||||||
|
{
|
||||||
|
emit tokenChange(getTokenList());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QMap<QString, AuthManager::AuthDefinition> AuthManager::getPendingRequests()
|
|
||||||
{
|
|
||||||
return _pendingRequests;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthManager::deleteToken(const QString &id)
|
bool AuthManager::deleteToken(const QString &id)
|
||||||
{
|
{
|
||||||
if (_authTable->deleteToken(id))
|
if (_authTable->deleteToken(id))
|
||||||
{
|
{
|
||||||
//emit tokenDeleted(token);
|
emit tokenChange(getTokenList());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -198,7 +233,7 @@ void AuthManager::handleSettingsUpdate(const settings::type& type, const QJsonDo
|
|||||||
const QJsonObject &obj = config.object();
|
const QJsonObject &obj = config.object();
|
||||||
_authRequired = obj["apiAuth"].toBool(true);
|
_authRequired = obj["apiAuth"].toBool(true);
|
||||||
_localAuthRequired = obj["localApiAuth"].toBool(false);
|
_localAuthRequired = obj["localApiAuth"].toBool(false);
|
||||||
_localAdminAuthRequired = obj["localAdminAuth"].toBool(false);
|
_localAdminAuthRequired = obj["localAdminAuth"].toBool(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,19 +258,24 @@ void AuthManager::checkTimeout()
|
|||||||
_timer->stop();
|
_timer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::checkAuthBlockTimeout(){
|
void AuthManager::checkAuthBlockTimeout()
|
||||||
|
{
|
||||||
// handle user auth block
|
// handle user auth block
|
||||||
for (auto it = _userAuthAttempts.begin(); it != _userAuthAttempts.end(); it++) {
|
for (auto it = _userAuthAttempts.begin(); it != _userAuthAttempts.end(); it++)
|
||||||
|
{
|
||||||
// after 10 minutes, we remove the entry
|
// after 10 minutes, we remove the entry
|
||||||
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch()) {
|
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch())
|
||||||
|
{
|
||||||
_userAuthAttempts.erase(it--);
|
_userAuthAttempts.erase(it--);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle token auth block
|
// handle token auth block
|
||||||
for (auto it = _tokenAuthAttempts.begin(); it != _tokenAuthAttempts.end(); it++) {
|
for (auto it = _tokenAuthAttempts.begin(); it != _tokenAuthAttempts.end(); it++)
|
||||||
|
{
|
||||||
// after 10 minutes, we remove the entry
|
// after 10 minutes, we remove the entry
|
||||||
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch()) {
|
if (*it < (uint64_t)QDateTime::currentMSecsSinceEpoch())
|
||||||
|
{
|
||||||
_tokenAuthAttempts.erase(it--);
|
_tokenAuthAttempts.erase(it--);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,13 +290,12 @@ unsigned Hyperion::getLedCount() const
|
|||||||
return _ledString.leds().size();
|
return _ledString.leds().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::setSourceAutoSelectEnabled(bool enabled)
|
void Hyperion::setSourceAutoSelect(const bool state)
|
||||||
{
|
{
|
||||||
if(_muxer.setSourceAutoSelectEnabled(enabled))
|
_muxer.setSourceAutoSelectEnabled(state);
|
||||||
update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hyperion::setCurrentSourcePriority(int priority )
|
bool Hyperion::setVisiblePriority(const int& priority)
|
||||||
{
|
{
|
||||||
return _muxer.setPriority(priority);
|
return _muxer.setPriority(priority);
|
||||||
}
|
}
|
||||||
@ -465,14 +464,14 @@ const Hyperion::InputInfo Hyperion::getPriorityInfo(const int priority) const
|
|||||||
return _muxer.getInputInfo(priority);
|
return _muxer.getInputInfo(priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hyperion::saveEffect(const QJsonObject& obj, QString& resultMsg)
|
QString Hyperion::saveEffect(const QJsonObject& obj)
|
||||||
{
|
{
|
||||||
return _effectEngine->saveEffect(obj, resultMsg);
|
return _effectEngine->saveEffect(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hyperion::deleteEffect(const QString& effectName, QString& resultMsg)
|
QString Hyperion::deleteEffect(const QString& effectName)
|
||||||
{
|
{
|
||||||
return _effectEngine->deleteEffect(effectName, resultMsg);
|
return _effectEngine->deleteEffect(effectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list<EffectDefinition> & Hyperion::getEffects() const
|
const std::list<EffectDefinition> & Hyperion::getEffects() const
|
||||||
|
Loading…
Reference in New Issue
Block a user