Moving preferences into ORM.

This commit is contained in:
stephb9959
2021-12-27 21:38:21 -08:00
parent b869da3b09
commit d202b9e365
23 changed files with 107 additions and 1421 deletions

View File

@@ -91,12 +91,7 @@ add_executable( owsec
src/RESTAPI/RESTAPI_email_handler.cpp src/RESTAPI/RESTAPI_email_handler.h
src/RESTAPI/RESTAPI_sms_handler.cpp src/RESTAPI/RESTAPI_sms_handler.h
src/storage/storage_avatar.cpp src/storage/storage_avatar.h
# src/storage/storage_users.h src/storage/storage_users.cpp
# src/storage/storage_subscribers.cpp src/storage/storage_subscribers.h
src/storage/storage_actionLinks.cpp src/storage/storage_actionLinks.h
# src/storage/storage_tokens.h src/storage/storage_tokens.cpp
# src/storage/storage_subtokens.h src/storage/storage_subtokens.cpp
src/storage/storage_preferences.cpp src/storage/storage_preferences.h
src/storage/storage_tables.cpp
src/RESTAPI/RESTAPI_suboauth2_handler.h src/RESTAPI/RESTAPI_suboauth2_handler.cpp
src/RESTAPI/RESTAPI_subuser_handler.h src/RESTAPI/RESTAPI_subuser_handler.cpp
@@ -117,7 +112,7 @@ add_executable( owsec
src/framework/OpenWifiTypes.h
src/RESTAPI/RESTAPI_submfa_handler.cpp src/RESTAPI/RESTAPI_submfa_handler.h
src/storage/orm_users.cpp src/storage/orm_users.h
src/storage/orm_tokens.cpp src/storage/orm_tokens.h)
src/storage/orm_tokens.cpp src/storage/orm_tokens.h src/storage/orm_preferences.cpp src/storage/orm_preferences.h)
if(NOT SMALL_BUILD)
target_link_libraries(owsec PUBLIC

2
build
View File

@@ -1 +1 @@
137
141

View File

@@ -10,7 +10,7 @@ namespace OpenWifi {
void RESTAPI_preferences::DoGet() {
SecurityObjects::Preferences P;
Poco::JSON::Object Answer;
StorageService()->GetPreferences(UserInfo_.userinfo.Id, P);
StorageService()->PreferencesDB().GetPreferences(UserInfo_.userinfo.Id, P);
P.to_json(Answer);
ReturnObject(Answer);
}
@@ -25,7 +25,7 @@ namespace OpenWifi {
P.id = UserInfo_.userinfo.Id;
P.modified = std::time(nullptr);
StorageService()->SetPreferences(P);
StorageService()->PreferencesDB().SetPreferences(P);
Poco::JSON::Object Answer;
P.to_json(Answer);

View File

@@ -64,7 +64,7 @@ namespace OpenWifi {
}
StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
StorageService()->DeletePreferences(UserInfo_.userinfo.email,Id);
StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
StorageService()->UserTokenDB().RevokeAllTokens(UInfo.email);

View File

@@ -20,11 +20,13 @@ namespace OpenWifi {
SubDB_ = std::make_unique<OpenWifi::BaseUserDB>("Subscribers", "sub", dbType_,*Pool_, Logger());
UserTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("Tokens", "tok", dbType_,*Pool_, Logger());
SubTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("SubTokens", "stk", dbType_,*Pool_, Logger());
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
UserDB_->Create();
SubDB_->Create();
UserTokenDB_->Create();
SubTokenDB_->Create();
PreferencesDB_->Create();
UserDB_->InitializeDefaultUser();

View File

@@ -17,6 +17,7 @@
#include "storage/orm_users.h"
#include "storage/orm_tokens.h"
#include "storage/orm_preferences.h"
namespace OpenWifi {
@@ -41,6 +42,7 @@ namespace OpenWifi {
OpenWifi::BaseUserDB & SubDB() { return *SubDB_; }
OpenWifi::BaseTokenDB & UserTokenDB() { return *UserTokenDB_; }
OpenWifi::BaseTokenDB & SubTokenDB() { return *SubTokenDB_; }
OpenWifi::PreferencesDB & PreferencesDB() { return *PreferencesDB_; }
/*
* All user management functions
@@ -61,16 +63,12 @@ namespace OpenWifi {
bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
void CleanOldActionLinks();
bool GetPreferences(std::string &Id, SecurityObjects::Preferences &P);
bool SetPreferences(SecurityObjects::Preferences &P);
bool DeletePreferences(const std::string &AdminId, std::string & Id);
private:
int Create_Tables();
int Create_AvatarTable();
int Create_ActionLinkTable();
int Create_Preferences();
// int Create_Preferences();
// int Create_UserTable();
// int Create_TokensTable();
// int Create_SubTokensTable();
@@ -80,7 +78,7 @@ namespace OpenWifi {
std::unique_ptr<OpenWifi::BaseUserDB> SubDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> UserTokenDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> SubTokenDB_;
std::unique_ptr<OpenWifi::PreferencesDB> PreferencesDB_;
Poco::Timer Timer_;
Archiver Archiver_;

View File

@@ -488,6 +488,18 @@ namespace ORM {
return false;
}
template <typename T> bool ReplaceRecord( const char *FieldName, T & Value, RecordType & R) {
try {
if(Exists(FieldName, Value)) {
return UpdateRecord(FieldName,Value,R);
}
return CreateRecord(R);
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
template <typename T> bool GetNameAndDescription(const char *FieldName, T & Value, std::string & Name, std::string & Description ) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );

View File

@@ -0,0 +1,50 @@
//
// Created by stephane bourque on 2021-12-27.
//
#include "orm_preferences.h"
/*
"Id varchar(36) UNIQUE PRIMARY KEY,"
"modified bigint,"
"data text"};
*/
namespace OpenWifi {
static ORM::FieldVec PreferencesDB_Fields{
ORM::Field{"id", 36, true},
ORM::Field{"modified", ORM::FieldType::FT_BIGINT},
ORM::Field{"data", ORM::FieldType::FT_TEXT}
};
PreferencesDB::PreferencesDB( const std::string &TableName, const std::string &Shortname ,OpenWifi::DBType T,
Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, TableName.c_str(), PreferencesDB_Fields, {}, P, L, Shortname.c_str()) {
}
bool PreferencesDB::GetPreferences(std::string &Id, SecurityObjects::Preferences &P) {
return GetRecord("id", Id, P);
}
bool PreferencesDB::SetPreferences(SecurityObjects::Preferences &P) {
return ReplaceRecord("id", P.id, P);
}
bool PreferencesDB::DeletePreferences(const std::string &AdminId, std::string &Id) {
return DeleteRecord("id",Id);
}
}
template<> void ORM::DB<OpenWifi::PreferencesRecordTuple, OpenWifi::SecurityObjects::Preferences>::Convert(OpenWifi::PreferencesRecordTuple &R, OpenWifi::SecurityObjects::Preferences &P ) {
P.id = R.get<0>();
P.modified = R.get<1>();
P.data = OpenWifi::RESTAPI_utils::to_stringpair_array(R.get<2>());
}
template<> void ORM::DB<OpenWifi::PreferencesRecordTuple, OpenWifi::SecurityObjects::Preferences>::Convert(OpenWifi::SecurityObjects::Preferences &P, OpenWifi::PreferencesRecordTuple &R ) {
R.set<0>(P.id);
R.set<1>(P.modified);
R.set<2>(OpenWifi::RESTAPI_utils::to_string(P.data));
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2021-12-27.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string, // id
uint64_t, // modified
std::string // data
> PreferencesRecordTuple;
typedef std::vector<PreferencesRecordTuple> PreferencesRecordTupleList;
class PreferencesDB : public ORM::DB<PreferencesRecordTuple, SecurityObjects::Preferences> {
public:
PreferencesDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
bool GetPreferences(std::string &Id, SecurityObjects::Preferences &P);
bool SetPreferences(SecurityObjects::Preferences &P);
bool DeletePreferences(const std::string &AdminId, std::string & Id);
private:
};
}

View File

@@ -17,7 +17,6 @@
namespace OpenWifi {
static ORM::FieldVec BaseTokenDB_Fields{
// object info
ORM::Field{"token", ORM::FT_TEXT, 0, true},
ORM::Field{"refreshToken", ORM::FieldType::FT_TEXT},
ORM::Field{"tokenType", ORM::FieldType::FT_TEXT},

View File

@@ -1,5 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#include "storage_conversions.h"

View File

@@ -1,77 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
inline bool Convert(const UserInfoRecordTuple &T, SecurityObjects::UserInfo &U) {
U.Id = T.get<0>();
U.name = T.get<1>();
U.description = T.get<2>();
U.avatar = T.get<3>();
U.email = T.get<4>();
U.validated = T.get<5>();
U.validationEmail = T.get<6>();
U.validationDate = T.get<7>();
U.creationDate = T.get<8>();
U.validationURI = T.get<9>();
U.changePassword = T.get<10>();
U.lastLogin = T.get<11>();
U.currentLoginURI = T.get<12>();
U.lastPasswordChange = T.get<13>();
U.lastEmailCheck = T.get<14>();
U.waitingForEmailCheck = T.get<15>();
U.locale = T.get<16>();
U.notes = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(T.get<17>());
U.location = T.get<18>();
U.owner = T.get<19>();
U.suspended = T.get<20>();
U.blackListed = T.get<21>();
U.userRole = SecurityObjects::UserTypeFromString(T.get<22>());
U.userTypeProprietaryInfo = RESTAPI_utils::to_object<SecurityObjects::UserLoginLoginExtensions>(T.get<23>());
U.securityPolicy = T.get<24>();
U.securityPolicyChange = T.get<25>();
U.currentPassword = T.get<26>();
U.lastPasswords = RESTAPI_utils::to_object_array(T.get<27>());
U.oauthType = T.get<28>();
U.oauthUserInfo = T.get<29>();
return true;
}
inline bool Convert(const SecurityObjects::UserInfo &U, UserInfoRecord &T) {
T.set<0>(U.Id);
T.set<1>(U.name);
T.set<2>(U.description);
T.set<3>(U.avatar);
T.set<4>(U.email);
T.set<5>(U.validated);
T.set<6>(U.validationEmail);
T.set<7>(U.validationDate);
T.set<8>(U.creationDate);
T.set<9>(U.validationURI);
T.set<10>(U.changePassword);
T.set<11>(U.lastLogin);
T.set<12>(U.currentLoginURI);
T.set<13>(U.lastPasswordChange);
T.set<14>(U.lastEmailCheck);
T.set<15>(U.waitingForEmailCheck);
T.set<16>(U.locale);
T.set<17>(RESTAPI_utils::to_string(U.notes));
T.set<18>(U.location);
T.set<19>(U.owner);
T.set<20>(U.suspended);
T.set<21>(U.blackListed);
T.set<22>(SecurityObjects::UserTypeToString(U.userRole));
T.set<23>(RESTAPI_utils::to_string(U.userTypeProprietaryInfo));
T.set<24>(U.securityPolicy);
T.set<25>(U.securityPolicyChange);
T.set<26>(U.currentPassword);
T.set<27>(RESTAPI_utils::to_string(U.lastPasswords));
T.set<28>(U.oauthType);
T.set<29>(U.oauthUserInfo);
return true;
}
}

View File

@@ -1,92 +0,0 @@
//
// Created by stephane bourque on 2021-11-16.
//
#include "StorageService.h"
#include "storage_preferences.h"
namespace OpenWifi {
void Convert(const PreferencesRecord &R,SecurityObjects::Preferences &P ) {
P.id = R.get<0>();
P.modified = R.get<1>();
P.data = OpenWifi::RESTAPI_utils::to_stringpair_array(R.get<2>());
}
void Convert(const SecurityObjects::Preferences &P, PreferencesRecord &R ) {
R.set<0>(P.id);
R.set<1>(P.modified);
R.set<2>(OpenWifi::RESTAPI_utils::to_string(P.data));
}
bool StorageService::GetPreferences(std::string &Id, SecurityObjects::Preferences &P) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
P.data.clear();
std::string St2{"SELECT " + AllPreferencesFieldsForSelect + " From Preferences WHERE Id=?"};
PreferencesRecord R;
Select << ConvertParams(St2),
Poco::Data::Keywords::into(R),
Poco::Data::Keywords::use(Id);
Select.execute();
Convert(R,P);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::SetPreferences(SecurityObjects::Preferences &P) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement InsertOrUpdate(Sess);
std::string InsertOrReplace{
"insert into Preferences (Id, Modified, Data) VALUES(?,?,?) on conflict(Id) do "
"update set Modified=?, Data=?"
};
P.modified = time(nullptr);
std::string Data = OpenWifi::RESTAPI_utils::to_string(P.data);
InsertOrUpdate << ConvertParams(InsertOrReplace),
Poco::Data::Keywords::use(P.id),
Poco::Data::Keywords::use(P.modified),
Poco::Data::Keywords::use(Data),
Poco::Data::Keywords::use(P.modified),
Poco::Data::Keywords::use(Data);
InsertOrUpdate.execute();
return true;
}
catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::DeletePreferences(const std::string &AdminId, std::string & Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St{ "delete from Preferences where id=?" };
Delete << ConvertParams(St),
Poco::Data::Keywords::use(Id);
Delete.execute();
return true;
}
catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
};

View File

@@ -1,36 +0,0 @@
//
// Created by stephane bourque on 2021-11-16.
//
#pragma once
#include <string>
#include <vector>
#include "Poco/Tuple.h"
namespace OpenWifi {
static const std::string AllPreferencesFieldsForCreation{
"Id varchar(36) UNIQUE PRIMARY KEY,"
"modified bigint,"
"data text"};
static const std::string AllPreferencesFieldsForSelect{
"Id, "
"modified, "
"data "};
static const std::string AllPreferencesFieldsForUpdate{
" Id=?, "
"modified=?, "
"data=? "};
typedef Poco::Tuple <
std::string, // id
uint64_t, // modified
std::string // data
> PreferencesRecord;
typedef std::vector <PreferencesRecord> PreferencesRecordList;
}

View File

@@ -1,283 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#include <vector>
#include "Poco/Tuple.h"
#include "storage_subscribers.h"
#include "StorageService.h"
#include "framework/MicroService.h"
#include "storage/storage_conversions.h"
namespace OpenWifi {
bool Storage::CreateSubUser(const std::string & Admin, SecurityObjects::UserInfo & NewUser, bool PasswordHashedAlready ) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::toLowerInPlace(NewUser.email);
// if the user exists, must return an error
std::string St1{"select " + AllSubUsersFieldsForSelect + " from Subscribers where email=?"};
UserInfoRecordList Records;
try {
Poco::Data::Statement Statement(Sess);
Statement << ConvertParams(St1),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(NewUser.email);
Statement.execute();
} catch (const Poco::Exception &E) {
}
if(!Records.empty())
return false;
if(!PasswordHashedAlready) {
NewUser.Id = MicroService::CreateUUID();
NewUser.creationDate = std::time(nullptr);
}
// if there is a password, we assume that we do not want email verification,
// if there is no password, we will do email verification
if(NewUser.currentPassword.empty()) {
} else {
if(!PasswordHashedAlready) {
NewUser.currentPassword = AuthService()->ComputeNewPasswordHash(NewUser.email,NewUser.currentPassword);
NewUser.lastPasswords.clear();
NewUser.lastPasswords.push_back(NewUser.currentPassword);
NewUser.lastPasswordChange = std::time(nullptr);
NewUser.validated = true;
}
}
auto Notes = RESTAPI_utils::to_string(NewUser.notes);
auto UserType = SecurityObjects::UserTypeToString(NewUser.userRole);
auto OldPasswords = RESTAPI_utils::to_string(NewUser.lastPasswords);
auto userTypeProprietaryInfo = RESTAPI_utils::to_string(NewUser.userTypeProprietaryInfo);
St1 = "INSERT INTO Subscribers (" + AllSubUsersFieldsForSelect + ") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
Poco::Data::Statement Statement(Sess);
UserInfoRecord R;
Convert(NewUser, R);
Statement << ConvertParams(St1),
Poco::Data::Keywords::use(R);
Statement.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << "What: " << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::GetSubUserByEmail(std::string & email, SecurityObjects::UserInfo & User) {
std::string St1;
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
Poco::toLowerInPlace(email);
// if the user exists, must return an error
St1 = "select " + AllSubUsersFieldsForSelect + " from Subscribers where email=?";
UserInfoRecordList Records;
Select << ConvertParams(St1) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(email);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],User);
return true;
} catch (const Poco::Exception &E) {
std::cout << "Statement: " << St1 << std::endl;
std::cout << "What:" << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::GetSubUserById(std::string &Id, SecurityObjects::UserInfo &User) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
// if the user exists, must return an error
std::string St1{"select " + AllSubUsersFieldsForSelect + " from Subscribers where id=?"};
UserInfoRecordList Records;
Select << ConvertParams(St1) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(Id);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],User);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::GetSubUsers( uint64_t Offset, uint64_t HowMany, SecurityObjects::UserInfoVec & Users) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
UserInfoRecordList Records;
std::string St1{"select " + AllSubUsersFieldsForSelect + " from Subscribers order by id ASC "};
Select << ConvertParams(St1) + ComputeRange(Offset, HowMany),
Poco::Data::Keywords::into(Records);
Select.execute();
for(const auto &R:Records) {
SecurityObjects::UserInfo U;
Convert(R,U);
Users.push_back(U);
}
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::UpdateSubUserInfo(const std::string & Admin, USER_ID_TYPE & Id, SecurityObjects::UserInfo &UInfo) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string St1{"update Subscribers set " + AllSubUsersFieldsForUpdate + " where id=?"};
auto Notes = RESTAPI_utils::to_string(UInfo.notes);
auto UserType = SecurityObjects::UserTypeToString(UInfo.userRole);
auto OldPasswords = RESTAPI_utils::to_string(UInfo.lastPasswords);
auto userTypeProprietaryInfo = RESTAPI_utils::to_string(UInfo.userTypeProprietaryInfo);
UserInfoRecord R;
Convert(UInfo, R);
Update << ConvertParams(St1),
Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(UInfo.Id);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << " Exception: " << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::DeleteSubUser(const std::string & Admin, USER_ID_TYPE & Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from Subscribers where id=?"};
Delete << ConvertParams(St1),
Poco::Data::Keywords::use(Id);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetSubOwner(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Owner) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetSubLocation(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Location) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetSubLastLogin(std::string &Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string St1{"update Subscribers set lastLogin=? where id=?"};
uint64_t Now=std::time(nullptr);
Update << ConvertParams(St1),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Id);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
Storage::AUTH_ERROR Storage::ChangeSubPassword(const std::string & Admin, USER_ID_TYPE & Id, const std::string &OldPassword, const std::string &NewPassword) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
return SUCCESS;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return INTERNAL_ERROR;
}
bool Storage::AddSubNotes(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Notes) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetSubPolicyChange(const std::string & Admin, USER_ID_TYPE & Id, const std::string &NewPolicy) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
}

View File

@@ -1,142 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#pragma once
#include <string>
#include <vector>
#include "Poco/Tuple.h"
namespace OpenWifi {
static const std::string AllSubUsersFieldsForCreation{
" Id varchar(36) UNIQUE PRIMARY KEY,"
"name varchar,"
"description varchar,"
"avatar varchar,"
"email varchar,"
"validated boolean,"
"validationEmail varchar,"
"validationDate bigint,"
"creationDate bigint,"
"validationURI varchar,"
"changePassword boolean,"
"lastLogin bigint,"
"currentLoginURI varchar,"
"lastPasswordChange bigint,"
"lastEmailCheck bigint,"
"waitingForEmailCheck boolean,"
"locale varchar,"
"notes text,"
"location varchar,"
"owner varchar,"
"suspended boolean,"
"blackListed boolean,"
"userRole varchar,"
"userTypeProprietaryInfo text,"
"securityPolicy text,"
"securityPolicyChange bigint,"
"currentPassword varchar,"
"lastPasswords varchar,"
"oauthType varchar,"
"oauthUserInfo text"};
static const std::string AllSubUsersFieldsForSelect{
"Id,"
"name,"
"description,"
"avatar,"
"email,"
"validated,"
"validationEmail,"
"validationDate,"
"creationDate,"
"validationURI,"
"changePassword,"
"lastLogin,"
"currentLoginURI,"
"lastPasswordChange,"
"lastEmailCheck,"
"waitingForEmailCheck,"
"locale,"
"notes,"
"location,"
"owner,"
"suspended,"
"blackListed,"
"userRole,"
"userTypeProprietaryInfo,"
"securityPolicy,"
"securityPolicyChange,"
"currentPassword,"
"lastPasswords,"
"oauthType,"
"oauthUserInfo"};
static const std::string AllSubUsersFieldsForUpdate{
" Id=?, "
"name=?, "
"description=?, "
"avatar=?, "
"email=?, "
"validated=?, "
"validationEmail=?, "
"validationDate=?, "
"creationDate=?, "
"validationURI=?, "
"changePassword=?, "
"lastLogin=?, "
"currentLoginURI=?, "
"lastPasswordChange=?, "
"lastEmailCheck=?, "
"waitingForEmailCheck=?, "
"locale=?, "
"notes=?, "
"location=?, "
"owner=?, "
"suspended=?, "
"blackListed=?, "
"userRole=?, "
"userTypeProprietaryInfo=?, "
"securityPolicy=?, "
"securityPolicyChange=?, "
"currentPassword=?, "
"lastPasswords=?, "
"oauthType=?, "
"oauthUserInfo=? "};
typedef Poco::Tuple <
std::string, // Id = 0;
std::string, // name;
std::string, // description;
std::string, // avatar;
std::string, // email;
bool, // bool validated = false;
std::string, // validationEmail;
uint64_t, // validationDate = 0;
uint64_t, // creationDate = 0;
std::string, // validationURI;
bool, // bool changePassword = true;
uint64_t, // lastLogin = 0;
std::string, // currentLoginURI;
uint64_t, // lastPasswordChange = 0;
uint64_t, // lastEmailCheck = 0;
bool, // bool waitingForEmailCheck = false;
std::string, // locale;
std::string, // notes;
std::string, // location;
std::string, // owner;
bool, // bool suspended = false;
bool, // bool blackListed = false;
std::string, // userRole;
std::string, // userTypeProprietaryInfo;
std::string, // securityPolicy;
uint64_t, // securityPolicyChange;
std::string, // currentPassword;
std::string, // lastPasswords;
std::string, // oauthType;
std::string // oauthUserInfo;
> UserInfoRecord;
typedef std::vector <UserInfoRecord> UserInfoRecordList;
}

View File

@@ -1,153 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#include "storage/storage_subtokens.h"
#include "StorageService.h"
namespace OpenWifi {
/*
"Token TEXT PRIMARY KEY, "
"RefreshToken TEXT, "
"TokenType TEXT, "
"UserName TEXT, "
"Created BIGINT, "
"Expires BIGINT, "
"IdleTimeOut BIGINT, "
"RevocationDate BIGINT "
*/
bool StorageService::AddSubToken(std::string &UserID, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
uint64_t Now = std::time(nullptr);
uint64_t Z = 0;
std::string St2{
"INSERT INTO SubTokens (" + AllSubTokensFieldsForSelect + ") VALUES(" + AllSubTokensValuesForSelect + ")"};
Insert << ConvertParams(St2),
Poco::Data::Keywords::use(Token),
Poco::Data::Keywords::use(RefreshToken),
Poco::Data::Keywords::use(TokenType),
Poco::Data::Keywords::use(UserID),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Expires),
Poco::Data::Keywords::use(TimeOut),
Poco::Data::Keywords::use(Z);
Insert.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::GetSubToken(std::string &Token, SecurityObjects::WebToken &WT, std::string & UserId, uint64_t &RevocationDate) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
RevocationDate = 0 ;
std::string St2{"SELECT " + AllSubTokensFieldsForSelect + " From SubTokens WHERE Token=?"};
Select << ConvertParams(St2),
Poco::Data::Keywords::into(WT.access_token_),
Poco::Data::Keywords::into(WT.refresh_token_),
Poco::Data::Keywords::into(WT.token_type_),
Poco::Data::Keywords::into(UserId),
Poco::Data::Keywords::into(WT.created_),
Poco::Data::Keywords::into(WT.expires_in_),
Poco::Data::Keywords::into(WT.idle_timeout_),
Poco::Data::Keywords::into(RevocationDate),
Poco::Data::Keywords::use(Token);
Select.execute();
if(Select.rowsExtracted()!=1)
return false;
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::IsSubTokenRevoked(std::string &Token) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
uint32_t RevocationDate = 0 ;
std::string St2{"SELECT RevocationDate From SubTokens WHERE Token=?"};
Select << ConvertParams(St2),
Poco::Data::Keywords::into(RevocationDate),
Poco::Data::Keywords::use(Token);
Select.execute();
if(Select.columnsExtracted()==0)
return false;
return RevocationDate>0 ;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::RevokeSubToken(std::string &Token) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
uint64_t Now = std::time(nullptr);
// update users set lastLogin=? where id=?
std::string St2{"UPDATE SubTokens Set RevocationDate=? WHERE Token=?"};
Update << ConvertParams(St2),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Token);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::CleanExpiredSubTokens() {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
uint64_t Now = std::time(nullptr);
std::string St2{"DELETE From SubTokens WHERE (Created+Expires) <= ?"};
Delete << ConvertParams(St2),
Poco::Data::Keywords::use(Now);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::RevokeAllSubTokens(std::string & UserId) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St2{"DELETE From SubTokens WHERE Username=?"};
Delete << ConvertParams(St2),
Poco::Data::Keywords::use(UserId);
Delete.execute();
return true;
} catch(const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
}

View File

@@ -1,27 +0,0 @@
//
// Created by stephane bourque on 2021-11-30.
//
#pragma once
#include <string>
#include <vector>
#include "Poco/Tuple.h"
namespace OpenWifi {
static std::string AllSubTokensFieldsForCreation{ "Token TEXT PRIMARY KEY, "
"RefreshToken TEXT, "
"TokenType TEXT, "
"UserName TEXT, "
"Created BIGINT, "
"Expires BIGINT, "
"IdleTimeOut BIGINT, "
"RevocationDate BIGINT "
};
static std::string AllSubTokensFieldsForSelect {"Token, RefreshToken, TokenType, Username, Created, Expires, IdleTimeOut, RevocationDate"};
static std::string AllSubTokensValuesForSelect{"?,?,?,?,?,?,?,?"};
}

View File

@@ -3,18 +3,15 @@
//
#include "StorageService.h"
#include "storage_users.h"
#include "storage_avatar.h"
#include "storage_actionLinks.h"
#include "storage_tokens.h"
#include "storage_preferences.h"
namespace OpenWifi {
int StorageService::Create_Tables() {
Create_AvatarTable();
Create_ActionLinkTable();
Create_Preferences();
// Create_Preferences();
// Create_UserTable();
// Create_TokensTable();
// Create_SubTokensTable();
@@ -133,7 +130,6 @@ namespace OpenWifi {
}
return 1;
}
*/
int StorageService::Create_Preferences() {
try {
@@ -148,4 +144,7 @@ namespace OpenWifi {
}
return 1;
}
*/
}

View File

@@ -1,151 +0,0 @@
#include "StorageService.h"
#include "storage/storage_tokens.h"
namespace OpenWifi {
/*
"Token TEXT PRIMARY KEY, "
"RefreshToken TEXT, "
"TokenType TEXT, "
"UserName TEXT, "
"Created BIGINT, "
"Expires BIGINT, "
"IdleTimeOut BIGINT, "
"RevocationDate BIGINT "
*/
bool StorageService::AddToken(std::string &UserID, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
uint64_t Now = std::time(nullptr);
uint64_t Z = 0;
std::string St2{
"INSERT INTO Tokens (" + AllTokensFieldsForSelect + ") VALUES(" + AllTokensValuesForSelect + ")"};
Insert << ConvertParams(St2),
Poco::Data::Keywords::use(Token),
Poco::Data::Keywords::use(RefreshToken),
Poco::Data::Keywords::use(TokenType),
Poco::Data::Keywords::use(UserID),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Expires),
Poco::Data::Keywords::use(TimeOut),
Poco::Data::Keywords::use(Z);
Insert.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::GetToken(std::string &Token, SecurityObjects::WebToken &WT, std::string & UserId, uint64_t &RevocationDate) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
RevocationDate = 0 ;
std::string St2{"SELECT " + AllTokensFieldsForSelect + " From Tokens WHERE Token=?"};
Select << ConvertParams(St2),
Poco::Data::Keywords::into(WT.access_token_),
Poco::Data::Keywords::into(WT.refresh_token_),
Poco::Data::Keywords::into(WT.token_type_),
Poco::Data::Keywords::into(UserId),
Poco::Data::Keywords::into(WT.created_),
Poco::Data::Keywords::into(WT.expires_in_),
Poco::Data::Keywords::into(WT.idle_timeout_),
Poco::Data::Keywords::into(RevocationDate),
Poco::Data::Keywords::use(Token);
Select.execute();
if(Select.rowsExtracted()!=1)
return false;
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::IsTokenRevoked(std::string &Token) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
uint32_t RevocationDate = 0 ;
std::string St2{"SELECT RevocationDate From Tokens WHERE Token=?"};
Select << ConvertParams(St2),
Poco::Data::Keywords::into(RevocationDate),
Poco::Data::Keywords::use(Token);
Select.execute();
if(Select.columnsExtracted()==0)
return false;
return RevocationDate>0 ;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::RevokeToken(std::string &Token) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
uint64_t Now = std::time(nullptr);
// update users set lastLogin=? where id=?
std::string St2{"UPDATE Tokens Set RevocationDate=? WHERE Token=?"};
Update << ConvertParams(St2),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Token);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::CleanExpiredTokens() {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
uint64_t Now = std::time(nullptr);
std::string St2{"DELETE From Tokens WHERE (Created+Expires) <= ?"};
Delete << ConvertParams(St2),
Poco::Data::Keywords::use(Now);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool StorageService::RevokeAllTokens(std::string & UserId) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St2{"DELETE From Tokens WHERE Username=?"};
Delete << ConvertParams(St2),
Poco::Data::Keywords::use(UserId);
Delete.execute();
return true;
} catch(const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
}

View File

@@ -1,27 +0,0 @@
//
// Created by stephane bourque on 2021-11-08.
//
#pragma once
#include <string>
#include <vector>
#include "Poco/Tuple.h"
namespace OpenWifi {
static std::string AllTokensFieldsForCreation{ "Token TEXT PRIMARY KEY, "
"RefreshToken TEXT, "
"TokenType TEXT, "
"UserName TEXT, "
"Created BIGINT, "
"Expires BIGINT, "
"IdleTimeOut BIGINT, "
"RevocationDate BIGINT "
};
static std::string AllTokensFieldsForSelect {"Token, RefreshToken, TokenType, Username, Created, Expires, IdleTimeOut, RevocationDate"};
static std::string AllTokensValuesForSelect{"?,?,?,?,?,?,?,?"};
}

View File

@@ -1,268 +0,0 @@
//
// Created by stephane bourque on 2021-06-25.
//
#include <vector>
#include "Poco/Tuple.h"
#include "storage_users.h"
#include "StorageService.h"
#include "framework/MicroService.h"
#include "storage/storage_conversions.h"
namespace OpenWifi {
std::string OldDefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"};
void Storage::ReplaceOldDefaultUUID() {
try {
Poco::Data::Session Sess = Pool_->get();
std::string St1{"update users set id=? where id=?"};
Poco::Data::Statement Update(Sess);
Update << ConvertParams(St1),
Poco::Data::Keywords::use(NewDefaultUseridStockUUID),
Poco::Data::Keywords::use(OldDefaultUseridStockUUID);
Update.execute();
} catch (...) {
}
}
// if we do not find a default user, then we need to create one based on the
// property file. We must set its flag to "must change password", this user has root privilege.
// if the "DEFAULT-USER-UUID", we keep the UUID of that user. We want to hide the UUID of the default root user
bool Storage::InitializeDefaultUser() {
SecurityObjects::UserInfo U;
bool DefaultUserCreated = false;
ReplaceOldDefaultUUID();
AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
if(!GetUserById(NewDefaultUseridStockUUID,U) && !DefaultUserCreated) {
U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
U.lastPasswords.push_back(U.currentPassword);
U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
U.Id = NewDefaultUseridStockUUID;
U.userRole = SecurityObjects::ROOT;
U.creationDate = std::time(nullptr);
U.validated = true;
U.name = "Default User";
U.description = "Default user should be deleted.";
U.changePassword = true;
CreateUser("SYSTEM",U, true);
AppServiceRegistry().Set("defaultusercreated",true);
return true;
}
return false;
}
bool Storage::CreateUser(const std::string & Admin, SecurityObjects::UserInfo & NewUser, bool PasswordHashedAlready ) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::toLowerInPlace(NewUser.email);
// if the user exists, must return an error
std::string St1{"select " + AllUsersFieldsForSelect + " from users where email=?"};
UserInfoRecordList Records;
try {
Poco::Data::Statement Statement(Sess);
Statement << ConvertParams(St1),
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(NewUser.email);
Statement.execute();
} catch (const Poco::Exception &E) {
}
if(!Records.empty())
return false;
if(!PasswordHashedAlready) {
NewUser.Id = MicroService::CreateUUID();
NewUser.creationDate = std::time(nullptr);
}
// if there is a password, we assume that we do not want email verification,
// if there is no password, we will do email verification
if(NewUser.currentPassword.empty()) {
} else {
if(!PasswordHashedAlready) {
NewUser.currentPassword = AuthService()->ComputeNewPasswordHash(NewUser.email,NewUser.currentPassword);
NewUser.lastPasswords.clear();
NewUser.lastPasswords.push_back(NewUser.currentPassword);
NewUser.lastPasswordChange = std::time(nullptr);
NewUser.validated = true;
}
}
auto Notes = RESTAPI_utils::to_string(NewUser.notes);
auto UserType = SecurityObjects::UserTypeToString(NewUser.userRole);
auto OldPasswords = RESTAPI_utils::to_string(NewUser.lastPasswords);
auto userTypeProprietaryInfo = RESTAPI_utils::to_string(NewUser.userTypeProprietaryInfo);
St1 = "INSERT INTO Users (" + AllUsersFieldsForSelect + ") VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
Poco::Data::Statement Statement(Sess);
UserInfoRecord R;
Convert(NewUser, R);
Statement << ConvertParams(St1),
Poco::Data::Keywords::use(R);
Statement.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << "What: " << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::GetUserByEmail(std::string & email, SecurityObjects::UserInfo & User) {
std::string St1;
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
Poco::toLowerInPlace(email);
// if the user exists, must return an error
St1 = "select " + AllUsersFieldsForSelect + " from users where email=?";
UserInfoRecordList Records;
Select << ConvertParams(St1) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(email);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],User);
return true;
} catch (const Poco::Exception &E) {
std::cout << "Statement: " << St1 << std::endl;
std::cout << "What:" << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::GetUserById(std::string &Id, SecurityObjects::UserInfo &User) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
// if the user exists, must return an error
std::string St1{"select " + AllUsersFieldsForSelect + " from users where id=?"};
UserInfoRecordList Records;
Select << ConvertParams(St1) ,
Poco::Data::Keywords::into(Records),
Poco::Data::Keywords::use(Id);
Select.execute();
if(Records.empty())
return false;
Convert(Records[0],User);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::GetUsers( uint64_t Offset, uint64_t HowMany, SecurityObjects::UserInfoVec & Users) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
UserInfoRecordList Records;
std::string St1{"select " + AllUsersFieldsForSelect + " from users order by id ASC "};
Select << ConvertParams(St1) + ComputeRange(Offset, HowMany),
Poco::Data::Keywords::into(Records);
Select.execute();
for(const auto &R:Records) {
SecurityObjects::UserInfo U;
Convert(R,U);
Users.push_back(U);
}
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::UpdateUserInfo(const std::string & Admin, USER_ID_TYPE & Id, SecurityObjects::UserInfo &UInfo) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string St1{"update users set " + AllUsersFieldsForUpdate + " where id=?"};
//auto Notes = RESTAPI_utils::to_string(UInfo.notes);
//auto UserType = SecurityObjects::UserTypeToString(UInfo.userRole);
//auto OldPasswords = RESTAPI_utils::to_string(UInfo.lastPasswords);
//auto userTypeProprietaryInfo = RESTAPI_utils::to_string(UInfo.userTypeProprietaryInfo);
UserInfoRecord R;
Convert(UInfo, R);
Update << ConvertParams(St1),
Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(UInfo.Id);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
std::cout << " Exception: " << E.what() << " name: " << E.name() << std::endl;
Logger().log(E);
}
return false;
}
bool Storage::DeleteUser(const std::string & Admin, USER_ID_TYPE & Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from users where id=?"};
Delete << ConvertParams(St1),
Poco::Data::Keywords::use(Id);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetLastLogin(std::string &Id) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string St1{"update users set lastLogin=? where id=?"};
uint64_t Now=std::time(nullptr);
Update << ConvertParams(St1),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Id);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
}

View File

@@ -1,138 +0,0 @@
//
// Created by stephane bourque on 2021-07-15.
//
#pragma once
namespace OpenWifi {
static const std::string AllUsersFieldsForCreation{
" Id varchar(36) UNIQUE PRIMARY KEY,"
"name varchar,"
"description varchar,"
"avatar varchar,"
"email varchar,"
"validated boolean,"
"validationEmail varchar,"
"validationDate bigint,"
"creationDate bigint,"
"validationURI varchar,"
"changePassword boolean,"
"lastLogin bigint,"
"currentLoginURI varchar,"
"lastPasswordChange bigint,"
"lastEmailCheck bigint,"
"waitingForEmailCheck boolean,"
"locale varchar,"
"notes text,"
"location varchar,"
"owner varchar,"
"suspended boolean,"
"blackListed boolean,"
"userRole varchar,"
"userTypeProprietaryInfo text,"
"securityPolicy text,"
"securityPolicyChange bigint,"
"currentPassword varchar,"
"lastPasswords varchar,"
"oauthType varchar,"
"oauthUserInfo text"};
static const std::string AllUsersFieldsForSelect{
"Id,"
"name,"
"description,"
"avatar,"
"email,"
"validated,"
"validationEmail,"
"validationDate,"
"creationDate,"
"validationURI,"
"changePassword,"
"lastLogin,"
"currentLoginURI,"
"lastPasswordChange,"
"lastEmailCheck,"
"waitingForEmailCheck,"
"locale,"
"notes,"
"location,"
"owner,"
"suspended,"
"blackListed,"
"userRole,"
"userTypeProprietaryInfo,"
"securityPolicy,"
"securityPolicyChange,"
"currentPassword,"
"lastPasswords,"
"oauthType,"
"oauthUserInfo"};
static const std::string AllUsersFieldsForUpdate{
" Id=?, "
"name=?, "
"description=?, "
"avatar=?, "
"email=?, "
"validated=?, "
"validationEmail=?, "
"validationDate=?, "
"creationDate=?, "
"validationURI=?, "
"changePassword=?, "
"lastLogin=?, "
"currentLoginURI=?, "
"lastPasswordChange=?, "
"lastEmailCheck=?, "
"waitingForEmailCheck=?, "
"locale=?, "
"notes=?, "
"location=?, "
"owner=?, "
"suspended=?, "
"blackListed=?, "
"userRole=?, "
"userTypeProprietaryInfo=?, "
"securityPolicy=?, "
"securityPolicyChange=?, "
"currentPassword=?, "
"lastPasswords=?, "
"oauthType=?, "
"oauthUserInfo=? "};
typedef Poco::Tuple <
std::string, // Id = 0;
std::string, // name;
std::string, // description;
std::string, // avatar;
std::string, // email;
bool, // bool validated = false;
std::string, // validationEmail;
uint64_t, // validationDate = 0;
uint64_t, // creationDate = 0;
std::string, // validationURI;
bool, // bool changePassword = true;
uint64_t, // lastLogin = 0;
std::string, // currentLoginURI;
uint64_t, // lastPasswordChange = 0;
uint64_t, // lastEmailCheck = 0;
bool, // bool waitingForEmailCheck = false;
std::string, // locale;
std::string, // notes;
std::string, // location;
std::string, // owner;
bool, // bool suspended = false;
bool, // bool blackListed = false;
std::string, // userRole;
std::string, // userTypeProprietaryInfo;
std::string, // securityPolicy;
uint64_t, // securityPolicyChange;
std::string, // currentPassword;
std::string, // lastPasswords;
std::string, // oauthType;
std::string // oauthUserInfo;
> UserInfoRecord;
typedef std::vector <UserInfoRecord> UserInfoRecordList;
}