1
0
mirror of https://github.com/binary-kitchen/doorlockd synced 2024-09-27 16:24:46 +02:00

Implemented better Response handling

Signed-off-by: Ralf Ramsauer <ralf@ramses-pyramidenbau.de>
This commit is contained in:
Ralf Ramsauer 2015-09-22 21:25:45 +02:00
parent 3b7338ea6e
commit 5c825a0958
3 changed files with 59 additions and 54 deletions

View File

@ -52,12 +52,12 @@ Logic::~Logic()
_tokenUpdater.join();
}
Logic::Response Logic::parseRequest(const Json::Value &root)
Response Logic::parseRequest(const Json::Value &root)
{
unique_lock<mutex> l(_mutex);
_logger(LogLevel::info, "Incoming request...");
Response retval = Fail;
Response response;
string action, user, password, ip, token;
try {
@ -70,7 +70,8 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
catch (...)
{
_logger(LogLevel::warning, "Error parsing JSON");
retval = JsonError;
response.code = Response::Code::JsonError;
response.message = "Error parsing JSON";
goto out;
}
@ -82,12 +83,13 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
if (_checkToken(token) == false)
{
_logger(LogLevel::error, "User provided invalid token");
retval = InvalidToken;
response.code = Response::Code::InvalidToken;
response.message = "User provided invalid token";
goto out;
}
retval = _checkLDAP(user,password);
if (retval != Success)
response = _checkLDAP(user,password);
if (!response)
{
_logger(LogLevel::error, "Ldap error");
goto out;
@ -95,45 +97,55 @@ Logic::Response Logic::parseRequest(const Json::Value &root)
if (action == "lock")
{
retval = _lock();
response = _lock();
} else if (action == "unlock") {
retval = _unlock();
response = _unlock();
} else {
_logger(LogLevel::error, "Unknown Action: %s", action.c_str());
retval = UnknownAction;
response.code = Response::Code::UnknownAction;
response.message = "Unknown Action: " + action;
_logger(response.message, LogLevel::error);
}
out:
return retval;
return response;
}
Logic::Response Logic::_lock()
Response Logic::_lock()
{
Response response;
if (_door.state() == Door::State::Locked)
{
_logger(LogLevel::warning, "Unable to lock: already closed");
return AlreadyLocked;
}
_door.lock();
_createNewToken(false);
response.code = Response::Code::AlreadyLocked;
response.message = "Unable to lock: already closed";
_logger(response.message, LogLevel::warning);
} else {
_door.lock();
_createNewToken(false);
return Success;
response.code = Response::Code::Success;
}
return response;
}
Logic::Response Logic::_unlock()
Response Logic::_unlock()
{
Response response;
const auto oldState = _door.state();
_door.unlock();
_createNewToken(false);
if (oldState == Door::State::Unlocked)
{
_logger(LogLevel::warning, "Unable to unlock: already unlocked");
return AlreadyUnlocked;
response.code = Response::Code::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)
@ -153,11 +165,12 @@ bool Logic::_checkToken(const string &strToken)
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;
char buffer[BUFFERSIZE];
Response retval = Fail;
Response retval;
int rc = -1;
LDAP* ld = nullptr;
unsigned long version = LDAP_VERSION3;
@ -167,9 +180,11 @@ Logic::Response Logic::_checkLDAP(const string &user, const string &password)
rc = ldap_initialize(&ld, _ldapUri.c_str());
if(rc != LDAP_SUCCESS)
{
_logger(LogLevel::error, "LDAP initialize error: %s", ldap_err2string(rc));
retval = LDAPInit;
{
retval.message = (string)"LDAP initialize error: "
+ ldap_err2string(rc);
retval.code = Response::Code::LDAPInit;
_logger(retval.message, LogLevel::error);
goto out2;
}
@ -178,21 +193,24 @@ Logic::Response Logic::_checkLDAP(const string &user, const string &password)
(void*)&version);
if (rc != LDAP_SUCCESS)
{
_logger(LogLevel::error, "LDAP set version failed");
retval = LDAPInit;
retval.code = Response::Code::LDAPInit;
retval.message = "LDAP set version failed";
_logger(retval.message, LogLevel::error);
goto out;
}
rc = ldap_simple_bind_s(ld, buffer, password.c_str());
if (rc != LDAP_SUCCESS)
{
_logger(LogLevel::error, "Credential check for user \"%s\" failed: %s", user.c_str(), ldap_err2string(rc));
retval = InvalidCredentials;
{
retval = Response::Code::InvalidCredentials;
retval.message = "Credential check for user \"" + user
+ "\" failed: " + ldap_err2string(rc);
_logger(retval.message, LogLevel::error);
goto out;
}
_logger(LogLevel::notice, "user \"%s\" successfully authenticated", user.c_str());
retval = Success;
retval = Response::Code::Success;
out:
ldap_unbind(ld);

View File

@ -7,11 +7,10 @@
#include <condition_variable>
#include <mutex>
#include <json/json.h>
#include "config.h"
#include "door.h"
#include "logger.h"
#include "response.h"
/* The "Logic" class
*
@ -31,20 +30,6 @@ public:
std::condition_variable &onTokenUpdate);
~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
Response parseRequest(const Json::Value &root);

View File

@ -53,16 +53,18 @@ static void session(tcp::socket &&sock)
Json::Reader reader;
Json::Value root;
Logic::Response rc = Logic::Response::Fail;
Response response;
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 {
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);
if (error == boost::asio::error::eof)