mirror of
https://github.com/binary-kitchen/doorlockd
synced 2024-12-22 18:34:25 +01:00
Implemented better Response handling
Signed-off-by: Ralf Ramsauer <ralf@ramses-pyramidenbau.de>
This commit is contained in:
parent
3b7338ea6e
commit
5c825a0958
@ -52,12 +52,12 @@ Logic::~Logic()
|
|||||||
_tokenUpdater.join();
|
_tokenUpdater.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Response Logic::parseRequest(const Json::Value &root)
|
Response Logic::parseRequest(const Json::Value &root)
|
||||||
{
|
{
|
||||||
unique_lock<mutex> l(_mutex);
|
unique_lock<mutex> l(_mutex);
|
||||||
|
|
||||||
_logger(LogLevel::info, "Incoming request...");
|
_logger(LogLevel::info, "Incoming request...");
|
||||||
Response retval = Fail;
|
Response response;
|
||||||
string action, user, password, ip, token;
|
string action, user, password, ip, token;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -70,7 +70,8 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
|
|||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::warning, "Error parsing JSON");
|
_logger(LogLevel::warning, "Error parsing JSON");
|
||||||
retval = JsonError;
|
response.code = Response::Code::JsonError;
|
||||||
|
response.message = "Error parsing JSON";
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,12 +83,13 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
|
|||||||
if (_checkToken(token) == false)
|
if (_checkToken(token) == false)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::error, "User provided invalid token");
|
_logger(LogLevel::error, "User provided invalid token");
|
||||||
retval = InvalidToken;
|
response.code = Response::Code::InvalidToken;
|
||||||
|
response.message = "User provided invalid token";
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = _checkLDAP(user,password);
|
response = _checkLDAP(user,password);
|
||||||
if (retval != Success)
|
if (!response)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::error, "Ldap error");
|
_logger(LogLevel::error, "Ldap error");
|
||||||
goto out;
|
goto out;
|
||||||
@ -95,45 +97,55 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
|
|||||||
|
|
||||||
if (action == "lock")
|
if (action == "lock")
|
||||||
{
|
{
|
||||||
retval = _lock();
|
response = _lock();
|
||||||
} else if (action == "unlock") {
|
} else if (action == "unlock") {
|
||||||
retval = _unlock();
|
response = _unlock();
|
||||||
} else {
|
} else {
|
||||||
_logger(LogLevel::error, "Unknown Action: %s", action.c_str());
|
response.code = Response::Code::UnknownAction;
|
||||||
retval = UnknownAction;
|
response.message = "Unknown Action: " + action;
|
||||||
|
_logger(response.message, LogLevel::error);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return retval;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Response Logic::_lock()
|
Response Logic::_lock()
|
||||||
{
|
{
|
||||||
|
Response response;
|
||||||
if (_door.state() == Door::State::Locked)
|
if (_door.state() == Door::State::Locked)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::warning, "Unable to lock: already closed");
|
response.code = Response::Code::AlreadyLocked;
|
||||||
return AlreadyLocked;
|
response.message = "Unable to lock: already closed";
|
||||||
|
_logger(response.message, LogLevel::warning);
|
||||||
|
} else {
|
||||||
|
_door.lock();
|
||||||
|
_createNewToken(false);
|
||||||
|
|
||||||
|
response.code = Response::Code::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
_door.lock();
|
return response;
|
||||||
_createNewToken(false);
|
|
||||||
|
|
||||||
return Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Response Logic::_unlock()
|
Response Logic::_unlock()
|
||||||
{
|
{
|
||||||
|
Response response;
|
||||||
|
|
||||||
const auto oldState = _door.state();
|
const auto oldState = _door.state();
|
||||||
_door.unlock();
|
_door.unlock();
|
||||||
_createNewToken(false);
|
_createNewToken(false);
|
||||||
|
|
||||||
if (oldState == Door::State::Unlocked)
|
if (oldState == Door::State::Unlocked)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::warning, "Unable to unlock: already unlocked");
|
response.code = Response::Code::AlreadyUnlocked;
|
||||||
return AlreadyUnlocked;
|
response.message = "Unable to unlock: already unlocked";
|
||||||
|
_logger(response.message, LogLevel::warning);
|
||||||
|
} else {
|
||||||
|
response.code = Response::Code::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Logic::_checkToken(const string &strToken)
|
bool Logic::_checkToken(const string &strToken)
|
||||||
@ -153,11 +165,12 @@ bool Logic::_checkToken(const string &strToken)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Response Logic::_checkLDAP(const string &user, const string &password)
|
Response Logic::_checkLDAP(const string &user, const string &password)
|
||||||
{
|
{
|
||||||
constexpr int BUFFERSIZE = 1024;
|
constexpr int BUFFERSIZE = 1024;
|
||||||
char buffer[BUFFERSIZE];
|
char buffer[BUFFERSIZE];
|
||||||
Response retval = Fail;
|
Response retval;
|
||||||
|
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
LDAP* ld = nullptr;
|
LDAP* ld = nullptr;
|
||||||
unsigned long version = LDAP_VERSION3;
|
unsigned long version = LDAP_VERSION3;
|
||||||
@ -168,8 +181,10 @@ Logic::Response Logic::_checkLDAP(const string &user, const string &password)
|
|||||||
rc = ldap_initialize(&ld, _ldapUri.c_str());
|
rc = ldap_initialize(&ld, _ldapUri.c_str());
|
||||||
if(rc != LDAP_SUCCESS)
|
if(rc != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::error, "LDAP initialize error: %s", ldap_err2string(rc));
|
retval.message = (string)"LDAP initialize error: "
|
||||||
retval = LDAPInit;
|
+ ldap_err2string(rc);
|
||||||
|
retval.code = Response::Code::LDAPInit;
|
||||||
|
_logger(retval.message, LogLevel::error);
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,21 +193,24 @@ Logic::Response Logic::_checkLDAP(const string &user, const string &password)
|
|||||||
(void*)&version);
|
(void*)&version);
|
||||||
if (rc != LDAP_SUCCESS)
|
if (rc != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::error, "LDAP set version failed");
|
retval.code = Response::Code::LDAPInit;
|
||||||
retval = LDAPInit;
|
retval.message = "LDAP set version failed";
|
||||||
|
_logger(retval.message, LogLevel::error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ldap_simple_bind_s(ld, buffer, password.c_str());
|
rc = ldap_simple_bind_s(ld, buffer, password.c_str());
|
||||||
if (rc != LDAP_SUCCESS)
|
if (rc != LDAP_SUCCESS)
|
||||||
{
|
{
|
||||||
_logger(LogLevel::error, "Credential check for user \"%s\" failed: %s", user.c_str(), ldap_err2string(rc));
|
retval = Response::Code::InvalidCredentials;
|
||||||
retval = InvalidCredentials;
|
retval.message = "Credential check for user \"" + user
|
||||||
|
+ "\" failed: " + ldap_err2string(rc);
|
||||||
|
_logger(retval.message, LogLevel::error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger(LogLevel::notice, "user \"%s\" successfully authenticated", user.c_str());
|
_logger(LogLevel::notice, "user \"%s\" successfully authenticated", user.c_str());
|
||||||
retval = Success;
|
retval = Response::Code::Success;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ldap_unbind(ld);
|
ldap_unbind(ld);
|
||||||
|
@ -7,11 +7,10 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <json/json.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "door.h"
|
#include "door.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
|
#include "response.h"
|
||||||
|
|
||||||
/* The "Logic" class
|
/* The "Logic" class
|
||||||
*
|
*
|
||||||
@ -31,20 +30,6 @@ public:
|
|||||||
std::condition_variable &onTokenUpdate);
|
std::condition_variable &onTokenUpdate);
|
||||||
~Logic();
|
~Logic();
|
||||||
|
|
||||||
enum Response {
|
|
||||||
Success = 0, // Request successful
|
|
||||||
Fail, // General non-specified error
|
|
||||||
AlreadyUnlocked, // Authentication successful, but door is already unlocked
|
|
||||||
AlreadyLocked, // Authentication successful, but door is already locked
|
|
||||||
NotJson, // Request is not a valid JSON object
|
|
||||||
JsonError, // Request is valid JSON, but does not contain necessary material
|
|
||||||
InvalidToken, // Request contains invalid token
|
|
||||||
InvalidCredentials, // Invalid LDAP credentials
|
|
||||||
InvalidIP, // IP check failure
|
|
||||||
UnknownAction, // Unknown action
|
|
||||||
LDAPInit, // Ldap initialization failed
|
|
||||||
};
|
|
||||||
|
|
||||||
// Parse incoming JSON Requests
|
// Parse incoming JSON Requests
|
||||||
Response parseRequest(const Json::Value &root);
|
Response parseRequest(const Json::Value &root);
|
||||||
|
|
||||||
|
@ -53,16 +53,18 @@ static void session(tcp::socket &&sock)
|
|||||||
|
|
||||||
Json::Reader reader;
|
Json::Reader reader;
|
||||||
Json::Value root;
|
Json::Value root;
|
||||||
Logic::Response rc = Logic::Response::Fail;
|
Response response;
|
||||||
|
|
||||||
if (reader.parse(request, root, false))
|
if (reader.parse(request, root, false))
|
||||||
{
|
{
|
||||||
l(LogLevel::warning, "Request ist not valid JSON!");
|
response.message = "Request is no valid JSON";
|
||||||
|
response.code = Response::Code::JsonError;
|
||||||
|
l(response.message, LogLevel::warning);
|
||||||
} else {
|
} else {
|
||||||
rc = logic->parseRequest(root);
|
response = logic->parseRequest(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
sock.write_some(boost::asio::buffer(std::to_string(rc) + "\n"),
|
sock.write_some(boost::asio::buffer(response.toJson()),
|
||||||
error);
|
error);
|
||||||
|
|
||||||
if (error == boost::asio::error::eof)
|
if (error == boost::asio::error::eof)
|
||||||
|
Loading…
Reference in New Issue
Block a user