1
0
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:
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(); _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(); _door.lock();
_createNewToken(false); _createNewToken(false);
return Success; response.code = Response::Code::Success;
} }
Logic::Response Logic::_unlock() return response;
}
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);

View File

@ -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);

View File

@ -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)