Commit 4bab04b5 authored by Guillaume BIENKOWSKI's avatar Guillaume BIENKOWSKI

Factorize some code in auth db

parent 1e5e4cbc
......@@ -34,7 +34,9 @@ FileAuthDb::FileAuthDb() {
sync();
}
void FileAuthDb::getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener *listener) {
void FileAuthDb::getPasswordFromBackend(su_root_t *root, const std::string &id, const std::string &domain, const std::string &authid, AuthDbListener *listener)
{
AuthDbResult res=AuthDbResult::PASSWORD_NOT_FOUND;
time_t now = getCurrentTime();
......@@ -42,9 +44,9 @@ void FileAuthDb::getPassword(su_root_t *root, const url_t *from, const char *aut
sync();
}
string key(createPasswordKey(from->url_user, from->url_host, auth_username));
string key(createPasswordKey(id, domain, authid));
if ( getCachedPassword(key, from->url_host, listener->mPassword) == VALID_PASS_FOUND ) {
if ( getCachedPassword(key, domain, listener->mPassword) == VALID_PASS_FOUND ) {
res = AuthDbResult::PASSWORD_FOUND;
}
listener->mResult=res;
......
......@@ -423,33 +423,14 @@ static void closeCursor(SQLHSTMT &stmt) {
void OdbcAuthDb::getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener *listener){
// Check for usable cached password
string id(from->url_user);
string domain(from->url_host);
string auth(auth_username);
string key(createPasswordKey(id, domain, auth));
switch(getCachedPassword(key, domain, listener->mPassword)) {
case VALID_PASS_FOUND:
listener->mResult=AuthDbResult::PASSWORD_FOUND;
listener->onResult();
return;
case EXPIRED_PASS_FOUND:
// Might check here if connection is failing
// If it is the case use fallback password and
//return AuthDbResult::PASSWORD_FOUND;
break;
case NO_PASS_FOUND:
break;
}
void OdbcAuthDb::getPasswordFromBackend(su_root_t *root, const std::string& id, const std::string& domain, const std::string& authid, AuthDbListener *listener){
if (mAsynchronousRetrieving) {
// Asynchronously retrieve password in a new thread.
// Allocate on the stack and detach. It is lawful since:
// "When detach() returns, *this no longer represents the possibly continuing thread of execution."
thread t=thread(bind(&OdbcAuthDb::doAsyncRetrievePassword, this, root, id, domain, auth, listener));
thread t=thread(bind(&OdbcAuthDb::doAsyncRetrievePassword, this, root, id, domain, authid, listener));
t.detach(); // Thread will continue running in detached mode
return;
} else {
......@@ -457,7 +438,7 @@ void OdbcAuthDb::getPassword(su_root_t *root, const url_t *from, const char *aut
string foundPassword;
timings.tStart=steady_clock::now();
ConnectionCtx ctx;
AuthDbResult ret = doRetrievePassword(ctx, id, domain, auth, foundPassword, timings);
AuthDbResult ret = doRetrievePassword(ctx, id, domain, authid, foundPassword, timings);
timings.tEnd=steady_clock::now();
if (ret == AUTH_ERROR) {
timings.error = true;
......@@ -469,15 +450,6 @@ void OdbcAuthDb::getPassword(su_root_t *root, const url_t *from, const char *aut
}
}
static void main_thread_async_response_cb(su_root_magic_t *rm, su_msg_r msg,
void *u) {
AuthDbListener **listenerStorage = (AuthDbListener**)su_msg_data(msg);
AuthDbListener *listener=*listenerStorage;
listener->onResult();
}
/*
static unsigned long threadCount=0;
static mutex threadCountMutex;
......@@ -499,39 +471,7 @@ void OdbcAuthDb::doAsyncRetrievePassword(su_root_t *root, string id, string doma
}
timings.done();
if (listener) {
su_msg_r mamc = SU_MSG_R_INIT;
if (-1 == su_msg_create(mamc,
su_root_task(root),
su_root_task(root),
main_thread_async_response_cb,
sizeof(AuthDbListener*))) {
LOGF("Couldn't create auth async message");
}
AuthDbListener **listenerStorage = (AuthDbListener **)su_msg_data(mamc);
*listenerStorage = listener;
switch (ret) {
case PASSWORD_FOUND:
listener->mResult=ret;
listener->mPassword=password;
break;
case PASSWORD_NOT_FOUND:
listener->mResult=AuthDbResult::PASSWORD_NOT_FOUND;
listener->mPassword="";
break;
case AUTH_ERROR:
/*in that case we can fallback to the cached password previously set*/
break;
case PENDING:
LOGF("unhandled case PENDING");
break;
}
if (-1 == su_msg_send(mamc)) {
LOGF("Couldn't send auth async message to main thread.");
}
}
notifyPasswordRetrieved(root, listener, ret, password);
/*
threadCountMutex.lock();
......
......@@ -30,7 +30,9 @@ AuthDbListener::~AuthDbListener(){
class FixedAuthDb : public AuthDb{
public:
FixedAuthDb(){}
virtual void getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener * listener) {
virtual void getPasswordFromBackend(su_root_t *root, const std::string& id, const std::string& domain, const std::string& authid, AuthDbListener *listener)
{
listener->mPassword.assign("fixed");
listener->mResult=PASSWORD_FOUND;
listener->onResult();
......@@ -111,6 +113,74 @@ bool AuthDb::cachePassword(const string &key, const string &domain, const string
return true;
}
void AuthDb::getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener *listener){
// Check for usable cached password
string id(from->url_user);
string domain(from->url_host);
string auth(auth_username);
string key(createPasswordKey(id, domain, auth));
switch(getCachedPassword(key, domain, listener->mPassword)) {
case VALID_PASS_FOUND:
listener->mResult=AuthDbResult::PASSWORD_FOUND;
listener->onResult();
return;
case EXPIRED_PASS_FOUND:
// Might check here if connection is failing
// If it is the case use fallback password and
//return AuthDbResult::PASSWORD_FOUND;
break;
case NO_PASS_FOUND:
break;
}
// if we reach here, password wasn't cached: we have to grab the password from the actual backend
getPasswordFromBackend(root, id, domain, auth, listener);
}
static void main_thread_async_response_cb(su_root_magic_t *rm, su_msg_r msg,
void *u) {
AuthDbListener **listenerStorage = (AuthDbListener**)su_msg_data(msg);
AuthDbListener *listener=*listenerStorage;
listener->onResult();
}
void AuthDb::notifyPasswordRetrieved(su_root_t *root, AuthDbListener *listener, AuthDbResult result, const std::string &password) {
if (listener) {
su_msg_r mamc = SU_MSG_R_INIT;
if (-1 == su_msg_create(mamc,
su_root_task(root),
su_root_task(root),
main_thread_async_response_cb,
sizeof(AuthDbListener*))) {
LOGF("Couldn't create auth async message");
}
AuthDbListener **listenerStorage = (AuthDbListener **)su_msg_data(mamc);
*listenerStorage = listener;
switch (result) {
case PASSWORD_FOUND:
listener->mResult=result;
listener->mPassword=password;
break;
case PASSWORD_NOT_FOUND:
listener->mResult=AuthDbResult::PASSWORD_NOT_FOUND;
listener->mPassword="";
break;
case AUTH_ERROR:
/*in that case we can fallback to the cached password previously set*/
break;
case PENDING:
LOGF("unhandled case PENDING");
break;
}
if (-1 == su_msg_send(mamc)) {
LOGF("Couldn't send auth async message to main thread.");
}
}
}
void AuthDb::createCachedAccount(const url_t *from, const char *auth_username, const char *password, int expires){
if (from->url_host && from->url_user){
string key=createPasswordKey(from->url_user, from->url_host, auth_username ? auth_username : "");
......
......@@ -71,10 +71,17 @@ protected:
void createCachedAccount(const url_t *from, const char *auth_username, const char *password, int expires);
void clearCache();
int mCacheExpire;
void notifyPasswordRetrieved(su_root_t *root, AuthDbListener*listener, AuthDbResult result, const std::string& password);
public:
virtual ~AuthDb();
virtual void getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener *listener)=0;
void getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener *listener);
virtual void createAccount(const url_t *from, const char *auth_username, const char *password, int expires);
virtual void getPasswordFromBackend(su_root_t *root, const std::string& id, const std::string& domain, const std::string& authid, AuthDbListener *listener) = 0;
static AuthDb* get();
AuthDb (const AuthDb &);
......@@ -91,10 +98,12 @@ protected:
public:
FileAuthDb();
virtual void getPassword(su_root_t *root, const url_t *from, const char *auth_username, AuthDbListener* listener);
virtual void getPasswordFromBackend(su_root_t *root, const std::string& id, const std::string& domain, const std::string& authid, AuthDbListener *listener);
};
#if ENABLE_ODBC
class OdbcAuthDb : public AuthDb {
~OdbcAuthDb();
const static int fieldLength = 500;
......@@ -129,13 +138,13 @@ class OdbcAuthDb : public AuthDb {
AuthDbResult doRetrievePassword(ConnectionCtx& ctx, const std::string &user, const std::string &host, const std::string &auth, std::string &foundPassword, AuthDbTimings &timings);
void doAsyncRetrievePassword(su_root_t *, std::string id, std::string domain, std::string auth, AuthDbListener *listener);
public:
virtual void getPassword(su_root_t*, const url_t *from, const char *auth_username, AuthDbListener *listener);
virtual void getPasswordFromBackend(su_root_t *root, const std::string& id, const std::string& domain, const std::string& authid, AuthDbListener *listener);
std::map<std::string,std::string> cachedPasswords;
void setExecuteDirect(const bool value);
bool connect(const std::string &dsn, const std::string &request, const std::vector<std::string> &parameters, int maxIdLength, int maxPassLength);
bool checkConnection();
OdbcAuthDb();
};
#endif
#endif /* ENABLE_ODBC */
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment