From ec7f25d804b6d7e69d79c29e5a079013b9493556 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Wed, 13 Jan 2016 14:21:45 -0500 Subject: [PATCH] Add a new API call: namespace=rpc, name=query This will probe all the known subsystems and return which ones are currently available and what level of access the user has (read/write). REST Request: ------------------------------- PUT /rpc/query { "junk" : "junk" } REST Response: ------------------------------- { "args": { "rpc/dispatcher": "read/write", "rpc/syscache": "read", "sysadm/lifepreserver": "read/write", "sysadm/network": "read/write" } } WebSocket Request: ------------------------------- { "id" : "fooid", "name" : "query", "namespace" : "rpc", "args" : { "junk" : "junk" } } WebSocket Response: ------------------------------- { "args": { "rpc/dispatcher": "read/write", "rpc/syscache": "read", "sysadm/lifepreserver": "read/write", "sysadm/network": "read/write" }, "id": "fooid", "name": "response", "namespace": "rpc" } --- src/server/WebBackend.cpp | 40 ++++++++++++++++++++++++++++++-- src/server/WebSocket.cpp | 4 +++- src/server/WebSocket.h | 2 ++ src/server/dispatcher-client.cpp | 4 ++++ src/server/dispatcher-client.h | 1 + 5 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/server/WebBackend.cpp b/src/server/WebBackend.cpp index 8394e4d..f4ef0a2 100644 --- a/src/server/WebBackend.cpp +++ b/src/server/WebBackend.cpp @@ -3,6 +3,9 @@ // Available under the 3-clause BSD License // Written by: Ken Moore DEC 2015 // ================================= +// Note: Don't forget to run "AUTHSYSTEM->hasFullAccess(SockAuthToken)" +// To restrict user access to some systems as needed! +// ================================= #include //sysadm library interface classes @@ -15,6 +18,34 @@ #define DEBUG 0 #define SCLISTDELIM QString("::::") //SysCache List Delimiter +RestOutputStruct::ExitCode WebSocket::AvailableSubsystems(QJsonObject *out){ + //Probe the various subsystems to see what is available through this server + //Output format: + /*{ + : , + : , + } + */ + bool allaccess = AUTHSYSTEM->hasFullAccess(SockAuthToken); + // - syscache + if(QFile::exists("/var/run/syscache.pipe")){ + out->insert("rpc/syscache","read"); //no write to syscache - only reads + } + // - dispatcher + if(DispatcherClient::DispatcherAvailable()){ + //"read" is the event notifications, "write" is the ability to queue up jobs + out->insert("rpc/dispatcher", allaccess ? "read/write" : "read"); + } + // - network + out->insert("sysadm/network","read/write"); + + // - lifepreserver + if(QFile::exists("/usr/local/bin/lpreserver")){ + out->insert("sysadm/lifepreserver", "read/write"); + } + + return RestOutputStruct::OK; +} RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(QString namesp, QString name, const QJsonValue args, QJsonObject *out){ /*Inputs: @@ -25,10 +56,12 @@ RestOutputStruct::ExitCode WebSocket::EvaluateBackendRequest(QString namesp, QSt */ namesp = namesp.toLower(); name = name.toLower(); //Go through and forward this request to the appropriate sub-system - if(namesp=="rpc" && name=="syscache"){ + if(namesp=="rpc" && name=="query"){ + return AvailableSubsystems(out); + }else if(namesp=="rpc" && name=="syscache"){ return EvaluateSyscacheRequest(args, out); }else if(namesp=="rpc" && name=="dispatcher"){ - return EvaluateSyscacheRequest(args, out); + return EvaluateDispatcherRequest(args, out); }else if(namesp=="sysadm" && name=="network"){ return EvaluateSysadmNetworkRequest(args, out); }else if(namesp=="sysadm" && name=="lifepreserver"){ @@ -75,6 +108,9 @@ RestOutputStruct::ExitCode WebSocket::EvaluateSyscacheRequest(const QJsonValue i //==== DISPATCHER ==== RestOutputStruct::ExitCode WebSocket::EvaluateDispatcherRequest(const QJsonValue in_args, QJsonObject *out){ //dispatcher only needs a list of sub-commands at the moment (might change later) + if(!AUTHSYSTEM->hasFullAccess(SockAuthToken)){ + return RestOutputStruct::FORBIDDEN; //this user does not have permission to queue jobs + } QStringList in_req; //Parse the input arguments structure diff --git a/src/server/WebSocket.cpp b/src/server/WebSocket.cpp index 325d0f1..a70ccc1 100644 --- a/src/server/WebSocket.cpp +++ b/src/server/WebSocket.cpp @@ -145,7 +145,9 @@ void WebSocket::EvaluateRequest(const RestInputStruct &REQ){ //Note: This sets/changes the current SockAuthToken AUTHSYSTEM->clearAuth(SockAuthToken); //new auth requested - clear any old token if(DEBUG){ qDebug() << "Authenticate Peer:" << SOCKET->peerAddress().toString(); } - bool localhost = (SOCKET->peerAddress() == QHostAddress::LocalHost) || (SOCKET->peerAddress() == QHostAddress::LocalHostIPv6); + bool localhost = false; + if(SOCKET!=0){ localhost = (SOCKET->peerAddress() == QHostAddress::LocalHost) || (SOCKET->peerAddress() == QHostAddress::LocalHostIPv6); } + else if(TSOCKET!=0){ localhost = (TSOCKET->peerAddress() == QHostAddress::LocalHost) || (TSOCKET->peerAddress() == QHostAddress::LocalHostIPv6); } //Now do the auth if(out.in_struct.name=="auth" && out.in_struct.args.isObject() ){ //username/password authentication diff --git a/src/server/WebSocket.h b/src/server/WebSocket.h index 1222ccf..6941b90 100644 --- a/src/server/WebSocket.h +++ b/src/server/WebSocket.h @@ -50,6 +50,8 @@ private: QStringList JsonArrayToStringList(QJsonArray); //Backend request/reply functions (contained in WebBackend.cpp) + // -- Subsystem listing routine + RestOutputStruct::ExitCode AvailableSubsystems(QJsonObject *out); // -- Main subsystem parser RestOutputStruct::ExitCode EvaluateBackendRequest(QString namesp, QString name, const QJsonValue in_args, QJsonObject *out); // -- Individual subsystems diff --git a/src/server/dispatcher-client.cpp b/src/server/dispatcher-client.cpp index 008ee24..bb358e2 100644 --- a/src/server/dispatcher-client.cpp +++ b/src/server/dispatcher-client.cpp @@ -58,6 +58,10 @@ QStringList DispatcherClient::parseInputs(QStringList inputs, AuthorizationManag return outputs; } +bool DispatcherClient::DispatcherAvailable(){ + return QFile::exists(DISPATCH); +} + QString DispatcherClient::ReadKey(){ QFile file(DISPATCHIDFILE); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)){ return ""; } diff --git a/src/server/dispatcher-client.h b/src/server/dispatcher-client.h index d355c38..3d2deeb 100644 --- a/src/server/dispatcher-client.h +++ b/src/server/dispatcher-client.h @@ -19,6 +19,7 @@ public: //Static function to run a request and wait for it to finish before returning static QStringList parseInputs(QStringList inputs, AuthorizationManager *auth); + static bool DispatcherAvailable(); private: AuthorizationManager *AUTH;