mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-11-01 19:27:59 +00:00
Moving preferences into ORM.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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() );
|
||||
|
||||
50
src/storage/orm_preferences.cpp
Normal file
50
src/storage/orm_preferences.cpp
Normal 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));
|
||||
}
|
||||
30
src/storage/orm_preferences.h
Normal file
30
src/storage/orm_preferences.h
Normal 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:
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-11-30.
|
||||
//
|
||||
|
||||
#include "storage_conversions.h"
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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{"?,?,?,?,?,?,?,?"};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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{"?,?,?,?,?,?,?,?"};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user