adding code for loading user role

This commit is contained in:
Dario 2020-01-15 09:16:59 +01:00
parent d8e3728201
commit 28900e04fe
11 changed files with 315 additions and 9 deletions

View File

@ -2,6 +2,7 @@
namespace controller {
User::User(model::table::User* dbModel)
: mUserRole(USER_ROLE_NOT_LOADED)
{
mDBModel = dbModel;
}
@ -31,4 +32,5 @@ namespace controller {
Poco::Data::BLOB pubkey(pubkey_array, 32);
return getModel()->loadFromDB("pubkey", pubkey);
}
}

View File

@ -3,9 +3,18 @@
#include "../model/table/User.h"
#include "TableControllerBase.h"
namespace controller {
enum UserLoadedRole {
USER_ROLE_NOT_LOADED,
USER_ROLE_CURRENTLY_LOADING,
USER_ROLE_NONE,
USER_ROLE_ADMIN
};
class User : public TableControllerBase
{
public:
@ -15,6 +24,8 @@ namespace controller {
static Poco::AutoPtr<User> create();
static Poco::AutoPtr<User> create(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed = 0, std::string languageKey = "de");
inline size_t load(const std::string& email) { return getModel()->loadFromDB("email", email); }
inline size_t load(int user_id) { return getModel()->loadFromDB("id", user_id); }
int load(const unsigned char* pubkey_array);
@ -22,8 +33,11 @@ namespace controller {
inline Poco::AutoPtr<model::table::User> getModel() { return _getModel<model::table::User>(); }
inline const model::table::User* getModel() const { return _getModel<model::table::User>(); }
protected:
User(model::table::User* dbModel);
UserLoadedRole mUserRole;
};
}

View File

@ -576,10 +576,16 @@ UserStates Session::loadUser(const std::string& email, const std::string& passwo
lock("Session::loadUser");
if (mSessionUser && mSessionUser->getEmail() != email) {
mSessionUser = nullptr;
mNewUser = nullptr;
}
if (!mSessionUser) {
//if (!mSessionUser) {
if (mNewUser.isNull()) {
mNewUser = controller::User::create();
// load user for email only once from db
mSessionUser = new User(email.data());
mNewUser->load(email);
mSessionUser = new User(mNewUser);
//mSessionUser = new User(email.data());
}
if (mSessionUser->getUserState() >= USER_LOADED_FROM_DB) {
if (!mSessionUser->validatePwd(password, this)) {

View File

@ -64,6 +64,7 @@ public:
// set new model objects
inline void setUser(Poco::AutoPtr<controller::User> user) { mNewUser = user; }
inline Poco::AutoPtr<controller::User> getNewUser() { return mNewUser; }
// ---------------- User functions ----------------------------
// TODO: automatic redirect after some time, median profiled time for register

View File

@ -11,6 +11,8 @@
#include "../../ServerConfig.h"
#include "Poco/JSON/Object.h"
//using namespace Poco::Data::Keywords;
namespace model {
@ -166,6 +168,8 @@ namespace model {
// ******************** Generic Tasks ************************************
// -------- Insert ---------------
class ModelInsertTask : public UniLib::controller::CPUTask
{
public:
@ -180,7 +184,7 @@ namespace model {
bool mLoadId;
};
// -------- Update ---------------
template <class T>
class ModelUpdateTask : public UniLib::controller::CPUTask
@ -210,6 +214,7 @@ namespace model {
bool mEmailErrors;
};
// -------- Load ---------------
}
}

View File

View File

@ -0,0 +1,60 @@
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_ROLES_INCLUDE
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_ROLES_INCLUDE
#include "ModelBase.h"
#include "Poco/Types.h"
#include "Poco/Tuple.h"
namespace model {
namespace table {
enum RoleType {
ROLE_ADMIN = 1
};
class Roles : public ModelBase
{
};
/*
typedef Poco::Tuple<int, int, Poco::UInt64, int> EmailOptInTuple;
class EmailOptIn : public ModelBase
{
public:
EmailOptIn(const Poco::UInt64& code, int user_id, EmailOptInType type);
EmailOptIn(const Poco::UInt64& code, EmailOptInType type);
EmailOptIn(const EmailOptInTuple& tuple);
EmailOptIn();
~EmailOptIn();
// generic db operations
const char* getTableName() { return "email_opt_in"; }
std::string toString();
inline Poco::UInt64 getCode() const { return mEmailVerificationCode; }
inline int getUserId() const { return mUserId; }
inline EmailOptInType getType() const { return static_cast<EmailOptInType>(mType); }
inline void setCode(Poco::UInt64 code) { mEmailVerificationCode = code; }
inline void setUserId(int user_Id) { mUserId = user_Id; }
static const char* typeToString(EmailOptInType type);
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
int mUserId;
// data type must be a multiple of 4
Poco::UInt64 mEmailVerificationCode;
int mType;
};
*/
}
}
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_ROLES_INCLUDE

View File

@ -12,12 +12,12 @@ namespace model {
namespace table {
User::User()
: mPasswordHashed(0), mEmailChecked(false), mLanguageKey("de")
: mPasswordHashed(0), mEmailChecked(false), mLanguageKey("de"), mRole(ROLE_NOT_LOADED)
{
}
User::User(const std::string& email, const std::string& first_name, const std::string& last_name, Poco::UInt64 passwordHashed/* = 0*/, std::string languageKey/* = "de"*/)
: mEmail(email), mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey)
: mEmail(email), mFirstName(first_name), mLastName(last_name), mPasswordHashed(passwordHashed), mEmailChecked(false), mLanguageKey(languageKey), mRole(ROLE_NOT_LOADED)
{
}
@ -69,9 +69,11 @@ namespace model {
{
Poco::Data::Statement select(session);
select << "SELECT id, email, first_name, last_name, password, pubkey, privkey, email_checked, language from " << getTableName() << " where " << fieldName << " = ?",
into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(mPublicKey), into(mPrivateKey), into(mEmailChecked), into(mLanguageKey);
select << "SELECT id, email, first_name, last_name, password, pubkey, privkey, email_checked, language, user_roles.role_id "
<< " FROM " << getTableName()
<< " LEFT JOIN user_roles ON " << getTableName() << ".id = user_roles.user_id "
<< " WHERE " << fieldName << " = ?"
,into(mID), into(mEmail), into(mFirstName), into(mLastName), into(mPasswordHashed), into(mPublicKey), into(mPrivateKey), into(mEmailChecked), into(mLanguageKey), into(mRole);
return select;
@ -138,5 +140,34 @@ namespace model {
return ss.str();
}
Poco::JSON::Object User::getJson()
{
auto mm = MemoryManager::getInstance();
auto pubkeyHex = mm->getFreeMemory(65);
memset(*pubkeyHex, 0, 65);
lock("User::getJson");
Poco::JSON::Object userObj;
if (!mPublicKey.isNull()) {
sodium_bin2hex(*pubkeyHex, 65, mPublicKey.value().content().data(), mPublicKey.value().content().size());
}
userObj.set("first_name", mFirstName);
userObj.set("last_name", mLastName);
userObj.set("email", mEmail);
userObj.set("public_hex", (char*)*pubkeyHex);
//userObj.set("state", userStateToString(mState));
userObj.set("email_checked", mEmailChecked);
userObj.set("ident_hash", DRMakeStringHash(mEmail.data(), mEmail.size()));
userObj.set("role", UserRoles::typeToString(getRole()));
unlock();
mm->releaseMemory(pubkeyHex);
return userObj;
}
}
}

View File

@ -7,6 +7,8 @@
//#include "Poco/Nullable.h"
//#include "Poco/Data/LOB.h"
#include "UserRoles.h"
namespace model {
namespace table {
enum UserFields
@ -41,6 +43,7 @@ namespace model {
inline const std::string& getFirstName() const { return mFirstName; }
inline const std::string& getLastName() const { return mLastName; }
inline const Poco::UInt64& getPasswordHashed() const { return mPasswordHashed; }
inline RoleType getRole() const { if (mRole.isNull()) return ROLE_NONE; return static_cast<RoleType>(mRole.value()); }
inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); }
inline bool existPrivateKeyCrypted() const { return !mPrivateKey.isNull(); }
inline const std::vector<unsigned char>& getPrivateKeyCrypted() const { return mPrivateKey.value().content(); }
@ -58,7 +61,7 @@ namespace model {
inline void setEmailChecked(bool emailChecked) { mEmailChecked = emailChecked; }
inline void setLanguageKey(const std::string& languageKey) { mLanguageKey = languageKey; }
Poco::JSON::Object getJson();
protected:
@ -80,6 +83,9 @@ namespace model {
bool mEmailChecked;
std::string mLanguageKey;
// from neighbor tables
Poco::Nullable<int> mRole;
};
}
}

View File

@ -0,0 +1,127 @@
#include "UserRoles.h"
using namespace Poco::Data::Keywords;
namespace model {
namespace table {
UserRoles::UserRoles(int user_id, RoleType type)
: mUserId(user_id), mType(type)
{
}
UserRoles::UserRoles(const UserRolesTuple& tuple)
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mType(tuple.get<2>())
{
}
UserRoles::UserRoles()
{
}
UserRoles::~UserRoles()
{
}
Poco::Data::Statement UserRoles::_insertIntoDB(Poco::Data::Session session)
{
Poco::Data::Statement insert(session);
lock();
insert << "INSERT INTO " << getTableName()
<< " (user_id, role_id) VALUES(?,?)"
, use(mUserId), bind(mType);
unlock();
return insert;
}
Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::string& fieldName)
{
Poco::Data::Statement select(session);
select << "SELECT id, user_id, role_id FROM " << getTableName()
<< " where " << fieldName << " = ?"
, into(mID), into(mUserId), into(mType);
return select;
}
Poco::Data::Statement UserRoles::_loadIdFromDB(Poco::Data::Session session)
{
Poco::Data::Statement select(session);
select << "SELECT id FROM " << getTableName()
<< " where user_id = ? and role_id = ?"
, into(mID), use(mUserId), use(mType);
return select;
}
Poco::Data::Statement UserRoles::_loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName)
{
Poco::Data::Statement select(session);
select << "SELECT id, user_id, role_id FROM " << getTableName()
<< " where " << fieldName << " = ?";
return select;
}
Poco::Data::Statement UserRoles::_loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType/* = MYSQL_CONDITION_AND*/)
{
Poco::Data::Statement select(session);
if (fieldNames.size() <= 1) {
throw Poco::NullValueException("UserRoles::_loadFromDB fieldNames empty or contain only one field");
}
select << "SELECT user_id, role_id FROM " << getTableName()
<< " where " << fieldNames[0] << " = ? ";
if (conditionType == MYSQL_CONDITION_AND) {
for (int i = 1; i < fieldNames.size(); i++) {
select << " AND " << fieldNames[i] << " = ? ";
}
}
else if (conditionType == MYSQL_CONDITION_OR) {
for (int i = 1; i < fieldNames.size(); i++) {
select << " OR " << fieldNames[i] << " = ? ";
}
}
else {
addError(new ParamError("UserRoles::_loadFromDB", "condition type not implemented", conditionType));
}
//<< " where " << fieldName << " = ?"
select, into(mUserId), into(mType);
return select;
}
// generic db operations
std::string UserRoles::toString()
{
std::stringstream ss;
ss << "user_id: " << mUserId << std::endl;
ss << "role: " << typeToString(static_cast<RoleType>(mType));
return ss.str();
}
const char* UserRoles::typeToString(RoleType type)
{
switch (type) {
case ROLE_NOT_LOADED: return "not loaded";
case ROLE_NONE: return "none";
case ROLE_ADMIN: return "admin";
default: return "unknown";
}
}
}
}

View File

@ -0,0 +1,54 @@
#ifndef GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_ROLES_INCLUDE
#define GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_ROLES_INCLUDE
#include "ModelBase.h"
#include "Poco/Types.h"
#include "Poco/Tuple.h"
//#include "Roles.h"
namespace model {
namespace table {
enum RoleType {
ROLE_NOT_LOADED = -1,
ROLE_NONE = 0,
ROLE_ADMIN = 1
};
typedef Poco::Tuple<int, int, int> UserRolesTuple;
class UserRoles : public ModelBase
{
public:
UserRoles(int user_id, RoleType type);
UserRoles(const UserRolesTuple& tuple);
UserRoles();
~UserRoles();
// generic db operations
const char* getTableName() { return "user_roles"; }
std::string toString();
inline int getUserId() const { return mUserId; }
inline RoleType getType() const { return static_cast<RoleType>(mType); }
inline void setUserId(int user_Id) { mUserId = user_Id; }
static const char* typeToString(RoleType type);
protected:
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadIdFromDB(Poco::Data::Session session);
Poco::Data::Statement _loadMultipleFromDB(Poco::Data::Session session, const std::string& fieldName);
Poco::Data::Statement _loadFromDB(Poco::Data::Session session, const std::vector<std::string>& fieldNames, MysqlConditionType conditionType = MYSQL_CONDITION_AND);
Poco::Data::Statement _insertIntoDB(Poco::Data::Session session);
int mUserId;
int mType;
};
}
}
#endif //GRADIDO_LOGIN_SERVER_MODEL_TABLE_USER_ROLES_INCLUDE