diff --git a/build b/build index 3cacc0b..ca7bf83 100644 --- a/build +++ b/build @@ -1 +1 @@ -12 \ No newline at end of file +13 \ No newline at end of file diff --git a/src/ACLProcessor.h b/src/ACLProcessor.h index 534200a..4dde189 100644 --- a/src/ACLProcessor.h +++ b/src/ACLProcessor.h @@ -9,131 +9,124 @@ namespace OpenWifi { - class ACLProcessor { - public: - enum ACL_OPS { - READ, - MODIFY, - DELETE, - CREATE - }; -/* - * 0) You can only delete yourself if you are a subscriber - 1) You cannot delete yourself - 2) If you are root, you can do anything. - 3) You can do anything to yourself - 4) Nobody can touch a root, unless they are a root, unless it is to get information on a ROOT - 5) Creation rules: - ROOT -> create anything - PARTNER -> (multi-tenant owner) admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning - ADMIN -> admin-subs-csr-installer-noc-accounting - ACCOUNTING -> subs-installer-csr + class ACLProcessor { + public: + enum ACL_OPS { READ, MODIFY, DELETE, CREATE }; + /* + * 0) You can only delete yourself if you are a subscriber + 1) You cannot delete yourself + 2) If you are root, you can do anything. + 3) You can do anything to yourself + 4) Nobody can touch a root, unless they are a root, unless it is to get information on a + ROOT 5) Creation rules: ROOT -> create anything PARTNER -> (multi-tenant owner) + admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning ADMIN -> + admin-subs-csr-installer-noc-accounting ACCOUNTING -> subs-installer-csr - */ - static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { + */ + static inline bool Can(const SecurityObjects::UserInfo &User, + const SecurityObjects::UserInfo &Target, ACL_OPS Op) { - switch(Op) { - case DELETE: { - // can a user delete themselves - yes - only if not root. We do not want a system to end up rootless - if(User.id==Target.id) { - return User.userRole != SecurityObjects::ROOT; - } - // Root can delete anyone - switch (User.userRole) { - case SecurityObjects::ROOT: - return true; - case SecurityObjects::ADMIN: - return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::SUBSCRIBER: - return User.id==Target.id; - case SecurityObjects::CSR: - return false; - case SecurityObjects::SYSTEM: - return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::INSTALLER: - return User.id==Target.id; - case SecurityObjects::NOC: - return Target.userRole==SecurityObjects::NOC; - case SecurityObjects::ACCOUNTING: - return Target.userRole==SecurityObjects::ACCOUNTING; - case SecurityObjects::PARTNER: - return Target.userRole!=SecurityObjects::ROOT; - default: - return false; - } - } - break; + switch (Op) { + case DELETE: { + // can a user delete themselves - yes - only if not root. We do not want a system + // to end up rootless + if (User.id == Target.id) { + return User.userRole != SecurityObjects::ROOT; + } + // Root can delete anyone + switch (User.userRole) { + case SecurityObjects::ROOT: + return true; + case SecurityObjects::ADMIN: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::SUBSCRIBER: + return User.id == Target.id; + case SecurityObjects::CSR: + return false; + case SecurityObjects::SYSTEM: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::INSTALLER: + return User.id == Target.id; + case SecurityObjects::NOC: + return Target.userRole == SecurityObjects::NOC; + case SecurityObjects::ACCOUNTING: + return Target.userRole == SecurityObjects::ACCOUNTING; + case SecurityObjects::PARTNER: + return Target.userRole != SecurityObjects::ROOT; + default: + return false; + } + } break; - case READ: { - return User.userRole == SecurityObjects::ROOT || - User.userRole == SecurityObjects::ADMIN || - User.userRole == SecurityObjects::PARTNER; - } - break; + case READ: { + return User.userRole == SecurityObjects::ROOT || + User.userRole == SecurityObjects::ADMIN || + User.userRole == SecurityObjects::PARTNER; + } break; - case CREATE: { - switch(User.userRole) { - case SecurityObjects::ROOT: - return true; - case SecurityObjects::ADMIN: - return Target.userRole!=SecurityObjects::ROOT && - Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::SUBSCRIBER: - return false; - case SecurityObjects::CSR: - return Target.userRole==SecurityObjects::CSR; - case SecurityObjects::SYSTEM: - return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::INSTALLER: - return Target.userRole==SecurityObjects::INSTALLER; - case SecurityObjects::NOC: - return Target.userRole==SecurityObjects::NOC; - case SecurityObjects::ACCOUNTING: - return Target.userRole==SecurityObjects::ACCOUNTING; - case SecurityObjects::PARTNER: - return Target.userRole!=SecurityObjects::ROOT; - default: - return false; - } - } - break; + case CREATE: { + switch (User.userRole) { + case SecurityObjects::ROOT: + return true; + case SecurityObjects::ADMIN: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::SUBSCRIBER: + return false; + case SecurityObjects::CSR: + return Target.userRole == SecurityObjects::CSR; + case SecurityObjects::SYSTEM: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::INSTALLER: + return Target.userRole == SecurityObjects::INSTALLER; + case SecurityObjects::NOC: + return Target.userRole == SecurityObjects::NOC; + case SecurityObjects::ACCOUNTING: + return Target.userRole == SecurityObjects::ACCOUNTING; + case SecurityObjects::PARTNER: + return Target.userRole != SecurityObjects::ROOT; + default: + return false; + } + } break; - case MODIFY: { - switch(User.userRole) { - case SecurityObjects::ROOT: - return true; - case SecurityObjects::ADMIN: - return Target.userRole!=SecurityObjects::ROOT && - Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::SUBSCRIBER: - return User.id==Target.id; - case SecurityObjects::CSR: - return Target.userRole==SecurityObjects::CSR; - case SecurityObjects::SYSTEM: - return Target.userRole!=SecurityObjects::ROOT && - Target.userRole!=SecurityObjects::PARTNER; - case SecurityObjects::INSTALLER: - return Target.userRole==SecurityObjects::INSTALLER; - case SecurityObjects::NOC: - return Target.userRole==SecurityObjects::NOC; - case SecurityObjects::ACCOUNTING: - return Target.userRole==SecurityObjects::ACCOUNTING; - case SecurityObjects::PARTNER: - return Target.userRole!=SecurityObjects::ROOT; - default: - return false; - } - } - break; - default: - return false; - } - } - private: + case MODIFY: { + switch (User.userRole) { + case SecurityObjects::ROOT: + return true; + case SecurityObjects::ADMIN: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::SUBSCRIBER: + return User.id == Target.id; + case SecurityObjects::CSR: + return Target.userRole == SecurityObjects::CSR; + case SecurityObjects::SYSTEM: + return Target.userRole != SecurityObjects::ROOT && + Target.userRole != SecurityObjects::PARTNER; + case SecurityObjects::INSTALLER: + return Target.userRole == SecurityObjects::INSTALLER; + case SecurityObjects::NOC: + return Target.userRole == SecurityObjects::NOC; + case SecurityObjects::ACCOUNTING: + return Target.userRole == SecurityObjects::ACCOUNTING; + case SecurityObjects::PARTNER: + return Target.userRole != SecurityObjects::ROOT; + default: + return false; + } + } break; + default: + return false; + } + } - }; + private: + }; -} +} // namespace OpenWifi - -#endif //OWSEC_ACLPROCESSOR_H +#endif // OWSEC_ACLPROCESSOR_H diff --git a/src/ActionLinkManager.cpp b/src/ActionLinkManager.cpp index 670f066..8e70826 100644 --- a/src/ActionLinkManager.cpp +++ b/src/ActionLinkManager.cpp @@ -3,126 +3,143 @@ // #include "ActionLinkManager.h" -#include "StorageService.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "MessagingTemplates.h" -#include "framework/utils.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "StorageService.h" #include "fmt/format.h" +#include "framework/utils.h" namespace OpenWifi { - int ActionLinkManager::Start() { - poco_information(Logger(),"Starting..."); - if(!Running_) - Thr_.start(*this); - return 0; - } + int ActionLinkManager::Start() { + poco_information(Logger(), "Starting..."); + if (!Running_) + Thr_.start(*this); + return 0; + } - void ActionLinkManager::Stop() { - poco_information(Logger(),"Stopping..."); - if(Running_) { - Running_ = false; - Thr_.wakeUp(); - Thr_.join(); - } - poco_information(Logger(),"Stopped..."); - } + void ActionLinkManager::Stop() { + poco_information(Logger(), "Stopping..."); + if (Running_) { + Running_ = false; + Thr_.wakeUp(); + Thr_.join(); + } + poco_information(Logger(), "Stopped..."); + } - void ActionLinkManager::run() { - Running_ = true ; - Utils::SetThreadName("action-mgr"); + void ActionLinkManager::run() { + Running_ = true; + Utils::SetThreadName("action-mgr"); - while(Running_) { - Poco::Thread::trySleep(2000); - if(!Running_) - break; - std::vector Links; - { - std::lock_guard G(Mutex_); - StorageService()->ActionLinksDB().GetActions(Links); - } + while (Running_) { + Poco::Thread::trySleep(2000); + if (!Running_) + break; + std::vector Links; + { + std::lock_guard G(Mutex_); + StorageService()->ActionLinksDB().GetActions(Links); + } - if(Links.empty()) - continue; + if (Links.empty()) + continue; - for(auto &i:Links) { - if(!Running_) - break; + for (auto &i : Links) { + if (!Running_) + break; - SecurityObjects::UserInfo UInfo; - if((i.action==OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD || - i.action==OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) && !StorageService()->UserDB().GetUserById(i.userId,UInfo)) { - StorageService()->ActionLinksDB().CancelAction(i.id); - continue; - } else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD || - i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL || - i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) { - StorageService()->ActionLinksDB().CancelAction(i.id); - continue; - } else if((i.action==OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) && - (OpenWifi::Now()-i.created)>(24*60*60)) { - StorageService()->ActionLinksDB().CancelAction(i.id); - continue; - } + SecurityObjects::UserInfo UInfo; + if ((i.action == OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD || + i.action == OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) && + !StorageService()->UserDB().GetUserById(i.userId, UInfo)) { + StorageService()->ActionLinksDB().CancelAction(i.id); + continue; + } else if ((i.action == + OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD || + i.action == OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL || + i.action == OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP) && + !StorageService()->SubDB().GetUserById(i.userId, UInfo)) { + StorageService()->ActionLinksDB().CancelAction(i.id); + continue; + } else if ((i.action == OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) && + (OpenWifi::Now() - i.created) > (24 * 60 * 60)) { + StorageService()->ActionLinksDB().CancelAction(i.id); + continue; + } - switch(i.action) { - case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { - if(AuthService()->SendEmailToUser(i.id, UInfo.email, MessagingTemplates::FORGOT_PASSWORD)) { - poco_information(Logger(),fmt::format("Send password reset link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + switch (i.action) { + case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { + if (AuthService()->SendEmailToUser(i.id, UInfo.email, + MessagingTemplates::FORGOT_PASSWORD)) { + poco_information( + Logger(), fmt::format("Send password reset link to {}", UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { - if(AuthService()->SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_VERIFICATION)) { - poco_information(Logger(),fmt::format("Send email verification link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { + if (AuthService()->SendEmailToUser(i.id, UInfo.email, + MessagingTemplates::EMAIL_VERIFICATION)) { + poco_information(Logger(), fmt::format("Send email verification link to {}", + UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: { - if(AuthService()->SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_INVITATION)) { - poco_information(Logger(),fmt::format("Send new subscriber email invitation link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: { + if (AuthService()->SendEmailToUser(i.id, UInfo.email, + MessagingTemplates::EMAIL_INVITATION)) { + poco_information( + Logger(), fmt::format("Send new subscriber email invitation link to {}", + UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { - auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); - if(AuthService()->SendEmailToSubUser(i.id, UInfo.email,MessagingTemplates::SUB_FORGOT_PASSWORD, Signup.count()==1 ? "" : Signup[0])) { - poco_information(Logger(),fmt::format("Send subscriber password reset link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { + auto Signup = Poco::StringTokenizer(UInfo.signingUp, ":"); + if (AuthService()->SendEmailToSubUser(i.id, UInfo.email, + MessagingTemplates::SUB_FORGOT_PASSWORD, + Signup.count() == 1 ? "" : Signup[0])) { + poco_information( + Logger(), + fmt::format("Send subscriber password reset link to {}", UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { - auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); - if(AuthService()->SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { - poco_information(Logger(),fmt::format("Send subscriber email verification link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { + auto Signup = Poco::StringTokenizer(UInfo.signingUp, ":"); + if (AuthService()->SendEmailToSubUser( + i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, + Signup.count() == 1 ? "" : Signup[0])) { + poco_information( + Logger(), fmt::format("Send subscriber email verification link to {}", + UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { - auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); - if(AuthService()->SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { - poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email)); - } - StorageService()->ActionLinksDB().SentAction(i.id); - } - break; + case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { + auto Signup = Poco::StringTokenizer(UInfo.signingUp, ":"); + if (AuthService()->SendEmailToSubUser( + i.id, UInfo.email, MessagingTemplates::SUB_SIGNUP_VERIFICATION, + Signup.count() == 1 ? "" : Signup[0])) { + poco_information( + Logger(), + fmt::format("Send new subscriber email verification link to {}", + UInfo.email)); + } + StorageService()->ActionLinksDB().SentAction(i.id); + } break; - default: { - StorageService()->ActionLinksDB().SentAction(i.id); - } - } - } - } - } + default: { + StorageService()->ActionLinksDB().SentAction(i.id); + } + } + } + } + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/ActionLinkManager.h b/src/ActionLinkManager.h index 479a96f..14be6f1 100644 --- a/src/ActionLinkManager.h +++ b/src/ActionLinkManager.h @@ -8,27 +8,23 @@ namespace OpenWifi { - class ActionLinkManager : public SubSystemServer, Poco::Runnable { - public: + class ActionLinkManager : public SubSystemServer, Poco::Runnable { + public: + static ActionLinkManager *instance() { + static auto instance_ = new ActionLinkManager; + return instance_; + } - static ActionLinkManager * instance() { - static auto instance_ = new ActionLinkManager; - return instance_; - } + int Start() final; + void Stop() final; + void run() final; - int Start() final; - void Stop() final; - void run() final; - - private: - Poco::Thread Thr_; - std::atomic_bool Running_ = false; - - ActionLinkManager() noexcept: - SubSystemServer("ActionLinkManager", "ACTION-SVR", "action.server") - { - } - }; - inline ActionLinkManager * ActionLinkManager() { return ActionLinkManager::instance(); } -} + private: + Poco::Thread Thr_; + std::atomic_bool Running_ = false; + ActionLinkManager() noexcept + : SubSystemServer("ActionLinkManager", "ACTION-SVR", "action.server") {} + }; + inline ActionLinkManager *ActionLinkManager() { return ActionLinkManager::instance(); } +} // namespace OpenWifi diff --git a/src/AuthService.cpp b/src/AuthService.cpp index 9dd8804..703ef84 100644 --- a/src/AuthService.cpp +++ b/src/AuthService.cpp @@ -11,26 +11,29 @@ #include "framework/KafkaManager.h" #include "framework/KafkaTopics.h" -#include "Poco/Net/OAuth20Credentials.h" -#include "Poco/JWT/Token.h" #include "Poco/JWT/Signer.h" +#include "Poco/JWT/Token.h" +#include "Poco/Net/OAuth20Credentials.h" #include "Poco/StringTokenizer.h" -#include "StorageService.h" #include "AuthService.h" +#include "StorageService.h" #include "framework/MicroServiceFuncs.h" -#include "SMTPMailerService.h" #include "MFAServer.h" #include "MessagingTemplates.h" +#include "SMTPMailerService.h" namespace OpenWifi { - AuthService::ACCESS_TYPE AuthService::IntToAccessType(int C) { + AuthService::ACCESS_TYPE AuthService::IntToAccessType(int C) { switch (C) { - case 1: return USERNAME; - case 2: return SERVER; - case 3: return CUSTOM; + case 1: + return USERNAME; + case 2: + return SERVER; + case 3: + return CUSTOM; default: return USERNAME; } @@ -38,818 +41,925 @@ namespace OpenWifi { int AuthService::AccessTypeToInt(ACCESS_TYPE T) { switch (T) { - case USERNAME: return 1; - case SERVER: return 2; - case CUSTOM: return 3; + case USERNAME: + return 1; + case SERVER: + return 2; + case CUSTOM: + return 3; } - return 1; // some compilers complain... + return 1; // some compilers complain... } #if defined(TIP_CERT_SERVICE) - static const std::string DefaultPasswordRule{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{12,}$"}; + static const std::string DefaultPasswordRule{ + "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\." + "\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{12,}$"}; #else - static const std::string DefaultPasswordRule{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; + static const std::string DefaultPasswordRule{ + "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\." + "\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; #endif - int AuthService::Start() { - poco_information(Logger(),"Starting..."); - TokenAging_ = (uint64_t) MicroServiceConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); - RefreshTokenLifeSpan_ = (uint64_t) MicroServiceConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); - HowManyOldPassword_ = MicroServiceConfigGetInt("authentication.oldpasswords", 5); + int AuthService::Start() { + poco_information(Logger(), "Starting..."); + TokenAging_ = + (uint64_t)MicroServiceConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); + RefreshTokenLifeSpan_ = (uint64_t)MicroServiceConfigGetInt( + "authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); + HowManyOldPassword_ = MicroServiceConfigGetInt("authentication.oldpasswords", 5); - AccessPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html"); - PasswordPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html"); - PasswordValidation_ = PasswordValidationStr_ = MicroServiceConfigGetString("authentication.validation.expression",DefaultPasswordRule); + AccessPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.access", + "/wwwassets/access_policy.html"); + PasswordPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.password", + "/wwwassets/password_policy.html"); + PasswordValidation_ = PasswordValidationStr_ = MicroServiceConfigGetString( + "authentication.validation.expression", DefaultPasswordRule); - SubPasswordValidation_ = SubPasswordValidationStr_ = MicroServiceConfigGetString("subscriber.validation.expression",DefaultPasswordRule); - SubAccessPolicy_ = MicroServiceConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html"); - SubPasswordPolicy_ = MicroServiceConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html"); + SubPasswordValidation_ = SubPasswordValidationStr_ = + MicroServiceConfigGetString("subscriber.validation.expression", DefaultPasswordRule); + SubAccessPolicy_ = MicroServiceConfigGetString("subscriber.policy.access", + "/wwwassets/access_policy.html"); + SubPasswordPolicy_ = MicroServiceConfigGetString("subscriber.policy.password", + "/wwwassets/password_policy.html"); - HelperEmail_ = MicroServiceConfigGetString("helper.user.email", "openwifi@telecominfraproject.com"); - SubHelperEmail_ = MicroServiceConfigGetString("helper.sub.email", "openwifi@telecominfraproject.com"); + HelperEmail_ = + MicroServiceConfigGetString("helper.user.email", "openwifi@telecominfraproject.com"); + SubHelperEmail_ = + MicroServiceConfigGetString("helper.sub.email", "openwifi@telecominfraproject.com"); - GlobalHelperEmail_ = MicroServiceConfigGetString("helper.user.global.email", "openwifi@telecominfraproject.com"); - GlobalSubHelperEmail_ = MicroServiceConfigGetString("helper.sub.global.email", "openwifi@telecominfraproject.com"); + GlobalHelperEmail_ = MicroServiceConfigGetString("helper.user.global.email", + "openwifi@telecominfraproject.com"); + GlobalSubHelperEmail_ = MicroServiceConfigGetString("helper.sub.global.email", + "openwifi@telecominfraproject.com"); - HelperSite_ = MicroServiceConfigGetString("helper.user.site", "telecominfraproject.com"); - SubHelperSite_ = MicroServiceConfigGetString("helper.sub.site", "telecominfraproject.com"); + HelperSite_ = MicroServiceConfigGetString("helper.user.site", "telecominfraproject.com"); + SubHelperSite_ = MicroServiceConfigGetString("helper.sub.site", "telecominfraproject.com"); - SystemLoginSite_ = MicroServiceConfigGetString("helper.user.login", "telecominfraproject.com"); - SubSystemLoginSite_ = MicroServiceConfigGetString("helper.sub.login", "telecominfraproject.com"); + SystemLoginSite_ = + MicroServiceConfigGetString("helper.user.login", "telecominfraproject.com"); + SubSystemLoginSite_ = + MicroServiceConfigGetString("helper.sub.login", "telecominfraproject.com"); - UserSignature_ = MicroServiceConfigGetString("helper.user.signature", "Telecom Infra Project"); - SubSignature_ = MicroServiceConfigGetString("helper.sub.signature", "Telecom Infra Project"); + UserSignature_ = + MicroServiceConfigGetString("helper.user.signature", "Telecom Infra Project"); + SubSignature_ = + MicroServiceConfigGetString("helper.sub.signature", "Telecom Infra Project"); - return 0; - } + return 0; + } - void AuthService::Stop() { - poco_information(Logger(),"Stopping..."); - poco_information(Logger(),"Stopped..."); - } + void AuthService::Stop() { + poco_information(Logger(), "Stopping..."); + poco_information(Logger(), "Stopped..."); + } - bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { - try { - std::string CallToken; - Poco::Net::OAuth20Credentials Auth(Request); - if (Auth.getScheme() == "Bearer") { - CallToken = Auth.getBearerToken(); - } + bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest &Request, + const std::string &RefreshToken, + SecurityObjects::UserInfoAndPolicy &UI) { + try { + std::string CallToken; + Poco::Net::OAuth20Credentials Auth(Request); + if (Auth.getScheme() == "Bearer") { + CallToken = Auth.getBearerToken(); + } - if (CallToken.empty()) { - return false; - } + if (CallToken.empty()) { + return false; + } - uint64_t RevocationDate=0; - std::string UserId; - if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { - auto now = Utils::Now(); + uint64_t RevocationDate = 0; + std::string UserId; + if (StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, + RevocationDate) && + UI.webtoken.refresh_token_ == RefreshToken) { + auto now = Utils::Now(); - // Create a new token - auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); - auto NewRefreshToken = RefreshToken; - if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { - NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM); - UI.webtoken.lastRefresh_ = now; - } + // Create a new token + auto NewToken = GenerateTokenHMAC(UI.webtoken.access_token_, CUSTOM); + auto NewRefreshToken = RefreshToken; + if (now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { + NewRefreshToken = GenerateTokenHMAC(UI.webtoken.refresh_token_, CUSTOM); + UI.webtoken.lastRefresh_ = now; + } - StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); - UI.webtoken.access_token_ = NewToken; - UI.webtoken.refresh_token_ = NewRefreshToken; - return true; - } - return false; + StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, + UI.webtoken.lastRefresh_); + UI.webtoken.access_token_ = NewToken; + UI.webtoken.refresh_token_ = NewRefreshToken; + return true; + } + return false; - } catch (...) { + } catch (...) { + } + return false; + } - } - return false; - } + bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest &Request, + const std::string &RefreshToken, + SecurityObjects::UserInfoAndPolicy &UI) { + try { + std::string CallToken; + Poco::Net::OAuth20Credentials Auth(Request); + if (Auth.getScheme() == "Bearer") { + CallToken = Auth.getBearerToken(); + } - bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { - try { - std::string CallToken; - Poco::Net::OAuth20Credentials Auth(Request); - if (Auth.getScheme() == "Bearer") { - CallToken = Auth.getBearerToken(); - } + if (CallToken.empty()) { + return false; + } - if (CallToken.empty()) { - return false; - } + uint64_t RevocationDate = 0; + std::string UserId; + if (StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, + RevocationDate) && + UI.webtoken.refresh_token_ == RefreshToken) { + auto now = Utils::Now(); - uint64_t RevocationDate=0; - std::string UserId; - if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { - auto now = Utils::Now(); + // Create a new token + auto NewToken = GenerateTokenHMAC(UI.webtoken.access_token_, CUSTOM); + auto NewRefreshToken = RefreshToken; + if (now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { + NewRefreshToken = GenerateTokenHMAC(UI.webtoken.refresh_token_, CUSTOM); + UI.webtoken.lastRefresh_ = now; + } - // Create a new token - auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); - auto NewRefreshToken = RefreshToken; - if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { - NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM); - UI.webtoken.lastRefresh_ = now; - } + StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, + UI.webtoken.lastRefresh_); + UI.webtoken.access_token_ = NewToken; + UI.webtoken.refresh_token_ = NewRefreshToken; + return true; + } + return false; - StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); - UI.webtoken.access_token_ = NewToken; - UI.webtoken.refresh_token_ = NewRefreshToken; - return true; - } - return false; + } catch (...) { + } + return false; + } - } catch (...) { + [[nodiscard]] bool AuthService::IsAuthorized(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired) { + // std::lock_guard Guard(Mutex_); + std::string CallToken{SessionToken}; + Expired = false; + try { + SecurityObjects::WebToken WT; + uint64_t RevocationDate = 0; + std::string UserId; + if (StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { + if (RevocationDate != 0) { + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", + TID, Utils::SanitizeToken(CallToken))); + return false; + } + auto now = Utils::Now(); + Expired = (WT.created_ + WT.expires_in_) < now; + if (StorageService()->UserDB().GetUserById(UserId, UInfo.userinfo)) { + UInfo.webtoken = WT; + poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", + TID, Utils::SanitizeToken(CallToken))); + return true; + } + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, + Utils::SanitizeToken(CallToken))); + return false; + } - } - return false; - } - - [[nodiscard]] bool AuthService::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired) { - // std::lock_guard Guard(Mutex_); - std::string CallToken{SessionToken}; - Expired = false; - try { - SecurityObjects::WebToken WT; - uint64_t RevocationDate=0; - std::string UserId; - if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { - if(RevocationDate!=0) { - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } - auto now=Utils::Now(); - Expired = (WT.created_ + WT.expires_in_) < now; - if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { - UInfo.webtoken = WT; - poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return true; - } - } - } catch(const Poco::Exception &E) { - Logger().log(E); - } - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } - - bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) - { - // std::lock_guard Guard(Mutex_); - std::string CallToken; - Expired = false; + bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest &Request, std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired) { + // std::lock_guard Guard(Mutex_); + std::string CallToken; + Expired = false; try { - Poco::Net::OAuth20Credentials Auth(Request); - if (Auth.getScheme() == "Bearer") { - CallToken = Auth.getBearerToken(); - } + Poco::Net::OAuth20Credentials Auth(Request); + if (Auth.getScheme() == "Bearer") { + CallToken = Auth.getBearerToken(); + } - if (CallToken.empty()) { - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } - SessionToken = CallToken; - return IsAuthorized(SessionToken, UInfo, TID, Expired); - } catch(const Poco::Exception &E) { - Logger().log(E); - } - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } + if (CallToken.empty()) { + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, + Utils::SanitizeToken(CallToken))); + return false; + } + SessionToken = CallToken; + return IsAuthorized(SessionToken, UInfo, TID, Expired); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, + Utils::SanitizeToken(CallToken))); + return false; + } - bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) - { - // std::lock_guard Guard(Mutex_); + bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest &Request, + std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired) { + // std::lock_guard Guard(Mutex_); - std::string CallToken; - Expired = false; - try { - Poco::Net::OAuth20Credentials Auth(Request); - if (Auth.getScheme() == "Bearer") { - CallToken = Auth.getBearerToken(); - } + std::string CallToken; + Expired = false; + try { + Poco::Net::OAuth20Credentials Auth(Request); + if (Auth.getScheme() == "Bearer") { + CallToken = Auth.getBearerToken(); + } - if(CallToken.empty()) { - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } + if (CallToken.empty()) { + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, + Utils::SanitizeToken(CallToken))); + return false; + } - SecurityObjects::WebToken WT; - uint64_t RevocationDate=0; - std::string UserId; - if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { - if(RevocationDate!=0) { - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } - auto now=Utils::Now(); - Expired = (WT.created_ + WT.expires_in_) < now; - if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) { - UInfo.webtoken = WT; - SessionToken = CallToken; - poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return true; - } - } - } catch(const Poco::Exception &E) { - Logger().log(E); - } - poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); - return false; - } + SecurityObjects::WebToken WT; + uint64_t RevocationDate = 0; + std::string UserId; + if (StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { + if (RevocationDate != 0) { + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", + TID, Utils::SanitizeToken(CallToken))); + return false; + } + auto now = Utils::Now(); + Expired = (WT.created_ + WT.expires_in_) < now; + if (StorageService()->SubDB().GetUserById(UserId, UInfo.userinfo)) { + UInfo.webtoken = WT; + SessionToken = CallToken; + poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", + TID, Utils::SanitizeToken(CallToken))); + return true; + } + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } + poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, + Utils::SanitizeToken(CallToken))); + return false; + } - void AuthService::RevokeToken(std::string & Token) { - StorageService()->UserTokenDB().RevokeToken(Token); - } + void AuthService::RevokeToken(std::string &Token) { + StorageService()->UserTokenDB().RevokeToken(Token); + } - void AuthService::RevokeSubToken(std::string & Token) { - StorageService()->SubTokenDB().RevokeToken(Token); - } + void AuthService::RevokeSubToken(std::string &Token) { + StorageService()->SubTokenDB().RevokeToken(Token); + } - bool AuthService::DeleteUserFromCache(const std::string &Id) { - return StorageService()->UserTokenDB().DeleteRecordsFromCache("userName",Id); - } + bool AuthService::DeleteUserFromCache(const std::string &Id) { + return StorageService()->UserTokenDB().DeleteRecordsFromCache("userName", Id); + } - bool AuthService::DeleteSubUserFromCache(const std::string &Id) { - return StorageService()->SubTokenDB().DeleteRecordsFromCache("userName",Id); - } + bool AuthService::DeleteSubUserFromCache(const std::string &Id) { + return StorageService()->SubTokenDB().DeleteRecordsFromCache("userName", Id); + } - bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) { - return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && MFAServer::MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)); - } + bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) { + return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && + MFAServer::MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)); + } - bool AuthService::ValidatePassword(const std::string &Password) { - return std::regex_match(Password, PasswordValidation_); - } + bool AuthService::ValidatePassword(const std::string &Password) { + return std::regex_match(Password, PasswordValidation_); + } - bool AuthService::ValidateSubPassword(const std::string &Password) { - return std::regex_match(Password, SubPasswordValidation_); - } + bool AuthService::ValidateSubPassword(const std::string &Password) { + return std::regex_match(Password, SubPasswordValidation_); + } - void AuthService::RemoveTokenSystemWide(const std::string &token) { - try { - if(KafkaManager()->Enabled()) { - Poco::JSON::Object Obj; - Obj.set("event", "remove-token"); - Obj.set("id", MicroServiceID()); - Obj.set("token", token); - std::stringstream ResultText; - Poco::JSON::Stringifier::stringify(Obj, ResultText); - KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), - ResultText.str(), - false); - } - } catch (const Poco::Exception &E) { - Logger().log(E); - } - } + void AuthService::RemoveTokenSystemWide(const std::string &token) { + try { + if (KafkaManager()->Enabled()) { + Poco::JSON::Object Obj; + Obj.set("event", "remove-token"); + Obj.set("id", MicroServiceID()); + Obj.set("token", token); + std::stringstream ResultText; + Poco::JSON::Stringifier::stringify(Obj, ResultText); + KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, + MicroServicePrivateEndPoint(), ResultText.str(), false); + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } + } - void AuthService::Logout(const std::string &Token,[[maybe_unused]] bool EraseFromCache) { - std::lock_guard Guard(Mutex_); + void AuthService::Logout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) { + std::lock_guard Guard(Mutex_); - try { - auto tToken{Token}; - StorageService()->UserTokenDB().DeleteRecord("token",tToken); - StorageService()->LoginDB().AddLogout(Token); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - } + try { + auto tToken{Token}; + StorageService()->UserTokenDB().DeleteRecord("token", tToken); + StorageService()->LoginDB().AddLogout(Token); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + } - void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) { - std::lock_guard Guard(Mutex_); + void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) { + std::lock_guard Guard(Mutex_); - try { - auto tToken{Token}; - StorageService()->SubTokenDB().DeleteRecord("token",tToken); - StorageService()->SubLoginDB().AddLogout(Token); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - } + try { + auto tToken{Token}; + StorageService()->SubTokenDB().DeleteRecord("token", tToken); + StorageService()->SubLoginDB().AddLogout(Token); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + } - [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) { - std::string Identity(UserName + ":" + fmt::format("{}",Utils::Now()) + ":" + std::to_string(rand())); - HMAC_.update(Identity); - return Poco::DigestEngine::digestToHex(HMAC_.digest()); - } + [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string &UserName, + [[maybe_unused]] ACCESS_TYPE Type) { + std::string Identity(UserName + ":" + fmt::format("{}", Utils::Now()) + ":" + + std::to_string(rand())); + HMAC_.update(Identity); + return Poco::DigestEngine::digestToHex(HMAC_.digest()); + } - std::string AuthService::GenerateTokenJWT(const std::string & Identity, ACCESS_TYPE Type) { - std::lock_guard Guard(Mutex_); + std::string AuthService::GenerateTokenJWT(const std::string &Identity, ACCESS_TYPE Type) { + std::lock_guard Guard(Mutex_); - Poco::JWT::Token T; + Poco::JWT::Token T; T.setType("JWT"); - switch(Type) { - case USERNAME: T.setSubject("usertoken"); break; - case SERVER: T.setSubject("servertoken"); break; - case CUSTOM: T.setSubject("customtoken"); break; + switch (Type) { + case USERNAME: + T.setSubject("usertoken"); + break; + case SERVER: + T.setSubject("servertoken"); + break; + case CUSTOM: + T.setSubject("customtoken"); + break; } T.payload().set("identity", Identity); T.setIssuedAt(Poco::Timestamp()); T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); - std::string JWT = MicroServiceSign(T,Poco::JWT::Signer::ALGO_RS256); + std::string JWT = MicroServiceSign(T, Poco::JWT::Signer::ALGO_RS256); return JWT; - } - - void AuthService::CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo) - { - std::lock_guard Guard(Mutex_); - - SecurityObjects::AclTemplate ACL; - ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true; - UInfo.webtoken.acl_template_ = ACL; - UInfo.webtoken.expires_in_ = TokenAging_ ; - UInfo.webtoken.idle_timeout_ = 5 * 60; - UInfo.webtoken.token_type_ = "Bearer"; - UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME); - UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME); - UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id,CUSTOM); - UInfo.webtoken.created_ = time(nullptr); - UInfo.webtoken.username_ = UserName; - UInfo.webtoken.errorCode = 0; - UInfo.webtoken.userMustChangePassword = false; - StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); - StorageService()->UserTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_, - UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_, - UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); - StorageService()->LoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ ); - } - - void AuthService::CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo) - { - std::lock_guard Guard(Mutex_); - - SecurityObjects::AclTemplate ACL; - ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true; - UInfo.webtoken.acl_template_ = ACL; - UInfo.webtoken.expires_in_ = TokenAging_ ; - UInfo.webtoken.idle_timeout_ = 5 * 60; - UInfo.webtoken.token_type_ = "Bearer"; - UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME); - UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME); - UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id,CUSTOM); - UInfo.webtoken.created_ = time(nullptr); - UInfo.webtoken.username_ = UserName; - UInfo.webtoken.errorCode = 0; - UInfo.webtoken.userMustChangePassword = false; - StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); - StorageService()->SubTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_, - UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_, - UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); - StorageService()->SubLoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ ); - } - - bool AuthService::SetPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) { - std::lock_guard G(Mutex_); - - Poco::toLowerInPlace(UInfo.email); - for (const auto &i:UInfo.lastPasswords) { - auto Tokens = Poco::StringTokenizer(i,"|"); - if(Tokens.count()==2) { - const auto & Salt = Tokens[0]; - for(const auto &j:UInfo.lastPasswords) { - auto OldTokens = Poco::StringTokenizer(j,"|"); - if(OldTokens.count()==2) { - SHA2_.update(Salt+NewPassword+UInfo.email); - if(OldTokens[1]==Utils::ToHex(SHA2_.digest())) - return false; - } - } - } else { - SHA2_.update(NewPassword+UInfo.email); - if(Tokens[0]==Utils::ToHex(SHA2_.digest())) - return false; - } - } - - if(UInfo.lastPasswords.size()==HowManyOldPassword_) { - UInfo.lastPasswords.erase(UInfo.lastPasswords.begin()); - } - - auto NewHash = ComputeNewPasswordHash(UInfo.email,NewPassword); - UInfo.lastPasswords.push_back(NewHash); - UInfo.currentPassword = NewHash; - UInfo.changePassword = false; - return true; - } - - bool AuthService::SetSubPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) { - std::lock_guard G(Mutex_); - - Poco::toLowerInPlace(UInfo.email); - for (const auto &i:UInfo.lastPasswords) { - auto Tokens = Poco::StringTokenizer(i,"|"); - if(Tokens.count()==2) { - const auto & Salt = Tokens[0]; - for(const auto &j:UInfo.lastPasswords) { - auto OldTokens = Poco::StringTokenizer(j,"|"); - if(OldTokens.count()==2) { - SHA2_.update(Salt+NewPassword+UInfo.email); - if(OldTokens[1]==Utils::ToHex(SHA2_.digest())) - return false; - } - } - } else { - SHA2_.update(NewPassword+UInfo.email); - if(Tokens[0]==Utils::ToHex(SHA2_.digest())) - return false; - } - } - - if(UInfo.lastPasswords.size()==HowManyOldPassword_) { - UInfo.lastPasswords.erase(UInfo.lastPasswords.begin()); - } - - auto NewHash = ComputeNewPasswordHash(UInfo.email,NewPassword); - UInfo.lastPasswords.push_back(NewHash); - UInfo.currentPassword = NewHash; - UInfo.changePassword = false; - return true; - } - - static std::string GetMeSomeSalt() { - auto start = std::chrono::high_resolution_clock::now(); - return std::to_string(start.time_since_epoch().count()); - } - - std::string AuthService::ComputeNewPasswordHash(const std::string &UserName, const std::string &Password) { - std::string UName = Poco::trim(Poco::toLower(UserName)); - auto Salt = GetMeSomeSalt(); - SHA2_.update(Salt + Password + UName ); - return Salt + "|" + Utils::ToHex(SHA2_.digest()); - } - - bool AuthService::ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword) { - std::lock_guard G(Mutex_); - - std::string UName = Poco::trim(Poco::toLower(UserName)); - auto Tokens = Poco::StringTokenizer(StoredPassword,"|"); - if(Tokens.count()==1) { - SHA2_.update(Password+UName); - if(Tokens[0]==Utils::ToHex(SHA2_.digest())) - return true; - } else if (Tokens.count()==2) { - SHA2_.update(Tokens[0]+Password+UName); - if(Tokens[1]==Utils::ToHex(SHA2_.digest())) - return true; - } - return false; - } - - bool AuthService::ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword) { - std::lock_guard G(Mutex_); - - std::string UName = Poco::trim(Poco::toLower(UserName)); - auto Tokens = Poco::StringTokenizer(StoredPassword,"|"); - if(Tokens.count()==1) { - SHA2_.update(Password+UName); - if(Tokens[0]==Utils::ToHex(SHA2_.digest())) - return true; - } else if (Tokens.count()==2) { - SHA2_.update(Tokens[0]+Password+UName); - if(Tokens[1]==Utils::ToHex(SHA2_.digest())) - return true; - } - return false; - } - - UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired ) - { - std::lock_guard Guard(Mutex_); - - Poco::toLowerInPlace(UserName); - - if(StorageService()->UserDB().GetUserByEmail(UserName,UInfo.userinfo)) { - - if(UInfo.userinfo.suspended) { - return ACCOUNT_SUSPENDED; - } - - if(UInfo.userinfo.waitingForEmailCheck) { - return USERNAME_PENDING_VERIFICATION; - } - - if(!ValidatePasswordHash(UserName,Password,UInfo.userinfo.currentPassword)) { - return INVALID_CREDENTIALS; - } - - if(UInfo.userinfo.changePassword && NewPassword.empty()) { - UInfo.webtoken.userMustChangePassword = true ; - return PASSWORD_CHANGE_REQUIRED; - } - - if(!NewPassword.empty() && !ValidatePassword(NewPassword)) { - return PASSWORD_INVALID; - } - - if(UInfo.userinfo.changePassword || !NewPassword.empty()) { - if(!SetPassword(NewPassword,UInfo.userinfo)) { - UInfo.webtoken.errorCode = 1; - return PASSWORD_ALREADY_USED; - } - UInfo.userinfo.lastPasswordChange = Utils::Now(); - UInfo.userinfo.changePassword = false; - UInfo.userinfo.modified = Utils::Now(); - StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); - } - - // so we have a good password, password up date has taken place if need be, now generate the token. - UInfo.userinfo.lastLogin=Utils::Now(); - StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); - CreateToken(UserName, UInfo ); - - return SUCCESS; - } - return INVALID_CREDENTIALS; - } - - UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired ) - { - std::lock_guard Guard(Mutex_); - - Poco::toLowerInPlace(UserName); - - if(StorageService()->SubDB().GetUserByEmail(UserName,UInfo.userinfo)) { - - if(UInfo.userinfo.suspended) { - return ACCOUNT_SUSPENDED; - } - - if(UInfo.userinfo.waitingForEmailCheck) { - return USERNAME_PENDING_VERIFICATION; - } - - if(!ValidateSubPasswordHash(UserName,Password,UInfo.userinfo.currentPassword)) { - return INVALID_CREDENTIALS; - } - - if(UInfo.userinfo.changePassword && NewPassword.empty()) { - UInfo.webtoken.userMustChangePassword = true ; - return PASSWORD_CHANGE_REQUIRED; - } - - if(!NewPassword.empty() && !ValidateSubPassword(NewPassword)) { - return PASSWORD_INVALID; - } - - if(UInfo.userinfo.changePassword || !NewPassword.empty()) { - if(!SetSubPassword(NewPassword,UInfo.userinfo)) { - UInfo.webtoken.errorCode = 1; - return PASSWORD_ALREADY_USED; - } - UInfo.userinfo.lastPasswordChange = Utils::Now(); - UInfo.userinfo.changePassword = false; - UInfo.userinfo.modified = Utils::Now(); - StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); - } - - // so we have a good password, password update has taken place if need be, now generate the token. - UInfo.userinfo.lastLogin=Utils::Now(); - StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); - CreateSubToken(UserName, UInfo ); - - return SUCCESS; - } - - return INVALID_CREDENTIALS; - } - - bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Challenge) { - auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp,":"); - - bool IsSub = UInfo.userinfo.userRole==SecurityObjects::SUBSCRIBER; - - if(UInfo.userinfo.signingUp.empty() || OperatorParts.count()!=2) { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; - Attrs[LOGO] = AuthService::GetLogoAssetURI(); - Attrs[SUBJECT] = "Login validation code"; - Attrs[CHALLENGE_CODE] = Challenge; - if(!IsSub) { - SMTPMailerService()->AddUserVars(Attrs); - } else { - SMTPMailerService()->AddSubVars(Attrs); - } - return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName( - MessagingTemplates::VERIFICATION_CODE), Attrs, false); - } else { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; - Attrs[LOGO] = AuthService::GetSubLogoAssetURI(); - Attrs[SUBJECT] = "Login validation code"; - Attrs[CHALLENGE_CODE] = Challenge; - if(!IsSub) { - SMTPMailerService()->AddUserVars(Attrs); - } else { - SMTPMailerService()->AddSubVars(Attrs); - } - return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs, true ); - } - } - - bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason) { - SecurityObjects::UserInfo UInfo; - - if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) { - switch (Reason) { - - case MessagingTemplates::FORGOT_PASSWORD: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetLogoAssetURI(); - Attrs[SUBJECT] = "Password reset link"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ; - SMTPMailerService()->AddUserVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs, false); - } - break; - - case MessagingTemplates::EMAIL_VERIFICATION: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetLogoAssetURI(); - Attrs[SUBJECT] = "e-mail Address Verification"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_verification&id=" + LinkId ; - SMTPMailerService()->AddUserVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs, false); - UInfo.waitingForEmailCheck = true; - } - break; - - case MessagingTemplates::EMAIL_INVITATION: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetLogoAssetURI(); - Attrs[SUBJECT] = "e-mail Invitation"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ; - SMTPMailerService()->AddUserVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs, false); - UInfo.waitingForEmailCheck = true; - } - break; - - default: - break; - } - return true; - } - return false; - } - - bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName ) { - SecurityObjects::UserInfo UInfo; - - if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) { - switch (Reason) { - - case MessagingTemplates::SUB_FORGOT_PASSWORD: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetSubLogoAssetURI(); - Attrs[SUBJECT] = "Password reset link"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId ; - SMTPMailerService()->AddSubVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs, true); - } - break; - - case MessagingTemplates::SUB_EMAIL_VERIFICATION: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetSubLogoAssetURI(); - Attrs[SUBJECT] = "e-mail Address Verification"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId ; - SMTPMailerService()->AddSubVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs, true); - UInfo.waitingForEmailCheck = true; - } - break; - - case MessagingTemplates::SUB_SIGNUP_VERIFICATION: { - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = UInfo.email; - Attrs[LOGO] = GetSubLogoAssetURI(); - Attrs[SUBJECT] = "Signup e-mail Address Verification"; - Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ; - Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=signup_verification&id=" + LinkId ; - SMTPMailerService()->AddSubVars(Attrs); - SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_SIGNUP_VERIFICATION, OperatorName), Attrs, true); - UInfo.waitingForEmailCheck = true; - } - break; - - default: - break; - } - return true; - } - return false; - } - - bool AuthService::VerifyEmail(SecurityObjects::UserInfo &UInfo) { - SecurityObjects::ActionLink A; - - A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; - A.userId = UInfo.id; - A.id = MicroServiceCreateUUID(); - A.created = Utils::Now(); - A.expires = A.created + 24*60*60; - A.userAction = true; - StorageService()->ActionLinksDB().CreateAction(A); - UInfo.waitingForEmailCheck = true; - UInfo.validated = false; - return true; - } - - bool AuthService::VerifySubEmail(SecurityObjects::UserInfo &UInfo) { - SecurityObjects::ActionLink A; - - A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; - A.userId = UInfo.id; - A.id = MicroServiceCreateUUID(); - A.created = Utils::Now(); - A.expires = A.created + 24*60*60; - A.userAction = false; - StorageService()->ActionLinksDB().CreateAction(A); - UInfo.waitingForEmailCheck = true; - UInfo.validated = false; - return true; - } - - bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) { - - std::lock_guard G(Mutex_); - Expired = false; - - std::string TToken{Token}, UserId; - SecurityObjects::WebToken WT; - uint64_t RevocationDate=0; - if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { - if(RevocationDate!=0) - return false; - Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); - if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { - WebToken = WT; - return true; - } - } - return false; - } - - bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) { - std::lock_guard G(Mutex_); - Expired = false; - - std::string TToken{Token}, UserId; - SecurityObjects::WebToken WT; - uint64_t RevocationDate=0; - if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { - if(RevocationDate!=0) - return false; - Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); - if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { - WebToken = WT; - return true; - } - } - return false; - } - - bool AuthService::IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, - SecurityObjects::UserInfo &UserInfo, bool &Expired, std::uint64_t &expiresOn, - bool & Suspended) { - - std::lock_guard G(Mutex_); - - Suspended = false; - std::string UserId; - SecurityObjects::WebToken WT; - SecurityObjects::ApiKeyEntry ApiKeyEntry; - if(StorageService()->ApiKeyDB().GetRecord("apiKey", ApiKey, ApiKeyEntry)) { - expiresOn = ApiKeyEntry.expiresOn; - Expired = ApiKeyEntry.expiresOn < Utils::Now(); - if(Expired) - return false; - if(StorageService()->UserDB().GetUserById(ApiKeyEntry.userUuid,UserInfo)) { - if(UserInfo.suspended) { - Suspended=true; - return false; - } - WebToken = WT; - ApiKeyEntry.lastUse = Utils::Now(); - StorageService()->ApiKeyDB().UpdateRecord("id", ApiKeyEntry.id, ApiKeyEntry); - return true; - } - } - return false; - } - -} // end of namespace + } + + void AuthService::CreateToken(const std::string &UserName, + SecurityObjects::UserInfoAndPolicy &UInfo) { + std::lock_guard Guard(Mutex_); + + SecurityObjects::AclTemplate ACL; + ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true; + UInfo.webtoken.acl_template_ = ACL; + UInfo.webtoken.expires_in_ = TokenAging_; + UInfo.webtoken.idle_timeout_ = 5 * 60; + UInfo.webtoken.token_type_ = "Bearer"; + UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id, USERNAME); + UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id, USERNAME); + UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id, CUSTOM); + UInfo.webtoken.created_ = time(nullptr); + UInfo.webtoken.username_ = UserName; + UInfo.webtoken.errorCode = 0; + UInfo.webtoken.userMustChangePassword = false; + StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); + StorageService()->UserTokenDB().AddToken( + UInfo.userinfo.id, UInfo.webtoken.access_token_, UInfo.webtoken.refresh_token_, + UInfo.webtoken.token_type_, UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); + StorageService()->LoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email, + UInfo.webtoken.access_token_); + } + + void AuthService::CreateSubToken(const std::string &UserName, + SecurityObjects::UserInfoAndPolicy &UInfo) { + std::lock_guard Guard(Mutex_); + + SecurityObjects::AclTemplate ACL; + ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true; + UInfo.webtoken.acl_template_ = ACL; + UInfo.webtoken.expires_in_ = TokenAging_; + UInfo.webtoken.idle_timeout_ = 5 * 60; + UInfo.webtoken.token_type_ = "Bearer"; + UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id, USERNAME); + UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id, USERNAME); + UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id, CUSTOM); + UInfo.webtoken.created_ = time(nullptr); + UInfo.webtoken.username_ = UserName; + UInfo.webtoken.errorCode = 0; + UInfo.webtoken.userMustChangePassword = false; + StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); + StorageService()->SubTokenDB().AddToken( + UInfo.userinfo.id, UInfo.webtoken.access_token_, UInfo.webtoken.refresh_token_, + UInfo.webtoken.token_type_, UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); + StorageService()->SubLoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email, + UInfo.webtoken.access_token_); + } + + bool AuthService::SetPassword(const std::string &NewPassword, + SecurityObjects::UserInfo &UInfo) { + std::lock_guard G(Mutex_); + + Poco::toLowerInPlace(UInfo.email); + for (const auto &i : UInfo.lastPasswords) { + auto Tokens = Poco::StringTokenizer(i, "|"); + if (Tokens.count() == 2) { + const auto &Salt = Tokens[0]; + for (const auto &j : UInfo.lastPasswords) { + auto OldTokens = Poco::StringTokenizer(j, "|"); + if (OldTokens.count() == 2) { + SHA2_.update(Salt + NewPassword + UInfo.email); + if (OldTokens[1] == Utils::ToHex(SHA2_.digest())) + return false; + } + } + } else { + SHA2_.update(NewPassword + UInfo.email); + if (Tokens[0] == Utils::ToHex(SHA2_.digest())) + return false; + } + } + + if (UInfo.lastPasswords.size() == HowManyOldPassword_) { + UInfo.lastPasswords.erase(UInfo.lastPasswords.begin()); + } + + auto NewHash = ComputeNewPasswordHash(UInfo.email, NewPassword); + UInfo.lastPasswords.push_back(NewHash); + UInfo.currentPassword = NewHash; + UInfo.changePassword = false; + return true; + } + + bool AuthService::SetSubPassword(const std::string &NewPassword, + SecurityObjects::UserInfo &UInfo) { + std::lock_guard G(Mutex_); + + Poco::toLowerInPlace(UInfo.email); + for (const auto &i : UInfo.lastPasswords) { + auto Tokens = Poco::StringTokenizer(i, "|"); + if (Tokens.count() == 2) { + const auto &Salt = Tokens[0]; + for (const auto &j : UInfo.lastPasswords) { + auto OldTokens = Poco::StringTokenizer(j, "|"); + if (OldTokens.count() == 2) { + SHA2_.update(Salt + NewPassword + UInfo.email); + if (OldTokens[1] == Utils::ToHex(SHA2_.digest())) + return false; + } + } + } else { + SHA2_.update(NewPassword + UInfo.email); + if (Tokens[0] == Utils::ToHex(SHA2_.digest())) + return false; + } + } + + if (UInfo.lastPasswords.size() == HowManyOldPassword_) { + UInfo.lastPasswords.erase(UInfo.lastPasswords.begin()); + } + + auto NewHash = ComputeNewPasswordHash(UInfo.email, NewPassword); + UInfo.lastPasswords.push_back(NewHash); + UInfo.currentPassword = NewHash; + UInfo.changePassword = false; + return true; + } + + static std::string GetMeSomeSalt() { + auto start = std::chrono::high_resolution_clock::now(); + return std::to_string(start.time_since_epoch().count()); + } + + std::string AuthService::ComputeNewPasswordHash(const std::string &UserName, + const std::string &Password) { + std::string UName = Poco::trim(Poco::toLower(UserName)); + auto Salt = GetMeSomeSalt(); + SHA2_.update(Salt + Password + UName); + return Salt + "|" + Utils::ToHex(SHA2_.digest()); + } + + bool AuthService::ValidatePasswordHash(const std::string &UserName, const std::string &Password, + const std::string &StoredPassword) { + std::lock_guard G(Mutex_); + + std::string UName = Poco::trim(Poco::toLower(UserName)); + auto Tokens = Poco::StringTokenizer(StoredPassword, "|"); + if (Tokens.count() == 1) { + SHA2_.update(Password + UName); + if (Tokens[0] == Utils::ToHex(SHA2_.digest())) + return true; + } else if (Tokens.count() == 2) { + SHA2_.update(Tokens[0] + Password + UName); + if (Tokens[1] == Utils::ToHex(SHA2_.digest())) + return true; + } + return false; + } + + bool AuthService::ValidateSubPasswordHash(const std::string &UserName, + const std::string &Password, + const std::string &StoredPassword) { + std::lock_guard G(Mutex_); + + std::string UName = Poco::trim(Poco::toLower(UserName)); + auto Tokens = Poco::StringTokenizer(StoredPassword, "|"); + if (Tokens.count() == 1) { + SHA2_.update(Password + UName); + if (Tokens[0] == Utils::ToHex(SHA2_.digest())) + return true; + } else if (Tokens.count() == 2) { + SHA2_.update(Tokens[0] + Password + UName); + if (Tokens[1] == Utils::ToHex(SHA2_.digest())) + return true; + } + return false; + } + + UNAUTHORIZED_REASON AuthService::Authorize(std::string &UserName, const std::string &Password, + const std::string &NewPassword, + SecurityObjects::UserInfoAndPolicy &UInfo, + [[maybe_unused]] bool &Expired) { + std::lock_guard Guard(Mutex_); + + Poco::toLowerInPlace(UserName); + + if (StorageService()->UserDB().GetUserByEmail(UserName, UInfo.userinfo)) { + + if (UInfo.userinfo.suspended) { + return ACCOUNT_SUSPENDED; + } + + if (UInfo.userinfo.waitingForEmailCheck) { + return USERNAME_PENDING_VERIFICATION; + } + + if (!ValidatePasswordHash(UserName, Password, UInfo.userinfo.currentPassword)) { + return INVALID_CREDENTIALS; + } + + if (UInfo.userinfo.changePassword && NewPassword.empty()) { + UInfo.webtoken.userMustChangePassword = true; + return PASSWORD_CHANGE_REQUIRED; + } + + if (!NewPassword.empty() && !ValidatePassword(NewPassword)) { + return PASSWORD_INVALID; + } + + if (UInfo.userinfo.changePassword || !NewPassword.empty()) { + if (!SetPassword(NewPassword, UInfo.userinfo)) { + UInfo.webtoken.errorCode = 1; + return PASSWORD_ALREADY_USED; + } + UInfo.userinfo.lastPasswordChange = Utils::Now(); + UInfo.userinfo.changePassword = false; + UInfo.userinfo.modified = Utils::Now(); + StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id, + UInfo.userinfo); + } + + // so we have a good password, password up date has taken place if need be, now + // generate the token. + UInfo.userinfo.lastLogin = Utils::Now(); + StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); + CreateToken(UserName, UInfo); + + return SUCCESS; + } + return INVALID_CREDENTIALS; + } + + UNAUTHORIZED_REASON AuthService::AuthorizeSub(std::string &UserName, + const std::string &Password, + const std::string &NewPassword, + SecurityObjects::UserInfoAndPolicy &UInfo, + [[maybe_unused]] bool &Expired) { + std::lock_guard Guard(Mutex_); + + Poco::toLowerInPlace(UserName); + + if (StorageService()->SubDB().GetUserByEmail(UserName, UInfo.userinfo)) { + + if (UInfo.userinfo.suspended) { + return ACCOUNT_SUSPENDED; + } + + if (UInfo.userinfo.waitingForEmailCheck) { + return USERNAME_PENDING_VERIFICATION; + } + + if (!ValidateSubPasswordHash(UserName, Password, UInfo.userinfo.currentPassword)) { + return INVALID_CREDENTIALS; + } + + if (UInfo.userinfo.changePassword && NewPassword.empty()) { + UInfo.webtoken.userMustChangePassword = true; + return PASSWORD_CHANGE_REQUIRED; + } + + if (!NewPassword.empty() && !ValidateSubPassword(NewPassword)) { + return PASSWORD_INVALID; + } + + if (UInfo.userinfo.changePassword || !NewPassword.empty()) { + if (!SetSubPassword(NewPassword, UInfo.userinfo)) { + UInfo.webtoken.errorCode = 1; + return PASSWORD_ALREADY_USED; + } + UInfo.userinfo.lastPasswordChange = Utils::Now(); + UInfo.userinfo.changePassword = false; + UInfo.userinfo.modified = Utils::Now(); + StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id, + UInfo.userinfo); + } + + // so we have a good password, password update has taken place if need be, now generate + // the token. + UInfo.userinfo.lastLogin = Utils::Now(); + StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); + CreateSubToken(UserName, UInfo); + + return SUCCESS; + } + + return INVALID_CREDENTIALS; + } + + bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, + const std::string &Challenge) { + auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp, ":"); + + bool IsSub = UInfo.userinfo.userRole == SecurityObjects::SUBSCRIBER; + + if (UInfo.userinfo.signingUp.empty() || OperatorParts.count() != 2) { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; + Attrs[LOGO] = AuthService::GetLogoAssetURI(); + Attrs[SUBJECT] = "Login validation code"; + Attrs[CHALLENGE_CODE] = Challenge; + if (!IsSub) { + SMTPMailerService()->AddUserVars(Attrs); + } else { + SMTPMailerService()->AddSubVars(Attrs); + } + return SMTPMailerService()->SendMessage( + UInfo.userinfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs, + false); + } else { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; + Attrs[LOGO] = AuthService::GetSubLogoAssetURI(); + Attrs[SUBJECT] = "Login validation code"; + Attrs[CHALLENGE_CODE] = Challenge; + if (!IsSub) { + SMTPMailerService()->AddUserVars(Attrs); + } else { + SMTPMailerService()->AddSubVars(Attrs); + } + return SMTPMailerService()->SendMessage( + UInfo.userinfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE, + OperatorParts[0]), + Attrs, true); + } + } + + bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, + MessagingTemplates::EMAIL_REASON Reason) { + SecurityObjects::UserInfo UInfo; + + if (StorageService()->UserDB().GetUserByEmail(Email, UInfo)) { + switch (Reason) { + + case MessagingTemplates::FORGOT_PASSWORD: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetLogoAssetURI(); + Attrs[SUBJECT] = "Password reset link"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=password_reset&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId; + SMTPMailerService()->AddUserVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs, + false); + } break; + + case MessagingTemplates::EMAIL_VERIFICATION: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetLogoAssetURI(); + Attrs[SUBJECT] = "e-mail Address Verification"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=email_verification&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = + "/api/v1/actionLink?action=email_verification&id=" + LinkId; + SMTPMailerService()->AddUserVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs, + false); + UInfo.waitingForEmailCheck = true; + } break; + + case MessagingTemplates::EMAIL_INVITATION: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetLogoAssetURI(); + Attrs[SUBJECT] = "e-mail Invitation"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=email_invitation&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId; + SMTPMailerService()->AddUserVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs, + false); + UInfo.waitingForEmailCheck = true; + } break; + + default: + break; + } + return true; + } + return false; + } + + bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, + MessagingTemplates::EMAIL_REASON Reason, + const std::string &OperatorName) { + SecurityObjects::UserInfo UInfo; + + if (StorageService()->SubDB().GetUserByEmail(Email, UInfo)) { + switch (Reason) { + + case MessagingTemplates::SUB_FORGOT_PASSWORD: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetSubLogoAssetURI(); + Attrs[SUBJECT] = "Password reset link"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=sub_password_reset&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = + "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId; + SMTPMailerService()->AddSubVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, + OperatorName), + Attrs, true); + } break; + + case MessagingTemplates::SUB_EMAIL_VERIFICATION: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetSubLogoAssetURI(); + Attrs[SUBJECT] = "e-mail Address Verification"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=sub_email_verification&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = + "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId; + SMTPMailerService()->AddSubVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, + OperatorName), + Attrs, true); + UInfo.waitingForEmailCheck = true; + } break; + + case MessagingTemplates::SUB_SIGNUP_VERIFICATION: { + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = UInfo.email; + Attrs[LOGO] = GetSubLogoAssetURI(); + Attrs[SUBJECT] = "Signup e-mail Address Verification"; + Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + + "/actionLink?action=signup_verification&id=" + LinkId; + Attrs[ACTION_LINK_HTML] = + "/api/v1/actionLink?action=signup_verification&id=" + LinkId; + SMTPMailerService()->AddSubVars(Attrs); + SMTPMailerService()->SendMessage( + UInfo.email, + MessagingTemplates::TemplateName(MessagingTemplates::SUB_SIGNUP_VERIFICATION, + OperatorName), + Attrs, true); + UInfo.waitingForEmailCheck = true; + } break; + + default: + break; + } + return true; + } + return false; + } + + bool AuthService::VerifyEmail(SecurityObjects::UserInfo &UInfo) { + SecurityObjects::ActionLink A; + + A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; + A.userId = UInfo.id; + A.id = MicroServiceCreateUUID(); + A.created = Utils::Now(); + A.expires = A.created + 24 * 60 * 60; + A.userAction = true; + StorageService()->ActionLinksDB().CreateAction(A); + UInfo.waitingForEmailCheck = true; + UInfo.validated = false; + return true; + } + + bool AuthService::VerifySubEmail(SecurityObjects::UserInfo &UInfo) { + SecurityObjects::ActionLink A; + + A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; + A.userId = UInfo.id; + A.id = MicroServiceCreateUUID(); + A.created = Utils::Now(); + A.expires = A.created + 24 * 60 * 60; + A.userAction = false; + StorageService()->ActionLinksDB().CreateAction(A); + UInfo.waitingForEmailCheck = true; + UInfo.validated = false; + return true; + } + + bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired) { + + std::lock_guard G(Mutex_); + Expired = false; + + std::string TToken{Token}, UserId; + SecurityObjects::WebToken WT; + uint64_t RevocationDate = 0; + if (StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { + if (RevocationDate != 0) + return false; + Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); + if (StorageService()->UserDB().GetUserById(UserId, UserInfo)) { + WebToken = WT; + return true; + } + } + return false; + } + + bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired) { + std::lock_guard G(Mutex_); + Expired = false; + + std::string TToken{Token}, UserId; + SecurityObjects::WebToken WT; + uint64_t RevocationDate = 0; + if (StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { + if (RevocationDate != 0) + return false; + Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); + if (StorageService()->SubDB().GetUserById(UserId, UserInfo)) { + WebToken = WT; + return true; + } + } + return false; + } + + bool AuthService::IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired, + std::uint64_t &expiresOn, bool &Suspended) { + + std::lock_guard G(Mutex_); + + Suspended = false; + std::string UserId; + SecurityObjects::WebToken WT; + SecurityObjects::ApiKeyEntry ApiKeyEntry; + if (StorageService()->ApiKeyDB().GetRecord("apiKey", ApiKey, ApiKeyEntry)) { + expiresOn = ApiKeyEntry.expiresOn; + Expired = ApiKeyEntry.expiresOn < Utils::Now(); + if (Expired) + return false; + if (StorageService()->UserDB().GetUserById(ApiKeyEntry.userUuid, UserInfo)) { + if (UserInfo.suspended) { + Suspended = true; + return false; + } + WebToken = WT; + ApiKeyEntry.lastUse = Utils::Now(); + StorageService()->ApiKeyDB().UpdateRecord("id", ApiKeyEntry.id, ApiKeyEntry); + return true; + } + } + return false; + } + +} // namespace OpenWifi diff --git a/src/AuthService.h b/src/AuthService.h index 6c7eb94..ec411e7 100644 --- a/src/AuthService.h +++ b/src/AuthService.h @@ -10,193 +10,225 @@ #include -#include "framework/SubSystemServer.h" +#include "Poco/Crypto/DigestEngine.h" +#include "Poco/ExpireLRUCache.h" +#include "Poco/HMACEngine.h" #include "Poco/JSON/Object.h" +#include "Poco/JWT/Signer.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponse.h" -#include "Poco/JWT/Signer.h" #include "Poco/SHA2Engine.h" -#include "Poco/Crypto/DigestEngine.h" -#include "Poco/HMACEngine.h" -#include "Poco/ExpireLRUCache.h" +#include "framework/SubSystemServer.h" #include "framework/MicroServiceFuncs.h" #include "framework/ow_constants.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "MessagingTemplates.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" -namespace OpenWifi{ +namespace OpenWifi { - static const std::string AUTHENTICATION_SYSTEM{"SYSTEM"}; + static const std::string AUTHENTICATION_SYSTEM{"SYSTEM"}; - class AuthService : public SubSystemServer { - public: + class AuthService : public SubSystemServer { + public: + enum ACCESS_TYPE { USERNAME, SERVER, CUSTOM }; - enum ACCESS_TYPE { - USERNAME, - SERVER, - CUSTOM - }; + static ACCESS_TYPE IntToAccessType(int C); + static int AccessTypeToInt(ACCESS_TYPE T); - static ACCESS_TYPE IntToAccessType(int C); - static int AccessTypeToInt(ACCESS_TYPE T); + static auto instance() { + static auto instance_ = new AuthService; + return instance_; + } - static auto instance() { - static auto instance_ = new AuthService; - return instance_; - } + int Start() override; + void Stop() override; - int Start() override; - void Stop() override; + [[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest &Request, + std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired); + [[nodiscard]] bool IsAuthorized(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired); - [[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); - [[nodiscard]] bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); + [[nodiscard]] UNAUTHORIZED_REASON Authorize(std::string &UserName, + const std::string &Password, + const std::string &NewPassword, + SecurityObjects::UserInfoAndPolicy &UInfo, + bool &Expired); + void CreateToken(const std::string &UserName, SecurityObjects::UserInfoAndPolicy &UInfo); + [[nodiscard]] bool SetPassword(const std::string &Password, + SecurityObjects::UserInfo &UInfo); + [[nodiscard]] const std::string &PasswordValidationExpression() const { + return PasswordValidationStr_; + }; + void Logout(const std::string &token, bool EraseFromCache = true); - [[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); - void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); - [[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); - [[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;}; - void Logout(const std::string &token, bool EraseFromCache=true); + [[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest &Request, + std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired); + [[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub(std::string &UserName, + const std::string &Password, + const std::string &NewPassword, + SecurityObjects::UserInfoAndPolicy &UInfo, + bool &Expired); - [[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); - [[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); + void CreateSubToken(const std::string &UserName, SecurityObjects::UserInfoAndPolicy &UInfo); + [[nodiscard]] bool SetSubPassword(const std::string &Password, + SecurityObjects::UserInfo &UInfo); + [[nodiscard]] const std::string &SubPasswordValidationExpression() const { + return PasswordValidationStr_; + }; + void SubLogout(const std::string &token, bool EraseFromCache = true); - void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); - [[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); - [[nodiscard]] const std:: string & SubPasswordValidationExpression() const { return PasswordValidationStr_;}; - void SubLogout(const std::string &token, bool EraseFromCache=true); + void RemoveTokenSystemWide(const std::string &token); - void RemoveTokenSystemWide(const std::string &token); + bool ValidatePassword(const std::string &pwd); + bool ValidateSubPassword(const std::string &pwd); - bool ValidatePassword(const std::string &pwd); - bool ValidateSubPassword(const std::string &pwd); + [[nodiscard]] bool IsValidToken(const std::string &Token, + SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired); + [[nodiscard]] bool IsValidSubToken(const std::string &Token, + SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired); + [[nodiscard]] std::string GenerateTokenJWT(const std::string &UserName, ACCESS_TYPE Type); + [[nodiscard]] std::string GenerateTokenHMAC(const std::string &UserName, ACCESS_TYPE Type); - [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired); - [[nodiscard]] bool IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired); - [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type); - [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type); + [[nodiscard]] bool IsValidApiKey(const std::string &ApiKey, + SecurityObjects::WebToken &WebToken, + SecurityObjects::UserInfo &UserInfo, bool &Expired, + std::uint64_t &expiresOn, bool &Suspended); + [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, + const std::string &Password); + [[nodiscard]] bool ValidatePasswordHash(const std::string &UserName, + const std::string &Password, + const std::string &StoredPassword); + [[nodiscard]] bool ValidateSubPasswordHash(const std::string &UserName, + const std::string &Password, + const std::string &StoredPassword); - [[nodiscard]] bool IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired, std::uint64_t & expiresOn, bool & Suspended); - [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, const std::string &Password); - [[nodiscard]] bool ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); - [[nodiscard]] bool ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); + [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, + const std::string &OldPassword, + const std::string &NewPassword); + [[nodiscard]] std::string ResetPassword(const std::string &Admin, + const std::string &UserName); - [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); - [[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName); + [[nodiscard]] bool UpdateSubPassword(const std::string &Admin, const std::string &UserName, + const std::string &OldPassword, + const std::string &NewPassword); + [[nodiscard]] std::string ResetSubPassword(const std::string &Admin, + const std::string &UserName); - [[nodiscard]] bool UpdateSubPassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); - [[nodiscard]] std::string ResetSubPassword(const std::string &Admin, const std::string &UserName); + [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo); + [[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo); - [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo); - [[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo); + [[nodiscard]] bool SendEmailToUser(const std::string &LinkId, std::string &Email, + MessagingTemplates::EMAIL_REASON Reason); + [[nodiscard]] bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, + MessagingTemplates::EMAIL_REASON Reason, + const std::string &OperatorName); + [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo); - [[nodiscard]] bool SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason); - [[nodiscard]] bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName); - [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo); + [[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, + const std::string &code); - [[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &code); + bool DeleteUserFromCache(const std::string &UserName); + bool DeleteSubUserFromCache(const std::string &UserName); + void RevokeToken(std::string &Token); + void RevokeSubToken(std::string &Token); - bool DeleteUserFromCache(const std::string &UserName); - bool DeleteSubUserFromCache(const std::string &UserName); - void RevokeToken(std::string & Token); - void RevokeSubToken(std::string & Token); + [[nodiscard]] static inline const std::string GetLogoAssetURI() { + return MicroServicePublicEndPoint() + "/wwwassets/logo.png"; + } - [[nodiscard]] static inline const std::string GetLogoAssetURI() { - return MicroServicePublicEndPoint() + "/wwwassets/logo.png"; - } + [[nodiscard]] static inline const std::string GetLogoAssetFileName() { + return MicroServiceWWWAssetsDir() + "/logo.png"; + } - [[nodiscard]] static inline const std::string GetLogoAssetFileName() { - return MicroServiceWWWAssetsDir() + "/logo.png"; - } + [[nodiscard]] static inline const std::string GetSubLogoAssetURI() { + return MicroServicePublicEndPoint() + "/wwwassets/sub_logo.png"; + } - [[nodiscard]] static inline const std::string GetSubLogoAssetURI() { - return MicroServicePublicEndPoint() + "/wwwassets/sub_logo.png"; - } + [[nodiscard]] static inline const std::string GetSubLogoAssetFileName() { + return MicroServiceWWWAssetsDir() + "/sub_logo.png"; + } - [[nodiscard]] static inline const std::string GetSubLogoAssetFileName() { - return MicroServiceWWWAssetsDir() + "/sub_logo.png"; - } + inline const std::string &GetPasswordPolicy() const { return PasswordPolicy_; } + inline const std::string &GetAccessPolicy() const { return AccessPolicy_; } - inline const std::string & GetPasswordPolicy() const { return PasswordPolicy_; } - inline const std::string & GetAccessPolicy() const { return AccessPolicy_; } + inline const std::string &GetSubPasswordPolicy() const { return SubPasswordPolicy_; } + inline const std::string &GetSubAccessPolicy() const { return SubAccessPolicy_; } - inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; } - inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; } + bool RefreshUserToken(Poco::Net::HTTPServerRequest &Request, + const std::string &RefreshToken, + SecurityObjects::UserInfoAndPolicy &UI); + bool RefreshSubToken(Poco::Net::HTTPServerRequest &Request, const std::string &RefreshToken, + SecurityObjects::UserInfoAndPolicy &UI); - bool RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI); - bool RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI); + [[nodiscard]] inline auto HelperEmail() const { return HelperEmail_; }; + [[nodiscard]] inline auto SubHelperEmail() const { return SubHelperEmail_; }; + [[nodiscard]] inline auto GlobalHelperEmail() const { return GlobalHelperEmail_; }; + [[nodiscard]] inline auto GlobalSubHelperEmail() const { return GlobalSubHelperEmail_; }; + [[nodiscard]] inline auto HelperSite() const { return HelperSite_; }; + [[nodiscard]] inline auto SubHelperSite() const { return SubHelperSite_; }; + [[nodiscard]] inline auto SystemLoginSite() const { return SystemLoginSite_; }; + [[nodiscard]] inline auto SubSystemLoginSite() const { return SubSystemLoginSite_; }; + [[nodiscard]] inline auto UserSignature() const { return UserSignature_; }; + [[nodiscard]] inline auto SubSignature() const { return SubSignature_; }; - [[nodiscard]] inline auto HelperEmail() const { return HelperEmail_; }; - [[nodiscard]] inline auto SubHelperEmail() const { return SubHelperEmail_; }; - [[nodiscard]] inline auto GlobalHelperEmail() const { return GlobalHelperEmail_; }; - [[nodiscard]] inline auto GlobalSubHelperEmail() const { return GlobalSubHelperEmail_; }; - [[nodiscard]] inline auto HelperSite() const { return HelperSite_; }; - [[nodiscard]] inline auto SubHelperSite() const { return SubHelperSite_;}; - [[nodiscard]] inline auto SystemLoginSite() const { return SystemLoginSite_;}; - [[nodiscard]] inline auto SubSystemLoginSite() const { return SubSystemLoginSite_; }; - [[nodiscard]] inline auto UserSignature() const { return UserSignature_;}; - [[nodiscard]] inline auto SubSignature() const { return SubSignature_; }; + private: + Poco::SHA2Engine SHA2_; - private: - Poco::SHA2Engine SHA2_; + std::string AccessPolicy_; + std::string PasswordPolicy_; + std::string SubAccessPolicy_; + std::string SubPasswordPolicy_; + std::string PasswordValidationStr_; + std::string SubPasswordValidationStr_; + std::regex PasswordValidation_; + std::regex SubPasswordValidation_; - std::string AccessPolicy_; - std::string PasswordPolicy_; - std::string SubAccessPolicy_; - std::string SubPasswordPolicy_; - std::string PasswordValidationStr_; - std::string SubPasswordValidationStr_; - std::regex PasswordValidation_; - std::regex SubPasswordValidation_; + uint64_t TokenAging_ = 15 * 24 * 60 * 60; + uint64_t HowManyOldPassword_ = 5; + uint64_t RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60; - uint64_t TokenAging_ = 15 * 24 * 60 * 60; - uint64_t HowManyOldPassword_=5; - uint64_t RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ; + std::string HelperEmail_; + std::string SubHelperEmail_; + std::string GlobalHelperEmail_; + std::string GlobalSubHelperEmail_; + std::string HelperSite_; + std::string SubHelperSite_; + std::string SystemLoginSite_; + std::string SubSystemLoginSite_; + std::string UserSignature_; + std::string SubSignature_; - std::string HelperEmail_; - std::string SubHelperEmail_; - std::string GlobalHelperEmail_; - std::string GlobalSubHelperEmail_; - std::string HelperSite_; - std::string SubHelperSite_; - std::string SystemLoginSite_; - std::string SubSystemLoginSite_; - std::string UserSignature_; - std::string SubSignature_; + class SHA256Engine : public Poco::Crypto::DigestEngine { + public: + enum { BLOCK_SIZE = 64, DIGEST_SIZE = 32 }; - class SHA256Engine : public Poco::Crypto::DigestEngine - { - public: - enum - { - BLOCK_SIZE = 64, - DIGEST_SIZE = 32 - }; + SHA256Engine() : DigestEngine("SHA256") {} + }; - SHA256Engine() - : DigestEngine("SHA256") - { - } + Poco::HMACEngine HMAC_{"tipopenwifi"}; - }; + AuthService() noexcept : SubSystemServer("Authentication", "AUTH-SVR", "authentication") {} + }; - Poco::HMACEngine HMAC_{"tipopenwifi"}; + inline auto AuthService() { return AuthService::instance(); } - AuthService() noexcept: - SubSystemServer("Authentication", "AUTH-SVR", "authentication") - { - } - }; - - inline auto AuthService() { return AuthService::instance(); } - - [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , std::uint64_t TID, bool & Expired, bool Sub ) { - if(Sub) - return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired ); - else - return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired ); - } - -} // end of namespace + [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request, + std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired, bool Sub) { + if (Sub) + return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired); + else + return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired); + } +} // namespace OpenWifi diff --git a/src/Daemon.cpp b/src/Daemon.cpp index c29744c..fcae1c4 100644 --- a/src/Daemon.cpp +++ b/src/Daemon.cpp @@ -10,82 +10,70 @@ // Arilia Wireless Inc. // - +#include "Poco/Environment.h" #include "Poco/Util/Application.h" #include "Poco/Util/Option.h" -#include "Poco/Environment.h" #include "Daemon.h" #include #include -#include "StorageService.h" -#include "SMTPMailerService.h" +#include "ActionLinkManager.h" #include "AuthService.h" #include "SMSSender.h" -#include "ActionLinkManager.h" +#include "SMTPMailerService.h" +#include "StorageService.h" #include "TotpCache.h" #include "framework/RESTAPI_RateLimiter.h" #include "framework/UI_WebSocketClientServer.h" #include namespace OpenWifi { - class Daemon *Daemon::instance_ = nullptr; + class Daemon *Daemon::instance_ = nullptr; - class Daemon *Daemon::instance() { - if (instance_ == nullptr) { - instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME, - vDAEMON_ROOT_ENV_VAR, - vDAEMON_CONFIG_ENV_VAR, - vDAEMON_APP_NAME, - vDAEMON_BUS_TIMER, - SubSystemVec{ - StorageService(), - SMSSender(), - ActionLinkManager(), - SMTPMailerService(), - RESTAPI_RateLimiter(), - TotpCache(), - AuthService(), - UI_WebSocketClientServer(), - SecretStore() - }); - } - return instance_; - } + class Daemon *Daemon::instance() { + if (instance_ == nullptr) { + instance_ = + new Daemon(vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, + vDAEMON_CONFIG_ENV_VAR, vDAEMON_APP_NAME, vDAEMON_BUS_TIMER, + SubSystemVec{StorageService(), SMSSender(), ActionLinkManager(), + SMTPMailerService(), RESTAPI_RateLimiter(), TotpCache(), + AuthService(), UI_WebSocketClientServer(), SecretStore()}); + } + return instance_; + } - void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { - AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets"); - } + void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { + AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets"); + } - void DaemonPostInitialization(Poco::Util::Application &self) { - Daemon()->PostInitialization(self); - } -} + void DaemonPostInitialization(Poco::Util::Application &self) { + Daemon()->PostInitialization(self); + } +} // namespace OpenWifi int main(int argc, char **argv) { - try { - SSL_library_init(); - Aws::SDKOptions AwsOptions; - AwsOptions.memoryManagementOptions.memoryManager = nullptr; - AwsOptions.cryptoOptions.initAndCleanupOpenSSL = false; - AwsOptions.httpOptions.initAndCleanupCurl = true; + try { + SSL_library_init(); + Aws::SDKOptions AwsOptions; + AwsOptions.memoryManagementOptions.memoryManager = nullptr; + AwsOptions.cryptoOptions.initAndCleanupOpenSSL = false; + AwsOptions.httpOptions.initAndCleanupCurl = true; - Aws::InitAPI(AwsOptions); + Aws::InitAPI(AwsOptions); - int ExitCode=0; - { - auto App = OpenWifi::Daemon::instance(); - ExitCode = App->run(argc, argv); - } - ShutdownAPI(AwsOptions); - return ExitCode; - } catch (Poco::Exception &exc) { - std::cout << exc.displayText() << std::endl; - return Poco::Util::Application::EXIT_SOFTWARE; - } + int ExitCode = 0; + { + auto App = OpenWifi::Daemon::instance(); + ExitCode = App->run(argc, argv); + } + ShutdownAPI(AwsOptions); + return ExitCode; + } catch (Poco::Exception &exc) { + std::cout << exc.displayText() << std::endl; + return Poco::Util::Application::EXIT_SOFTWARE; + } } - // end of namespace diff --git a/src/Daemon.h b/src/Daemon.h index ae6b788..0f7ce5a 100644 --- a/src/Daemon.h +++ b/src/Daemon.h @@ -4,52 +4,48 @@ #pragma once -#include #include -#include +#include #include +#include -#include "framework/MicroServiceNames.h" #include "framework/MicroService.h" +#include "framework/MicroServiceNames.h" +#include "Poco/Crypto/Cipher.h" +#include "Poco/Crypto/CipherFactory.h" +#include "Poco/Crypto/RSAKey.h" +#include "Poco/ErrorHandler.h" +#include "Poco/UUIDGenerator.h" #include "Poco/Util/Application.h" -#include "Poco/Util/ServerApplication.h" #include "Poco/Util/Option.h" #include "Poco/Util/OptionSet.h" -#include "Poco/UUIDGenerator.h" -#include "Poco/ErrorHandler.h" -#include "Poco/Crypto/RSAKey.h" -#include "Poco/Crypto/CipherFactory.h" -#include "Poco/Crypto/Cipher.h" - +#include "Poco/Util/ServerApplication.h" namespace OpenWifi { - [[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties"; - [[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT"; - [[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG"; - [[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str(); - [[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 5000; + [[maybe_unused]] static const char *vDAEMON_PROPERTIES_FILENAME = "owsec.properties"; + [[maybe_unused]] static const char *vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT"; + [[maybe_unused]] static const char *vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG"; + [[maybe_unused]] static const char *vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str(); + [[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 5000; - class Daemon : public MicroService { - public: - explicit Daemon(const std::string & PropFile, - const std::string & RootEnv, - const std::string & ConfigEnv, - const std::string & AppName, - uint64_t BusTimer, - const SubSystemVec & SubSystems) : - MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; + class Daemon : public MicroService { + public: + explicit Daemon(const std::string &PropFile, const std::string &RootEnv, + const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer, + const SubSystemVec &SubSystems) + : MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){}; - void PostInitialization(Poco::Util::Application &self); - static Daemon *instance(); - inline const std::string & AssetDir() { return AssetDir_; } - private: - static Daemon *instance_; - std::string AssetDir_; - }; + void PostInitialization(Poco::Util::Application &self); + static Daemon *instance(); + inline const std::string &AssetDir() { return AssetDir_; } - inline Daemon * Daemon() { return Daemon::instance(); } - void DaemonPostInitialization(Poco::Util::Application &self); -} + private: + static Daemon *instance_; + std::string AssetDir_; + }; + inline Daemon *Daemon() { return Daemon::instance(); } + void DaemonPostInitialization(Poco::Util::Application &self); +} // namespace OpenWifi diff --git a/src/MFAServer.cpp b/src/MFAServer.cpp index 72ba631..dc73272 100644 --- a/src/MFAServer.cpp +++ b/src/MFAServer.cpp @@ -3,9 +3,9 @@ // #include "MFAServer.h" +#include "AuthService.h" #include "SMSSender.h" #include "SMTPMailerService.h" -#include "AuthService.h" #include "TotpCache.h" #include "framework/MicroServiceFuncs.h" @@ -13,104 +13,114 @@ namespace OpenWifi { - int MFAServer::Start() { - return 0; - } + int MFAServer::Start() { return 0; } - void MFAServer::Stop() { - } + void MFAServer::Stop() {} - bool MFAServer::StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &ChallengeStart) { - std::lock_guard G(Mutex_); + bool MFAServer::StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, + Poco::JSON::Object &ChallengeStart) { + std::lock_guard G(Mutex_); - CleanCache(); + CleanCache(); - if(!MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)) - return false; + if (!MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)) + return false; - std::string Challenge = MakeChallenge(); - std::string uuid = MicroServiceCreateUUID(); - uint64_t Created = Utils::Now(); + std::string Challenge = MakeChallenge(); + std::string uuid = MicroServiceCreateUUID(); + uint64_t Created = Utils::Now(); - ChallengeStart.set("uuid",uuid); - ChallengeStart.set("created", Created); - ChallengeStart.set("question", "mfa challenge"); - ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method); + ChallengeStart.set("uuid", uuid); + ChallengeStart.set("created", Created); + ChallengeStart.set("question", "mfa challenge"); + ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method); - Cache_[uuid] = MFACacheEntry{ .UInfo = UInfo, .Answer=Challenge, .Created=Created, .Method=UInfo.userinfo.userTypeProprietaryInfo.mfa.method }; - return SendChallenge(UInfo, UInfo.userinfo.userTypeProprietaryInfo.mfa.method, Challenge); - } + Cache_[uuid] = MFACacheEntry{.UInfo = UInfo, + .Answer = Challenge, + .Created = Created, + .Method = UInfo.userinfo.userTypeProprietaryInfo.mfa.method}; + return SendChallenge(UInfo, UInfo.userinfo.userTypeProprietaryInfo.mfa.method, Challenge); + } - bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge) { - if(Method==MFAMETHODS::SMS && SMSSender()->Enabled() && !UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) { - std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen."; - return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message); - } else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) { - return AuthService()->SendEmailChallengeCode(UInfo,Challenge); - } else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) { - return true; - } + bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, + const std::string &Method, const std::string &Challenge) { + if (Method == MFAMETHODS::SMS && SMSSender()->Enabled() && + !UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) { + std::string Message = "This is your login code: " + Challenge + + " Please enter this in your login screen."; + return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, + Message); + } else if (Method == MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && + !UInfo.userinfo.email.empty()) { + return AuthService()->SendEmailChallengeCode(UInfo, Challenge); + } else if (Method == MFAMETHODS::AUTHENTICATOR && + !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) { + return true; + } - return false; - } + return false; + } - bool MFAServer::ResendCode(const std::string &uuid) { - std::lock_guard G(Mutex_); - auto Hint = Cache_.find(uuid); - if(Hint==Cache_.end()) - return false; - return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); - } + bool MFAServer::ResendCode(const std::string &uuid) { + std::lock_guard G(Mutex_); + auto Hint = Cache_.find(uuid); + if (Hint == Cache_.end()) + return false; + return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); + } - bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) { - std::lock_guard G(Mutex_); + bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, + SecurityObjects::UserInfoAndPolicy &UInfo) { + std::lock_guard G(Mutex_); - if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) - return false; + if (!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) + return false; - auto uuid = ChallengeResponse->get("uuid").toString(); - auto Hint = Cache_.find(uuid); - if(Hint == end(Cache_)) { - return false; - } + auto uuid = ChallengeResponse->get("uuid").toString(); + auto Hint = Cache_.find(uuid); + if (Hint == end(Cache_)) { + return false; + } - auto answer = ChallengeResponse->get("answer").toString(); - std::string Expecting; - if(Hint->second.Method==MFAMETHODS::AUTHENTICATOR) { - if(!TotpCache()->ValidateCode(Hint->second.UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret,answer, Expecting)) { - return false; - } - } else if(Hint->second.Answer!=answer) { - return false; - } + auto answer = ChallengeResponse->get("answer").toString(); + std::string Expecting; + if (Hint->second.Method == MFAMETHODS::AUTHENTICATOR) { + if (!TotpCache()->ValidateCode( + Hint->second.UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret, answer, + Expecting)) { + return false; + } + } else if (Hint->second.Answer != answer) { + return false; + } - UInfo = Hint->second.UInfo; - Cache_.erase(Hint); - return true; - } + UInfo = Hint->second.UInfo; + Cache_.erase(Hint); + return true; + } - bool MFAServer::MethodEnabled(const std::string &Method) { - if(Method==MFAMETHODS::SMS) - return SMSSender()->Enabled(); + bool MFAServer::MethodEnabled(const std::string &Method) { + if (Method == MFAMETHODS::SMS) + return SMSSender()->Enabled(); - if(Method==MFAMETHODS::EMAIL) - return SMTPMailerService()->Enabled(); + if (Method == MFAMETHODS::EMAIL) + return SMTPMailerService()->Enabled(); - if(Method==MFAMETHODS::AUTHENTICATOR) - return true; + if (Method == MFAMETHODS::AUTHENTICATOR) + return true; - return false; - } + return false; + } - void MFAServer::CleanCache() { - // it is assumed that you have locked Cache_ at this point. - uint64_t Now = Utils::Now(); - for(auto i=begin(Cache_);i!=end(Cache_);) { - if((Now-i->second.Created)>300) { - i = Cache_.erase(i); - } else { - ++i; - } - } - } -} \ No newline at end of file + void MFAServer::CleanCache() { + // it is assumed that you have locked Cache_ at this point. + uint64_t Now = Utils::Now(); + for (auto i = begin(Cache_); i != end(Cache_);) { + if ((Now - i->second.Created) > 300) { + i = Cache_.erase(i); + } else { + ++i; + } + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/MFAServer.h b/src/MFAServer.h index 1982b5f..74846ef 100644 --- a/src/MFAServer.h +++ b/src/MFAServer.h @@ -6,62 +6,60 @@ #include "Poco/JSON/Object.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" -#include "framework/SubSystemServer.h" #include "framework/MicroServiceFuncs.h" +#include "framework/SubSystemServer.h" #include "fmt/format.h" namespace OpenWifi { - namespace MFAMETHODS { - inline const static std::string SMS{"sms"}; - inline const static std::string EMAIL{"email"}; - inline const static std::string AUTHENTICATOR{"authenticator"}; - inline const static std::vector Methods{ SMS, EMAIL, AUTHENTICATOR }; - inline bool Validate(const std::string &M) { - return std::find(cbegin(Methods), cend(Methods),M)!=Methods.end(); - } - } + namespace MFAMETHODS { + inline const static std::string SMS{"sms"}; + inline const static std::string EMAIL{"email"}; + inline const static std::string AUTHENTICATOR{"authenticator"}; + inline const static std::vector Methods{SMS, EMAIL, AUTHENTICATOR}; + inline bool Validate(const std::string &M) { + return std::find(cbegin(Methods), cend(Methods), M) != Methods.end(); + } + } // namespace MFAMETHODS - struct MFACacheEntry { - SecurityObjects::UserInfoAndPolicy UInfo; - std::string Answer; - uint64_t Created; - std::string Method; - }; + struct MFACacheEntry { + SecurityObjects::UserInfoAndPolicy UInfo; + std::string Answer; + uint64_t Created; + std::string Method; + }; + typedef std::map MFAChallengeCache; - typedef std::map MFAChallengeCache; + class MFAServer : public SubSystemServer { + public: + int Start() override; + void Stop() override; + static auto instance() { + static auto instance_ = new MFAServer; + return instance_; + } - class MFAServer : public SubSystemServer{ - public: - int Start() override; - void Stop() override; - static auto instance() { - static auto instance_ = new MFAServer; - return instance_; - } + bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, + Poco::JSON::Object &Challenge); + bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, + SecurityObjects::UserInfoAndPolicy &UInfo); + static bool MethodEnabled(const std::string &Method); + bool ResendCode(const std::string &uuid); + static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, + const std::string &Method, const std::string &Challenge); - bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge); - bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo); - static bool MethodEnabled(const std::string &Method); - bool ResendCode(const std::string &uuid); - static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge); + static inline std::string MakeChallenge() { + return fmt::format("{0:06}", MicroServiceRandom(1, 999999)); + } - static inline std::string MakeChallenge() { - return fmt::format("{0:06}" , MicroServiceRandom(1,999999) ); - } + private: + MFAChallengeCache Cache_; + MFAServer() noexcept : SubSystemServer("MFServer", "MFA-SVR", "mfa") {} - private: - MFAChallengeCache Cache_; - MFAServer() noexcept: - SubSystemServer("MFServer", "MFA-SVR", "mfa") - { - } - - void CleanCache(); - }; - - inline auto MFAServer() { return MFAServer::instance(); } -} + void CleanCache(); + }; + inline auto MFAServer() { return MFAServer::instance(); } +} // namespace OpenWifi diff --git a/src/MessagingTemplates.h b/src/MessagingTemplates.h index a55b854..0721af1 100644 --- a/src/MessagingTemplates.h +++ b/src/MessagingTemplates.h @@ -9,88 +9,104 @@ namespace OpenWifi { - class MessagingTemplates { - public: - static MessagingTemplates & instance() { - static auto instance = new MessagingTemplates; - return *instance; - } + class MessagingTemplates { + public: + static MessagingTemplates &instance() { + static auto instance = new MessagingTemplates; + return *instance; + } - enum EMAIL_REASON { - FORGOT_PASSWORD = 0, - EMAIL_VERIFICATION, - SUB_SIGNUP_VERIFICATION, - EMAIL_INVITATION, - VERIFICATION_CODE, - SUB_FORGOT_PASSWORD, - SUB_EMAIL_VERIFICATION, - SUB_VERIFICATION_CODE, - CERTIFICATE_TRANSFER_NOTIFICATION, - CERTIFICATE_TRANSFER_AUTHORIZATION, - CERTIFICATE_DISPUTE_SUCCESS, - CERTIFICATE_DISPUTE_REJECTED, - CERTIFICATE_TRANSFER_CANCELED, - CERTIFICATE_TRANSFER_ACCEPTED, - CERTIFICATE_TRANSFER_REJECTED - }; + enum EMAIL_REASON { + FORGOT_PASSWORD = 0, + EMAIL_VERIFICATION, + SUB_SIGNUP_VERIFICATION, + EMAIL_INVITATION, + VERIFICATION_CODE, + SUB_FORGOT_PASSWORD, + SUB_EMAIL_VERIFICATION, + SUB_VERIFICATION_CODE, + CERTIFICATE_TRANSFER_NOTIFICATION, + CERTIFICATE_TRANSFER_AUTHORIZATION, + CERTIFICATE_DISPUTE_SUCCESS, + CERTIFICATE_DISPUTE_REJECTED, + CERTIFICATE_TRANSFER_CANCELED, + CERTIFICATE_TRANSFER_ACCEPTED, + CERTIFICATE_TRANSFER_REJECTED + }; - static std::string AddOperator(const std::string & filename, const std::string &OperatorName) { - if(OperatorName.empty()) - return "/" + filename; - return "/" + OperatorName + "/" + filename; - } + static std::string AddOperator(const std::string &filename, + const std::string &OperatorName) { + if (OperatorName.empty()) + return "/" + filename; + return "/" + OperatorName + "/" + filename; + } - static std::string TemplateName( EMAIL_REASON r , const std::string &OperatorName="") { - switch (r) { - case FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[FORGOT_PASSWORD],OperatorName); - case EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION],OperatorName); - case SUB_SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_SIGNUP_VERIFICATION],OperatorName); - case EMAIL_INVITATION: return AddOperator(EmailTemplateNames[EMAIL_INVITATION],OperatorName); - case VERIFICATION_CODE: return AddOperator(EmailTemplateNames[VERIFICATION_CODE],OperatorName); - case SUB_FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD],OperatorName); - case SUB_EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION],OperatorName); - case SUB_VERIFICATION_CODE: return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE],OperatorName); - case CERTIFICATE_TRANSFER_NOTIFICATION: return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_NOTIFICATION],OperatorName); - case CERTIFICATE_TRANSFER_AUTHORIZATION: return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_AUTHORIZATION],OperatorName); - case CERTIFICATE_DISPUTE_SUCCESS: return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_SUCCESS],OperatorName); - case CERTIFICATE_DISPUTE_REJECTED: return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_REJECTED],OperatorName); - case CERTIFICATE_TRANSFER_CANCELED: return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_CANCELED],OperatorName); - case CERTIFICATE_TRANSFER_ACCEPTED: return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_ACCEPTED],OperatorName); - case CERTIFICATE_TRANSFER_REJECTED: return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_REJECTED],OperatorName); - default: - return ""; - } - } + static std::string TemplateName(EMAIL_REASON r, const std::string &OperatorName = "") { + switch (r) { + case FORGOT_PASSWORD: + return AddOperator(EmailTemplateNames[FORGOT_PASSWORD], OperatorName); + case EMAIL_VERIFICATION: + return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION], OperatorName); + case SUB_SIGNUP_VERIFICATION: + return AddOperator(EmailTemplateNames[SUB_SIGNUP_VERIFICATION], OperatorName); + case EMAIL_INVITATION: + return AddOperator(EmailTemplateNames[EMAIL_INVITATION], OperatorName); + case VERIFICATION_CODE: + return AddOperator(EmailTemplateNames[VERIFICATION_CODE], OperatorName); + case SUB_FORGOT_PASSWORD: + return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD], OperatorName); + case SUB_EMAIL_VERIFICATION: + return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION], OperatorName); + case SUB_VERIFICATION_CODE: + return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE], OperatorName); + case CERTIFICATE_TRANSFER_NOTIFICATION: + return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_NOTIFICATION], + OperatorName); + case CERTIFICATE_TRANSFER_AUTHORIZATION: + return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_AUTHORIZATION], + OperatorName); + case CERTIFICATE_DISPUTE_SUCCESS: + return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_SUCCESS], OperatorName); + case CERTIFICATE_DISPUTE_REJECTED: + return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_REJECTED], OperatorName); + case CERTIFICATE_TRANSFER_CANCELED: + return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_CANCELED], OperatorName); + case CERTIFICATE_TRANSFER_ACCEPTED: + return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_ACCEPTED], OperatorName); + case CERTIFICATE_TRANSFER_REJECTED: + return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_REJECTED], OperatorName); + default: + return ""; + } + } - static std::string Logo(const std::string &OperatorName = "" ) { - return AddOperator("logo.png", OperatorName); - } + static std::string Logo(const std::string &OperatorName = "") { + return AddOperator("logo.png", OperatorName); + } - static std::string SubLogo(const std::string &OperatorName = "" ) { - return AddOperator("sub_logo.png", OperatorName); - } + static std::string SubLogo(const std::string &OperatorName = "") { + return AddOperator("sub_logo.png", OperatorName); + } - private: - inline const static std::vector EmailTemplateNames = { - "password_reset", - "email_verification", - "sub_signup_verification", - "email_invitation", - "verification_code", - "sub_password_reset", - "sub_email_verification", - "sub_verification_code", - "certificate_transfer_notification", - "certificate_transfer_authorization", - "certificate_dispute_success", - "certificate_dispute_rejected", - "certificate_transfer_canceled", - "certificate_transfer_accepted", - "certificate_transfer_rejected" - }; - }; + private: + inline const static std::vector EmailTemplateNames = { + "password_reset", + "email_verification", + "sub_signup_verification", + "email_invitation", + "verification_code", + "sub_password_reset", + "sub_email_verification", + "sub_verification_code", + "certificate_transfer_notification", + "certificate_transfer_authorization", + "certificate_dispute_success", + "certificate_dispute_rejected", + "certificate_transfer_canceled", + "certificate_transfer_accepted", + "certificate_transfer_rejected"}; + }; - inline MessagingTemplates & MessagingTemplates() { return MessagingTemplates::instance(); } - -} // OpenWifi + inline MessagingTemplates &MessagingTemplates() { return MessagingTemplates::instance(); } +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_action_links.cpp b/src/RESTAPI/RESTAPI_action_links.cpp index 5a78322..9f9354e 100644 --- a/src/RESTAPI/RESTAPI_action_links.cpp +++ b/src/RESTAPI/RESTAPI_action_links.cpp @@ -7,321 +7,351 @@ #include "RESTAPI_action_links.h" #include "StorageService.h" -#include "framework/RESTAPI_PartHandler.h" #include "framework/OpenAPIRequests.h" +#include "framework/RESTAPI_PartHandler.h" #include "Daemon.h" namespace OpenWifi { #if defined(TIP_CERT_SERVICE) - bool ProcessExternalActionLinks(RESTAPIHandler &handler,const std::string &Id, const std::string &Action); + bool ProcessExternalActionLinks(RESTAPIHandler &handler, const std::string &Id, + const std::string &Action); #endif - void RESTAPI_action_links::DoGet() { + void RESTAPI_action_links::DoGet() { - auto Action = GetParameter("action",""); - auto Id = GetParameter("id",""); + auto Action = GetParameter("action", ""); + auto Id = GetParameter("id", ""); #if defined(TIP_CERT_SERVICE) - if(!OpenWifi::ProcessExternalActionLinks(*this,Id,Action)) { - return; - } + if (!OpenWifi::ProcessExternalActionLinks(*this, Id, Action)) { + return; + } #endif - SecurityObjects::ActionLink Link; - if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) - return DoReturnA404(); + SecurityObjects::ActionLink Link; + if (!StorageService()->ActionLinksDB().GetActionLink(Id, Link)) + return DoReturnA404(); - if(Action=="password_reset") - return RequestResetPassword(Link); - else if(Action=="sub_password_reset") - return RequestSubResetPassword(Link); - else if(Action=="email_verification") - return DoEmailVerification(Link); - else if(Action=="sub_email_verification") - return DoSubEmailVerification(Link); - else if(Action=="signup_verification") - return DoNewSubVerification(Link); - else - return DoReturnA404(); - } + if (Action == "password_reset") + return RequestResetPassword(Link); + else if (Action == "sub_password_reset") + return RequestSubResetPassword(Link); + else if (Action == "email_verification") + return DoEmailVerification(Link); + else if (Action == "sub_email_verification") + return DoSubEmailVerification(Link); + else if (Action == "signup_verification") + return DoNewSubVerification(Link); + else + return DoReturnA404(); + } - void RESTAPI_action_links::DoPost() { - auto Action = GetParameter("action",""); + void RESTAPI_action_links::DoPost() { + auto Action = GetParameter("action", ""); - if(Action=="password_reset") - return CompleteResetPassword(); - else if(Action=="sub_password_reset") - return CompleteResetPassword(); - else if(Action=="signup_completion") - return CompleteSubVerification(); - else if(Action=="email_invitation") - return CompleteEmailInvitation(); - else - return DoReturnA404(); - } + if (Action == "password_reset") + return CompleteResetPassword(); + else if (Action == "sub_password_reset") + return CompleteResetPassword(); + else if (Action == "signup_completion") + return CompleteSubVerification(); + else if (Action == "email_invitation") + return CompleteEmailInvitation(); + else + return DoReturnA404(); + } - void RESTAPI_action_links::AddGlobalVars(Types::StringPairVec & Vars) { - Vars.push_back(std::make_pair("USER_HELPER_EMAIL",AuthService()->HelperEmail())); - Vars.push_back(std::make_pair("SUB_HELPER_EMAIL",AuthService()->SubHelperEmail())); - Vars.push_back(std::make_pair("GLOBAL_USER_HELPER_EMAIL",AuthService()->GlobalHelperEmail())); - Vars.push_back(std::make_pair("GLOBAL_SUB_HELPER_EMAIL",AuthService()->GlobalSubHelperEmail())); - Vars.push_back(std::make_pair("USER_HELPER_SITE",AuthService()->HelperSite())); - Vars.push_back(std::make_pair("SUB_HELPER_SITE",AuthService()->SubHelperSite())); - Vars.push_back(std::make_pair("USER_SYSTEM_LOGIN",AuthService()->SystemLoginSite())); - Vars.push_back(std::make_pair("SUB_SYSTEM_LOGIN",AuthService()->SubSystemLoginSite())); - Vars.push_back(std::make_pair("USER_SIGNATURE",AuthService()->UserSignature())); - Vars.push_back(std::make_pair("SUB_SIGNATURE",AuthService()->SubSignature())); - } + void RESTAPI_action_links::AddGlobalVars(Types::StringPairVec &Vars) { + Vars.push_back(std::make_pair("USER_HELPER_EMAIL", AuthService()->HelperEmail())); + Vars.push_back(std::make_pair("SUB_HELPER_EMAIL", AuthService()->SubHelperEmail())); + Vars.push_back( + std::make_pair("GLOBAL_USER_HELPER_EMAIL", AuthService()->GlobalHelperEmail())); + Vars.push_back( + std::make_pair("GLOBAL_SUB_HELPER_EMAIL", AuthService()->GlobalSubHelperEmail())); + Vars.push_back(std::make_pair("USER_HELPER_SITE", AuthService()->HelperSite())); + Vars.push_back(std::make_pair("SUB_HELPER_SITE", AuthService()->SubHelperSite())); + Vars.push_back(std::make_pair("USER_SYSTEM_LOGIN", AuthService()->SystemLoginSite())); + Vars.push_back(std::make_pair("SUB_SYSTEM_LOGIN", AuthService()->SubSystemLoginSite())); + Vars.push_back(std::make_pair("USER_SIGNATURE", AuthService()->UserSignature())); + Vars.push_back(std::make_pair("SUB_SIGNATURE", AuthService()->SubSignature())); + } - void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { - Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", Request->clientAddress().toString(), Link.userId)); - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset.html"}; - Types::StringPairVec FormVars{ {"UUID", Link.id}, - {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; - AddGlobalVars(FormVars); - SendHTMLFileBack(FormFile,FormVars); - } + void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { + Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", + Request->clientAddress().toString(), Link.userId)); + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset.html"}; + Types::StringPairVec FormVars{ + {"UUID", Link.id}, + {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; + AddGlobalVars(FormVars); + SendHTMLFileBack(FormFile, FormVars); + } - void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) { - Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", Request->clientAddress().toString(), Link.userId)); - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_signup_verification.html"}; - Types::StringPairVec FormVars{ {"UUID", Link.id}, - {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; - AddGlobalVars(FormVars); - SendHTMLFileBack(FormFile,FormVars); - } + void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) { + Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", + Request->clientAddress().toString(), Link.userId)); + Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification.html"}; + Types::StringPairVec FormVars{ + {"UUID", Link.id}, + {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; + AddGlobalVars(FormVars); + SendHTMLFileBack(FormFile, FormVars); + } - void RESTAPI_action_links::CompleteResetPassword() { - // form has been posted... - RESTAPI_PartHandler PartHandler; - Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); - if (!Form.empty()) { + void RESTAPI_action_links::CompleteResetPassword() { + // form has been posted... + RESTAPI_PartHandler PartHandler; + Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); + if (!Form.empty()) { - auto Password1 = Form.get("password1","bla"); - auto Password2 = Form.get("password2","blu"); - auto Id = Form.get("id",""); - auto now = OpenWifi::Now(); + auto Password1 = Form.get("password1", "bla"); + auto Password2 = Form.get("password2", "blu"); + auto Id = Form.get("id", ""); + auto now = OpenWifi::Now(); - SecurityObjects::ActionLink Link; - if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) - return DoReturnA404(); + SecurityObjects::ActionLink Link; + if (!StorageService()->ActionLinksDB().GetActionLink(Id, Link)) + return DoReturnA404(); - if(now > Link.expires) { - StorageService()->ActionLinksDB().CancelAction(Id); - return DoReturnA404(); - } + if (now > Link.expires) { + StorageService()->ActionLinksDB().CancelAction(Id); + return DoReturnA404(); + } - if(Password1!=Password2 || !AuthService()->ValidatePassword(Password2) || !AuthService()->ValidatePassword(Password1)) { - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" - " accepted password creation restrictions. Please consult our on-line help" - " to look at the our password policy. If you would like to contact us, please mention" - " id(" + Id + ")"}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + if (Password1 != Password2 || !AuthService()->ValidatePassword(Password2) || + !AuthService()->ValidatePassword(Password1)) { + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", + "For some reason, the passwords entered do not match or they do not comply " + "with" + " accepted password creation restrictions. Please consult our on-line help" + " to look at the our password policy. If you would like to contact us, please " + "mention" + " id(" + + Id + ")"}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - SecurityObjects::UserInfo UInfo; + SecurityObjects::UserInfo UInfo; - bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo); - if(!Found) { - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + bool Found = Link.userAction + ? StorageService()->UserDB().GetUserById(Link.userId, UInfo) + : StorageService()->SubDB().GetUserById(Link.userId, UInfo); + if (!Found) { + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact " + "your system administrator."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - if(UInfo.blackListed || UInfo.suspended) { - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + if (UInfo.blackListed || UInfo.suspended) { + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", "Please contact our system administrators. We have identified " + "an error in your account that must be resolved first."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - bool GoodPassword = Link.userAction ? AuthService()->SetPassword(Password1,UInfo) : AuthService()->SetSubPassword(Password1,UInfo); - if(!GoodPassword) { - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + bool GoodPassword = Link.userAction ? AuthService()->SetPassword(Password1, UInfo) + : AuthService()->SetSubPassword(Password1, UInfo); + if (!GoodPassword) { + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - UInfo.modified = OpenWifi::Now(); - if(Link.userAction) - StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); - else - StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); + UInfo.modified = OpenWifi::Now(); + if (Link.userAction) + StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); + else + StorageService()->SubDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); - Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_success.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"USERNAME", UInfo.email}, - {"ACTION_LINK",MicroService::instance().GetUIURI()}}; - AddGlobalVars(FormVars); - StorageService()->ActionLinksDB().CompleteAction(Id); - SendHTMLFileBack(FormFile,FormVars); - } else { - DoReturnA404(); - } - } + Poco::File FormFile{Daemon()->AssetDir() + "/password_reset_success.html"}; + Types::StringPairVec FormVars{{"UUID", Id}, + {"USERNAME", UInfo.email}, + {"ACTION_LINK", MicroService::instance().GetUIURI()}}; + AddGlobalVars(FormVars); + StorageService()->ActionLinksDB().CompleteAction(Id); + SendHTMLFileBack(FormFile, FormVars); + } else { + DoReturnA404(); + } + } - void RESTAPI_action_links::CompleteSubVerification() { - RESTAPI_PartHandler PartHandler; - Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); + void RESTAPI_action_links::CompleteSubVerification() { + RESTAPI_PartHandler PartHandler; + Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); - if (!Form.empty()) { - auto Password1 = Form.get("password1","bla"); - auto Password2 = Form.get("password2","blu"); - auto Id = Form.get("id",""); - auto now = OpenWifi::Now(); + if (!Form.empty()) { + auto Password1 = Form.get("password1", "bla"); + auto Password2 = Form.get("password2", "blu"); + auto Id = Form.get("id", ""); + auto now = OpenWifi::Now(); - SecurityObjects::ActionLink Link; - if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) { - return DoReturnA404(); - } + SecurityObjects::ActionLink Link; + if (!StorageService()->ActionLinksDB().GetActionLink(Id, Link)) { + return DoReturnA404(); + } - if(now > Link.expires) { - StorageService()->ActionLinksDB().CancelAction(Id); - return DoReturnA404(); - } + if (now > Link.expires) { + StorageService()->ActionLinksDB().CancelAction(Id); + return DoReturnA404(); + } - if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) { - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_password_reset_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" - " accepted password creation restrictions. Please consult our on-line help" - " to look at the our password policy. If you would like to contact us, please mention" - " id(" + Id + ")"}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + if (Password1 != Password2 || !AuthService()->ValidateSubPassword(Password1)) { + Poco::File FormFile{Daemon()->AssetDir() + "/sub_password_reset_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", + "For some reason, the passwords entered do not match or they do not comply " + "with" + " accepted password creation restrictions. Please consult our on-line help" + " to look at the our password policy. If you would like to contact us, please " + "mention" + " id(" + + Id + ")"}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - SecurityObjects::UserInfo UInfo; - bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo); - if(!Found) { - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + SecurityObjects::UserInfo UInfo; + bool Found = StorageService()->SubDB().GetUserById(Link.userId, UInfo); + if (!Found) { + Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact " + "your system administrator."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - if(UInfo.blackListed || UInfo.suspended) { - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + if (UInfo.blackListed || UInfo.suspended) { + Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, + {"ERROR_TEXT", "Please contact our system administrators. We have identified " + "an error in your account that must be resolved first."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo); - if(!GoodPassword) { - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile,FormVars); - } + bool GoodPassword = AuthService()->SetSubPassword(Password1, UInfo); + if (!GoodPassword) { + Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; + Types::StringPairVec FormVars{ + {"UUID", Id}, {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - UInfo.modified = OpenWifi::Now(); - UInfo.changePassword = false; - UInfo.lastEmailCheck = OpenWifi::Now(); - UInfo.waitingForEmailCheck = false; - UInfo.validated = OpenWifi::Now(); + UInfo.modified = OpenWifi::Now(); + UInfo.changePassword = false; + UInfo.lastEmailCheck = OpenWifi::Now(); + UInfo.waitingForEmailCheck = false; + UInfo.validated = OpenWifi::Now(); - StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); + StorageService()->SubDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); - Poco::File FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_success.html"}; - Types::StringPairVec FormVars{ {"UUID", Id}, - {"USERNAME", UInfo.email} }; - StorageService()->ActionLinksDB().CompleteAction(Id); + Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_success.html"}; + Types::StringPairVec FormVars{{"UUID", Id}, {"USERNAME", UInfo.email}}; + StorageService()->ActionLinksDB().CompleteAction(Id); - // Send the update to the provisioning service - Poco::JSON::Object Body; - auto RawSignup = Poco::StringTokenizer(UInfo.signingUp,":"); - Body.set("signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]); - OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup", - { - {"signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]} , - {"operation", "emailVerified"} - }, - Body,30000); - Logger().information(fmt::format("({}): Completed subscriber e-mail verification and password.",UInfo.email)); - Poco::JSON::Object::Ptr Response; - auto Status = ProvRequest.Do(Response); - std::stringstream ooo; - if(Response!= nullptr) - Response->stringify(ooo); - Logger().information(fmt::format("({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.", - UInfo.email, Status)); - AddGlobalVars(FormVars); - SendHTMLFileBack(FormFile,FormVars); - Logger().information(fmt::format("({}): Completed subscriber e-mail verification. FORM notified.",UInfo.email)); - } else { - DoReturnA404(); - } - } + // Send the update to the provisioning service + Poco::JSON::Object Body; + auto RawSignup = Poco::StringTokenizer(UInfo.signingUp, ":"); + Body.set("signupUUID", RawSignup.count() == 1 ? UInfo.signingUp : RawSignup[1]); + OpenAPIRequestPut ProvRequest( + uSERVICE_PROVISIONING, "/api/v1/signup", + {{"signupUUID", RawSignup.count() == 1 ? UInfo.signingUp : RawSignup[1]}, + {"operation", "emailVerified"}}, + Body, 30000); + Logger().information(fmt::format( + "({}): Completed subscriber e-mail verification and password.", UInfo.email)); + Poco::JSON::Object::Ptr Response; + auto Status = ProvRequest.Do(Response); + std::stringstream ooo; + if (Response != nullptr) + Response->stringify(ooo); + Logger().information(fmt::format( + "({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.", + UInfo.email, Status)); + AddGlobalVars(FormVars); + SendHTMLFileBack(FormFile, FormVars); + Logger().information(fmt::format( + "({}): Completed subscriber e-mail verification. FORM notified.", UInfo.email)); + } else { + DoReturnA404(); + } + } - void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) { - auto now = OpenWifi::Now(); + void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) { + auto now = OpenWifi::Now(); - if(now > Link.expires) { - StorageService()->ActionLinksDB().CancelAction(Link.id); - return DoReturnA404(); - } + if (now > Link.expires) { + StorageService()->ActionLinksDB().CancelAction(Link.id); + return DoReturnA404(); + } - SecurityObjects::UserInfo UInfo; - bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo); - if (!Found) { - Types::StringPairVec FormVars{{"UUID", Link.id}, - {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}}; - Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"}; - AddGlobalVars(FormVars); - return SendHTMLFileBack(FormFile, FormVars); - } + SecurityObjects::UserInfo UInfo; + bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId, UInfo) + : StorageService()->SubDB().GetUserById(Link.userId, UInfo); + if (!Found) { + Types::StringPairVec FormVars{ + {"UUID", Link.id}, + {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}}; + Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"}; + AddGlobalVars(FormVars); + return SendHTMLFileBack(FormFile, FormVars); + } - Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(), - UInfo.email)); - UInfo.waitingForEmailCheck = false; - UInfo.validated = true; - UInfo.lastEmailCheck = OpenWifi::Now(); - UInfo.validationDate = OpenWifi::Now(); - UInfo.modified = OpenWifi::Now(); - if(Link.userAction) - StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); - else - StorageService()->SubDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); - Types::StringPairVec FormVars{{"UUID", Link.id}, - {"USERNAME", UInfo.email}, - {"ACTION_LINK",MicroService::instance().GetUIURI()}}; - Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"}; - AddGlobalVars(FormVars); - StorageService()->ActionLinksDB().CompleteAction(Link.id); - SendHTMLFileBack(FormFile, FormVars); - } + Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", + Request->clientAddress().toString(), UInfo.email)); + UInfo.waitingForEmailCheck = false; + UInfo.validated = true; + UInfo.lastEmailCheck = OpenWifi::Now(); + UInfo.validationDate = OpenWifi::Now(); + UInfo.modified = OpenWifi::Now(); + if (Link.userAction) + StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); + else + StorageService()->SubDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); + Types::StringPairVec FormVars{{"UUID", Link.id}, + {"USERNAME", UInfo.email}, + {"ACTION_LINK", MicroService::instance().GetUIURI()}}; + Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"}; + AddGlobalVars(FormVars); + StorageService()->ActionLinksDB().CompleteAction(Link.id); + SendHTMLFileBack(FormFile, FormVars); + } - void RESTAPI_action_links::DoReturnA404() { - Types::StringPairVec FormVars; - Poco::File FormFile{Daemon()->AssetDir() + "/404_error.html"}; - AddGlobalVars(FormVars); - SendHTMLFileBack(FormFile, FormVars); - } + void RESTAPI_action_links::DoReturnA404() { + Types::StringPairVec FormVars; + Poco::File FormFile{Daemon()->AssetDir() + "/404_error.html"}; + AddGlobalVars(FormVars); + SendHTMLFileBack(FormFile, FormVars); + } - void RESTAPI_action_links::CompleteEmailInvitation() { - /// TODO: - } + void RESTAPI_action_links::CompleteEmailInvitation() { + /// TODO: + } - void RESTAPI_action_links::RequestSubResetPassword([[maybe_unused]] SecurityObjects::ActionLink &Link) { + void RESTAPI_action_links::RequestSubResetPassword( + [[maybe_unused]] SecurityObjects::ActionLink &Link) {} - } + void RESTAPI_action_links::DoSubEmailVerification( + [[maybe_unused]] SecurityObjects::ActionLink &Link) {} - void RESTAPI_action_links::DoSubEmailVerification([[maybe_unused]] SecurityObjects::ActionLink &Link) { - - } - -} +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_action_links.h b/src/RESTAPI/RESTAPI_action_links.h index bca3a24..940ab51 100644 --- a/src/RESTAPI/RESTAPI_action_links.h +++ b/src/RESTAPI/RESTAPI_action_links.h @@ -7,34 +7,32 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_action_links : public RESTAPIHandler { - public: - RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal, - false, - true, RateLimit{.Interval=1000,.MaxCalls=10}) {} - static auto PathName() { return std::list{"/api/v1/actionLink"}; }; - void RequestResetPassword(SecurityObjects::ActionLink &Link); - void RequestSubResetPassword(SecurityObjects::ActionLink &Link); - void CompleteResetPassword(); - void CompleteSubVerification(); - void DoEmailVerification(SecurityObjects::ActionLink &Link); - void DoSubEmailVerification(SecurityObjects::ActionLink &Link); - void DoReturnA404(); - void DoNewSubVerification(SecurityObjects::ActionLink &Link); - void CompleteEmailInvitation(); - static void AddGlobalVars(Types::StringPairVec & Vars); + class RESTAPI_action_links : public RESTAPIHandler { + public: + RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal, false, true, + RateLimit{.Interval = 1000, .MaxCalls = 10}) {} + static auto PathName() { return std::list{"/api/v1/actionLink"}; }; + void RequestResetPassword(SecurityObjects::ActionLink &Link); + void RequestSubResetPassword(SecurityObjects::ActionLink &Link); + void CompleteResetPassword(); + void CompleteSubVerification(); + void DoEmailVerification(SecurityObjects::ActionLink &Link); + void DoSubEmailVerification(SecurityObjects::ActionLink &Link); + void DoReturnA404(); + void DoNewSubVerification(SecurityObjects::ActionLink &Link); + void CompleteEmailInvitation(); + static void AddGlobalVars(Types::StringPairVec &Vars); - void DoGet() final; - void DoPost() final; - void DoDelete() final {}; - void DoPut() final {}; - }; -} + void DoGet() final; + void DoPost() final; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_apiKey_handler.cpp b/src/RESTAPI/RESTAPI_apiKey_handler.cpp index c5a00c7..4d7b94b 100644 --- a/src/RESTAPI/RESTAPI_apiKey_handler.cpp +++ b/src/RESTAPI/RESTAPI_apiKey_handler.cpp @@ -7,152 +7,159 @@ namespace OpenWifi { - void RESTAPI_apiKey_handler::DoGet() { - std::string user_uuid = GetBinding("uuid",""); - if(user_uuid.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + void RESTAPI_apiKey_handler::DoGet() { + std::string user_uuid = GetBinding("uuid", ""); + if (user_uuid.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + if (user_uuid != UserInfo_.userinfo.id && + UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - SecurityObjects::ApiKeyEntryList List; - if(DB_.GetRecords(0,500, List.apiKeys, fmt::format(" userUuid='{}' ", user_uuid))) { - for(auto &key:List.apiKeys) { - Sanitize(UserInfo_, key); - } - Poco::JSON::Object Answer; - List.to_json(Answer); - return ReturnObject(Answer); - } - return NotFound(); - } + SecurityObjects::ApiKeyEntryList List; + if (DB_.GetRecords(0, 500, List.apiKeys, fmt::format(" userUuid='{}' ", user_uuid))) { + for (auto &key : List.apiKeys) { + Sanitize(UserInfo_, key); + } + Poco::JSON::Object Answer; + List.to_json(Answer); + return ReturnObject(Answer); + } + return NotFound(); + } - void RESTAPI_apiKey_handler::DoDelete() { - std::string user_uuid = GetBinding("uuid",""); - if(user_uuid.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + void RESTAPI_apiKey_handler::DoDelete() { + std::string user_uuid = GetBinding("uuid", ""); + if (user_uuid.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (user_uuid != UserInfo_.userinfo.id && + UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(user_uuid!=UserInfo_.userinfo.id) { - if(!StorageService()->UserDB().Exists("id",user_uuid)) { - return NotFound(); - } - } + if (user_uuid != UserInfo_.userinfo.id) { + if (!StorageService()->UserDB().Exists("id", user_uuid)) { + return NotFound(); + } + } - std::string ApiKeyId= GetParameter("keyUuid",""); - if(ApiKeyId.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + std::string ApiKeyId = GetParameter("keyUuid", ""); + if (ApiKeyId.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - SecurityObjects::ApiKeyEntry ApiKey; - if(StorageService()->ApiKeyDB().GetRecord("id",ApiKeyId,ApiKey)) { - if(ApiKey.userUuid==user_uuid) { - AuthService()->RemoveTokenSystemWide(ApiKey.apiKey); - DB_.DeleteRecord("id", ApiKeyId); - return OK(); - } - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - return NotFound(); - } + SecurityObjects::ApiKeyEntry ApiKey; + if (StorageService()->ApiKeyDB().GetRecord("id", ApiKeyId, ApiKey)) { + if (ApiKey.userUuid == user_uuid) { + AuthService()->RemoveTokenSystemWide(ApiKey.apiKey); + DB_.DeleteRecord("id", ApiKeyId); + return OK(); + } + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + return NotFound(); + } - void RESTAPI_apiKey_handler::DoPost() { - std::string user_uuid = GetBinding("uuid",""); + void RESTAPI_apiKey_handler::DoPost() { + std::string user_uuid = GetBinding("uuid", ""); - if(user_uuid.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + if (user_uuid.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (user_uuid != UserInfo_.userinfo.id && + UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(user_uuid!=UserInfo_.userinfo.id) { - // Must verify if the user exists - if(!StorageService()->UserDB().Exists("id",user_uuid)) { - return BadRequest(RESTAPI::Errors::UserMustExist); - } - } + if (user_uuid != UserInfo_.userinfo.id) { + // Must verify if the user exists + if (!StorageService()->UserDB().Exists("id", user_uuid)) { + return BadRequest(RESTAPI::Errors::UserMustExist); + } + } - SecurityObjects::ApiKeyEntry NewKey; - if(!NewKey.from_json(ParsedBody_)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } - NewKey.lastUse = 0 ; + SecurityObjects::ApiKeyEntry NewKey; + if (!NewKey.from_json(ParsedBody_)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } + NewKey.lastUse = 0; - if(!Utils::IsAlphaNumeric(NewKey.name) || NewKey.name.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + if (!Utils::IsAlphaNumeric(NewKey.name) || NewKey.name.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - Poco::toLowerInPlace(NewKey.name); - NewKey.userUuid = user_uuid; - if(NewKey.expiresOn < Utils::Now()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + Poco::toLowerInPlace(NewKey.name); + NewKey.userUuid = user_uuid; + if (NewKey.expiresOn < Utils::Now()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - // does a key of that name already exit for this user? - SecurityObjects::ApiKeyEntryList ExistingList; - if(DB_.GetRecords(0,500, ExistingList.apiKeys, fmt::format(" userUuid='{}' ", user_uuid))) { - if(std::find_if(ExistingList.apiKeys.begin(),ExistingList.apiKeys.end(), [NewKey](const SecurityObjects::ApiKeyEntry &E) -> bool { - return E.name==NewKey.name; - })!=ExistingList.apiKeys.end()) { - return BadRequest(RESTAPI::Errors::ApiKeyNameAlreadyExists); - } - } + // does a key of that name already exit for this user? + SecurityObjects::ApiKeyEntryList ExistingList; + if (DB_.GetRecords(0, 500, ExistingList.apiKeys, + fmt::format(" userUuid='{}' ", user_uuid))) { + if (std::find_if(ExistingList.apiKeys.begin(), ExistingList.apiKeys.end(), + [NewKey](const SecurityObjects::ApiKeyEntry &E) -> bool { + return E.name == NewKey.name; + }) != ExistingList.apiKeys.end()) { + return BadRequest(RESTAPI::Errors::ApiKeyNameAlreadyExists); + } + } - if(ExistingList.apiKeys.size()>=10) { - return BadRequest(RESTAPI::Errors::TooManyApiKeys); - } + if (ExistingList.apiKeys.size() >= 10) { + return BadRequest(RESTAPI::Errors::TooManyApiKeys); + } - NewKey.id = MicroServiceCreateUUID(); - NewKey.userUuid = user_uuid; - NewKey.salt = std::to_string(Utils::Now()); - NewKey.apiKey = Utils::ComputeHash(NewKey.salt, UserInfo_.userinfo.id, UserInfo_.webtoken.access_token_ ); - NewKey.created = Utils::Now(); + NewKey.id = MicroServiceCreateUUID(); + NewKey.userUuid = user_uuid; + NewKey.salt = std::to_string(Utils::Now()); + NewKey.apiKey = Utils::ComputeHash(NewKey.salt, UserInfo_.userinfo.id, + UserInfo_.webtoken.access_token_); + NewKey.created = Utils::Now(); - if(DB_.CreateRecord(NewKey)) { - Poco::JSON::Object Answer; - NewKey.to_json(Answer); - return ReturnObject(Answer); - } - return BadRequest(RESTAPI::Errors::RecordNotCreated); - } + if (DB_.CreateRecord(NewKey)) { + Poco::JSON::Object Answer; + NewKey.to_json(Answer); + return ReturnObject(Answer); + } + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } - void RESTAPI_apiKey_handler::DoPut() { - std::string user_uuid = GetBinding("uuid",""); - if(user_uuid.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - SecurityObjects::ApiKeyEntry NewKey; - if(!NewKey.from_json(ParsedBody_)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + void RESTAPI_apiKey_handler::DoPut() { + std::string user_uuid = GetBinding("uuid", ""); + if (user_uuid.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + if (user_uuid != UserInfo_.userinfo.id && + UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + SecurityObjects::ApiKeyEntry NewKey; + if (!NewKey.from_json(ParsedBody_)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - SecurityObjects::ApiKeyEntry ExistingKey; - if(!DB_.GetRecord("id",NewKey.id,ExistingKey)) { - return BadRequest(RESTAPI::Errors::ApiKeyDoesNotExist); - } + SecurityObjects::ApiKeyEntry ExistingKey; + if (!DB_.GetRecord("id", NewKey.id, ExistingKey)) { + return BadRequest(RESTAPI::Errors::ApiKeyDoesNotExist); + } - if(ExistingKey.userUuid!=user_uuid) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + if (ExistingKey.userUuid != user_uuid) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - AssignIfPresent(ParsedBody_,"description",ExistingKey.description); + AssignIfPresent(ParsedBody_, "description", ExistingKey.description); - if(DB_.UpdateRecord("id",ExistingKey.id,ExistingKey)) { - Poco::JSON::Object Answer; - ExistingKey.to_json(Answer); - return ReturnObject(Answer); - } - BadRequest(RESTAPI::Errors::RecordNotUpdated); - } + if (DB_.UpdateRecord("id", ExistingKey.id, ExistingKey)) { + Poco::JSON::Object Answer; + ExistingKey.to_json(Answer); + return ReturnObject(Answer); + } + BadRequest(RESTAPI::Errors::RecordNotUpdated); + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_apiKey_handler.h b/src/RESTAPI/RESTAPI_apiKey_handler.h index 19a66a4..0469f55 100644 --- a/src/RESTAPI/RESTAPI_apiKey_handler.h +++ b/src/RESTAPI/RESTAPI_apiKey_handler.h @@ -4,31 +4,29 @@ #pragma once -#include "framework/RESTAPI_Handler.h" #include "StorageService.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_apiKey_handler : public RESTAPIHandler { - public: - RESTAPI_apiKey_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/apiKey/{uuid}"}; }; - private: - ApiKeyDB &DB_=StorageService()->ApiKeyDB(); + class RESTAPI_apiKey_handler : public RESTAPIHandler { + public: + RESTAPI_apiKey_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/apiKey/{uuid}"}; }; - void DoGet() final; - void DoPut() final; - void DoPost() final; - void DoDelete() final; - - }; -} + private: + ApiKeyDB &DB_ = StorageService()->ApiKeyDB(); + void DoGet() final; + void DoPut() final; + void DoPost() final; + void DoDelete() final; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_asset_server.cpp b/src/RESTAPI/RESTAPI_asset_server.cpp index 433ca01..89905cb 100644 --- a/src/RESTAPI/RESTAPI_asset_server.cpp +++ b/src/RESTAPI/RESTAPI_asset_server.cpp @@ -3,23 +3,23 @@ // #include "RESTAPI_asset_server.h" +#include "Daemon.h" #include "Poco/File.h" #include "framework/ow_constants.h" -#include "Daemon.h" namespace OpenWifi { - void RESTAPI_asset_server::DoGet() { - Poco::File AssetFile; + void RESTAPI_asset_server::DoGet() { + Poco::File AssetFile; - if(Request->getURI().find("/favicon.ico") != std::string::npos) { - AssetFile = Daemon()->AssetDir() + "/favicon.ico"; - } else { - std::string AssetName = GetBinding(RESTAPI::Protocol::ID, ""); - AssetFile = Daemon()->AssetDir() + "/" + AssetName; - } - if(!AssetFile.isFile()) { - return NotFound(); - } - SendFile(AssetFile); - } -} \ No newline at end of file + if (Request->getURI().find("/favicon.ico") != std::string::npos) { + AssetFile = Daemon()->AssetDir() + "/favicon.ico"; + } else { + std::string AssetName = GetBinding(RESTAPI::Protocol::ID, ""); + AssetFile = Daemon()->AssetDir() + "/" + AssetName; + } + if (!AssetFile.isFile()) { + return NotFound(); + } + SendFile(AssetFile); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_asset_server.h b/src/RESTAPI/RESTAPI_asset_server.h index a1e0a87..6f1fbe4 100644 --- a/src/RESTAPI/RESTAPI_asset_server.h +++ b/src/RESTAPI/RESTAPI_asset_server.h @@ -7,28 +7,26 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_asset_server : public RESTAPIHandler { - public: - RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal, false) {} - static auto PathName() { return std::list{"/wwwassets/{id}" , - "/favicon.ico"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - - private: - - }; -} + class RESTAPI_asset_server : public RESTAPIHandler { + public: + RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal, false) {} + static auto PathName() { + return std::list{"/wwwassets/{id}", "/favicon.ico"}; + }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_avatar_handler.cpp b/src/RESTAPI/RESTAPI_avatar_handler.cpp index 40e59fc..191abaa 100644 --- a/src/RESTAPI/RESTAPI_avatar_handler.cpp +++ b/src/RESTAPI/RESTAPI_avatar_handler.cpp @@ -5,79 +5,85 @@ #include #include +#include "Poco/CountingStream.h" +#include "Poco/Net/HTMLForm.h" #include "RESTAPI_avatar_handler.h" #include "StorageService.h" -#include "Poco/Net/HTMLForm.h" -#include "Poco/CountingStream.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - void AvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) { - FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); - if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { - std::string Disposition; - Poco::Net::NameValueCollection Parameters; - Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters); - Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); - } - Poco::CountingInputStream InputStream(Stream); - Poco::StreamCopier::copyStream(InputStream, OutputStream_); - Length_ = OutputStream_.str().size(); - }; + void AvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, + std::istream &Stream) { + FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); + if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { + std::string Disposition; + Poco::Net::NameValueCollection Parameters; + Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], + Disposition, Parameters); + Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); + } + Poco::CountingInputStream InputStream(Stream); + Poco::StreamCopier::copyStream(InputStream, OutputStream_); + Length_ = OutputStream_.str().size(); + }; - void RESTAPI_avatar_handler::DoPost() { - std::string Id = UserInfo_.userinfo.id; - SecurityObjects::UserInfo UInfo; + void RESTAPI_avatar_handler::DoPost() { + std::string Id = UserInfo_.userinfo.id; + SecurityObjects::UserInfo UInfo; - std::stringstream SS; - AvatarPartHandler partHandler(Id, Logger_, SS); - Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); - Poco::JSON::Object Answer; + std::stringstream SS; + AvatarPartHandler partHandler(Id, Logger_, SS); + Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); + Poco::JSON::Object Answer; - if (!partHandler.Name().empty() && partHandler.Length()< MicroServiceConfigGetInt("openwifi.avatar.maxsize",2000000)) { - Answer.set(RESTAPI::Protocol::AVATARID, Id); - Answer.set(RESTAPI::Protocol::ERRORCODE, 0); - Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); - StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email, - Id, SS.str(), partHandler.ContentType(), partHandler.Name()); - StorageService()->UserDB().SetAvatar(Id,"1"); - Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); - } else { - Answer.set(RESTAPI::Protocol::AVATARID, Id); - Answer.set(RESTAPI::Protocol::ERRORCODE, 13); - Answer.set(RESTAPI::Protocol::ERRORTEXT, "Avatar upload could not complete."); - } - ReturnObject(Answer); - } + if (!partHandler.Name().empty() && + partHandler.Length() < MicroServiceConfigGetInt("openwifi.avatar.maxsize", 2000000)) { + Answer.set(RESTAPI::Protocol::AVATARID, Id); + Answer.set(RESTAPI::Protocol::ERRORCODE, 0); + Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), + partHandler.ContentType())); + StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email, Id, SS.str(), + partHandler.ContentType(), partHandler.Name()); + StorageService()->UserDB().SetAvatar(Id, "1"); + Logger().information(fmt::format("Adding avatar for {}", UserInfo_.userinfo.email)); + } else { + Answer.set(RESTAPI::Protocol::AVATARID, Id); + Answer.set(RESTAPI::Protocol::ERRORCODE, 13); + Answer.set(RESTAPI::Protocol::ERRORTEXT, "Avatar upload could not complete."); + } + ReturnObject(Answer); + } - void RESTAPI_avatar_handler::DoGet() { - std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); - if (Id.empty()) { - return NotFound(); - } + void RESTAPI_avatar_handler::DoGet() { + std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); + if (Id.empty()) { + return NotFound(); + } - std::string Type, Name, AvatarContent; - if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) { - return NotFound(); - } - Logger().information(fmt::format("Retrieving avatar for {}, size:{}",UserInfo_.userinfo.email,AvatarContent.size())); - return SendFileContent(AvatarContent, Type, Name); - } + std::string Type, Name, AvatarContent; + if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, + Type, Name)) { + return NotFound(); + } + Logger().information(fmt::format("Retrieving avatar for {}, size:{}", + UserInfo_.userinfo.email, AvatarContent.size())); + return SendFileContent(AvatarContent, Type, Name); + } - void RESTAPI_avatar_handler::DoDelete() { - std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); + void RESTAPI_avatar_handler::DoDelete() { + std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && Id != UserInfo_.userinfo.id) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if (!StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) { - return NotFound(); - } + if (!StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) { + return NotFound(); + } - Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email)); - StorageService()->UserDB().SetAvatar(Id,""); - OK(); - } -} + Logger().information(fmt::format("Deleted avatar for {}", UserInfo_.userinfo.email)); + StorageService()->UserDB().SetAvatar(Id, ""); + OK(); + } +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_avatar_handler.h b/src/RESTAPI/RESTAPI_avatar_handler.h index 51add4e..8c17a16 100644 --- a/src/RESTAPI/RESTAPI_avatar_handler.h +++ b/src/RESTAPI/RESTAPI_avatar_handler.h @@ -3,51 +3,47 @@ // #pragma once -#include "framework/RESTAPI_Handler.h" #include "Poco/Net/PartHandler.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class AvatarPartHandler : public Poco::Net::PartHandler { - public: - AvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) : - Id_(std::move(Id)), - Logger_(Logger), - OutputStream_(ofs){ - } - void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); - [[nodiscard]] uint64_t Length() const { return Length_; } - [[nodiscard]] std::string &Name() { return Name_; } - [[nodiscard]] std::string &ContentType() { return FileType_; } + class AvatarPartHandler : public Poco::Net::PartHandler { + public: + AvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream &ofs) + : Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {} + void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); + [[nodiscard]] uint64_t Length() const { return Length_; } + [[nodiscard]] std::string &Name() { return Name_; } + [[nodiscard]] std::string &ContentType() { return FileType_; } - private: - uint64_t Length_ = 0; - std::string FileType_; - std::string Name_; - std::string Id_; - Poco::Logger &Logger_; - std::stringstream &OutputStream_; + private: + uint64_t Length_ = 0; + std::string FileType_; + std::string Name_; + std::string Id_; + Poco::Logger &Logger_; + std::stringstream &OutputStream_; - inline Poco::Logger & Logger() { return Logger_; }; - }; + inline Poco::Logger &Logger() { return Logger_; }; + }; - class RESTAPI_avatar_handler : public RESTAPIHandler { - public: - RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/avatar/{id}"}; }; + class RESTAPI_avatar_handler : public RESTAPIHandler { + public: + RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/avatar/{id}"}; }; - void DoGet() final; - void DoPost() final; - void DoDelete() final; - void DoPut() final {}; - }; -} + void DoGet() final; + void DoPost() final; + void DoDelete() final; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_db_helpers.h b/src/RESTAPI/RESTAPI_db_helpers.h index 70d089a..36a5447 100644 --- a/src/RESTAPI/RESTAPI_db_helpers.h +++ b/src/RESTAPI/RESTAPI_db_helpers.h @@ -8,13 +8,15 @@ namespace OpenWifi { - inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) { - U.currentPassword.clear(); - U.lastPasswords.clear(); - U.oauthType.clear(); - } + inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, + SecurityObjects::UserInfo &U) { + U.currentPassword.clear(); + U.lastPasswords.clear(); + U.oauthType.clear(); + } - inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::ApiKeyEntry & U) { - U.salt.clear(); - } -} \ No newline at end of file + inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, + SecurityObjects::ApiKeyEntry &U) { + U.salt.clear(); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_email_handler.cpp b/src/RESTAPI/RESTAPI_email_handler.cpp index d9ccb74..78d03f4 100644 --- a/src/RESTAPI/RESTAPI_email_handler.cpp +++ b/src/RESTAPI/RESTAPI_email_handler.cpp @@ -9,26 +9,23 @@ #include "framework/ow_constants.h" namespace OpenWifi { - void RESTAPI_email_handler::DoPost() { - const auto & Obj = ParsedBody_; - if (Obj->has("subject") && - Obj->has("from") && - Obj->has("text") && - Obj->has("recipients") && - Obj->isArray("recipients")) { + void RESTAPI_email_handler::DoPost() { + const auto &Obj = ParsedBody_; + if (Obj->has("subject") && Obj->has("from") && Obj->has("text") && Obj->has("recipients") && + Obj->isArray("recipients")) { - Poco::JSON::Array::Ptr Recipients = Obj->getArray("recipients"); - auto Recipient = Recipients->get(0).toString(); - MessageAttributes Attrs; - Attrs[RECIPIENT_EMAIL] = Recipient; - Attrs[SUBJECT] = Obj->get("subject").toString(); - Attrs[TEXT] = Obj->get("text").toString(); - Attrs[SENDER] = Obj->get("from").toString(); - if(SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs, false)) { - return OK(); - } - return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); - } - BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } -} \ No newline at end of file + Poco::JSON::Array::Ptr Recipients = Obj->getArray("recipients"); + auto Recipient = Recipients->get(0).toString(); + MessageAttributes Attrs; + Attrs[RECIPIENT_EMAIL] = Recipient; + Attrs[SUBJECT] = Obj->get("subject").toString(); + Attrs[TEXT] = Obj->get("text").toString(); + Attrs[SENDER] = Obj->get("from").toString(); + if (SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs, false)) { + return OK(); + } + return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); + } + BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_email_handler.h b/src/RESTAPI/RESTAPI_email_handler.h index 1662d91..ede4cb5 100644 --- a/src/RESTAPI/RESTAPI_email_handler.h +++ b/src/RESTAPI/RESTAPI_email_handler.h @@ -7,19 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_email_handler : public RESTAPIHandler { - public: - RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/email"};} - void DoGet() final {}; - void DoPost() final; - void DoDelete() final {}; - void DoPut() final {}; - }; -} + class RESTAPI_email_handler : public RESTAPIHandler { + public: + RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/email"}; } + void DoGet() final{}; + void DoPost() final; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_oauth2_handler.cpp b/src/RESTAPI/RESTAPI_oauth2_handler.cpp index 0f2c79c..327c65c 100644 --- a/src/RESTAPI/RESTAPI_oauth2_handler.cpp +++ b/src/RESTAPI/RESTAPI_oauth2_handler.cpp @@ -9,170 +9,176 @@ #include "Poco/JSON/Parser.h" #include "AuthService.h" -#include "RESTAPI_oauth2_handler.h" #include "MFAServer.h" -#include "framework/ow_constants.h" -#include "framework/MicroService.h" -#include "StorageService.h" #include "RESTAPI_db_helpers.h" +#include "RESTAPI_oauth2_handler.h" +#include "StorageService.h" +#include "framework/MicroService.h" +#include "framework/ow_constants.h" namespace OpenWifi { - void RESTAPI_oauth2_handler::DoGet() { - bool Expired = false, Contacted = false; - if (!IsAuthorized(Expired, Contacted)) { - if (Expired) - return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN); - return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); - } - if (GetBoolParameter(RESTAPI::Protocol::ME)) { - Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(), - UserInfo_.userinfo.email)); - Poco::JSON::Object Me; - SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; - Sanitize(UserInfo_, ReturnedUser); - ReturnedUser.to_json(Me); - return ReturnObject(Me); - } - BadRequest(RESTAPI::Errors::UnrecognizedRequest); - } + void RESTAPI_oauth2_handler::DoGet() { + bool Expired = false, Contacted = false; + if (!IsAuthorized(Expired, Contacted)) { + if (Expired) + return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN); + return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); + } + if (GetBoolParameter(RESTAPI::Protocol::ME)) { + Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", + Request->clientAddress().toString(), + UserInfo_.userinfo.email)); + Poco::JSON::Object Me; + SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; + Sanitize(UserInfo_, ReturnedUser); + ReturnedUser.to_json(Me); + return ReturnObject(Me); + } + BadRequest(RESTAPI::Errors::UnrecognizedRequest); + } - void RESTAPI_oauth2_handler::DoDelete() { - auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); - std::string SessionToken; - try { - Poco::Net::OAuth20Credentials Auth(*Request); - if (Auth.getScheme() == "Bearer") { - SessionToken = Auth.getBearerToken(); - } - } catch (const Poco::Exception &E) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - if (Token.empty() || (Token != SessionToken)) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + void RESTAPI_oauth2_handler::DoDelete() { + auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); + std::string SessionToken; + try { + Poco::Net::OAuth20Credentials Auth(*Request); + if (Auth.getScheme() == "Bearer") { + SessionToken = Auth.getBearerToken(); + } + } catch (const Poco::Exception &E) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + if (Token.empty() || (Token != SessionToken)) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - AuthService()->Logout(Token); - return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); - } + AuthService()->Logout(Token); + return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); + } void RESTAPI_oauth2_handler::DoPost() { - const auto & Obj = ParsedBody_; - if(Obj == nullptr) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + const auto &Obj = ParsedBody_; + if (Obj == nullptr) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - auto userId = GetS(RESTAPI::Protocol::USERID, Obj); - auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj); - auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj); - auto refreshToken = GetS("refreshToken", Obj); - auto grant_type = GetParameter("grant_type"); + auto userId = GetS(RESTAPI::Protocol::USERID, Obj); + auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj); + auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj); + auto refreshToken = GetS("refreshToken", Obj); + auto grant_type = GetParameter("grant_type"); - Poco::toLowerInPlace(userId); + Poco::toLowerInPlace(userId); - if(!refreshToken.empty() && grant_type == "refresh_token") { - SecurityObjects::UserInfoAndPolicy UInfo; - if(AuthService()->RefreshUserToken(*Request, refreshToken, UInfo)) { - Poco::JSON::Object Answer; - UInfo.webtoken.to_json(Answer); - return ReturnObject(Answer); - } else { - return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN); - } - } + if (!refreshToken.empty() && grant_type == "refresh_token") { + SecurityObjects::UserInfoAndPolicy UInfo; + if (AuthService()->RefreshUserToken(*Request, refreshToken, UInfo)) { + Poco::JSON::Object Answer; + UInfo.webtoken.to_json(Answer); + return ReturnObject(Answer); + } else { + return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN); + } + } - if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { - Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); - Poco::JSON::Object Answer; - Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression()); - Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy()); - Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetPasswordPolicy()); - return ReturnObject(Answer); - } + if (GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { + Logger_.information( + fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); + Poco::JSON::Object Answer; + Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, + AuthService()->PasswordValidationExpression()); + Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy()); + Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetPasswordPolicy()); + return ReturnObject(Answer); + } - if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { - SecurityObjects::UserInfo UInfo1; - auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1); - if(UserExists) { - Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); - SecurityObjects::ActionLink NewLink; + if (GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { + SecurityObjects::UserInfo UInfo1; + auto UserExists = StorageService()->UserDB().GetUserByEmail(userId, UInfo1); + if (UserExists) { + Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", + Request->clientAddress().toString(), userId)); + SecurityObjects::ActionLink NewLink; - NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; - NewLink.id = MicroService::CreateUUID(); - NewLink.userId = UInfo1.id; - NewLink.created = OpenWifi::Now(); - NewLink.expires = NewLink.created + (24*60*60); - NewLink.userAction = true; - StorageService()->ActionLinksDB().CreateAction(NewLink); + NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; + NewLink.id = MicroService::CreateUUID(); + NewLink.userId = UInfo1.id; + NewLink.created = OpenWifi::Now(); + NewLink.expires = NewLink.created + (24 * 60 * 60); + NewLink.userAction = true; + StorageService()->ActionLinksDB().CreateAction(NewLink); - Poco::JSON::Object ReturnObj; - SecurityObjects::UserInfoAndPolicy UInfo; - UInfo.webtoken.userMustChangePassword = true; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } else { - Poco::JSON::Object ReturnObj; - SecurityObjects::UserInfoAndPolicy UInfo; - UInfo.webtoken.userMustChangePassword = true; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - } + Poco::JSON::Object ReturnObj; + SecurityObjects::UserInfoAndPolicy UInfo; + UInfo.webtoken.userMustChangePassword = true; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } else { + Poco::JSON::Object ReturnObj; + SecurityObjects::UserInfoAndPolicy UInfo; + UInfo.webtoken.userMustChangePassword = true; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + } - if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { - Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); - if(Obj->has("uuid")) { - auto uuid = Obj->get("uuid").toString(); - if(MFAServer()->ResendCode(uuid)) - return OK(); - } - return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION); - } + if (GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { + Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", + Request->clientAddress().toString(), userId)); + if (Obj->has("uuid")) { + auto uuid = Obj->get("uuid").toString(); + if (MFAServer()->ResendCode(uuid)) + return OK(); + } + return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION); + } - if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { - Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); - if(Obj->has("uuid")) { - SecurityObjects::UserInfoAndPolicy UInfo; - if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { - Poco::JSON::Object ReturnObj; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - } - return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); - } + if (GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE, false)) { + Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", + Request->clientAddress().toString(), userId)); + if (Obj->has("uuid")) { + SecurityObjects::UserInfoAndPolicy UInfo; + if (MFAServer()->CompleteMFAChallenge(Obj, UInfo)) { + Poco::JSON::Object ReturnObj; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + } + return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); + } - SecurityObjects::UserInfoAndPolicy UInfo; - bool Expired=false; - auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired); - switch(Code) { - case SUCCESS: - { - Poco::JSON::Object ReturnObj; - if(AuthService()->RequiresMFA(UInfo)) { - if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { - return ReturnObject(ReturnObj); - } - Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now."); - } - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - case INVALID_CREDENTIALS: - return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); - case PASSWORD_INVALID: - return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); - case PASSWORD_ALREADY_USED: - return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); - case USERNAME_PENDING_VERIFICATION: - return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); - case PASSWORD_CHANGE_REQUIRED: - return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); - case ACCOUNT_SUSPENDED: - return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); - default: - return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); - } + SecurityObjects::UserInfoAndPolicy UInfo; + bool Expired = false; + auto Code = AuthService()->Authorize(userId, password, newPassword, UInfo, Expired); + switch (Code) { + case SUCCESS: { + Poco::JSON::Object ReturnObj; + if (AuthService()->RequiresMFA(UInfo)) { + if (MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { + return ReturnObject(ReturnObj); + } + Logger_.warning( + "MFA Seems to be broken. Please fix. Disabling MFA checking for now."); + } + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + case INVALID_CREDENTIALS: + return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); + case PASSWORD_INVALID: + return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); + case PASSWORD_ALREADY_USED: + return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); + case USERNAME_PENDING_VERIFICATION: + return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); + case PASSWORD_CHANGE_REQUIRED: + return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); + case ACCOUNT_SUSPENDED: + return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); + default: + return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); + } } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_oauth2_handler.h b/src/RESTAPI/RESTAPI_oauth2_handler.h index f7277d2..96f103b 100644 --- a/src/RESTAPI/RESTAPI_oauth2_handler.h +++ b/src/RESTAPI/RESTAPI_oauth2_handler.h @@ -12,21 +12,22 @@ namespace OpenWifi { class RESTAPI_oauth2_handler : public RESTAPIHandler { public: - RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) + RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) : RESTAPIHandler(bindings, L, std::vector{Poco::Net::HTTPRequest::HTTP_POST, Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {} - static auto PathName() { return std::list{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; }; + Server, TransactionId, Internal, false, true, + RateLimit{.Interval = 1000, .MaxCalls = 10}) {} + static auto PathName() { + return std::list{"/api/v1/oauth2/{token}", "/api/v1/oauth2"}; + }; void DoGet() final; void DoPost() final; void DoDelete() final; - void DoPut() final {}; + void DoPut() final{}; }; -} - - +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_preferences.cpp b/src/RESTAPI/RESTAPI_preferences.cpp index 6b6b67e..c932587 100644 --- a/src/RESTAPI/RESTAPI_preferences.cpp +++ b/src/RESTAPI/RESTAPI_preferences.cpp @@ -7,30 +7,30 @@ namespace OpenWifi { - void RESTAPI_preferences::DoGet() { - SecurityObjects::Preferences P; - Poco::JSON::Object Answer; - StorageService()->PreferencesDB().GetPreferences(UserInfo_.userinfo.id, P); - P.to_json(Answer); - ReturnObject(Answer); - } + void RESTAPI_preferences::DoGet() { + SecurityObjects::Preferences P; + Poco::JSON::Object Answer; + StorageService()->PreferencesDB().GetPreferences(UserInfo_.userinfo.id, P); + P.to_json(Answer); + ReturnObject(Answer); + } - void RESTAPI_preferences::DoPut() { + void RESTAPI_preferences::DoPut() { - SecurityObjects::Preferences P; + SecurityObjects::Preferences P; - const auto & RawObject = ParsedBody_; - if(!P.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + const auto &RawObject = ParsedBody_; + if (!P.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - P.id = UserInfo_.userinfo.id; - P.modified = OpenWifi::Now(); - StorageService()->PreferencesDB().SetPreferences(P); + P.id = UserInfo_.userinfo.id; + P.modified = OpenWifi::Now(); + StorageService()->PreferencesDB().SetPreferences(P); - Poco::JSON::Object Answer; - P.to_json(Answer); - ReturnObject(Answer); - } + Poco::JSON::Object Answer; + P.to_json(Answer); + ReturnObject(Answer); + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_preferences.h b/src/RESTAPI/RESTAPI_preferences.h index c336fcf..968363e 100644 --- a/src/RESTAPI/RESTAPI_preferences.h +++ b/src/RESTAPI/RESTAPI_preferences.h @@ -7,21 +7,20 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_preferences : public RESTAPIHandler { - public: - RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/preferences"}; }; - void DoGet() final; - void DoPut() final; - void DoPost() final {}; - void DoDelete() final {}; - }; -} + class RESTAPI_preferences : public RESTAPIHandler { + public: + RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/preferences"}; }; + void DoGet() final; + void DoPut() final; + void DoPost() final{}; + void DoDelete() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_routers.cpp b/src/RESTAPI/RESTAPI_routers.cpp index dd2f956..2c6ac16 100644 --- a/src/RESTAPI/RESTAPI_routers.cpp +++ b/src/RESTAPI/RESTAPI_routers.cpp @@ -2,97 +2,65 @@ // Created by stephane bourque on 2021-10-23. // -#include "RESTAPI/RESTAPI_oauth2_handler.h" -#include "RESTAPI/RESTAPI_user_handler.h" -#include "RESTAPI/RESTAPI_users_handler.h" #include "RESTAPI/RESTAPI_action_links.h" -#include "RESTAPI/RESTAPI_system_endpoints_handler.h" +#include "RESTAPI/RESTAPI_apiKey_handler.h" #include "RESTAPI/RESTAPI_asset_server.h" #include "RESTAPI/RESTAPI_avatar_handler.h" -#include "RESTAPI/RESTAPI_subavatar_handler.h" #include "RESTAPI/RESTAPI_email_handler.h" -#include "RESTAPI/RESTAPI_sms_handler.h" -#include "RESTAPI/RESTAPI_validate_token_handler.h" +#include "RESTAPI/RESTAPI_oauth2_handler.h" #include "RESTAPI/RESTAPI_preferences.h" -#include "RESTAPI/RESTAPI_subpreferences.h" +#include "RESTAPI/RESTAPI_signup_handler.h" +#include "RESTAPI/RESTAPI_sms_handler.h" +#include "RESTAPI/RESTAPI_subavatar_handler.h" +#include "RESTAPI/RESTAPI_submfa_handler.h" #include "RESTAPI/RESTAPI_suboauth2_handler.h" +#include "RESTAPI/RESTAPI_subpreferences.h" +#include "RESTAPI/RESTAPI_subtotp_handler.h" #include "RESTAPI/RESTAPI_subuser_handler.h" #include "RESTAPI/RESTAPI_subusers_handler.h" -#include "RESTAPI/RESTAPI_validate_sub_token_handler.h" -#include "RESTAPI/RESTAPI_submfa_handler.h" +#include "RESTAPI/RESTAPI_system_endpoints_handler.h" #include "RESTAPI/RESTAPI_totp_handler.h" -#include "RESTAPI/RESTAPI_subtotp_handler.h" -#include "RESTAPI/RESTAPI_signup_handler.h" -#include "RESTAPI/RESTAPI_apiKey_handler.h" +#include "RESTAPI/RESTAPI_user_handler.h" +#include "RESTAPI/RESTAPI_users_handler.h" #include "RESTAPI/RESTAPI_validate_apikey.h" +#include "RESTAPI/RESTAPI_validate_sub_token_handler.h" +#include "RESTAPI/RESTAPI_validate_token_handler.h" +#include "RESTAPI_systemSecret_handler.h" #include "framework/RESTAPI_SystemCommand.h" #include "framework/RESTAPI_WebSocketServer.h" -#include "RESTAPI_systemSecret_handler.h" namespace OpenWifi { - Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & L, RESTAPI_GenericServerAccounting & S, - uint64_t TransactionId) { - return RESTAPI_Router< - RESTAPI_oauth2_handler, - RESTAPI_user_handler, - RESTAPI_users_handler, - RESTAPI_system_command, - RESTAPI_asset_server, - RESTAPI_system_endpoints_handler, - RESTAPI_action_links, - RESTAPI_avatar_handler, - RESTAPI_subavatar_handler, - RESTAPI_email_handler, - RESTAPI_sms_handler, - RESTAPI_preferences, - RESTAPI_subpreferences, - RESTAPI_suboauth2_handler, - RESTAPI_subuser_handler, - RESTAPI_subusers_handler, - RESTAPI_submfa_handler, - RESTAPI_totp_handler, - RESTAPI_subtotp_handler, - RESTAPI_signup_handler, - RESTAPI_validate_sub_token_handler, - RESTAPI_validate_token_handler, - RESTAPI_validate_apikey, - RESTAPI_webSocketServer, - RESTAPI_apiKey_handler, - RESTAPI_systemSecret_handler - >(Path, Bindings, L, S,TransactionId); - } + Poco::Net::HTTPRequestHandler * + RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t TransactionId) { + return RESTAPI_Router< + RESTAPI_oauth2_handler, RESTAPI_user_handler, RESTAPI_users_handler, + RESTAPI_system_command, RESTAPI_asset_server, RESTAPI_system_endpoints_handler, + RESTAPI_action_links, RESTAPI_avatar_handler, RESTAPI_subavatar_handler, + RESTAPI_email_handler, RESTAPI_sms_handler, RESTAPI_preferences, RESTAPI_subpreferences, + RESTAPI_suboauth2_handler, RESTAPI_subuser_handler, RESTAPI_subusers_handler, + RESTAPI_submfa_handler, RESTAPI_totp_handler, RESTAPI_subtotp_handler, + RESTAPI_signup_handler, RESTAPI_validate_sub_token_handler, + RESTAPI_validate_token_handler, RESTAPI_validate_apikey, RESTAPI_webSocketServer, + RESTAPI_apiKey_handler, RESTAPI_systemSecret_handler>(Path, Bindings, L, S, + TransactionId); + } - Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) { + Poco::Net::HTTPRequestHandler * + RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t TransactionId) { - return RESTAPI_Router_I< - RESTAPI_oauth2_handler, - RESTAPI_user_handler, - RESTAPI_users_handler, - RESTAPI_system_command, - RESTAPI_asset_server, - RESTAPI_system_endpoints_handler, - RESTAPI_action_links, - RESTAPI_avatar_handler, - RESTAPI_subavatar_handler, - RESTAPI_email_handler, - RESTAPI_sms_handler, - RESTAPI_preferences, - RESTAPI_subpreferences, - RESTAPI_suboauth2_handler, - RESTAPI_subuser_handler, - RESTAPI_subusers_handler, - RESTAPI_submfa_handler, - RESTAPI_totp_handler, - RESTAPI_subtotp_handler, - RESTAPI_validate_sub_token_handler, - RESTAPI_validate_token_handler, - RESTAPI_validate_apikey, - RESTAPI_signup_handler, - RESTAPI_systemSecret_handler - >(Path, Bindings, L, S, TransactionId); - } -} \ No newline at end of file + return RESTAPI_Router_I< + RESTAPI_oauth2_handler, RESTAPI_user_handler, RESTAPI_users_handler, + RESTAPI_system_command, RESTAPI_asset_server, RESTAPI_system_endpoints_handler, + RESTAPI_action_links, RESTAPI_avatar_handler, RESTAPI_subavatar_handler, + RESTAPI_email_handler, RESTAPI_sms_handler, RESTAPI_preferences, RESTAPI_subpreferences, + RESTAPI_suboauth2_handler, RESTAPI_subuser_handler, RESTAPI_subusers_handler, + RESTAPI_submfa_handler, RESTAPI_totp_handler, RESTAPI_subtotp_handler, + RESTAPI_validate_sub_token_handler, RESTAPI_validate_token_handler, + RESTAPI_validate_apikey, RESTAPI_signup_handler, RESTAPI_systemSecret_handler>( + Path, Bindings, L, S, TransactionId); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_signup_handler.cpp b/src/RESTAPI/RESTAPI_signup_handler.cpp index a460450..d650768 100644 --- a/src/RESTAPI/RESTAPI_signup_handler.cpp +++ b/src/RESTAPI/RESTAPI_signup_handler.cpp @@ -3,73 +3,74 @@ // #include "RESTAPI_signup_handler.h" -#include "StorageService.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "StorageService.h" #include "framework/MicroServiceFuncs.h" #define __DBG__ std::cout << __LINE__ << std::endl; namespace OpenWifi { - void RESTAPI_signup_handler::DoPost() { - auto UserName = GetParameter("email"); - auto signupUUID = GetParameter("signupUUID"); - auto owner = GetParameter("owner"); - auto operatorName = GetParameter("operatorName"); - if(UserName.empty() || signupUUID.empty() || owner.empty() || operatorName.empty()) { - Logger().error("Signup requires: email, signupUUID, operatorName, and owner."); - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + void RESTAPI_signup_handler::DoPost() { + auto UserName = GetParameter("email"); + auto signupUUID = GetParameter("signupUUID"); + auto owner = GetParameter("owner"); + auto operatorName = GetParameter("operatorName"); + if (UserName.empty() || signupUUID.empty() || owner.empty() || operatorName.empty()) { + Logger().error("Signup requires: email, signupUUID, operatorName, and owner."); + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - if(!Utils::ValidEMailAddress(UserName)) { - return BadRequest(RESTAPI::Errors::InvalidEmailAddress); - } + if (!Utils::ValidEMailAddress(UserName)) { + return BadRequest(RESTAPI::Errors::InvalidEmailAddress); + } - // Do we already exist? Can only signup once... - SecurityObjects::UserInfo Existing; - if(StorageService()->SubDB().GetUserByEmail(UserName,Existing)) { - if(Existing.signingUp.empty()) { - return BadRequest(RESTAPI::Errors::SignupAlreadySigned); - } + // Do we already exist? Can only signup once... + SecurityObjects::UserInfo Existing; + if (StorageService()->SubDB().GetUserByEmail(UserName, Existing)) { + if (Existing.signingUp.empty()) { + return BadRequest(RESTAPI::Errors::SignupAlreadySigned); + } - if(Existing.waitingForEmailCheck) { - return BadRequest(RESTAPI::Errors::SignupEmailCheck); - } + if (Existing.waitingForEmailCheck) { + return BadRequest(RESTAPI::Errors::SignupEmailCheck); + } - return BadRequest(RESTAPI::Errors::SignupWaitingForDevice); - } + return BadRequest(RESTAPI::Errors::SignupWaitingForDevice); + } - SecurityObjects::UserInfo NewSub; - NewSub.signingUp = operatorName + ":" + signupUUID; - NewSub.waitingForEmailCheck = true; - NewSub.name = UserName; - NewSub.modified = OpenWifi::Now(); - NewSub.creationDate = OpenWifi::Now(); - NewSub.id = MicroServiceCreateUUID(); - NewSub.email = UserName; - NewSub.userRole = SecurityObjects::SUBSCRIBER; - NewSub.changePassword = true; - NewSub.owner = owner; + SecurityObjects::UserInfo NewSub; + NewSub.signingUp = operatorName + ":" + signupUUID; + NewSub.waitingForEmailCheck = true; + NewSub.name = UserName; + NewSub.modified = OpenWifi::Now(); + NewSub.creationDate = OpenWifi::Now(); + NewSub.id = MicroServiceCreateUUID(); + NewSub.email = UserName; + NewSub.userRole = SecurityObjects::SUBSCRIBER; + NewSub.changePassword = true; + NewSub.owner = owner; - StorageService()->SubDB().CreateRecord(NewSub); + StorageService()->SubDB().CreateRecord(NewSub); - Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", Request->clientAddress().toString(), UserName)); - SecurityObjects::ActionLink NewLink; + Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", + Request->clientAddress().toString(), UserName)); + SecurityObjects::ActionLink NewLink; - NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; - NewLink.id = MicroServiceCreateUUID(); - NewLink.userId = NewSub.id; - NewLink.created = OpenWifi::Now(); - NewLink.expires = NewLink.created + (1*60*60); // 1 hour - NewLink.userAction = false; - StorageService()->ActionLinksDB().CreateAction(NewLink); + NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; + NewLink.id = MicroServiceCreateUUID(); + NewLink.userId = NewSub.id; + NewLink.created = OpenWifi::Now(); + NewLink.expires = NewLink.created + (1 * 60 * 60); // 1 hour + NewLink.userAction = false; + StorageService()->ActionLinksDB().CreateAction(NewLink); - Poco::JSON::Object Answer; - NewSub.to_json(Answer); - return ReturnObject(Answer); - } + Poco::JSON::Object Answer; + NewSub.to_json(Answer); + return ReturnObject(Answer); + } - void RESTAPI_signup_handler::DoPut() { - // TODO - } + void RESTAPI_signup_handler::DoPut() { + // TODO + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_signup_handler.h b/src/RESTAPI/RESTAPI_signup_handler.h index b163cf0..723901a 100644 --- a/src/RESTAPI/RESTAPI_signup_handler.h +++ b/src/RESTAPI/RESTAPI_signup_handler.h @@ -7,33 +7,32 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_signup_handler : public RESTAPIHandler { - public: - RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_OPTIONS, - Poco::Net::HTTPRequest::HTTP_PUT}, - Server, - TransactionId, - Internal, false, true ){} + class RESTAPI_signup_handler : public RESTAPIHandler { + public: + RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS, + Poco::Net::HTTPRequest::HTTP_PUT}, + Server, TransactionId, Internal, false, true) {} - static auto PathName() { return std::list{"/api/v1/signup"}; }; + static auto PathName() { return std::list{"/api/v1/signup"}; }; -/* inline bool RoleIsAuthorized(std::string & Reason) { - if(UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::SUBSCRIBER) { - Reason = "User must be a subscriber"; - return false; - } - return true; - } -*/ - void DoGet() final {}; - void DoPost() final; - void DoPut() final ; - void DoDelete() final {}; - private: + /* inline bool RoleIsAuthorized(std::string & Reason) { + if(UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::SUBSCRIBER) { + Reason = "User must be a subscriber"; + return false; + } + return true; + } + */ + void DoGet() final{}; + void DoPost() final; + void DoPut() final; + void DoDelete() final{}; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_sms_handler.cpp b/src/RESTAPI/RESTAPI_sms_handler.cpp index dd1f2ec..e4a41f9 100644 --- a/src/RESTAPI/RESTAPI_sms_handler.cpp +++ b/src/RESTAPI/RESTAPI_sms_handler.cpp @@ -8,51 +8,48 @@ namespace OpenWifi { - void OpenWifi::RESTAPI_sms_handler::DoPost() { - const auto &Obj = ParsedBody_; + void OpenWifi::RESTAPI_sms_handler::DoPost() { + const auto &Obj = ParsedBody_; - if(!SMSSender()->Enabled()) { - return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); - } + if (!SMSSender()->Enabled()) { + return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); + } - std::string Arg; - if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) { - auto Number = Obj->get("to").toString(); - if(SMSSender()->StartValidation(Number, UserInfo_.userinfo.email)) { - return OK(); - } - return BadRequest(RESTAPI::Errors::SMSCouldNotBeSentRetry); - } + std::string Arg; + if (HasParameter("validateNumber", Arg) && Arg == "true" && Obj->has("to")) { + auto Number = Obj->get("to").toString(); + if (SMSSender()->StartValidation(Number, UserInfo_.userinfo.email)) { + return OK(); + } + return BadRequest(RESTAPI::Errors::SMSCouldNotBeSentRetry); + } - std::string Code; - if( HasParameter("completeValidation",Arg) && - Arg=="true" && - HasParameter("validationCode", Code) && - Obj->has("to")) { - auto Number = Obj->get("to").toString(); - if(SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) { - return OK(); - } - return BadRequest(RESTAPI::Errors::SMSCouldNotValidate); - } + std::string Code; + if (HasParameter("completeValidation", Arg) && Arg == "true" && + HasParameter("validationCode", Code) && Obj->has("to")) { + auto Number = Obj->get("to").toString(); + if (SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) { + return OK(); + } + return BadRequest(RESTAPI::Errors::SMSCouldNotValidate); + } - if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && - UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER && - UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && + UserInfo_.userinfo.userRole != SecurityObjects::PARTNER && + UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if (Obj->has("to") && - Obj->has("text")) { + if (Obj->has("to") && Obj->has("text")) { - std::string PhoneNumber = Obj->get("to").toString(); - std::string Text = Obj->get("text").toString(); - if(SMSSender()->Send(PhoneNumber, Text)) - return OK(); + std::string PhoneNumber = Obj->get("to").toString(); + std::string Text = Obj->get("text").toString(); + if (SMSSender()->Send(PhoneNumber, Text)) + return OK(); - return InternalError(RESTAPI::Errors::SMSCouldNotBeSentRetry); - } - BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + return InternalError(RESTAPI::Errors::SMSCouldNotBeSentRetry); + } + BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_sms_handler.h b/src/RESTAPI/RESTAPI_sms_handler.h index b24fd76..2c5df89 100644 --- a/src/RESTAPI/RESTAPI_sms_handler.h +++ b/src/RESTAPI/RESTAPI_sms_handler.h @@ -7,19 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_sms_handler : public RESTAPIHandler { - public: - RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/sms"};} - void DoGet() final {}; - void DoPost() final; - void DoDelete() final {}; - void DoPut() final {}; - }; -} + class RESTAPI_sms_handler : public RESTAPIHandler { + public: + RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/sms"}; } + void DoGet() final{}; + void DoPost() final; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subavatar_handler.cpp b/src/RESTAPI/RESTAPI_subavatar_handler.cpp index e9002ac..a2b889f 100644 --- a/src/RESTAPI/RESTAPI_subavatar_handler.cpp +++ b/src/RESTAPI/RESTAPI_subavatar_handler.cpp @@ -5,78 +5,84 @@ #include #include +#include "Poco/CountingStream.h" +#include "Poco/Net/HTMLForm.h" #include "RESTAPI_subavatar_handler.h" #include "StorageService.h" -#include "Poco/Net/HTMLForm.h" -#include "Poco/CountingStream.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - void SubAvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) { - FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); - if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { - std::string Disposition; - Poco::Net::NameValueCollection Parameters; - Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters); - Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); - } - Poco::CountingInputStream InputStream(Stream); - Poco::StreamCopier::copyStream(InputStream, OutputStream_); - Length_ = OutputStream_.str().size(); - }; + void SubAvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, + std::istream &Stream) { + FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); + if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { + std::string Disposition; + Poco::Net::NameValueCollection Parameters; + Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], + Disposition, Parameters); + Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); + } + Poco::CountingInputStream InputStream(Stream); + Poco::StreamCopier::copyStream(InputStream, OutputStream_); + Length_ = OutputStream_.str().size(); + }; - void RESTAPI_subavatar_handler::DoPost() { - std::string Id = UserInfo_.userinfo.id; - SecurityObjects::UserInfo UInfo; + void RESTAPI_subavatar_handler::DoPost() { + std::string Id = UserInfo_.userinfo.id; + SecurityObjects::UserInfo UInfo; - std::stringstream SS; - SubAvatarPartHandler partHandler(Id, Logger_, SS); - Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); - Poco::JSON::Object Answer; + std::stringstream SS; + SubAvatarPartHandler partHandler(Id, Logger_, SS); + Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); + Poco::JSON::Object Answer; - if (!partHandler.Name().empty() && partHandler.Length()< MicroServiceConfigGetInt("openwifi.avatar.maxsize",2000000)) { - Answer.set(RESTAPI::Protocol::AVATARID, Id); - Answer.set(RESTAPI::Protocol::ERRORCODE, 0); - Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); - StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email, - Id, SS.str(), partHandler.ContentType(), partHandler.Name()); - StorageService()->SubDB().SetAvatar(Id,"1"); - Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); - } else { - Answer.set(RESTAPI::Protocol::AVATARID, Id); - Answer.set(RESTAPI::Protocol::ERRORCODE, 13); - Answer.set(RESTAPI::Protocol::ERRORTEXT, "Avatar upload could not complete."); - } - ReturnObject(Answer); - } + if (!partHandler.Name().empty() && + partHandler.Length() < MicroServiceConfigGetInt("openwifi.avatar.maxsize", 2000000)) { + Answer.set(RESTAPI::Protocol::AVATARID, Id); + Answer.set(RESTAPI::Protocol::ERRORCODE, 0); + Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), + partHandler.ContentType())); + StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email, Id, SS.str(), + partHandler.ContentType(), + partHandler.Name()); + StorageService()->SubDB().SetAvatar(Id, "1"); + Logger().information(fmt::format("Adding avatar for {}", UserInfo_.userinfo.email)); + } else { + Answer.set(RESTAPI::Protocol::AVATARID, Id); + Answer.set(RESTAPI::Protocol::ERRORCODE, 13); + Answer.set(RESTAPI::Protocol::ERRORTEXT, "Avatar upload could not complete."); + } + ReturnObject(Answer); + } - void RESTAPI_subavatar_handler::DoGet() { - std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); - if (Id.empty()) { - return NotFound(); - } + void RESTAPI_subavatar_handler::DoGet() { + std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); + if (Id.empty()) { + return NotFound(); + } - std::string Type, Name, AvatarContent; - if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) { - return NotFound(); - } - Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email)); - return SendFileContent(AvatarContent, Type, Name); - } + std::string Type, Name, AvatarContent; + if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, + Type, Name)) { + return NotFound(); + } + Logger().information(fmt::format("Retrieving avatar for {}", UserInfo_.userinfo.email)); + return SendFileContent(AvatarContent, Type, Name); + } - void RESTAPI_subavatar_handler::DoDelete() { - std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); + void RESTAPI_subavatar_handler::DoDelete() { + std::string Id = GetBinding(RESTAPI::Protocol::ID, ""); - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && Id != UserInfo_.userinfo.id) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) { - return NotFound(); - } - Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email)); - StorageService()->SubDB().SetAvatar(Id,""); - OK(); - } -} + if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) { + return NotFound(); + } + Logger().information(fmt::format("Deleted avatar for {}", UserInfo_.userinfo.email)); + StorageService()->SubDB().SetAvatar(Id, ""); + OK(); + } +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subavatar_handler.h b/src/RESTAPI/RESTAPI_subavatar_handler.h index 9b7697b..d619a4a 100644 --- a/src/RESTAPI/RESTAPI_subavatar_handler.h +++ b/src/RESTAPI/RESTAPI_subavatar_handler.h @@ -3,52 +3,47 @@ // #pragma once -#include "framework/RESTAPI_Handler.h" #include "Poco/Net/PartHandler.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class SubAvatarPartHandler : public Poco::Net::PartHandler { - public: - SubAvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) : - Id_(std::move(Id)), - Logger_(Logger), - OutputStream_(ofs){ - } - void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); - [[nodiscard]] uint64_t Length() const { return Length_; } - [[nodiscard]] std::string &Name() { return Name_; } - [[nodiscard]] std::string &ContentType() { return FileType_; } + class SubAvatarPartHandler : public Poco::Net::PartHandler { + public: + SubAvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream &ofs) + : Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {} + void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); + [[nodiscard]] uint64_t Length() const { return Length_; } + [[nodiscard]] std::string &Name() { return Name_; } + [[nodiscard]] std::string &ContentType() { return FileType_; } - private: - uint64_t Length_ = 0; - std::string FileType_; - std::string Name_; - std::string Id_; - Poco::Logger &Logger_; - std::stringstream &OutputStream_; + private: + uint64_t Length_ = 0; + std::string FileType_; + std::string Name_; + std::string Id_; + Poco::Logger &Logger_; + std::stringstream &OutputStream_; - inline Poco::Logger & Logger() { return Logger_; } - }; + inline Poco::Logger &Logger() { return Logger_; } + }; - class RESTAPI_subavatar_handler : public RESTAPIHandler { - public: - RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/subavatar/{id}"}; }; + class RESTAPI_subavatar_handler : public RESTAPIHandler { + public: + RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/subavatar/{id}"}; }; - void DoGet() final; - void DoPost() final; - void DoDelete() final; - void DoPut() final {}; - - }; -} + void DoGet() final; + void DoPost() final; + void DoDelete() final; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_submfa_handler.cpp b/src/RESTAPI/RESTAPI_submfa_handler.cpp index 0ecd31e..9e38c9a 100644 --- a/src/RESTAPI/RESTAPI_submfa_handler.cpp +++ b/src/RESTAPI/RESTAPI_submfa_handler.cpp @@ -3,136 +3,140 @@ // #include "RESTAPI_submfa_handler.h" -#include "StorageService.h" #include "SMSSender.h" +#include "StorageService.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - void RESTAPI_submfa_handler::DoGet() { - SecurityObjects::UserInfo User; + void RESTAPI_submfa_handler::DoGet() { + SecurityObjects::UserInfo User; - if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) { - Poco::JSON::Object Answer; - SecurityObjects::SubMfaConfig MFC; + if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User)) { + Poco::JSON::Object Answer; + SecurityObjects::SubMfaConfig MFC; - MFC.id = User.id; - if(User.userTypeProprietaryInfo.mfa.enabled) { - if(User.userTypeProprietaryInfo.mfa.method == "sms") { - MFC.sms = User.userTypeProprietaryInfo.mobiles[0].number; - MFC.type = "sms"; - } else if(User.userTypeProprietaryInfo.mfa.method == "email") { - MFC.email = User.email; - MFC.type = "email"; - } - } else { - MFC.type = "disabled"; - } - MFC.to_json(Answer); - return ReturnObject(Answer); - } - NotFound(); - } + MFC.id = User.id; + if (User.userTypeProprietaryInfo.mfa.enabled) { + if (User.userTypeProprietaryInfo.mfa.method == "sms") { + MFC.sms = User.userTypeProprietaryInfo.mobiles[0].number; + MFC.type = "sms"; + } else if (User.userTypeProprietaryInfo.mfa.method == "email") { + MFC.email = User.email; + MFC.type = "email"; + } + } else { + MFC.type = "disabled"; + } + MFC.to_json(Answer); + return ReturnObject(Answer); + } + NotFound(); + } - void RESTAPI_submfa_handler::DoPut() { + void RESTAPI_submfa_handler::DoPut() { - try { - const auto & Body = ParsedBody_; + try { + const auto &Body = ParsedBody_; - SecurityObjects::SubMfaConfig MFC; + SecurityObjects::SubMfaConfig MFC; - if (!MFC.from_json(Body)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + if (!MFC.from_json(Body)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - if (MFC.type == "disabled") { - SecurityObjects::UserInfo User; - StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); - User.userTypeProprietaryInfo.mfa.enabled = false; - StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); + if (MFC.type == "disabled") { + SecurityObjects::UserInfo User; + StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); + User.userTypeProprietaryInfo.mfa.enabled = false; + StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, + UserInfo_.userinfo.id, User); - Poco::JSON::Object Answer; - MFC.to_json(Answer); - return ReturnObject(Answer); - } else if (MFC.type == "email") { - SecurityObjects::UserInfo User; + Poco::JSON::Object Answer; + MFC.to_json(Answer); + return ReturnObject(Answer); + } else if (MFC.type == "email") { + SecurityObjects::UserInfo User; - StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); - User.userTypeProprietaryInfo.mfa.enabled = true; - User.userTypeProprietaryInfo.mfa.method = "email"; - StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); + StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); + User.userTypeProprietaryInfo.mfa.enabled = true; + User.userTypeProprietaryInfo.mfa.method = "email"; + StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, + UserInfo_.userinfo.id, User); - MFC.sms = MFC.sms; - MFC.type = "email"; - MFC.email = UserInfo_.userinfo.email; - MFC.id = MicroServiceCreateUUID(); + MFC.sms = MFC.sms; + MFC.type = "email"; + MFC.email = UserInfo_.userinfo.email; + MFC.id = MicroServiceCreateUUID(); - Poco::JSON::Object Answer; - MFC.to_json(Answer); - return ReturnObject(Answer); + Poco::JSON::Object Answer; + MFC.to_json(Answer); + return ReturnObject(Answer); - } else if (MFC.type == "sms") { - if (GetBoolParameter("startValidation", false)) { - if (MFC.sms.empty()) { - return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); - } + } else if (MFC.type == "sms") { + if (GetBoolParameter("startValidation", false)) { + if (MFC.sms.empty()) { + return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); + } - if(!SMSSender()->Enabled()) { - return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); - } + if (!SMSSender()->Enabled()) { + return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); + } - if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) { - return OK(); - } else { - return InternalError(RESTAPI::Errors::SMSTryLater); - } - } else if (GetBoolParameter("completeValidation", false)) { + if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) { + return OK(); + } else { + return InternalError(RESTAPI::Errors::SMSTryLater); + } + } else if (GetBoolParameter("completeValidation", false)) { - if(!SMSSender()->Enabled()) { - return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); - } + if (!SMSSender()->Enabled()) { + return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); + } - auto ChallengeCode = GetParameter("challengeCode", ""); - if (ChallengeCode.empty()) { - return BadRequest(RESTAPI::Errors::SMSMissingChallenge); - } - if (MFC.sms.empty()) { - return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); - } - if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) { - SecurityObjects::UserInfo User; + auto ChallengeCode = GetParameter("challengeCode", ""); + if (ChallengeCode.empty()) { + return BadRequest(RESTAPI::Errors::SMSMissingChallenge); + } + if (MFC.sms.empty()) { + return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); + } + if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, + UserInfo_.userinfo.email)) { + SecurityObjects::UserInfo User; - StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); - User.userTypeProprietaryInfo.mfa.enabled = true; - User.userTypeProprietaryInfo.mfa.method = "sms"; - SecurityObjects::MobilePhoneNumber PhoneNumber; - PhoneNumber.number = MFC.sms; - PhoneNumber.primary = true; - PhoneNumber.verified = true; - User.userTypeProprietaryInfo.mobiles.clear(); - User.userTypeProprietaryInfo.mobiles.push_back(PhoneNumber); + StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); + User.userTypeProprietaryInfo.mfa.enabled = true; + User.userTypeProprietaryInfo.mfa.method = "sms"; + SecurityObjects::MobilePhoneNumber PhoneNumber; + PhoneNumber.number = MFC.sms; + PhoneNumber.primary = true; + PhoneNumber.verified = true; + User.userTypeProprietaryInfo.mobiles.clear(); + User.userTypeProprietaryInfo.mobiles.push_back(PhoneNumber); - StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); + StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, + UserInfo_.userinfo.id, User); - MFC.sms = MFC.sms; - MFC.type = "sms"; - MFC.email = UserInfo_.userinfo.email; - MFC.id = MicroServiceCreateUUID(); + MFC.sms = MFC.sms; + MFC.type = "sms"; + MFC.email = UserInfo_.userinfo.email; + MFC.id = MicroServiceCreateUUID(); - Poco::JSON::Object Answer; - MFC.to_json(Answer); + Poco::JSON::Object Answer; + MFC.to_json(Answer); - return ReturnObject(Answer); + return ReturnObject(Answer); - } else { - return InternalError(RESTAPI::Errors::SMSTryLater); - } - } - } - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + } else { + return InternalError(RESTAPI::Errors::SMSTryLater); + } + } + } + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } -} +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_submfa_handler.h b/src/RESTAPI/RESTAPI_submfa_handler.h index 0da1eb1..54b1c15 100644 --- a/src/RESTAPI/RESTAPI_submfa_handler.h +++ b/src/RESTAPI/RESTAPI_submfa_handler.h @@ -7,21 +7,21 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_submfa_handler : public RESTAPIHandler { - public: - RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10}, - true) {} - static auto PathName() { return std::list{"/api/v1/submfa"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final ; - }; -} + class RESTAPI_submfa_handler : public RESTAPIHandler { + public: + RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal, true, false, + RateLimit{.Interval = 1000, .MaxCalls = 10}, true) {} + static auto PathName() { return std::list{"/api/v1/submfa"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_suboauth2_handler.cpp b/src/RESTAPI/RESTAPI_suboauth2_handler.cpp index a7ad358..d0311a1 100644 --- a/src/RESTAPI/RESTAPI_suboauth2_handler.cpp +++ b/src/RESTAPI/RESTAPI_suboauth2_handler.cpp @@ -5,161 +5,167 @@ #include "RESTAPI_suboauth2_handler.h" #include "AuthService.h" #include "MFAServer.h" -#include "StorageService.h" #include "RESTAPI/RESTAPI_db_helpers.h" +#include "StorageService.h" namespace OpenWifi { - void RESTAPI_suboauth2_handler::DoGet() { - bool Expired = false, Contacted = false; - if (!IsAuthorized(Expired, Contacted, true)) { - if(Expired) - return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN); - return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); - } - bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); - if(GetMe) { - Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(), - UserInfo_.userinfo.email)); - Poco::JSON::Object Me; - SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; - Sanitize(UserInfo_, ReturnedUser); - ReturnedUser.to_json(Me); - return ReturnObject(Me); - } - BadRequest(RESTAPI::Errors::UnrecognizedRequest); - } + void RESTAPI_suboauth2_handler::DoGet() { + bool Expired = false, Contacted = false; + if (!IsAuthorized(Expired, Contacted, true)) { + if (Expired) + return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN); + return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); + } + bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); + if (GetMe) { + Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", + Request->clientAddress().toString(), + UserInfo_.userinfo.email)); + Poco::JSON::Object Me; + SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; + Sanitize(UserInfo_, ReturnedUser); + ReturnedUser.to_json(Me); + return ReturnObject(Me); + } + BadRequest(RESTAPI::Errors::UnrecognizedRequest); + } - void RESTAPI_suboauth2_handler::DoDelete() { - auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); - std::string SessionToken; - try { - Poco::Net::OAuth20Credentials Auth(*Request); - if (Auth.getScheme() == "Bearer") { - SessionToken = Auth.getBearerToken(); - } - } catch (const Poco::Exception &E) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - if (Token.empty() || (Token != SessionToken)) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } - AuthService()->SubLogout(Token); - return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); - } + void RESTAPI_suboauth2_handler::DoDelete() { + auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); + std::string SessionToken; + try { + Poco::Net::OAuth20Credentials Auth(*Request); + if (Auth.getScheme() == "Bearer") { + SessionToken = Auth.getBearerToken(); + } + } catch (const Poco::Exception &E) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + if (Token.empty() || (Token != SessionToken)) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + AuthService()->SubLogout(Token); + return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); + } - void RESTAPI_suboauth2_handler::DoPost() { - const auto & Obj = ParsedBody_; - auto userId = GetS(RESTAPI::Protocol::USERID, Obj); - auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj); - auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj); - auto refreshToken = GetS("refreshToken", Obj); - auto grant_type = GetParameter("grant_type"); + void RESTAPI_suboauth2_handler::DoPost() { + const auto &Obj = ParsedBody_; + auto userId = GetS(RESTAPI::Protocol::USERID, Obj); + auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj); + auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj); + auto refreshToken = GetS("refreshToken", Obj); + auto grant_type = GetParameter("grant_type"); - Poco::toLowerInPlace(userId); + Poco::toLowerInPlace(userId); - if(!refreshToken.empty() && grant_type == "refresh_token") { - SecurityObjects::UserInfoAndPolicy UInfo; - if(AuthService()->RefreshSubToken(*Request, refreshToken, UInfo)) { - Poco::JSON::Object Answer; - UInfo.webtoken.to_json(Answer); - return ReturnObject(Answer); - } else { - return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN); - } - } + if (!refreshToken.empty() && grant_type == "refresh_token") { + SecurityObjects::UserInfoAndPolicy UInfo; + if (AuthService()->RefreshSubToken(*Request, refreshToken, UInfo)) { + Poco::JSON::Object Answer; + UInfo.webtoken.to_json(Answer); + return ReturnObject(Answer); + } else { + return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN); + } + } - if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { - Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); - Poco::JSON::Object Answer; - Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression()); - Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy()); - Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetSubPasswordPolicy()); - return ReturnObject(Answer); - } + if (GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { + Logger_.information( + fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); + Poco::JSON::Object Answer; + Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, + AuthService()->SubPasswordValidationExpression()); + Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy()); + Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetSubPasswordPolicy()); + return ReturnObject(Answer); + } - if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { - SecurityObjects::UserInfo UInfo1; - auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1); - if(UserExists) { - Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); - SecurityObjects::ActionLink NewLink; + if (GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { + SecurityObjects::UserInfo UInfo1; + auto UserExists = StorageService()->SubDB().GetUserByEmail(userId, UInfo1); + if (UserExists) { + Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", + Request->clientAddress().toString(), userId)); + SecurityObjects::ActionLink NewLink; - NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; - NewLink.id = MicroServiceCreateUUID(); - NewLink.userId = UInfo1.id; - NewLink.created = OpenWifi::Now(); - NewLink.expires = NewLink.created + (24*60*60); - NewLink.userAction = false; - StorageService()->ActionLinksDB().CreateAction(NewLink); + NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; + NewLink.id = MicroServiceCreateUUID(); + NewLink.userId = UInfo1.id; + NewLink.created = OpenWifi::Now(); + NewLink.expires = NewLink.created + (24 * 60 * 60); + NewLink.userAction = false; + StorageService()->ActionLinksDB().CreateAction(NewLink); - Poco::JSON::Object ReturnObj; - SecurityObjects::UserInfoAndPolicy UInfo; - UInfo.webtoken.userMustChangePassword = true; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } else { - Poco::JSON::Object ReturnObj; - SecurityObjects::UserInfoAndPolicy UInfo; - UInfo.webtoken.userMustChangePassword = true; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - } + Poco::JSON::Object ReturnObj; + SecurityObjects::UserInfoAndPolicy UInfo; + UInfo.webtoken.userMustChangePassword = true; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } else { + Poco::JSON::Object ReturnObj; + SecurityObjects::UserInfoAndPolicy UInfo; + UInfo.webtoken.userMustChangePassword = true; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + } - if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { - Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); - if(Obj->has("uuid")) { - auto uuid = Obj->get("uuid").toString(); - if(MFAServer()->ResendCode(uuid)) - return OK(); - } - return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION); - } + if (GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { + Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", + Request->clientAddress().toString(), userId)); + if (Obj->has("uuid")) { + auto uuid = Obj->get("uuid").toString(); + if (MFAServer()->ResendCode(uuid)) + return OK(); + } + return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION); + } - if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) { - Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); - if(Obj->has("uuid") && Obj->has("answer")) { - SecurityObjects::UserInfoAndPolicy UInfo; - if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { - Poco::JSON::Object ReturnObj; - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - } - return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); - } + if (GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) { + Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", + Request->clientAddress().toString(), userId)); + if (Obj->has("uuid") && Obj->has("answer")) { + SecurityObjects::UserInfoAndPolicy UInfo; + if (MFAServer()->CompleteMFAChallenge(Obj, UInfo)) { + Poco::JSON::Object ReturnObj; + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + } + return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); + } - SecurityObjects::UserInfoAndPolicy UInfo; - bool Expired=false; - auto Code=AuthService()->AuthorizeSub(userId, password, newPassword, UInfo, Expired); - switch(Code) { - case SUCCESS: - { - Poco::JSON::Object ReturnObj; - if(AuthService()->RequiresMFA(UInfo)) { - if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { - return ReturnObject(ReturnObj); - } - Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now."); - } - UInfo.webtoken.to_json(ReturnObj); - return ReturnObject(ReturnObj); - } - case INVALID_CREDENTIALS: - return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); - case PASSWORD_INVALID: - return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); - case PASSWORD_ALREADY_USED: - return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); - case USERNAME_PENDING_VERIFICATION: - return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); - case PASSWORD_CHANGE_REQUIRED: - return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); - case ACCOUNT_SUSPENDED: - return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); - default: - return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); - } - } -} \ No newline at end of file + SecurityObjects::UserInfoAndPolicy UInfo; + bool Expired = false; + auto Code = AuthService()->AuthorizeSub(userId, password, newPassword, UInfo, Expired); + switch (Code) { + case SUCCESS: { + Poco::JSON::Object ReturnObj; + if (AuthService()->RequiresMFA(UInfo)) { + if (MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { + return ReturnObject(ReturnObj); + } + Logger_.warning( + "MFA Seems to be broken. Please fix. Disabling MFA checking for now."); + } + UInfo.webtoken.to_json(ReturnObj); + return ReturnObject(ReturnObj); + } + case INVALID_CREDENTIALS: + return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); + case PASSWORD_INVALID: + return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); + case PASSWORD_ALREADY_USED: + return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); + case USERNAME_PENDING_VERIFICATION: + return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); + case PASSWORD_CHANGE_REQUIRED: + return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); + case ACCOUNT_SUSPENDED: + return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); + default: + return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_suboauth2_handler.h b/src/RESTAPI/RESTAPI_suboauth2_handler.h index 567d0d4..d87d337 100644 --- a/src/RESTAPI/RESTAPI_suboauth2_handler.h +++ b/src/RESTAPI/RESTAPI_suboauth2_handler.h @@ -6,22 +6,24 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_suboauth2_handler : public RESTAPIHandler { - public: - RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10}, - false) {} - static auto PathName() { return std::list{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; }; - void DoGet() final; - void DoPost() final; - void DoDelete() final; - void DoPut() final {}; - }; -} + class RESTAPI_suboauth2_handler : public RESTAPIHandler { + public: + RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal, false, false, + RateLimit{.Interval = 1000, .MaxCalls = 10}, false) {} + static auto PathName() { + return std::list{"/api/v1/suboauth2/{token}", "/api/v1/suboauth2"}; + }; + void DoGet() final; + void DoPost() final; + void DoDelete() final; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subpreferences.cpp b/src/RESTAPI/RESTAPI_subpreferences.cpp index 8a5b0f4..9629b96 100644 --- a/src/RESTAPI/RESTAPI_subpreferences.cpp +++ b/src/RESTAPI/RESTAPI_subpreferences.cpp @@ -7,30 +7,30 @@ namespace OpenWifi { - void RESTAPI_subpreferences::DoGet() { - SecurityObjects::Preferences P; - Poco::JSON::Object Answer; - StorageService()->SubPreferencesDB().GetPreferences(UserInfo_.userinfo.id, P); - P.to_json(Answer); - ReturnObject(Answer); - } + void RESTAPI_subpreferences::DoGet() { + SecurityObjects::Preferences P; + Poco::JSON::Object Answer; + StorageService()->SubPreferencesDB().GetPreferences(UserInfo_.userinfo.id, P); + P.to_json(Answer); + ReturnObject(Answer); + } - void RESTAPI_subpreferences::DoPut() { + void RESTAPI_subpreferences::DoPut() { - SecurityObjects::Preferences P; + SecurityObjects::Preferences P; - const auto & RawObject = ParsedBody_; - if(!P.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + const auto &RawObject = ParsedBody_; + if (!P.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - P.id = UserInfo_.userinfo.id; - P.modified = OpenWifi::Now(); - StorageService()->SubPreferencesDB().SetPreferences(P); + P.id = UserInfo_.userinfo.id; + P.modified = OpenWifi::Now(); + StorageService()->SubPreferencesDB().SetPreferences(P); - Poco::JSON::Object Answer; - P.to_json(Answer); - ReturnObject(Answer); - } + Poco::JSON::Object Answer; + P.to_json(Answer); + ReturnObject(Answer); + } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_subpreferences.h b/src/RESTAPI/RESTAPI_subpreferences.h index 0a71616..a464ff8 100644 --- a/src/RESTAPI/RESTAPI_subpreferences.h +++ b/src/RESTAPI/RESTAPI_subpreferences.h @@ -7,21 +7,20 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_subpreferences : public RESTAPIHandler { - public: - RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{ - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/subpreferences"}; }; - void DoGet() final; - void DoPut() final; - void DoPost() final {}; - void DoDelete() final {}; - }; -} + class RESTAPI_subpreferences : public RESTAPIHandler { + public: + RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/subpreferences"}; }; + void DoGet() final; + void DoPut() final; + void DoPost() final{}; + void DoDelete() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subtotp_handler.cpp b/src/RESTAPI/RESTAPI_subtotp_handler.cpp index 0772a59..60c0f0a 100644 --- a/src/RESTAPI/RESTAPI_subtotp_handler.cpp +++ b/src/RESTAPI/RESTAPI_subtotp_handler.cpp @@ -9,30 +9,31 @@ namespace OpenWifi { - void RESTAPI_subtotp_handler::DoGet() { + void RESTAPI_subtotp_handler::DoGet() { - auto Reset = GetBoolParameter("reset",false); - std::string QRCode; + auto Reset = GetBoolParameter("reset", false); + std::string QRCode; - if(TotpCache()->StartValidation(UserInfo_.userinfo,true,QRCode,Reset)) { - return SendFileContent(QRCode, "image/svg+xml","qrcode.svg"); - } - return BadRequest(RESTAPI::Errors::InvalidCommand); - } + if (TotpCache()->StartValidation(UserInfo_.userinfo, true, QRCode, Reset)) { + return SendFileContent(QRCode, "image/svg+xml", "qrcode.svg"); + } + return BadRequest(RESTAPI::Errors::InvalidCommand); + } - void RESTAPI_subtotp_handler::DoPut() { - auto Value = GetParameter("value",""); - auto nextIndex = GetParameter("index",0); - bool moreCodes=false; + void RESTAPI_subtotp_handler::DoPut() { + auto Value = GetParameter("value", ""); + auto nextIndex = GetParameter("index", 0); + bool moreCodes = false; - RESTAPI::Errors::msg Error; - if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) { - Poco::JSON::Object Answer; - Answer.set("nextIndex", nextIndex); - Answer.set("moreCodes", moreCodes); - return ReturnObject(Answer); - } - return BadRequest(Error); - } + RESTAPI::Errors::msg Error; + if (TotpCache()->ContinueValidation(UserInfo_.userinfo, true, Value, nextIndex, moreCodes, + Error)) { + Poco::JSON::Object Answer; + Answer.set("nextIndex", nextIndex); + Answer.set("moreCodes", moreCodes); + return ReturnObject(Answer); + } + return BadRequest(Error); + } -} +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subtotp_handler.h b/src/RESTAPI/RESTAPI_subtotp_handler.h index cee4aaf..52a1226 100644 --- a/src/RESTAPI/RESTAPI_subtotp_handler.h +++ b/src/RESTAPI/RESTAPI_subtotp_handler.h @@ -5,25 +5,22 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_subtotp_handler : public RESTAPIHandler { - public: - RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - { - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_OPTIONS - }, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/subtotp"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final; - private: + class RESTAPI_subtotp_handler : public RESTAPIHandler { + public: + RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/subtotp"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subuser_handler.cpp b/src/RESTAPI/RESTAPI_subuser_handler.cpp index 738a8cd..b8c1b21 100644 --- a/src/RESTAPI/RESTAPI_subuser_handler.cpp +++ b/src/RESTAPI/RESTAPI_subuser_handler.cpp @@ -3,316 +3,338 @@ // #include "RESTAPI_subuser_handler.h" -#include "StorageService.h" -#include "framework/ow_constants.h" -#include "SMSSender.h" -#include "SMTPMailerService.h" #include "ACLProcessor.h" #include "AuthService.h" -#include "RESTAPI/RESTAPI_db_helpers.h" #include "MFAServer.h" +#include "RESTAPI/RESTAPI_db_helpers.h" +#include "SMSSender.h" +#include "SMTPMailerService.h" +#include "StorageService.h" #include "TotpCache.h" +#include "framework/ow_constants.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - void RESTAPI_subuser_handler::DoGet() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + void RESTAPI_subuser_handler::DoGet() { + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - Poco::toLowerInPlace(Id); - std::string Arg; - SecurityObjects::UserInfo UInfo; - if(HasParameter("byEmail",Arg) && Arg=="true") { - if(!StorageService()->SubDB().GetUserByEmail(Id,UInfo)) { - return NotFound(); - } - } else if(!StorageService()->SubDB().GetUserById(Id,UInfo)) { - return NotFound(); - } + Poco::toLowerInPlace(Id); + std::string Arg; + SecurityObjects::UserInfo UInfo; + if (HasParameter("byEmail", Arg) && Arg == "true") { + if (!StorageService()->SubDB().GetUserByEmail(Id, UInfo)) { + return NotFound(); + } + } else if (!StorageService()->SubDB().GetUserById(Id, UInfo)) { + return NotFound(); + } - Poco::JSON::Object UserInfoObject; - Sanitize(UserInfo_, UInfo); - UInfo.to_json(UserInfoObject); - ReturnObject(UserInfoObject); - } + Poco::JSON::Object UserInfoObject; + Sanitize(UserInfo_, UInfo); + UInfo.to_json(UserInfoObject); + ReturnObject(UserInfoObject); + } - void RESTAPI_subuser_handler::DoDelete() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + void RESTAPI_subuser_handler::DoDelete() { + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - SecurityObjects::UserInfo TargetUser; - if(!StorageService()->SubDB().GetUserById(Id,TargetUser)) { - return NotFound(); - } + SecurityObjects::UserInfo TargetUser; + if (!StorageService()->SubDB().GetUserById(Id, TargetUser)) { + return NotFound(); + } - if(TargetUser.userRole != SecurityObjects::SUBSCRIBER) { - return BadRequest(RESTAPI::Errors::InvalidUserRole); - } + if (TargetUser.userRole != SecurityObjects::SUBSCRIBER) { + return BadRequest(RESTAPI::Errors::InvalidUserRole); + } - if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!Internal_ && + !ACLProcessor::Can(UserInfo_.userinfo, TargetUser, ACLProcessor::DELETE)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) { - return NotFound(); - } + if (!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email, Id)) { + return NotFound(); + } - AuthService()->DeleteSubUserFromCache(Id); - StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email); - StorageService()->SubPreferencesDB().DeleteRecord("id", Id); - StorageService()->SubAvatarDB().DeleteRecord("id", Id); - Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); - OK(); - } + AuthService()->DeleteSubUserFromCache(Id); + StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email); + StorageService()->SubPreferencesDB().DeleteRecord("id", Id); + StorageService()->SubAvatarDB().DeleteRecord("id", Id); + Logger_.information( + fmt::format("User '{}' deleted by '{}'.", Id, UserInfo_.userinfo.email)); + OK(); + } - void RESTAPI_subuser_handler::DoPost() { - std::string Id = GetBinding("id", ""); - if(Id!="0") { - return BadRequest(RESTAPI::Errors::IdMustBe0); - } + void RESTAPI_subuser_handler::DoPost() { + std::string Id = GetBinding("id", ""); + if (Id != "0") { + return BadRequest(RESTAPI::Errors::IdMustBe0); + } - SecurityObjects::UserInfo NewUser; - const auto & RawObject = ParsedBody_; - if(!NewUser.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + SecurityObjects::UserInfo NewUser; + const auto &RawObject = ParsedBody_; + if (!NewUser.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { - return BadRequest(RESTAPI::Errors::InvalidUserRole); - } + if (NewUser.userRole == SecurityObjects::UNKNOWN || + NewUser.userRole != SecurityObjects::SUBSCRIBER) { + return BadRequest(RESTAPI::Errors::InvalidUserRole); + } - Poco::toLowerInPlace(NewUser.email); - SecurityObjects::UserInfo Existing; - if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) { - return BadRequest(RESTAPI::Errors::UserAlreadyExists); - } + Poco::toLowerInPlace(NewUser.email); + SecurityObjects::UserInfo Existing; + if (StorageService()->SubDB().GetUserByEmail(NewUser.email, Existing)) { + return BadRequest(RESTAPI::Errors::UserAlreadyExists); + } - if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, NewUser, ACLProcessor::CREATE)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - Poco::toLowerInPlace(NewUser.email); - if(!Utils::ValidEMailAddress(NewUser.email)) { - return BadRequest(RESTAPI::Errors::InvalidEmailAddress); - } + Poco::toLowerInPlace(NewUser.email); + if (!Utils::ValidEMailAddress(NewUser.email)) { + return BadRequest(RESTAPI::Errors::InvalidEmailAddress); + } - if(!NewUser.currentPassword.empty()) { - if(!AuthService()->ValidateSubPassword(NewUser.currentPassword)) { - return BadRequest(RESTAPI::Errors::InvalidPassword); - } - } + if (!NewUser.currentPassword.empty()) { + if (!AuthService()->ValidateSubPassword(NewUser.currentPassword)) { + return BadRequest(RESTAPI::Errors::InvalidPassword); + } + } - if(NewUser.name.empty()) - NewUser.name = NewUser.email; + if (NewUser.name.empty()) + NewUser.name = NewUser.email; - // You cannot enable MFA during user creation - NewUser.userTypeProprietaryInfo.mfa.enabled = false; - NewUser.userTypeProprietaryInfo.mfa.method = ""; - NewUser.userTypeProprietaryInfo.mobiles.clear(); - NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); + // You cannot enable MFA during user creation + NewUser.userTypeProprietaryInfo.mfa.enabled = false; + NewUser.userTypeProprietaryInfo.mfa.method = ""; + NewUser.userTypeProprietaryInfo.mobiles.clear(); + NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); - if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) { - Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email)); - return BadRequest(RESTAPI::Errors::RecordNotCreated); - } + if (!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) { + Logger_.information(fmt::format("Could not add user '{}'.", NewUser.email)); + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } - if(GetParameter("email_verification","false")=="true") { - if(AuthService::VerifySubEmail(NewUser)) - Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email)); - StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser); - } + if (GetParameter("email_verification", "false") == "true") { + if (AuthService::VerifySubEmail(NewUser)) + Logger_.information( + fmt::format("Verification e-mail requested for {}", NewUser.email)); + StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, NewUser.id, NewUser); + } - if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) { - Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email)); - return NotFound(); - } + if (!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) { + Logger_.information(fmt::format("User '{}' but not retrieved.", NewUser.email)); + return NotFound(); + } - Poco::JSON::Object UserInfoObject; - Sanitize(UserInfo_, NewUser); - NewUser.to_json(UserInfoObject); - ReturnObject(UserInfoObject); - Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email)); - } + Poco::JSON::Object UserInfoObject; + Sanitize(UserInfo_, NewUser); + NewUser.to_json(UserInfoObject); + ReturnObject(UserInfoObject); + Logger_.information(fmt::format("User '{}' has been added by '{}')", NewUser.email, + UserInfo_.userinfo.email)); + } - void RESTAPI_subuser_handler::DoPut() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + void RESTAPI_subuser_handler::DoPut() { + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - SecurityObjects::UserInfo Existing; - if(!StorageService()->SubDB().GetUserById(Id,Existing)) { - return NotFound(); - } + SecurityObjects::UserInfo Existing; + if (!StorageService()->SubDB().GetUserById(Id, Existing)) { + return NotFound(); + } - if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, Existing, ACLProcessor::MODIFY)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(GetBoolParameter("resetMFA")) { - if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || - (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) || - (UserInfo_.userinfo.id == Id)) { - Existing.userTypeProprietaryInfo.mfa.enabled = false; - Existing.userTypeProprietaryInfo.mfa.method.clear(); - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.modified = OpenWifi::Now(); - Existing.notes.push_back( SecurityObjects::NoteInfo{ - .created=OpenWifi::Now(), - .createdBy=UserInfo_.userinfo.email, - .note="MFA Reset by " + UserInfo_.userinfo.email}); - StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing); - SecurityObjects::UserInfo NewUserInfo; - StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); - Poco::JSON::Object ModifiedObject; - Sanitize(UserInfo_, NewUserInfo); - NewUserInfo.to_json(ModifiedObject); - return ReturnObject(ModifiedObject); - } else { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - } + if (GetBoolParameter("resetMFA")) { + if ((UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || + (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && + Existing.userRole != SecurityObjects::ROOT) || + (UserInfo_.userinfo.id == Id)) { + Existing.userTypeProprietaryInfo.mfa.enabled = false; + Existing.userTypeProprietaryInfo.mfa.method.clear(); + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.modified = OpenWifi::Now(); + Existing.notes.push_back( + SecurityObjects::NoteInfo{.created = OpenWifi::Now(), + .createdBy = UserInfo_.userinfo.email, + .note = "MFA Reset by " + UserInfo_.userinfo.email}); + StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, Id, Existing); + SecurityObjects::UserInfo NewUserInfo; + StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email, NewUserInfo); + Poco::JSON::Object ModifiedObject; + Sanitize(UserInfo_, NewUserInfo); + NewUserInfo.to_json(ModifiedObject); + return ReturnObject(ModifiedObject); + } else { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + } - if(GetBoolParameter("forgotPassword")) { - Existing.changePassword = true; - Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email)); + if (GetBoolParameter("forgotPassword")) { + Existing.changePassword = true; + Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", + Request->clientAddress().toString(), Existing.email)); - SecurityObjects::ActionLink NewLink; - NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; - NewLink.id = MicroServiceCreateUUID(); - NewLink.userId = Existing.id; - NewLink.created = OpenWifi::Now(); - NewLink.expires = NewLink.created + (24*60*60); - NewLink.userAction = false; - StorageService()->ActionLinksDB().CreateAction(NewLink); + SecurityObjects::ActionLink NewLink; + NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; + NewLink.id = MicroServiceCreateUUID(); + NewLink.userId = Existing.id; + NewLink.created = OpenWifi::Now(); + NewLink.expires = NewLink.created + (24 * 60 * 60); + NewLink.userAction = false; + StorageService()->ActionLinksDB().CreateAction(NewLink); - return OK(); - } + return OK(); + } - SecurityObjects::UserInfo NewUser; - const auto & RawObject = ParsedBody_; - if(!NewUser.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + SecurityObjects::UserInfo NewUser; + const auto &RawObject = ParsedBody_; + if (!NewUser.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - // some basic validations - if(RawObject->has("userRole") && - (SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN || - SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::SUBSCRIBER)) { - return BadRequest(RESTAPI::Errors::InvalidUserRole); - } + // some basic validations + if (RawObject->has("userRole") && + (SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()) == + SecurityObjects::UNKNOWN || + SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()) == + SecurityObjects::SUBSCRIBER)) { + return BadRequest(RESTAPI::Errors::InvalidUserRole); + } - // The only valid things to change are: changePassword, name, - AssignIfPresent(RawObject,"name", Existing.name); - AssignIfPresent(RawObject,"description", Existing.description); - AssignIfPresent(RawObject,"owner", Existing.owner); - AssignIfPresent(RawObject,"location", Existing.location); - AssignIfPresent(RawObject,"locale", Existing.locale); - AssignIfPresent(RawObject,"changePassword", Existing.changePassword); - AssignIfPresent(RawObject,"suspended", Existing.suspended); - AssignIfPresent(RawObject,"blackListed", Existing.blackListed); + // The only valid things to change are: changePassword, name, + AssignIfPresent(RawObject, "name", Existing.name); + AssignIfPresent(RawObject, "description", Existing.description); + AssignIfPresent(RawObject, "owner", Existing.owner); + AssignIfPresent(RawObject, "location", Existing.location); + AssignIfPresent(RawObject, "locale", Existing.locale); + AssignIfPresent(RawObject, "changePassword", Existing.changePassword); + AssignIfPresent(RawObject, "suspended", Existing.suspended); + AssignIfPresent(RawObject, "blackListed", Existing.blackListed); - if(RawObject->has("userRole")) { - auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); - if(NewRole!=Existing.userRole) { - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - if(Id==UserInfo_.userinfo.id) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - Existing.userRole = NewRole; - } - } + if (RawObject->has("userRole")) { + auto NewRole = + SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); + if (NewRole != Existing.userRole) { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && + NewRole == SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + if (Id == UserInfo_.userinfo.id) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + Existing.userRole = NewRole; + } + } - if(RawObject->has("notes")) { - SecurityObjects::NoteInfoVec NIV; - NIV = RESTAPI_utils::to_object_array(RawObject->get("notes").toString()); - for(auto const &i:NIV) { - SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; - Existing.notes.push_back(ii); - } - } - if(RawObject->has("currentPassword")) { - if(!AuthService()->ValidateSubPassword(RawObject->get("currentPassword").toString())) { - return BadRequest(RESTAPI::Errors::InvalidPassword); - } - if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),Existing)) { - return BadRequest(RESTAPI::Errors::PasswordRejected); - } - } + if (RawObject->has("notes")) { + SecurityObjects::NoteInfoVec NIV; + NIV = RESTAPI_utils::to_object_array( + RawObject->get("notes").toString()); + for (auto const &i : NIV) { + SecurityObjects::NoteInfo ii{.created = (uint64_t)OpenWifi::Now(), + .createdBy = UserInfo_.userinfo.email, + .note = i.note}; + Existing.notes.push_back(ii); + } + } + if (RawObject->has("currentPassword")) { + if (!AuthService()->ValidateSubPassword(RawObject->get("currentPassword").toString())) { + return BadRequest(RESTAPI::Errors::InvalidPassword); + } + if (!AuthService()->SetPassword(RawObject->get("currentPassword").toString(), + Existing)) { + return BadRequest(RESTAPI::Errors::PasswordRejected); + } + } - if(GetParameter("email_verification","false")=="true") { - if(AuthService::VerifySubEmail(Existing)) - Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email)); - } + if (GetParameter("email_verification", "false") == "true") { + if (AuthService::VerifySubEmail(Existing)) + Logger_.information( + fmt::format("Verification e-mail requested for {}", Existing.email)); + } - if(RawObject->has("userTypeProprietaryInfo")) { - if(NewUser.userTypeProprietaryInfo.mfa.enabled) { - if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) { - return BadRequest(RESTAPI::Errors::BadMFAMethod); - } + if (RawObject->has("userTypeProprietaryInfo")) { + if (NewUser.userTypeProprietaryInfo.mfa.enabled) { + if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) { + return BadRequest(RESTAPI::Errors::BadMFAMethod); + } - if( NewUser.userTypeProprietaryInfo.mfa.enabled && - NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && - !SMSSender()->Enabled()) { - return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); - } + if (NewUser.userTypeProprietaryInfo.mfa.enabled && + NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && + !SMSSender()->Enabled()) { + return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); + } - if( NewUser.userTypeProprietaryInfo.mfa.enabled && - NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && - !SMTPMailerService()->Enabled()) { - return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); - } + if (NewUser.userTypeProprietaryInfo.mfa.enabled && + NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && + !SMTPMailerService()->Enabled()) { + return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); + } - Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method; - Existing.userTypeProprietaryInfo.mfa.enabled = true; + Existing.userTypeProprietaryInfo.mfa.method = + NewUser.userTypeProprietaryInfo.mfa.method; + Existing.userTypeProprietaryInfo.mfa.enabled = true; - if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { - if(NewUser.userTypeProprietaryInfo.mobiles.empty()) { - return BadRequest(RESTAPI::Errors::NeedMobileNumber); - } - if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) { - return BadRequest(RESTAPI::Errors::NeedMobileNumber); - } - Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; - Existing.userTypeProprietaryInfo.mobiles[0].verified = true; - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { - std::string Secret; - Existing.userTypeProprietaryInfo.mobiles.clear(); - if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) { - Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; - } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { - // we allow someone to use their old secret - } else { - return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); - } - } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - } - } else { - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.userTypeProprietaryInfo.mfa.enabled = false; - } - } + if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { + if (NewUser.userTypeProprietaryInfo.mobiles.empty()) { + return BadRequest(RESTAPI::Errors::NeedMobileNumber); + } + if (!SMSSender()->IsNumberValid( + NewUser.userTypeProprietaryInfo.mobiles[0].number, + UserInfo_.userinfo.email)) { + return BadRequest(RESTAPI::Errors::NeedMobileNumber); + } + Existing.userTypeProprietaryInfo.mobiles = + NewUser.userTypeProprietaryInfo.mobiles; + Existing.userTypeProprietaryInfo.mobiles[0].verified = true; + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + } else if (NewUser.userTypeProprietaryInfo.mfa.method == + MFAMETHODS::AUTHENTICATOR) { + std::string Secret; + Existing.userTypeProprietaryInfo.mobiles.clear(); + if (Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && + TotpCache()->CompleteValidation(UserInfo_.userinfo, false, Secret)) { + Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; + } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { + // we allow someone to use their old secret + } else { + return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); + } + } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + } + } else { + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.userTypeProprietaryInfo.mfa.enabled = false; + } + } - if(StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) { - SecurityObjects::UserInfo NewUserInfo; - StorageService()->SubDB().GetUserById(Id,NewUserInfo); - Poco::JSON::Object ModifiedObject; - Sanitize(UserInfo_, NewUserInfo); - NewUserInfo.to_json(ModifiedObject); - return ReturnObject(ModifiedObject); - } - BadRequest(RESTAPI::Errors::RecordNotUpdated); - } -} \ No newline at end of file + if (StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, Id, Existing)) { + SecurityObjects::UserInfo NewUserInfo; + StorageService()->SubDB().GetUserById(Id, NewUserInfo); + Poco::JSON::Object ModifiedObject; + Sanitize(UserInfo_, NewUserInfo); + NewUserInfo.to_json(ModifiedObject); + return ReturnObject(ModifiedObject); + } + BadRequest(RESTAPI::Errors::RecordNotUpdated); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_subuser_handler.h b/src/RESTAPI/RESTAPI_subuser_handler.h index f9432ad..49f45b2 100644 --- a/src/RESTAPI/RESTAPI_subuser_handler.h +++ b/src/RESTAPI/RESTAPI_subuser_handler.h @@ -7,25 +7,24 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_subuser_handler : public RESTAPIHandler { - public: - RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/subuser/{id}"}; }; - void DoGet() final; - void DoPost() final; - void DoDelete() final; - void DoPut() final; - private: + class RESTAPI_subuser_handler : public RESTAPIHandler { + public: + RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/subuser/{id}"}; }; + void DoGet() final; + void DoPost() final; + void DoDelete() final; + void DoPut() final; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_subusers_handler.cpp b/src/RESTAPI/RESTAPI_subusers_handler.cpp index ff3dbbf..8c4caf0 100644 --- a/src/RESTAPI/RESTAPI_subusers_handler.cpp +++ b/src/RESTAPI/RESTAPI_subusers_handler.cpp @@ -3,77 +3,84 @@ // #include "RESTAPI_subusers_handler.h" -#include "StorageService.h" #include "RESTAPI/RESTAPI_db_helpers.h" +#include "StorageService.h" namespace OpenWifi { - void RESTAPI_subusers_handler::DoGet() { - bool IdOnly = GetBoolParameter("idOnly"); - auto operatorId = GetParameter("operatorId"); - auto nameSearch = GetParameter("nameSearch"); - auto emailSearch = GetParameter("emailSearch"); + void RESTAPI_subusers_handler::DoGet() { + bool IdOnly = GetBoolParameter("idOnly"); + auto operatorId = GetParameter("operatorId"); + auto nameSearch = GetParameter("nameSearch"); + auto emailSearch = GetParameter("emailSearch"); - std::string baseQuery; - if(!nameSearch.empty() || !emailSearch.empty()) { - if(!nameSearch.empty()) - baseQuery = fmt::format(" Lower(name) like('%{}%') ", ORM::Escape(Poco::toLower(nameSearch)) ); - if(!emailSearch.empty()) - baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", ORM::Escape(Poco::toLower(emailSearch))) - : fmt::format(" and Lower(email) like('%{}%') ", ORM::Escape(Poco::toLower(emailSearch))); - } + std::string baseQuery; + if (!nameSearch.empty() || !emailSearch.empty()) { + if (!nameSearch.empty()) + baseQuery = fmt::format(" Lower(name) like('%{}%') ", + ORM::Escape(Poco::toLower(nameSearch))); + if (!emailSearch.empty()) + baseQuery += baseQuery.empty() + ? fmt::format(" Lower(email) like('%{}%') ", + ORM::Escape(Poco::toLower(emailSearch))) + : fmt::format(" and Lower(email) like('%{}%') ", + ORM::Escape(Poco::toLower(emailSearch))); + } - if(QB_.CountOnly) { - std::string whereClause; - if(!operatorId.empty() && Utils::ValidUUID(operatorId)) { - whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : - fmt::format(" owner='{}' and {} ", operatorId, baseQuery); - auto count = StorageService()->SubDB().Count(whereClause); - return ReturnCountOnly(count); - } - auto count = StorageService()->UserDB().Count(); - return ReturnCountOnly(count); - } else if(QB_.Select.empty()) { - std::string whereClause; - if(!operatorId.empty() && Utils::ValidUUID(operatorId)) { - whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : - fmt::format(" owner='{}' and {} ", operatorId, baseQuery); - } + if (QB_.CountOnly) { + std::string whereClause; + if (!operatorId.empty() && Utils::ValidUUID(operatorId)) { + whereClause = baseQuery.empty() + ? fmt::format(" owner='{}' ", operatorId) + : fmt::format(" owner='{}' and {} ", operatorId, baseQuery); + auto count = StorageService()->SubDB().Count(whereClause); + return ReturnCountOnly(count); + } + auto count = StorageService()->UserDB().Count(); + return ReturnCountOnly(count); + } else if (QB_.Select.empty()) { + std::string whereClause; + if (!operatorId.empty() && Utils::ValidUUID(operatorId)) { + whereClause = baseQuery.empty() + ? fmt::format(" owner='{}' ", operatorId) + : fmt::format(" owner='{}' and {} ", operatorId, baseQuery); + } - SecurityObjects::UserInfoList Users; - if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, whereClause)) { - for (auto &i : Users.users) { - Sanitize(UserInfo_, i); - } - } + SecurityObjects::UserInfoList Users; + if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, + whereClause)) { + for (auto &i : Users.users) { + Sanitize(UserInfo_, i); + } + } - if(IdOnly) { - Poco::JSON::Array Arr; - Poco::JSON::Object Answer; + if (IdOnly) { + Poco::JSON::Array Arr; + Poco::JSON::Object Answer; - for(const auto &i:Users.users) { - Arr.add(i.id); - } - Answer.set("users",Arr); - return ReturnObject(Answer); - } + for (const auto &i : Users.users) { + Arr.add(i.id); + } + Answer.set("users", Arr); + return ReturnObject(Answer); + } - Poco::JSON::Object Answer; - Users.to_json(Answer); - return ReturnObject(Answer); - } else { - SecurityObjects::UserInfoList Users; - for(auto &i:SelectedRecords()) { - SecurityObjects::UserInfo UInfo; - if(StorageService()->SubDB().GetUserById(i,UInfo)) { - Poco::JSON::Object Obj; - Sanitize(UserInfo_, UInfo); - Users.users.emplace_back(UInfo); - } - } - Poco::JSON::Object Answer; - Users.to_json(Answer); - return ReturnObject(Answer); - } - } -} \ No newline at end of file + Poco::JSON::Object Answer; + Users.to_json(Answer); + return ReturnObject(Answer); + } else { + SecurityObjects::UserInfoList Users; + for (auto &i : SelectedRecords()) { + SecurityObjects::UserInfo UInfo; + if (StorageService()->SubDB().GetUserById(i, UInfo)) { + Poco::JSON::Object Obj; + Sanitize(UserInfo_, UInfo); + Users.users.emplace_back(UInfo); + } + } + Poco::JSON::Object Answer; + Users.to_json(Answer); + return ReturnObject(Answer); + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_subusers_handler.h b/src/RESTAPI/RESTAPI_subusers_handler.h index 78fa1ba..98cd0af 100644 --- a/src/RESTAPI/RESTAPI_subusers_handler.h +++ b/src/RESTAPI/RESTAPI_subusers_handler.h @@ -7,20 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_subusers_handler : public RESTAPIHandler { - public: - RESTAPI_subusers_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/subusers"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -}; + class RESTAPI_subusers_handler : public RESTAPIHandler { + public: + RESTAPI_subusers_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/subusers"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +}; // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_systemSecret_handler.cpp b/src/RESTAPI/RESTAPI_systemSecret_handler.cpp index 9c390e4..b2ad06f 100644 --- a/src/RESTAPI/RESTAPI_systemSecret_handler.cpp +++ b/src/RESTAPI/RESTAPI_systemSecret_handler.cpp @@ -7,92 +7,90 @@ namespace OpenWifi { - void RESTAPI_systemSecret_handler::DoGet() { - if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + void RESTAPI_systemSecret_handler::DoGet() { + if (!Internal_ && UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(GetBoolParameter("all")) { - auto Store = SecretStore()->Store(); - Poco::JSON::Array Entries; - Poco::JSON::Object List; + if (GetBoolParameter("all")) { + auto Store = SecretStore()->Store(); + Poco::JSON::Array Entries; + Poco::JSON::Object List; - for(const auto &[Key,Value]:Store) { - Poco::JSON::Object E; - E.set("key",Key); - E.set("value",Value); - Entries.add(E); - } - List.set("secrets",Entries); - return ReturnObject(List); - } + for (const auto &[Key, Value] : Store) { + Poco::JSON::Object E; + E.set("key", Key); + E.set("value", Value); + Entries.add(E); + } + List.set("secrets", Entries); + return ReturnObject(List); + } - if(GetBoolParameter("dictionary")) { - static std::vector> KnownKeys = - { - { "google.maps.apikey" , "A Google Key specific for the Google MAPS API."}, - { "iptocountry.ipinfo.token", "IPInfo.io service token."}, - { "iptocountry.ipdata.apikey", "IPData.co API Key."}, - { "iptocountry.ip2location.apikey", "IP2Location.com API Key"} - }; + if (GetBoolParameter("dictionary")) { + static std::vector> KnownKeys = { + {"google.maps.apikey", "A Google Key specific for the Google MAPS API."}, + {"iptocountry.ipinfo.token", "IPInfo.io service token."}, + {"iptocountry.ipdata.apikey", "IPData.co API Key."}, + {"iptocountry.ip2location.apikey", "IP2Location.com API Key"}}; - Poco::JSON::Object Answer; - Poco::JSON::Array Entries; - for(const auto &[key,description]:KnownKeys) { - Poco::JSON::Object E; - E.set("key",key); - E.set("description",description); - Entries.add(E); - } - Answer.set("knownKeys", Entries); - return ReturnObject(Answer); - } + Poco::JSON::Object Answer; + Poco::JSON::Array Entries; + for (const auto &[key, description] : KnownKeys) { + Poco::JSON::Object E; + E.set("key", key); + E.set("description", description); + Entries.add(E); + } + Answer.set("knownKeys", Entries); + return ReturnObject(Answer); + } - auto Key = GetBinding("secret"); - if(Key.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + auto Key = GetBinding("secret"); + if (Key.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - std::string Value; - if(SecretStore()->Get(Key,Value,"")) { - Poco::JSON::Object Answer; - Answer.set("key", Key); - Answer.set("value", Value); - return ReturnObject(Answer); - } - return NotFound(); - } + std::string Value; + if (SecretStore()->Get(Key, Value, "")) { + Poco::JSON::Object Answer; + Answer.set("key", Key); + Answer.set("value", Value); + return ReturnObject(Answer); + } + return NotFound(); + } - void RESTAPI_systemSecret_handler::DoDelete() { - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + void RESTAPI_systemSecret_handler::DoDelete() { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - auto Key = GetBinding("secret"); - if(Key.empty()) { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + auto Key = GetBinding("secret"); + if (Key.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - SecretStore()->Remove(Key); - return OK(); - } + SecretStore()->Remove(Key); + return OK(); + } - void RESTAPI_systemSecret_handler::DoPut() { - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + void RESTAPI_systemSecret_handler::DoPut() { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - auto Key = GetBinding("secret"); - auto Value = GetParameter("value","_______no_value_____"); - if(Key.empty() || Value == "_______no_value_____") { - return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); - } + auto Key = GetBinding("secret"); + auto Value = GetParameter("value", "_______no_value_____"); + if (Key.empty() || Value == "_______no_value_____") { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } - SecretStore()->Set(Key,Value); - Poco::JSON::Object Answer; - Answer.set("key", Key); - Answer.set("value", Value); - return ReturnObject(Answer); - } + SecretStore()->Set(Key, Value); + Poco::JSON::Object Answer; + Answer.set("key", Key); + Answer.set("value", Value); + return ReturnObject(Answer); + } -} // OpenWifi \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_systemSecret_handler.h b/src/RESTAPI/RESTAPI_systemSecret_handler.h index caddaae..727bcaa 100644 --- a/src/RESTAPI/RESTAPI_systemSecret_handler.h +++ b/src/RESTAPI/RESTAPI_systemSecret_handler.h @@ -7,26 +7,23 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_systemSecret_handler : public RESTAPIHandler { - public: - RESTAPI_systemSecret_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - { - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS - }, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/systemSecret/{secret}"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final; - void DoPut() final; - private: + class RESTAPI_systemSecret_handler : public RESTAPIHandler { + public: + RESTAPI_systemSecret_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/systemSecret/{secret}"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final; + void DoPut() final; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_system_endpoints_handler.cpp b/src/RESTAPI/RESTAPI_system_endpoints_handler.cpp index 549c493..dc4585e 100644 --- a/src/RESTAPI/RESTAPI_system_endpoints_handler.cpp +++ b/src/RESTAPI/RESTAPI_system_endpoints_handler.cpp @@ -8,18 +8,15 @@ namespace OpenWifi { - void RESTAPI_system_endpoints_handler::DoGet() { - auto Services = MicroServiceGetServices(); - SecurityObjects::SystemEndpointList L; - for(const auto &i:Services) { - SecurityObjects::SystemEndpoint S{ - .type = i.Type, - .id = i.Id, - .uri = i.PublicEndPoint}; - L.endpoints.push_back(S); - } - Poco::JSON::Object Obj; - L.to_json(Obj); - ReturnObject(Obj); - } -} + void RESTAPI_system_endpoints_handler::DoGet() { + auto Services = MicroServiceGetServices(); + SecurityObjects::SystemEndpointList L; + for (const auto &i : Services) { + SecurityObjects::SystemEndpoint S{.type = i.Type, .id = i.Id, .uri = i.PublicEndPoint}; + L.endpoints.push_back(S); + } + Poco::JSON::Object Obj; + L.to_json(Obj); + ReturnObject(Obj); + } +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_system_endpoints_handler.h b/src/RESTAPI/RESTAPI_system_endpoints_handler.h index 6caffe6..76696fd 100644 --- a/src/RESTAPI/RESTAPI_system_endpoints_handler.h +++ b/src/RESTAPI/RESTAPI_system_endpoints_handler.h @@ -7,19 +7,19 @@ #include "../framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_system_endpoints_handler : public RESTAPIHandler { - public: - RESTAPI_system_endpoints_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector{Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/systemEndpoints"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -} + class RESTAPI_system_endpoints_handler : public RESTAPIHandler { + public: + RESTAPI_system_endpoints_handler(const RESTAPIHandler::BindingMap &bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/systemEndpoints"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_totp_handler.cpp b/src/RESTAPI/RESTAPI_totp_handler.cpp index f39b0f7..615e8bc 100644 --- a/src/RESTAPI/RESTAPI_totp_handler.cpp +++ b/src/RESTAPI/RESTAPI_totp_handler.cpp @@ -7,29 +7,30 @@ namespace OpenWifi { - void RESTAPI_totp_handler::DoGet() { + void RESTAPI_totp_handler::DoGet() { - auto Reset = GetBoolParameter("reset",false); - std::string QRCode; - if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) { - return SendFileContent(QRCode, "image/svg+xml","qrcode.svg"); - } - return BadRequest(RESTAPI::Errors::InvalidCommand); - } + auto Reset = GetBoolParameter("reset", false); + std::string QRCode; + if (TotpCache()->StartValidation(UserInfo_.userinfo, false, QRCode, Reset)) { + return SendFileContent(QRCode, "image/svg+xml", "qrcode.svg"); + } + return BadRequest(RESTAPI::Errors::InvalidCommand); + } - void RESTAPI_totp_handler::DoPut() { - auto Value = GetParameter("value",""); - auto nextIndex = GetParameter("index",0); - bool moreCodes=false; + void RESTAPI_totp_handler::DoPut() { + auto Value = GetParameter("value", ""); + auto nextIndex = GetParameter("index", 0); + bool moreCodes = false; - RESTAPI::Errors::msg Err; - if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, Err)) { - Poco::JSON::Object Answer; - Answer.set("nextIndex", nextIndex); - Answer.set("moreCodes", moreCodes); - return ReturnObject(Answer); - } - return BadRequest(Err); - } + RESTAPI::Errors::msg Err; + if (TotpCache()->ContinueValidation(UserInfo_.userinfo, false, Value, nextIndex, moreCodes, + Err)) { + Poco::JSON::Object Answer; + Answer.set("nextIndex", nextIndex); + Answer.set("moreCodes", moreCodes); + return ReturnObject(Answer); + } + return BadRequest(Err); + } -} +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_totp_handler.h b/src/RESTAPI/RESTAPI_totp_handler.h index 1f6cde1..c2c9c35 100644 --- a/src/RESTAPI/RESTAPI_totp_handler.h +++ b/src/RESTAPI/RESTAPI_totp_handler.h @@ -7,25 +7,22 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_totp_handler : public RESTAPIHandler { - public: - RESTAPI_totp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - { - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_OPTIONS - }, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/totp"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final; - private: + class RESTAPI_totp_handler : public RESTAPIHandler { + public: + RESTAPI_totp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/totp"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_user_handler.cpp b/src/RESTAPI/RESTAPI_user_handler.cpp index acb55ee..afed086 100644 --- a/src/RESTAPI/RESTAPI_user_handler.cpp +++ b/src/RESTAPI/RESTAPI_user_handler.cpp @@ -3,327 +3,348 @@ // #include "RESTAPI_user_handler.h" -#include "StorageService.h" -#include "framework/ow_constants.h" -#include "SMSSender.h" -#include "SMTPMailerService.h" #include "ACLProcessor.h" #include "AuthService.h" -#include "RESTAPI/RESTAPI_db_helpers.h" #include "MFAServer.h" +#include "RESTAPI/RESTAPI_db_helpers.h" +#include "SMSSender.h" +#include "SMTPMailerService.h" +#include "StorageService.h" #include "TotpCache.h" #include "framework/MicroServiceFuncs.h" +#include "framework/ow_constants.h" namespace OpenWifi { - void RESTAPI_user_handler::DoGet() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + void RESTAPI_user_handler::DoGet() { + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - Poco::toLowerInPlace(Id); - std::string Arg; - SecurityObjects::UserInfo UInfo; - if(HasParameter("byEmail",Arg) && Arg=="true") { - if(!StorageService()->UserDB().GetUserByEmail(Id,UInfo)) { - return NotFound(); - } - } else if(!StorageService()->UserDB().GetUserById(Id,UInfo)) { - return NotFound(); - } + Poco::toLowerInPlace(Id); + std::string Arg; + SecurityObjects::UserInfo UInfo; + if (HasParameter("byEmail", Arg) && Arg == "true") { + if (!StorageService()->UserDB().GetUserByEmail(Id, UInfo)) { + return NotFound(); + } + } else if (!StorageService()->UserDB().GetUserById(Id, UInfo)) { + return NotFound(); + } - if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!ACLProcessor::Can(UserInfo_.userinfo, UInfo, ACLProcessor::READ)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - Poco::JSON::Object UserInfoObject; - Sanitize(UserInfo_, UInfo); - UInfo.to_json(UserInfoObject); - ReturnObject(UserInfoObject); - } + Poco::JSON::Object UserInfoObject; + Sanitize(UserInfo_, UInfo); + UInfo.to_json(UserInfoObject); + ReturnObject(UserInfoObject); + } - void RESTAPI_user_handler::DoDelete() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + void RESTAPI_user_handler::DoDelete() { + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - SecurityObjects::UserInfo UInfo; - if(!StorageService()->UserDB().GetUserById(Id,UInfo)) { - return NotFound(); - } + SecurityObjects::UserInfo UInfo; + if (!StorageService()->UserDB().GetUserById(Id, UInfo)) { + return NotFound(); + } - if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!ACLProcessor::Can(UserInfo_.userinfo, UInfo, ACLProcessor::DELETE)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) { - return NotFound(); - } + if (!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email, Id)) { + return NotFound(); + } - AuthService()->DeleteUserFromCache(Id); - StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id); - StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id); - StorageService()->UserTokenDB().RevokeAllTokens(Id); - StorageService()->ApiKeyDB().RemoveAllApiKeys(Id); - Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); - OK(); - } + AuthService()->DeleteUserFromCache(Id); + StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id); + StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email, Id); + StorageService()->UserTokenDB().RevokeAllTokens(Id); + StorageService()->ApiKeyDB().RemoveAllApiKeys(Id); + Logger_.information( + fmt::format("User '{}' deleted by '{}'.", Id, UserInfo_.userinfo.email)); + OK(); + } - void RESTAPI_user_handler::DoPost() { + void RESTAPI_user_handler::DoPost() { - std::string Id = GetBinding("id", ""); - if(Id!="0") { - return BadRequest(RESTAPI::Errors::IdMustBe0); - } + std::string Id = GetBinding("id", ""); + if (Id != "0") { + return BadRequest(RESTAPI::Errors::IdMustBe0); + } - SecurityObjects::UserInfo NewUser; - const auto & RawObject = ParsedBody_; - if(!NewUser.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + SecurityObjects::UserInfo NewUser; + const auto &RawObject = ParsedBody_; + if (!NewUser.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - if(NewUser.userRole == SecurityObjects::UNKNOWN) { - return BadRequest(RESTAPI::Errors::InvalidUserRole); - } + if (NewUser.userRole == SecurityObjects::UNKNOWN) { + return BadRequest(RESTAPI::Errors::InvalidUserRole); + } - if(UserInfo_.userinfo.userRole==SecurityObjects::ROOT) { - NewUser.owner = GetParameter("entity",""); - } else { - NewUser.owner = UserInfo_.userinfo.owner; - } + if (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) { + NewUser.owner = GetParameter("entity", ""); + } else { + NewUser.owner = UserInfo_.userinfo.owner; + } - if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!ACLProcessor::Can(UserInfo_.userinfo, NewUser, ACLProcessor::CREATE)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - Poco::toLowerInPlace(NewUser.email); - if(!Utils::ValidEMailAddress(NewUser.email)) { - return BadRequest(RESTAPI::Errors::InvalidEmailAddress); - } + Poco::toLowerInPlace(NewUser.email); + if (!Utils::ValidEMailAddress(NewUser.email)) { + return BadRequest(RESTAPI::Errors::InvalidEmailAddress); + } - SecurityObjects::UserInfo Existing; - if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) { - return BadRequest(RESTAPI::Errors::UserAlreadyExists); - } + SecurityObjects::UserInfo Existing; + if (StorageService()->SubDB().GetUserByEmail(NewUser.email, Existing)) { + return BadRequest(RESTAPI::Errors::UserAlreadyExists); + } - if(!NewUser.currentPassword.empty()) { - if(!AuthService()->ValidatePassword(NewUser.currentPassword)) { - return BadRequest(RESTAPI::Errors::InvalidPassword); - } - } + if (!NewUser.currentPassword.empty()) { + if (!AuthService()->ValidatePassword(NewUser.currentPassword)) { + return BadRequest(RESTAPI::Errors::InvalidPassword); + } + } - if(NewUser.name.empty()) - NewUser.name = NewUser.email; + if (NewUser.name.empty()) + NewUser.name = NewUser.email; - // You cannot enable MFA during user creation - NewUser.userTypeProprietaryInfo.mfa.enabled = false; - NewUser.userTypeProprietaryInfo.mfa.method = ""; - NewUser.userTypeProprietaryInfo.mobiles.clear(); - NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); - NewUser.validated = true; + // You cannot enable MFA during user creation + NewUser.userTypeProprietaryInfo.mfa.enabled = false; + NewUser.userTypeProprietaryInfo.mfa.method = ""; + NewUser.userTypeProprietaryInfo.mobiles.clear(); + NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); + NewUser.validated = true; - if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) { - Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email)); - return BadRequest(RESTAPI::Errors::RecordNotCreated); - } + if (!StorageService()->UserDB().CreateUser(NewUser.email, NewUser)) { + Logger_.information(fmt::format("Could not add user '{}'.", NewUser.email)); + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } - if(GetBoolParameter("email_verification")) { - if(AuthService::VerifyEmail(NewUser)) - Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email)); - StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser); - } + if (GetBoolParameter("email_verification")) { + if (AuthService::VerifyEmail(NewUser)) + Logger_.information( + fmt::format("Verification e-mail requested for {}", NewUser.email)); + StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email, NewUser.id, + NewUser); + } - if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) { - Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email)); - return NotFound(); - } + if (!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) { + Logger_.information(fmt::format("User '{}' but not retrieved.", NewUser.email)); + return NotFound(); + } - Poco::JSON::Object UserInfoObject; - Sanitize(UserInfo_, NewUser); - NewUser.to_json(UserInfoObject); - ReturnObject(UserInfoObject); - Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email)); - } + Poco::JSON::Object UserInfoObject; + Sanitize(UserInfo_, NewUser); + NewUser.to_json(UserInfoObject); + ReturnObject(UserInfoObject); + Logger_.information(fmt::format("User '{}' has been added by '{}')", NewUser.email, + UserInfo_.userinfo.email)); + } - void RESTAPI_user_handler::DoPut() { + void RESTAPI_user_handler::DoPut() { - std::string Id = GetBinding("id", ""); - if(Id.empty()) { - return BadRequest(RESTAPI::Errors::MissingUserID); - } + std::string Id = GetBinding("id", ""); + if (Id.empty()) { + return BadRequest(RESTAPI::Errors::MissingUserID); + } - SecurityObjects::UserInfo Existing; - if(!StorageService()->UserDB().GetUserById(Id,Existing)) { - return NotFound(); - } + SecurityObjects::UserInfo Existing; + if (!StorageService()->UserDB().GetUserById(Id, Existing)) { + return NotFound(); + } - if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } + if (!ACLProcessor::Can(UserInfo_.userinfo, Existing, ACLProcessor::MODIFY)) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } - if(GetBoolParameter("resetMFA")) { - if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || - (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) || - (UserInfo_.userinfo.id == Id)) { - Existing.userTypeProprietaryInfo.mfa.enabled = false; - Existing.userTypeProprietaryInfo.mfa.method.clear(); - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.modified = OpenWifi::Now(); - Existing.notes.push_back( SecurityObjects::NoteInfo{ - .created=OpenWifi::Now(), - .createdBy=UserInfo_.userinfo.email, - .note="MFA Reset by " + UserInfo_.userinfo.email}); - StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing); - SecurityObjects::UserInfo NewUserInfo; - StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); - Poco::JSON::Object ModifiedObject; - Sanitize(UserInfo_, NewUserInfo); - NewUserInfo.to_json(ModifiedObject); - return ReturnObject(ModifiedObject); - } else { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - } + if (GetBoolParameter("resetMFA")) { + if ((UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || + (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && + Existing.userRole != SecurityObjects::ROOT) || + (UserInfo_.userinfo.id == Id)) { + Existing.userTypeProprietaryInfo.mfa.enabled = false; + Existing.userTypeProprietaryInfo.mfa.method.clear(); + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.modified = OpenWifi::Now(); + Existing.notes.push_back( + SecurityObjects::NoteInfo{.created = OpenWifi::Now(), + .createdBy = UserInfo_.userinfo.email, + .note = "MFA Reset by " + UserInfo_.userinfo.email}); + StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email, Id, Existing); + SecurityObjects::UserInfo NewUserInfo; + StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email, NewUserInfo); + Poco::JSON::Object ModifiedObject; + Sanitize(UserInfo_, NewUserInfo); + NewUserInfo.to_json(ModifiedObject); + return ReturnObject(ModifiedObject); + } else { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + } - if(GetBoolParameter("forgotPassword")) { - Existing.changePassword = true; - Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email)); - SecurityObjects::ActionLink NewLink; + if (GetBoolParameter("forgotPassword")) { + Existing.changePassword = true; + Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", + Request->clientAddress().toString(), Existing.email)); + SecurityObjects::ActionLink NewLink; - NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; - NewLink.id = MicroServiceCreateUUID(); - NewLink.userId = Existing.id; - NewLink.created = OpenWifi::Now(); - NewLink.expires = NewLink.created + (24*60*60); - NewLink.userAction = true; - StorageService()->ActionLinksDB().CreateAction(NewLink); - return OK(); - } + NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; + NewLink.id = MicroServiceCreateUUID(); + NewLink.userId = Existing.id; + NewLink.created = OpenWifi::Now(); + NewLink.expires = NewLink.created + (24 * 60 * 60); + NewLink.userAction = true; + StorageService()->ActionLinksDB().CreateAction(NewLink); + return OK(); + } - SecurityObjects::UserInfo NewUser; - const auto & RawObject = ParsedBody_; - if(!NewUser.from_json(RawObject)) { - return BadRequest(RESTAPI::Errors::InvalidJSONDocument); - } + SecurityObjects::UserInfo NewUser; + const auto &RawObject = ParsedBody_; + if (!NewUser.from_json(RawObject)) { + return BadRequest(RESTAPI::Errors::InvalidJSONDocument); + } - // some basic validations - if(RawObject->has("userRole") && SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN) { - return BadRequest(RESTAPI::Errors::InvalidUserRole); - } + // some basic validations + if (RawObject->has("userRole") && + SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()) == + SecurityObjects::UNKNOWN) { + return BadRequest(RESTAPI::Errors::InvalidUserRole); + } - if(RawObject->has("owner")) { - if (UserInfo_.userinfo.userRole == SecurityObjects::ROOT && Existing.owner.empty()) { - AssignIfPresent(RawObject, "owner", Existing.owner); - } - } + if (RawObject->has("owner")) { + if (UserInfo_.userinfo.userRole == SecurityObjects::ROOT && Existing.owner.empty()) { + AssignIfPresent(RawObject, "owner", Existing.owner); + } + } - // The only valid things to change are: changePassword, name, - AssignIfPresent(RawObject,"name", Existing.name); - AssignIfPresent(RawObject,"description", Existing.description); - AssignIfPresent(RawObject,"location", Existing.location); - AssignIfPresent(RawObject,"locale", Existing.locale); - AssignIfPresent(RawObject,"changePassword", Existing.changePassword); - AssignIfPresent(RawObject,"suspended", Existing.suspended); - AssignIfPresent(RawObject,"blackListed", Existing.blackListed); + // The only valid things to change are: changePassword, name, + AssignIfPresent(RawObject, "name", Existing.name); + AssignIfPresent(RawObject, "description", Existing.description); + AssignIfPresent(RawObject, "location", Existing.location); + AssignIfPresent(RawObject, "locale", Existing.locale); + AssignIfPresent(RawObject, "changePassword", Existing.changePassword); + AssignIfPresent(RawObject, "suspended", Existing.suspended); + AssignIfPresent(RawObject, "blackListed", Existing.blackListed); - if(RawObject->has("userRole")) { - auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); - if(NewRole!=Existing.userRole) { - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - if(Id==UserInfo_.userinfo.id) { - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - Existing.userRole = NewRole; - } - } + if (RawObject->has("userRole")) { + auto NewRole = + SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); + if (NewRole != Existing.userRole) { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && + NewRole == SecurityObjects::ROOT) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + if (Id == UserInfo_.userinfo.id) { + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + Existing.userRole = NewRole; + } + } - if(RawObject->has("notes")) { - SecurityObjects::NoteInfoVec NIV; - NIV = RESTAPI_utils::to_object_array(RawObject->get("notes").toString()); - for(auto const &i:NIV) { - SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; - Existing.notes.push_back(ii); - } - } - if(RawObject->has("currentPassword")) { - if(!AuthService()->ValidatePassword(RawObject->get("currentPassword").toString())) { - return BadRequest(RESTAPI::Errors::InvalidPassword); - } - if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),Existing)) { - return BadRequest(RESTAPI::Errors::PasswordRejected); - } - } + if (RawObject->has("notes")) { + SecurityObjects::NoteInfoVec NIV; + NIV = RESTAPI_utils::to_object_array( + RawObject->get("notes").toString()); + for (auto const &i : NIV) { + SecurityObjects::NoteInfo ii{.created = (uint64_t)OpenWifi::Now(), + .createdBy = UserInfo_.userinfo.email, + .note = i.note}; + Existing.notes.push_back(ii); + } + } + if (RawObject->has("currentPassword")) { + if (!AuthService()->ValidatePassword(RawObject->get("currentPassword").toString())) { + return BadRequest(RESTAPI::Errors::InvalidPassword); + } + if (!AuthService()->SetPassword(RawObject->get("currentPassword").toString(), + Existing)) { + return BadRequest(RESTAPI::Errors::PasswordRejected); + } + } - if(GetBoolParameter("email_verification")) { - if(AuthService::VerifyEmail(Existing)) - Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email)); - } + if (GetBoolParameter("email_verification")) { + if (AuthService::VerifyEmail(Existing)) + Logger_.information( + fmt::format("Verification e-mail requested for {}", Existing.email)); + } - if(RawObject->has("userTypeProprietaryInfo")) { - if(NewUser.userTypeProprietaryInfo.mfa.enabled) { - if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) { - return BadRequest(RESTAPI::Errors::BadMFAMethod); - } + if (RawObject->has("userTypeProprietaryInfo")) { + if (NewUser.userTypeProprietaryInfo.mfa.enabled) { + if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) { + return BadRequest(RESTAPI::Errors::BadMFAMethod); + } - if( NewUser.userTypeProprietaryInfo.mfa.enabled && - NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && - !SMSSender()->Enabled()) { - return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); - } + if (NewUser.userTypeProprietaryInfo.mfa.enabled && + NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && + !SMSSender()->Enabled()) { + return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); + } - if( NewUser.userTypeProprietaryInfo.mfa.enabled && - NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && - !SMTPMailerService()->Enabled()) { - return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); - } + if (NewUser.userTypeProprietaryInfo.mfa.enabled && + NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && + !SMTPMailerService()->Enabled()) { + return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); + } - Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method; - Existing.userTypeProprietaryInfo.mfa.enabled = true; + Existing.userTypeProprietaryInfo.mfa.method = + NewUser.userTypeProprietaryInfo.mfa.method; + Existing.userTypeProprietaryInfo.mfa.enabled = true; - if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { - if(NewUser.userTypeProprietaryInfo.mobiles.empty()) { - return BadRequest(RESTAPI::Errors::NeedMobileNumber); - } - if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) { - return BadRequest(RESTAPI::Errors::NeedMobileNumber); - } - Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; - Existing.userTypeProprietaryInfo.mobiles[0].verified = true; - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { - std::string Secret; - Existing.userTypeProprietaryInfo.mobiles.clear(); - if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) { - Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; - } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { - // we allow someone to use their old secret - } else { - return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); - } - } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - } - } else { - Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); - Existing.userTypeProprietaryInfo.mobiles.clear(); - Existing.userTypeProprietaryInfo.mfa.enabled = false; - } - } + if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { + if (NewUser.userTypeProprietaryInfo.mobiles.empty()) { + return BadRequest(RESTAPI::Errors::NeedMobileNumber); + } + if (!SMSSender()->IsNumberValid( + NewUser.userTypeProprietaryInfo.mobiles[0].number, + UserInfo_.userinfo.email)) { + return BadRequest(RESTAPI::Errors::NeedMobileNumber); + } + Existing.userTypeProprietaryInfo.mobiles = + NewUser.userTypeProprietaryInfo.mobiles; + Existing.userTypeProprietaryInfo.mobiles[0].verified = true; + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + } else if (NewUser.userTypeProprietaryInfo.mfa.method == + MFAMETHODS::AUTHENTICATOR) { + std::string Secret; + Existing.userTypeProprietaryInfo.mobiles.clear(); + if (Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && + TotpCache()->CompleteValidation(UserInfo_.userinfo, false, Secret)) { + Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; + } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { + // we allow someone to use their old secret + } else { + return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); + } + } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + } + } else { + Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); + Existing.userTypeProprietaryInfo.mobiles.clear(); + Existing.userTypeProprietaryInfo.mfa.enabled = false; + } + } - Existing.modified = OpenWifi::Now(); - if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) { - SecurityObjects::UserInfo NewUserInfo; - StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); - Poco::JSON::Object ModifiedObject; - Sanitize(UserInfo_, NewUserInfo); - NewUserInfo.to_json(ModifiedObject); - return ReturnObject(ModifiedObject); - } - BadRequest(RESTAPI::Errors::RecordNotUpdated); - } -} \ No newline at end of file + Existing.modified = OpenWifi::Now(); + if (StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email, Id, Existing)) { + SecurityObjects::UserInfo NewUserInfo; + StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email, NewUserInfo); + Poco::JSON::Object ModifiedObject; + Sanitize(UserInfo_, NewUserInfo); + NewUserInfo.to_json(ModifiedObject); + return ReturnObject(ModifiedObject); + } + BadRequest(RESTAPI::Errors::RecordNotUpdated); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_user_handler.h b/src/RESTAPI/RESTAPI_user_handler.h index 29a42de..3286039 100644 --- a/src/RESTAPI/RESTAPI_user_handler.h +++ b/src/RESTAPI/RESTAPI_user_handler.h @@ -7,25 +7,24 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_user_handler : public RESTAPIHandler { - public: - RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_POST, - Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_PUT, - Poco::Net::HTTPRequest::HTTP_DELETE, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/user/{id}"}; }; - void DoGet() final; - void DoPost() final; - void DoDelete() final; - void DoPut() final; - private: + class RESTAPI_user_handler : public RESTAPIHandler { + public: + RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_PUT, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/user/{id}"}; }; + void DoGet() final; + void DoPost() final; + void DoDelete() final; + void DoPut() final; - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_users_handler.cpp b/src/RESTAPI/RESTAPI_users_handler.cpp index 0b4b7bc..47bfd20 100644 --- a/src/RESTAPI/RESTAPI_users_handler.cpp +++ b/src/RESTAPI/RESTAPI_users_handler.cpp @@ -3,55 +3,60 @@ // #include "RESTAPI_users_handler.h" -#include "StorageService.h" #include "RESTAPI/RESTAPI_db_helpers.h" +#include "StorageService.h" namespace OpenWifi { - void RESTAPI_users_handler::DoGet() { - bool IdOnly = (GetParameter("idOnly","false")=="true"); - auto nameSearch = GetParameter("nameSearch"); - auto emailSearch = GetParameter("emailSearch"); + void RESTAPI_users_handler::DoGet() { + bool IdOnly = (GetParameter("idOnly", "false") == "true"); + auto nameSearch = GetParameter("nameSearch"); + auto emailSearch = GetParameter("emailSearch"); - std::string baseQuery; - if(!nameSearch.empty() || !emailSearch.empty()) { - if(!nameSearch.empty()) - baseQuery = fmt::format(" Lower(name) like('%{}%') ", ORM::Escape(Poco::toLower(nameSearch)) ); - if(!emailSearch.empty()) - baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", ORM::Escape(Poco::toLower(emailSearch))) - : fmt::format(" and Lower(email) like('%{}%') ", ORM::Escape(Poco::toLower(emailSearch))); - } + std::string baseQuery; + if (!nameSearch.empty() || !emailSearch.empty()) { + if (!nameSearch.empty()) + baseQuery = fmt::format(" Lower(name) like('%{}%') ", + ORM::Escape(Poco::toLower(nameSearch))); + if (!emailSearch.empty()) + baseQuery += baseQuery.empty() + ? fmt::format(" Lower(email) like('%{}%') ", + ORM::Escape(Poco::toLower(emailSearch))) + : fmt::format(" and Lower(email) like('%{}%') ", + ORM::Escape(Poco::toLower(emailSearch))); + } - if(QB_.Select.empty()) { - SecurityObjects::UserInfoList Users; - if(StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, baseQuery)) { - for (auto &i : Users.users) { - Sanitize(UserInfo_, i); - } - if(IdOnly) { - Poco::JSON::Array Arr; - for(const auto &i:Users.users) - Arr.add(i.id); - Poco::JSON::Object Answer; - Answer.set("users", Arr); - return ReturnObject(Answer); - } - } - Poco::JSON::Object Answer; - Users.to_json(Answer); - return ReturnObject(Answer); - } else { - SecurityObjects::UserInfoList Users; - for(auto &i:SelectedRecords()) { - SecurityObjects::UserInfo UInfo; - if(StorageService()->UserDB().GetUserById(i,UInfo)) { - Poco::JSON::Object Obj; - Sanitize(UserInfo_, UInfo); - Users.users.emplace_back(UInfo); - } - } - Poco::JSON::Object Answer; - Users.to_json(Answer); - return ReturnObject(Answer); - } - } -} \ No newline at end of file + if (QB_.Select.empty()) { + SecurityObjects::UserInfoList Users; + if (StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, + baseQuery)) { + for (auto &i : Users.users) { + Sanitize(UserInfo_, i); + } + if (IdOnly) { + Poco::JSON::Array Arr; + for (const auto &i : Users.users) + Arr.add(i.id); + Poco::JSON::Object Answer; + Answer.set("users", Arr); + return ReturnObject(Answer); + } + } + Poco::JSON::Object Answer; + Users.to_json(Answer); + return ReturnObject(Answer); + } else { + SecurityObjects::UserInfoList Users; + for (auto &i : SelectedRecords()) { + SecurityObjects::UserInfo UInfo; + if (StorageService()->UserDB().GetUserById(i, UInfo)) { + Poco::JSON::Object Obj; + Sanitize(UserInfo_, UInfo); + Users.users.emplace_back(UInfo); + } + } + Poco::JSON::Object Answer; + Users.to_json(Answer); + return ReturnObject(Answer); + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_users_handler.h b/src/RESTAPI/RESTAPI_users_handler.h index a1c5bda..efe4749 100644 --- a/src/RESTAPI/RESTAPI_users_handler.h +++ b/src/RESTAPI/RESTAPI_users_handler.h @@ -7,21 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_users_handler : public RESTAPIHandler { - public: - RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/users"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -}; - + class RESTAPI_users_handler : public RESTAPIHandler { + public: + RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/users"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +}; // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_validate_apikey.cpp b/src/RESTAPI/RESTAPI_validate_apikey.cpp index 7029f46..393721e 100644 --- a/src/RESTAPI/RESTAPI_validate_apikey.cpp +++ b/src/RESTAPI/RESTAPI_validate_apikey.cpp @@ -7,28 +7,29 @@ namespace OpenWifi { - void RESTAPI_validate_apikey::DoGet() { - Poco::URI URI(Request->getURI()); - auto Parameters = URI.getQueryParameters(); - for(auto const &i:Parameters) { - if (i.first == "apikey") { - // can we find this token? - SecurityObjects::UserInfoAndPolicy SecObj; - bool Expired = false; - bool Suspended = false; - std::uint64_t expiresOn=0; - if (AuthService()->IsValidApiKey(i.second, SecObj.webtoken, SecObj.userinfo, Expired, expiresOn, Suspended)) { - Poco::JSON::Object Answer; - SecObj.to_json(Answer); - Answer.set("expiresOn", expiresOn); - return ReturnObject(Answer); - } - if(Suspended) - return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); - return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); - } - } - return NotFound(); - } + void RESTAPI_validate_apikey::DoGet() { + Poco::URI URI(Request->getURI()); + auto Parameters = URI.getQueryParameters(); + for (auto const &i : Parameters) { + if (i.first == "apikey") { + // can we find this token? + SecurityObjects::UserInfoAndPolicy SecObj; + bool Expired = false; + bool Suspended = false; + std::uint64_t expiresOn = 0; + if (AuthService()->IsValidApiKey(i.second, SecObj.webtoken, SecObj.userinfo, + Expired, expiresOn, Suspended)) { + Poco::JSON::Object Answer; + SecObj.to_json(Answer); + Answer.set("expiresOn", expiresOn); + return ReturnObject(Answer); + } + if (Suspended) + return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); + return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); + } + } + return NotFound(); + } -} // OpenWifi \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_validate_apikey.h b/src/RESTAPI/RESTAPI_validate_apikey.h index 3a21867..2067739 100644 --- a/src/RESTAPI/RESTAPI_validate_apikey.h +++ b/src/RESTAPI/RESTAPI_validate_apikey.h @@ -7,21 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_validate_apikey : public RESTAPIHandler { - public: - RESTAPI_validate_apikey(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {}; - static auto PathName() { return std::list{"/api/v1/validateApiKey"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -} - + class RESTAPI_validate_apikey : public RESTAPIHandler { + public: + RESTAPI_validate_apikey(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal){}; + static auto PathName() { return std::list{"/api/v1/validateApiKey"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_validate_sub_token_handler.cpp b/src/RESTAPI/RESTAPI_validate_sub_token_handler.cpp index 5507adc..ac7ddd3 100644 --- a/src/RESTAPI/RESTAPI_validate_sub_token_handler.cpp +++ b/src/RESTAPI/RESTAPI_validate_sub_token_handler.cpp @@ -6,21 +6,22 @@ #include "AuthService.h" namespace OpenWifi { - void RESTAPI_validate_sub_token_handler::DoGet() { - Poco::URI URI(Request->getURI()); - auto Parameters = URI.getQueryParameters(); - for(auto const &i:Parameters) { - if (i.first == "token") { - // can we find this token? - SecurityObjects::UserInfoAndPolicy SecObj; - bool Expired = false; - if (AuthService()->IsValidSubToken(i.second, SecObj.webtoken, SecObj.userinfo, Expired)) { - Poco::JSON::Object Obj; - SecObj.to_json(Obj); - return ReturnObject(Obj); - } - } - } - return NotFound(); - } -} \ No newline at end of file + void RESTAPI_validate_sub_token_handler::DoGet() { + Poco::URI URI(Request->getURI()); + auto Parameters = URI.getQueryParameters(); + for (auto const &i : Parameters) { + if (i.first == "token") { + // can we find this token? + SecurityObjects::UserInfoAndPolicy SecObj; + bool Expired = false; + if (AuthService()->IsValidSubToken(i.second, SecObj.webtoken, SecObj.userinfo, + Expired)) { + Poco::JSON::Object Obj; + SecObj.to_json(Obj); + return ReturnObject(Obj); + } + } + } + return NotFound(); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_validate_sub_token_handler.h b/src/RESTAPI/RESTAPI_validate_sub_token_handler.h index 907bdb9..cbcc161 100644 --- a/src/RESTAPI/RESTAPI_validate_sub_token_handler.h +++ b/src/RESTAPI/RESTAPI_validate_sub_token_handler.h @@ -7,20 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_validate_sub_token_handler : public RESTAPIHandler { - public: - RESTAPI_validate_sub_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {}; - static auto PathName() { return std::list{"/api/v1/validateSubToken"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -} + class RESTAPI_validate_sub_token_handler : public RESTAPIHandler { + public: + RESTAPI_validate_sub_token_handler(const RESTAPIHandler::BindingMap &bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal){}; + static auto PathName() { return std::list{"/api/v1/validateSubToken"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_validate_token_handler.cpp b/src/RESTAPI/RESTAPI_validate_token_handler.cpp index f92aeb6..9e5d293 100644 --- a/src/RESTAPI/RESTAPI_validate_token_handler.cpp +++ b/src/RESTAPI/RESTAPI_validate_token_handler.cpp @@ -6,21 +6,22 @@ #include "AuthService.h" namespace OpenWifi { - void RESTAPI_validate_token_handler::DoGet() { - Poco::URI URI(Request->getURI()); - auto Parameters = URI.getQueryParameters(); - for(auto const &i:Parameters) { - if (i.first == "token") { - // can we find this token? - SecurityObjects::UserInfoAndPolicy SecObj; - bool Expired = false; - if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo, Expired)) { - Poco::JSON::Object Obj; - SecObj.to_json(Obj); - return ReturnObject(Obj); - } - } - } - return NotFound(); - } -} \ No newline at end of file + void RESTAPI_validate_token_handler::DoGet() { + Poco::URI URI(Request->getURI()); + auto Parameters = URI.getQueryParameters(); + for (auto const &i : Parameters) { + if (i.first == "token") { + // can we find this token? + SecurityObjects::UserInfoAndPolicy SecObj; + bool Expired = false; + if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo, + Expired)) { + Poco::JSON::Object Obj; + SecObj.to_json(Obj); + return ReturnObject(Obj); + } + } + } + return NotFound(); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_validate_token_handler.h b/src/RESTAPI/RESTAPI_validate_token_handler.h index c08d382..b68b386 100644 --- a/src/RESTAPI/RESTAPI_validate_token_handler.h +++ b/src/RESTAPI/RESTAPI_validate_token_handler.h @@ -7,21 +7,19 @@ #include "framework/RESTAPI_Handler.h" namespace OpenWifi { - class RESTAPI_validate_token_handler : public RESTAPIHandler { - public: - RESTAPI_validate_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, - std::vector - {Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {}; - static auto PathName() { return std::list{"/api/v1/validateToken"}; }; - void DoGet() final; - void DoPost() final {}; - void DoDelete() final {}; - void DoPut() final {}; - }; -} - + class RESTAPI_validate_token_handler : public RESTAPIHandler { + public: + RESTAPI_validate_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal){}; + static auto PathName() { return std::list{"/api/v1/validateToken"}; }; + void DoGet() final; + void DoPost() final{}; + void DoDelete() final{}; + void DoPut() final{}; + }; +} // namespace OpenWifi diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp index 6e095e3..82991c2 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp @@ -6,619 +6,600 @@ #include "RESTAPI_ProvObjects.h" #include "framework/RESTAPI_utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::AnalyticsObjects { - void Report::reset() { - } + void Report::reset() {} - void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const { - } + void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {} - void VenueInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"name",name); - field_to_json(Obj,"description",description); - field_to_json(Obj,"retention",retention); - field_to_json(Obj,"interval",interval); - field_to_json(Obj,"monitorSubVenues",monitorSubVenues); - } + void VenueInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "retention", retention); + field_to_json(Obj, "interval", interval); + field_to_json(Obj, "monitorSubVenues", monitorSubVenues); + } - bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"retention",retention); - field_from_json(Obj,"interval",interval); - field_from_json(Obj,"monitorSubVenues",monitorSubVenues); - return true; - } catch(...) { + bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "retention", retention); + field_from_json(Obj, "interval", interval); + field_from_json(Obj, "monitorSubVenues", monitorSubVenues); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void BoardInfo::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "venueList", venueList); + } - void BoardInfo::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json(Obj,"venueList",venueList); - } + bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "venueList", venueList); + return true; + } catch (...) { + } + return false; + } - bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json(Obj,"venueList",venueList); - return true; - } catch(...) { + void DeviceInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "boardId", boardId); + field_to_json(Obj, "type", type); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "lastContact", lastContact); + field_to_json(Obj, "lastPing", lastPing); + field_to_json(Obj, "lastState", lastState); + field_to_json(Obj, "lastFirmware", lastFirmware); + field_to_json(Obj, "lastFirmwareUpdate", lastFirmwareUpdate); + field_to_json(Obj, "lastConnection", lastConnection); + field_to_json(Obj, "lastDisconnection", lastDisconnection); + field_to_json(Obj, "pings", pings); + field_to_json(Obj, "states", states); + field_to_json(Obj, "connected", connected); + field_to_json(Obj, "connectionIp", connectionIp); + field_to_json(Obj, "associations_2g", associations_2g); + field_to_json(Obj, "associations_5g", associations_5g); + field_to_json(Obj, "associations_6g", associations_6g); + field_to_json(Obj, "health", health); + field_to_json(Obj, "lastHealth", lastHealth); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "uptime", uptime); + field_to_json(Obj, "memory", memory); + } - } - return false; - } + bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "boardId", boardId); + field_from_json(Obj, "type", type); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "lastContact", lastContact); + field_from_json(Obj, "lastPing", lastPing); + field_from_json(Obj, "lastState", lastState); + field_from_json(Obj, "lastFirmware", lastFirmware); + field_from_json(Obj, "lastFirmwareUpdate", lastFirmwareUpdate); + field_from_json(Obj, "lastConnection", lastConnection); + field_from_json(Obj, "lastDisconnection", lastDisconnection); + field_from_json(Obj, "pings", pings); + field_from_json(Obj, "states", states); + field_from_json(Obj, "connected", connected); + field_from_json(Obj, "connectionIp", connectionIp); + field_from_json(Obj, "associations_2g", associations_2g); + field_from_json(Obj, "associations_5g", associations_5g); + field_from_json(Obj, "associations_6g", associations_6g); + field_from_json(Obj, "health", health); + field_from_json(Obj, "lastHealth", lastHealth); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "uptime", uptime); + field_from_json(Obj, "memory", memory); + return true; + } catch (...) { + } + return false; + } - void DeviceInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"boardId",boardId); - field_to_json(Obj,"type",type); - field_to_json(Obj,"serialNumber",serialNumber); - field_to_json(Obj,"deviceType",deviceType); - field_to_json(Obj,"lastContact",lastContact); - field_to_json(Obj,"lastPing",lastPing); - field_to_json(Obj,"lastState",lastState); - field_to_json(Obj,"lastFirmware",lastFirmware); - field_to_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate); - field_to_json(Obj,"lastConnection",lastConnection); - field_to_json(Obj,"lastDisconnection",lastDisconnection); - field_to_json(Obj,"pings",pings); - field_to_json(Obj,"states",states); - field_to_json(Obj,"connected",connected); - field_to_json(Obj,"connectionIp",connectionIp); - field_to_json(Obj,"associations_2g",associations_2g); - field_to_json(Obj,"associations_5g",associations_5g); - field_to_json(Obj,"associations_6g",associations_6g); - field_to_json(Obj,"health",health); - field_to_json(Obj,"lastHealth",lastHealth); - field_to_json(Obj,"locale",locale); - field_to_json(Obj,"uptime",uptime); - field_to_json(Obj,"memory",memory); - } + void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "devices", devices); + } - bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"boardId",boardId); - field_from_json(Obj,"type",type); - field_from_json(Obj,"serialNumber",serialNumber); - field_from_json(Obj,"deviceType",deviceType); - field_from_json(Obj,"lastContact",lastContact); - field_from_json(Obj,"lastPing",lastPing); - field_from_json(Obj,"lastState",lastState); - field_from_json(Obj,"lastFirmware",lastFirmware); - field_from_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate); - field_from_json(Obj,"lastConnection",lastConnection); - field_from_json(Obj,"lastDisconnection",lastDisconnection); - field_from_json(Obj,"pings",pings); - field_from_json(Obj,"states",states); - field_from_json(Obj,"connected",connected); - field_from_json(Obj,"connectionIp",connectionIp); - field_from_json(Obj,"associations_2g",associations_2g); - field_from_json(Obj,"associations_5g",associations_5g); - field_from_json(Obj,"associations_6g",associations_6g); - field_from_json(Obj,"health",health); - field_from_json(Obj,"lastHealth",lastHealth); - field_from_json(Obj,"locale",locale); - field_from_json(Obj,"uptime",uptime); - field_from_json(Obj,"memory",memory); - return true; - } catch(...) { + bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "devices", devices); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void UE_rate::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "bitrate", bitrate); + field_to_json(Obj, "mcs", mcs); + field_to_json(Obj, "nss", nss); + field_to_json(Obj, "ht", ht); + field_to_json(Obj, "sgi", sgi); + field_to_json(Obj, "chwidth", chwidth); + } - void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"devices",devices); - } + bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "bitrate", bitrate); + field_from_json(Obj, "mcs", mcs); + field_from_json(Obj, "nss", nss); + field_from_json(Obj, "ht", ht); + field_from_json(Obj, "sgi", sgi); + field_from_json(Obj, "chwidth", chwidth); + return true; + } catch (...) { + } + return false; + } - bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"devices",devices); - return true; - } catch(...) { + void UETimePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "station", station); + field_to_json(Obj, "rssi", rssi); + field_to_json(Obj, "tx_bytes", tx_bytes); + field_to_json(Obj, "rx_bytes", rx_bytes); + field_to_json(Obj, "tx_duration", tx_duration); + field_to_json(Obj, "rx_packets", rx_packets); + field_to_json(Obj, "tx_packets", tx_packets); + field_to_json(Obj, "tx_retries", tx_retries); + field_to_json(Obj, "tx_failed", tx_failed); + field_to_json(Obj, "connected", connected); + field_to_json(Obj, "inactive", inactive); + field_to_json(Obj, "tx_rate", tx_rate); + field_to_json(Obj, "rx_rate", rx_rate); + // field_to_json(Obj, "tidstats", tidstats); - } - return false; - } + field_to_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_to_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_to_json(Obj, "tx_packets_bw", tx_packets_bw); + field_to_json(Obj, "rx_packets_bw", rx_packets_bw); + field_to_json(Obj, "tx_failed_pct", tx_failed_pct); + field_to_json(Obj, "tx_retries_pct", tx_retries_pct); + field_to_json(Obj, "tx_duration_pct", tx_duration_pct); - void UE_rate::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"bitrate",bitrate); - field_to_json(Obj,"mcs",mcs); - field_to_json(Obj,"nss",nss); - field_to_json(Obj,"ht",ht); - field_to_json(Obj,"sgi",sgi); - field_to_json(Obj,"chwidth",chwidth); - } + field_to_json(Obj, "tx_bytes_delta", tx_bytes_delta); + field_to_json(Obj, "rx_bytes_delta", rx_bytes_delta); + field_to_json(Obj, "tx_packets_delta", tx_packets_delta); + field_to_json(Obj, "rx_packets_delta", rx_packets_delta); + field_to_json(Obj, "tx_failed_delta", tx_failed_delta); + field_to_json(Obj, "tx_retries_delta", tx_retries_delta); + field_to_json(Obj, "tx_duration_delta", tx_duration_delta); + } - bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"bitrate",bitrate); - field_from_json(Obj,"mcs",mcs); - field_from_json(Obj,"nss",nss); - field_from_json(Obj,"ht",ht); - field_from_json(Obj,"sgi",sgi); - field_from_json(Obj,"chwidth",chwidth); - return true; - } catch(...) { + bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "station", station); + field_from_json(Obj, "rssi", rssi); + field_from_json(Obj, "tx_bytes", tx_bytes); + field_from_json(Obj, "rx_bytes", rx_bytes); + field_from_json(Obj, "tx_duration", tx_duration); + field_from_json(Obj, "rx_packets", rx_packets); + field_from_json(Obj, "tx_packets", tx_packets); + field_from_json(Obj, "tx_retries", tx_retries); + field_from_json(Obj, "tx_failed", tx_failed); + field_from_json(Obj, "connected", connected); + field_from_json(Obj, "inactive", inactive); + field_from_json(Obj, "tx_rate", tx_rate); + field_from_json(Obj, "rx_rate", rx_rate); + // field_from_json(Obj,"tidstats",tidstats); + field_from_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_from_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_from_json(Obj, "tx_packets_bw", tx_packets_bw); + field_from_json(Obj, "rx_packets_bw", rx_packets_bw); + field_from_json(Obj, "tx_failed_pct", tx_failed_pct); + field_from_json(Obj, "tx_retries_pct", tx_retries_pct); + field_from_json(Obj, "tx_duration_pct", tx_duration_pct); + field_from_json(Obj, "tx_bytes_delta", tx_bytes_delta); + field_from_json(Obj, "rx_bytes_delta", rx_bytes_delta); + field_from_json(Obj, "tx_packets_delta", tx_packets_delta); + field_from_json(Obj, "rx_packets_delta", rx_packets_delta); + field_from_json(Obj, "tx_failed_delta", tx_failed_delta); + field_from_json(Obj, "tx_retries_delta", tx_retries_delta); + field_from_json(Obj, "tx_duration_delta", tx_duration_delta); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void APTimePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "collisions", collisions); + field_to_json(Obj, "multicast", multicast); + field_to_json(Obj, "rx_bytes", rx_bytes); + field_to_json(Obj, "rx_dropped", rx_dropped); + field_to_json(Obj, "rx_errors", rx_errors); + field_to_json(Obj, "rx_packets", rx_packets); + field_to_json(Obj, "tx_bytes", tx_bytes); + field_to_json(Obj, "tx_packets", tx_packets); + field_to_json(Obj, "tx_dropped", tx_dropped); + field_to_json(Obj, "tx_errors", tx_errors); + field_to_json(Obj, "tx_packets", tx_packets); - void UETimePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"station",station); - field_to_json(Obj,"rssi",rssi); - field_to_json(Obj,"tx_bytes",tx_bytes); - field_to_json(Obj,"rx_bytes",rx_bytes); - field_to_json(Obj,"tx_duration",tx_duration); - field_to_json(Obj,"rx_packets",rx_packets); - field_to_json(Obj,"tx_packets",tx_packets); - field_to_json(Obj,"tx_retries",tx_retries); - field_to_json(Obj,"tx_failed",tx_failed); - field_to_json(Obj,"connected",connected); - field_to_json(Obj,"inactive",inactive); - field_to_json(Obj,"tx_rate",tx_rate); - field_to_json(Obj,"rx_rate",rx_rate); -// field_to_json(Obj, "tidstats", tidstats); + field_to_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_to_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_to_json(Obj, "rx_dropped_pct", rx_dropped_pct); + field_to_json(Obj, "tx_dropped_pct", tx_dropped_pct); + field_to_json(Obj, "rx_packets_bw", rx_packets_bw); + field_to_json(Obj, "tx_packets_bw", tx_packets_bw); + field_to_json(Obj, "rx_errors_pct", rx_errors_pct); + field_to_json(Obj, "tx_errors_pct", tx_errors_pct); - field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_to_json(Obj,"tx_packets_bw",tx_packets_bw); - field_to_json(Obj,"rx_packets_bw",rx_packets_bw); - field_to_json(Obj,"tx_failed_pct",tx_failed_pct); - field_to_json(Obj,"tx_retries_pct",tx_retries_pct); - field_to_json(Obj,"tx_duration_pct",tx_duration_pct); + field_to_json(Obj, "tx_bytes_delta", tx_bytes_delta); + field_to_json(Obj, "rx_bytes_delta", rx_bytes_delta); + field_to_json(Obj, "rx_dropped_delta", rx_dropped_delta); + field_to_json(Obj, "tx_dropped_delta", tx_dropped_delta); + field_to_json(Obj, "rx_packets_delta", rx_packets_delta); + field_to_json(Obj, "tx_packets_delta", tx_packets_delta); + field_to_json(Obj, "rx_errors_delta", rx_errors_delta); + field_to_json(Obj, "tx_errors_delta", tx_errors_delta); + } - field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta); - field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta); - field_to_json(Obj,"tx_packets_delta",tx_packets_delta); - field_to_json(Obj,"rx_packets_delta",rx_packets_delta); - field_to_json(Obj,"tx_failed_delta",tx_failed_delta); - field_to_json(Obj,"tx_retries_delta",tx_retries_delta); - field_to_json(Obj,"tx_duration_delta",tx_duration_delta); - } + bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "collisions", collisions); + field_from_json(Obj, "multicast", multicast); + field_from_json(Obj, "rx_bytes", rx_bytes); + field_from_json(Obj, "rx_dropped", rx_dropped); + field_from_json(Obj, "rx_errors", rx_errors); + field_from_json(Obj, "rx_packets", rx_packets); + field_from_json(Obj, "tx_bytes", tx_bytes); + field_from_json(Obj, "tx_packets", tx_packets); + field_from_json(Obj, "tx_dropped", tx_dropped); + field_from_json(Obj, "tx_errors", tx_errors); + field_from_json(Obj, "tx_packets", tx_packets); - bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"station",station); - field_from_json(Obj,"rssi",rssi); - field_from_json(Obj,"tx_bytes",tx_bytes); - field_from_json(Obj,"rx_bytes",rx_bytes); - field_from_json(Obj,"tx_duration",tx_duration); - field_from_json(Obj,"rx_packets",rx_packets); - field_from_json(Obj,"tx_packets",tx_packets); - field_from_json(Obj,"tx_retries",tx_retries); - field_from_json(Obj,"tx_failed",tx_failed); - field_from_json(Obj,"connected",connected); - field_from_json(Obj,"inactive",inactive); - field_from_json(Obj,"tx_rate",tx_rate); - field_from_json(Obj,"rx_rate",rx_rate); -// field_from_json(Obj,"tidstats",tidstats); - field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_from_json(Obj,"tx_packets_bw",tx_packets_bw); - field_from_json(Obj,"rx_packets_bw",rx_packets_bw); - field_from_json(Obj,"tx_failed_pct",tx_failed_pct); - field_from_json(Obj,"tx_retries_pct",tx_retries_pct); - field_from_json(Obj,"tx_duration_pct",tx_duration_pct); - field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta); - field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta); - field_from_json(Obj,"tx_packets_delta",tx_packets_delta); - field_from_json(Obj,"rx_packets_delta",rx_packets_delta); - field_from_json(Obj,"tx_failed_delta",tx_failed_delta); - field_from_json(Obj,"tx_retries_delta",tx_retries_delta); - field_from_json(Obj,"tx_duration_delta",tx_duration_delta); - return true; - } catch(...) { + field_from_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_from_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_from_json(Obj, "rx_dropped_pct", rx_dropped_pct); + field_from_json(Obj, "tx_dropped_pct", tx_dropped_pct); + field_from_json(Obj, "rx_packets_bw", rx_packets_bw); + field_from_json(Obj, "tx_packets_bw", tx_packets_bw); + field_from_json(Obj, "rx_errors_pct", rx_errors_pct); + field_from_json(Obj, "tx_errors_pct", tx_errors_pct); - } - return false; - } + field_from_json(Obj, "tx_bytes_delta", tx_bytes_delta); + field_from_json(Obj, "rx_bytes_delta", rx_bytes_delta); + field_from_json(Obj, "rx_dropped_delta", rx_dropped_delta); + field_from_json(Obj, "tx_dropped_delta", tx_dropped_delta); + field_from_json(Obj, "rx_packets_delta", rx_packets_delta); + field_from_json(Obj, "tx_packets_delta", tx_packets_delta); + field_from_json(Obj, "rx_errors_delta", rx_errors_delta); + field_from_json(Obj, "tx_errors_delta", tx_errors_delta); - void APTimePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"collisions",collisions); - field_to_json(Obj,"multicast",multicast); - field_to_json(Obj,"rx_bytes",rx_bytes); - field_to_json(Obj,"rx_dropped",rx_dropped); - field_to_json(Obj,"rx_errors",rx_errors); - field_to_json(Obj,"rx_packets",rx_packets); - field_to_json(Obj,"tx_bytes",tx_bytes); - field_to_json(Obj,"tx_packets",tx_packets); - field_to_json(Obj,"tx_dropped",tx_dropped); - field_to_json(Obj,"tx_errors",tx_errors); - field_to_json(Obj,"tx_packets",tx_packets); + return true; + } catch (...) { + } + return false; + } - field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct); - field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct); - field_to_json(Obj,"rx_packets_bw",rx_packets_bw); - field_to_json(Obj,"tx_packets_bw",tx_packets_bw); - field_to_json(Obj,"rx_errors_pct",rx_errors_pct); - field_to_json(Obj,"tx_errors_pct",tx_errors_pct); + void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "rx_msdu", rx_msdu); + field_to_json(Obj, "tx_msdu", tx_msdu); + field_to_json(Obj, "tx_msdu_failed", tx_msdu_failed); + field_to_json(Obj, "tx_msdu_retries", tx_msdu_retries); + } - field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta); - field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta); - field_to_json(Obj,"rx_dropped_delta",rx_dropped_delta); - field_to_json(Obj,"tx_dropped_delta",tx_dropped_delta); - field_to_json(Obj,"rx_packets_delta",rx_packets_delta); - field_to_json(Obj,"tx_packets_delta",tx_packets_delta); - field_to_json(Obj,"rx_errors_delta",rx_errors_delta); - field_to_json(Obj,"tx_errors_delta",tx_errors_delta); - } + bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "rx_msdu", rx_msdu); + field_from_json(Obj, "tx_msdu", tx_msdu); + field_from_json(Obj, "tx_msdu_failed", tx_msdu_failed); + field_from_json(Obj, "tx_msdu_retries", tx_msdu_retries); + return true; + } catch (...) { + } + return false; + } - bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"collisions",collisions); - field_from_json(Obj,"multicast",multicast); - field_from_json(Obj,"rx_bytes",rx_bytes); - field_from_json(Obj,"rx_dropped",rx_dropped); - field_from_json(Obj,"rx_errors",rx_errors); - field_from_json(Obj,"rx_packets",rx_packets); - field_from_json(Obj,"tx_bytes",tx_bytes); - field_from_json(Obj,"tx_packets",tx_packets); - field_from_json(Obj,"tx_dropped",tx_dropped); - field_from_json(Obj,"tx_errors",tx_errors); - field_from_json(Obj,"tx_packets",tx_packets); + void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "band", band); + field_to_json(Obj, "channel_width", channel_width); + field_to_json(Obj, "active_ms", active_ms); + field_to_json(Obj, "busy_ms", busy_ms); + field_to_json(Obj, "receive_ms", receive_ms); + field_to_json(Obj, "transmit_ms", transmit_ms); + field_to_json(Obj, "tx_power", tx_power); + field_to_json(Obj, "channel", channel); + field_to_json(Obj, "temperature", temperature); + field_to_json(Obj, "noise", noise); + field_to_json(Obj, "active_pct", active_pct); + field_to_json(Obj, "busy_pct", busy_pct); + field_to_json(Obj, "receive_pct", receive_pct); + field_to_json(Obj, "transmit_pct", transmit_pct); + } - field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct); - field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct); - field_from_json(Obj,"rx_packets_bw",rx_packets_bw); - field_from_json(Obj,"tx_packets_bw",tx_packets_bw); - field_from_json(Obj,"rx_errors_pct",rx_errors_pct); - field_from_json(Obj,"tx_errors_pct",tx_errors_pct); + bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "band", band); + field_from_json(Obj, "channel_width", channel_width); + field_from_json(Obj, "active_ms", active_ms); + field_from_json(Obj, "busy_ms", busy_ms); + field_from_json(Obj, "receive_ms", receive_ms); + field_from_json(Obj, "transmit_ms", transmit_ms); + field_from_json(Obj, "tx_power", tx_power); + field_from_json(Obj, "channel", channel); + field_from_json(Obj, "temperature", temperature); + field_from_json(Obj, "noise", noise); + field_from_json(Obj, "active_pct", active_pct); + field_from_json(Obj, "busy_pct", busy_pct); + field_from_json(Obj, "receive_pct", receive_pct); + field_from_json(Obj, "transmit_pct", transmit_pct); + return true; + } catch (...) { + } + return false; + } - field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta); - field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta); - field_from_json(Obj,"rx_dropped_delta",rx_dropped_delta); - field_from_json(Obj,"tx_dropped_delta",tx_dropped_delta); - field_from_json(Obj,"rx_packets_delta",rx_packets_delta); - field_from_json(Obj,"tx_packets_delta",tx_packets_delta); - field_from_json(Obj,"rx_errors_delta",rx_errors_delta); - field_from_json(Obj,"tx_errors_delta",tx_errors_delta); + void AveragePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "min", min); + field_to_json(Obj, "max", max); + field_to_json(Obj, "avg", avg); + } - return true; - } catch(...) { + bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "min", min); + field_from_json(Obj, "max", max); + field_from_json(Obj, "avg", avg); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "bssid", bssid); + field_to_json(Obj, "mode", mode); + field_to_json(Obj, "ssid", ssid); + field_to_json(Obj, "band", band); + field_to_json(Obj, "channel", channel); + field_to_json(Obj, "associations", associations); + field_to_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_to_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_to_json(Obj, "tx_packets_bw", tx_packets_bw); + field_to_json(Obj, "rx_packets_bw", rx_packets_bw); + field_to_json(Obj, "tx_failed_pct", tx_failed_pct); + field_to_json(Obj, "tx_retries_pct", tx_retries_pct); + field_to_json(Obj, "tx_duration_pct", tx_duration_pct); + } - void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"rx_msdu",rx_msdu); - field_to_json(Obj,"tx_msdu",tx_msdu); - field_to_json(Obj,"tx_msdu_failed",tx_msdu_failed); - field_to_json(Obj,"tx_msdu_retries",tx_msdu_retries); - } + bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "bssid", bssid); + field_from_json(Obj, "mode", mode); + field_from_json(Obj, "ssid", ssid); + field_from_json(Obj, "band", band); + field_from_json(Obj, "channel", channel); + field_from_json(Obj, "associations", associations); + field_from_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_from_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_from_json(Obj, "tx_packets_bw", tx_packets_bw); + field_from_json(Obj, "rx_packets_bw", rx_packets_bw); + field_from_json(Obj, "tx_failed_pct", tx_failed_pct); + field_from_json(Obj, "tx_retries_pct", tx_retries_pct); + field_from_json(Obj, "tx_duration_pct", tx_duration_pct); + return true; + } catch (...) { + } + return false; + } - bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"rx_msdu",rx_msdu); - field_from_json(Obj,"tx_msdu",tx_msdu); - field_from_json(Obj,"tx_msdu_failed",tx_msdu_failed); - field_from_json(Obj,"tx_msdu_retries",tx_msdu_retries); - return true; - } catch(...) { + void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "boardId", boardId); + field_to_json(Obj, "timestamp", timestamp); + field_to_json(Obj, "ap_data", ap_data); + field_to_json(Obj, "ssid_data", ssid_data); + field_to_json(Obj, "radio_data", radio_data); + field_to_json(Obj, "device_info", device_info); + field_to_json(Obj, "serialNumber", serialNumber); + } - } - return false; - } + bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "boardId", boardId); + field_from_json(Obj, "timestamp", timestamp); + field_from_json(Obj, "ap_data", ap_data); + field_from_json(Obj, "ssid_data", ssid_data); + field_from_json(Obj, "radio_data", radio_data); + field_from_json(Obj, "device_info", device_info); + field_from_json(Obj, "serialNumber", serialNumber); + return true; + } catch (...) { + } + return false; + } - void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"band",band); - field_to_json(Obj,"channel_width",channel_width); - field_to_json(Obj,"active_ms",active_ms); - field_to_json(Obj,"busy_ms",busy_ms); - field_to_json(Obj,"receive_ms",receive_ms); - field_to_json(Obj,"transmit_ms",transmit_ms); - field_to_json(Obj,"tx_power",tx_power); - field_to_json(Obj,"channel",channel); - field_to_json(Obj,"temperature",temperature); - field_to_json(Obj,"noise",noise); - field_to_json(Obj,"active_pct",active_pct); - field_to_json(Obj,"busy_pct",busy_pct); - field_to_json(Obj,"receive_pct",receive_pct); - field_to_json(Obj,"transmit_pct",transmit_pct); - } + void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "noise", noise); + field_to_json(Obj, "temperature", temperature); + field_to_json(Obj, "active_pct", active_pct); + field_to_json(Obj, "busy_pct", busy_pct); + field_to_json(Obj, "receive_pct", receive_pct); + field_to_json(Obj, "transmit_pct", transmit_pct); + field_to_json(Obj, "tx_power", tx_power); + field_to_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_to_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_to_json(Obj, "rx_dropped_pct", rx_dropped_pct); + field_to_json(Obj, "tx_dropped_pct", tx_dropped_pct); + field_to_json(Obj, "rx_packets_bw", rx_packets_bw); + field_to_json(Obj, "tx_packets_bw", tx_packets_bw); + field_to_json(Obj, "rx_errors_pct", rx_errors_pct); + field_to_json(Obj, "tx_errors_pct", tx_errors_pct); + } - bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"band",band); - field_from_json(Obj,"channel_width",channel_width); - field_from_json(Obj,"active_ms",active_ms); - field_from_json(Obj,"busy_ms",busy_ms); - field_from_json(Obj,"receive_ms",receive_ms); - field_from_json(Obj,"transmit_ms",transmit_ms); - field_from_json(Obj,"tx_power",tx_power); - field_from_json(Obj,"channel",channel); - field_from_json(Obj,"temperature",temperature); - field_from_json(Obj,"noise",noise); - field_from_json(Obj,"active_pct",active_pct); - field_from_json(Obj,"busy_pct",busy_pct); - field_from_json(Obj,"receive_pct",receive_pct); - field_from_json(Obj,"transmit_pct",transmit_pct); - return true; - } catch(...) { + bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "noise", noise); + field_from_json(Obj, "temperature", temperature); + field_from_json(Obj, "active_pct", active_pct); + field_from_json(Obj, "busy_pct", busy_pct); + field_from_json(Obj, "receive_pct", receive_pct); + field_from_json(Obj, "transmit_pct", transmit_pct); + field_from_json(Obj, "tx_power", tx_power); + field_from_json(Obj, "tx_bytes_bw", tx_bytes_bw); + field_from_json(Obj, "rx_bytes_bw", rx_bytes_bw); + field_from_json(Obj, "rx_dropped_pct", rx_dropped_pct); + field_from_json(Obj, "tx_dropped_pct", tx_dropped_pct); + field_from_json(Obj, "rx_packets_bw", rx_packets_bw); + field_from_json(Obj, "tx_packets_bw", tx_packets_bw); + field_from_json(Obj, "rx_errors_pct", rx_errors_pct); + field_from_json(Obj, "tx_errors_pct", tx_errors_pct); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "points", points); + field_to_json(Obj, "stats", stats); + } - void AveragePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"min",min); - field_to_json(Obj,"max",max); - field_to_json(Obj,"avg",avg); - } + bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "points", points); + field_from_json(Obj, "stats", stats); + return true; + } catch (...) { + } + return false; + } - bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"min",min); - field_from_json(Obj,"max",max); - field_from_json(Obj,"avg",avg); - return true; - } catch(...) { + void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "firstPoint", firstPoint); + field_to_json(Obj, "lastPoint", lastPoint); + field_to_json(Obj, "count", count); + } - } - return false; - } + bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "firstPoint", firstPoint); + field_from_json(Obj, "lastPoint", lastPoint); + field_from_json(Obj, "count", count); + return true; + } catch (...) { + } + return false; + } - void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"bssid",bssid); - field_to_json(Obj,"mode",mode); - field_to_json(Obj,"ssid",ssid); - field_to_json(Obj,"band",band); - field_to_json(Obj,"channel",channel); - field_to_json(Obj,"associations",associations); - field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_to_json(Obj,"tx_packets_bw",tx_packets_bw); - field_to_json(Obj,"rx_packets_bw",rx_packets_bw); - field_to_json(Obj,"tx_failed_pct",tx_failed_pct); - field_to_json(Obj,"tx_retries_pct",tx_retries_pct); - field_to_json(Obj,"tx_duration_pct",tx_duration_pct); - } + void WifiClientRate::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "bitrate", bitrate); + field_to_json(Obj, "chwidth", chwidth); + field_to_json(Obj, "mcs", mcs); + field_to_json(Obj, "nss", nss); + field_to_json(Obj, "vht", vht); + } - bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"bssid",bssid); - field_from_json(Obj,"mode",mode); - field_from_json(Obj,"ssid",ssid); - field_from_json(Obj,"band",band); - field_from_json(Obj,"channel",channel); - field_from_json(Obj,"associations",associations); - field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_from_json(Obj,"tx_packets_bw",tx_packets_bw); - field_from_json(Obj,"rx_packets_bw",rx_packets_bw); - field_from_json(Obj,"tx_failed_pct",tx_failed_pct); - field_from_json(Obj,"tx_retries_pct",tx_retries_pct); - field_from_json(Obj,"tx_duration_pct",tx_duration_pct); - return true; - } catch(...) { + bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "bitrate", bitrate); + field_from_json(Obj, "chwidth", chwidth); + field_from_json(Obj, "mcs", mcs); + field_from_json(Obj, "nss", nss); + field_from_json(Obj, "vht", vht); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "timestamp", timestamp); + field_to_json(Obj, "station_id", station_id); + field_to_json(Obj, "bssid", bssid); + field_to_json(Obj, "ssid", ssid); + field_to_json(Obj, "rssi", rssi); + field_to_json(Obj, "rx_bitrate", rx_bitrate); + field_to_json(Obj, "rx_chwidth", rx_chwidth); + field_to_json(Obj, "rx_mcs", rx_mcs); + field_to_json(Obj, "rx_nss", rx_nss); + field_to_json(Obj, "rx_vht", rx_vht); + field_to_json(Obj, "tx_bitrate", tx_bitrate); + field_to_json(Obj, "tx_chwidth", tx_chwidth); + field_to_json(Obj, "tx_mcs", tx_mcs); + field_to_json(Obj, "tx_nss", tx_nss); + field_to_json(Obj, "tx_vht", tx_vht); + field_to_json(Obj, "rx_bytes", rx_bytes); + field_to_json(Obj, "tx_bytes", tx_bytes); + field_to_json(Obj, "rx_duration", rx_duration); + field_to_json(Obj, "tx_duration", tx_duration); + field_to_json(Obj, "rx_packets", rx_packets); + field_to_json(Obj, "tx_packets", tx_packets); + field_to_json(Obj, "ipv4", ipv4); + field_to_json(Obj, "ipv6", ipv6); + field_to_json(Obj, "channel_width", channel_width); + field_to_json(Obj, "noise", noise); + field_to_json(Obj, "tx_power", tx_power); + field_to_json(Obj, "channel", channel); + field_to_json(Obj, "active_ms", active_ms); + field_to_json(Obj, "busy_ms", busy_ms); + field_to_json(Obj, "receive_ms", receive_ms); + field_to_json(Obj, "mode", mode); + field_to_json(Obj, "ack_signal", ack_signal); + field_to_json(Obj, "ack_signal_avg", ack_signal_avg); + field_to_json(Obj, "connected", connected); + field_to_json(Obj, "inactive", inactive); + field_to_json(Obj, "tx_retries", tx_retries); + field_to_json(Obj, "venue_id", venue_id); + } - void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"boardId",boardId); - field_to_json(Obj,"timestamp",timestamp); - field_to_json(Obj,"ap_data",ap_data); - field_to_json(Obj,"ssid_data",ssid_data); - field_to_json(Obj,"radio_data",radio_data); - field_to_json(Obj,"device_info",device_info); - field_to_json(Obj,"serialNumber",serialNumber); - } - - bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"boardId",boardId); - field_from_json(Obj,"timestamp",timestamp); - field_from_json(Obj,"ap_data",ap_data); - field_from_json(Obj,"ssid_data",ssid_data); - field_from_json(Obj,"radio_data",radio_data); - field_from_json(Obj,"device_info",device_info); - field_from_json(Obj,"serialNumber",serialNumber); - return true; - } catch(...) { - - } - return false; - } - - void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"noise",noise); - field_to_json(Obj,"temperature",temperature); - field_to_json(Obj,"active_pct",active_pct); - field_to_json(Obj,"busy_pct",busy_pct); - field_to_json(Obj,"receive_pct",receive_pct); - field_to_json(Obj,"transmit_pct",transmit_pct); - field_to_json(Obj,"tx_power",tx_power); - field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct); - field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct); - field_to_json(Obj,"rx_packets_bw",rx_packets_bw); - field_to_json(Obj,"tx_packets_bw",tx_packets_bw); - field_to_json(Obj,"rx_errors_pct",rx_errors_pct); - field_to_json(Obj,"tx_errors_pct",tx_errors_pct); - } - - bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"noise",noise); - field_from_json(Obj,"temperature",temperature); - field_from_json(Obj,"active_pct",active_pct); - field_from_json(Obj,"busy_pct",busy_pct); - field_from_json(Obj,"receive_pct",receive_pct); - field_from_json(Obj,"transmit_pct",transmit_pct); - field_from_json(Obj,"tx_power",tx_power); - field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw); - field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw); - field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct); - field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct); - field_from_json(Obj,"rx_packets_bw",rx_packets_bw); - field_from_json(Obj,"tx_packets_bw",tx_packets_bw); - field_from_json(Obj,"rx_errors_pct",rx_errors_pct); - field_from_json(Obj,"tx_errors_pct",tx_errors_pct); - return true; - } catch(...) { - - } - return false; - } - - void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"points",points); - field_to_json(Obj,"stats",stats); - } - - bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"points",points); - field_from_json(Obj,"stats",stats); - return true; - } catch(...) { - - } - return false; - } - - void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"firstPoint",firstPoint); - field_to_json(Obj,"lastPoint",lastPoint); - field_to_json(Obj,"count",count); - } - - bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"firstPoint",firstPoint); - field_from_json(Obj,"lastPoint",lastPoint); - field_from_json(Obj,"count",count); - return true; - } catch(...) { - - } - return false; - } - - void WifiClientRate::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"bitrate",bitrate); - field_to_json(Obj,"chwidth",chwidth); - field_to_json(Obj,"mcs",mcs); - field_to_json(Obj,"nss",nss); - field_to_json(Obj,"vht",vht); - } - - bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"bitrate",bitrate); - field_from_json(Obj,"chwidth",chwidth); - field_from_json(Obj,"mcs",mcs); - field_from_json(Obj,"nss",nss); - field_from_json(Obj,"vht",vht); - return true; - } catch(...) { - - } - return false; - } - - void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"timestamp",timestamp); - field_to_json(Obj,"station_id",station_id); - field_to_json(Obj,"bssid",bssid); - field_to_json(Obj,"ssid",ssid); - field_to_json(Obj,"rssi",rssi); - field_to_json(Obj,"rx_bitrate",rx_bitrate); - field_to_json(Obj,"rx_chwidth",rx_chwidth); - field_to_json(Obj,"rx_mcs",rx_mcs); - field_to_json(Obj,"rx_nss",rx_nss); - field_to_json(Obj,"rx_vht",rx_vht); - field_to_json(Obj,"tx_bitrate",tx_bitrate); - field_to_json(Obj,"tx_chwidth",tx_chwidth); - field_to_json(Obj,"tx_mcs",tx_mcs); - field_to_json(Obj,"tx_nss",tx_nss); - field_to_json(Obj,"tx_vht",tx_vht); - field_to_json(Obj,"rx_bytes",rx_bytes); - field_to_json(Obj,"tx_bytes",tx_bytes); - field_to_json(Obj,"rx_duration",rx_duration); - field_to_json(Obj,"tx_duration",tx_duration); - field_to_json(Obj,"rx_packets",rx_packets); - field_to_json(Obj,"tx_packets",tx_packets); - field_to_json(Obj,"ipv4",ipv4); - field_to_json(Obj,"ipv6",ipv6); - field_to_json(Obj,"channel_width",channel_width); - field_to_json(Obj,"noise",noise); - field_to_json(Obj,"tx_power",tx_power); - field_to_json(Obj,"channel",channel); - field_to_json(Obj,"active_ms",active_ms); - field_to_json(Obj,"busy_ms",busy_ms); - field_to_json(Obj,"receive_ms",receive_ms); - field_to_json(Obj,"mode",mode); - field_to_json(Obj,"ack_signal",ack_signal); - field_to_json(Obj,"ack_signal_avg",ack_signal_avg); - field_to_json(Obj,"connected",connected); - field_to_json(Obj,"inactive",inactive); - field_to_json(Obj,"tx_retries",tx_retries); - field_to_json(Obj,"venue_id",venue_id); - } - - bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"timestamp",timestamp); - field_from_json(Obj,"station_id",station_id); - field_from_json(Obj,"bssid",bssid); - field_from_json(Obj,"ssid",ssid); - field_from_json(Obj,"rssi",rssi); - field_from_json(Obj,"rx_bitrate",rx_bitrate); - field_from_json(Obj,"rx_chwidth",rx_chwidth); - field_from_json(Obj,"rx_mcs",rx_mcs); - field_from_json(Obj,"rx_nss",rx_nss); - field_from_json(Obj,"rx_vht",rx_vht); - field_from_json(Obj,"tx_bitrate",tx_bitrate); - field_from_json(Obj,"tx_chwidth",tx_chwidth); - field_from_json(Obj,"tx_mcs",tx_mcs); - field_from_json(Obj,"tx_nss",tx_nss); - field_from_json(Obj,"tx_vht",tx_vht); - field_from_json(Obj,"rx_bytes",rx_bytes); - field_from_json(Obj,"tx_bytes",tx_bytes); - field_from_json(Obj,"rx_duration",rx_duration); - field_from_json(Obj,"tx_duration",tx_duration); - field_from_json(Obj,"rx_packets",rx_packets); - field_from_json(Obj,"tx_packets",tx_packets); - field_from_json(Obj,"ipv4",ipv4); - field_from_json(Obj,"ipv6",ipv6); - field_from_json(Obj,"channel_width",channel_width); - field_from_json(Obj,"noise",noise); - field_from_json(Obj,"tx_power",tx_power); - field_from_json(Obj,"channel",channel); - field_from_json(Obj,"active_ms",active_ms); - field_from_json(Obj,"busy_ms",busy_ms); - field_from_json(Obj,"receive_ms",receive_ms); - field_from_json(Obj,"mode",mode); - field_from_json(Obj,"ack_signal",ack_signal); - field_from_json(Obj,"ack_signal_avg",ack_signal_avg); - field_from_json(Obj,"connected",connected); - field_from_json(Obj,"inactive",inactive); - field_from_json(Obj,"tx_retries",tx_retries); - field_from_json(Obj,"venue_id",venue_id); - return true; - } catch(...) { - - } - return false; - } -} \ No newline at end of file + bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "timestamp", timestamp); + field_from_json(Obj, "station_id", station_id); + field_from_json(Obj, "bssid", bssid); + field_from_json(Obj, "ssid", ssid); + field_from_json(Obj, "rssi", rssi); + field_from_json(Obj, "rx_bitrate", rx_bitrate); + field_from_json(Obj, "rx_chwidth", rx_chwidth); + field_from_json(Obj, "rx_mcs", rx_mcs); + field_from_json(Obj, "rx_nss", rx_nss); + field_from_json(Obj, "rx_vht", rx_vht); + field_from_json(Obj, "tx_bitrate", tx_bitrate); + field_from_json(Obj, "tx_chwidth", tx_chwidth); + field_from_json(Obj, "tx_mcs", tx_mcs); + field_from_json(Obj, "tx_nss", tx_nss); + field_from_json(Obj, "tx_vht", tx_vht); + field_from_json(Obj, "rx_bytes", rx_bytes); + field_from_json(Obj, "tx_bytes", tx_bytes); + field_from_json(Obj, "rx_duration", rx_duration); + field_from_json(Obj, "tx_duration", tx_duration); + field_from_json(Obj, "rx_packets", rx_packets); + field_from_json(Obj, "tx_packets", tx_packets); + field_from_json(Obj, "ipv4", ipv4); + field_from_json(Obj, "ipv6", ipv6); + field_from_json(Obj, "channel_width", channel_width); + field_from_json(Obj, "noise", noise); + field_from_json(Obj, "tx_power", tx_power); + field_from_json(Obj, "channel", channel); + field_from_json(Obj, "active_ms", active_ms); + field_from_json(Obj, "busy_ms", busy_ms); + field_from_json(Obj, "receive_ms", receive_ms); + field_from_json(Obj, "mode", mode); + field_from_json(Obj, "ack_signal", ack_signal); + field_from_json(Obj, "ack_signal_avg", ack_signal_avg); + field_from_json(Obj, "connected", connected); + field_from_json(Obj, "inactive", inactive); + field_from_json(Obj, "tx_retries", tx_retries); + field_from_json(Obj, "venue_id", venue_id); + return true; + } catch (...) { + } + return false; + } +} // namespace OpenWifi::AnalyticsObjects \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.h b/src/RESTObjects/RESTAPI_AnalyticsObjects.h index d5585f5..dac46c7 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.h +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.h @@ -10,414 +10,334 @@ namespace OpenWifi { - namespace AnalyticsObjects { - - struct Report { - uint64_t snapShot = 0; - - void reset(); - - void to_json(Poco::JSON::Object &Obj) const; - }; - - struct VenueInfo { - OpenWifi::Types::UUID_t id; - std::string name; - std::string description; - uint64_t retention = 0; - uint64_t interval = 0; - bool monitorSubVenues = false; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct BoardInfo { - ProvObjects::ObjectInfo info; - std::vector venueList; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - - inline bool operator<(const BoardInfo &bb) const { - return info.id < bb.info.id; - } - - inline bool operator==(const BoardInfo &bb) const { - return info.id == bb.info.id; - } - }; - - struct DeviceInfo { - std::string boardId; - std::string type; - std::string serialNumber; - std::string deviceType; - uint64_t lastContact = 0 ; - uint64_t lastPing = 0; - uint64_t lastState = 0; - std::string lastFirmware; - uint64_t lastFirmwareUpdate = 0; - uint64_t lastConnection = 0; - uint64_t lastDisconnection = 0; - uint64_t pings = 0; - uint64_t states = 0; - bool connected = false; - std::string connectionIp; - uint64_t associations_2g = 0; - uint64_t associations_5g = 0; - uint64_t associations_6g = 0; - uint64_t health = 0; - uint64_t lastHealth = 0; - std::string locale; - uint64_t uptime = 0; - double memory = 0.0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct DeviceInfoList { - std::vector devices; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - enum wifi_band { - band_2g = 0, band_5g = 1, band_6g = 2 - }; - - struct TIDstat_entry { - uint64_t rx_msdu = 0, - tx_msdu = 0, - tx_msdu_failed = 0, - tx_msdu_retries = 0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct UE_rate { - uint64_t bitrate=0; - uint64_t mcs=0; - uint64_t nss=0; - bool ht=false; - bool sgi=false; - uint64_t chwidth=0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct AveragePoint { - double min = 0.0, - max = 0.0, - avg = 0.0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct UETimePoint { - std::string station; - int64_t rssi = 0; - uint64_t tx_bytes = 0, - rx_bytes = 0, - tx_duration = 0, - rx_packets = 0, - tx_packets = 0, - tx_retries = 0, - tx_failed = 0, - connected = 0, - inactive = 0; - - double tx_bytes_bw = 0.0 , - rx_bytes_bw = 0.0 , - tx_packets_bw = 0.0 , - rx_packets_bw = 0.0 , - tx_failed_pct = 0.0 , - tx_retries_pct = 0.0 , - tx_duration_pct = 0.0; - - uint64_t tx_bytes_delta = 0, - rx_bytes_delta = 0, - tx_duration_delta = 0, - rx_packets_delta = 0, - tx_packets_delta = 0, - tx_retries_delta = 0, - tx_failed_delta = 0; - - UE_rate tx_rate, - rx_rate; - std::vector tidstats; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - enum SSID_MODES { - unknown = 0, - ap, - mesh, - sta, - wds_ap, - wds_sta, - wds_repeater - }; - - inline SSID_MODES SSID_Mode(const std::string &m) { - if (m == "ap") - return ap; - if (m == "sta") - return sta; - if (m == "mesh") - return mesh; - if (m == "wds-ap") - return wds_ap; - if (m == "wds-sta") - return wds_sta; - if (m == "wds-repeater") - return wds_repeater; - return unknown; - } - - struct SSIDTimePoint { - std::string bssid, - mode, - ssid; - uint64_t band=0, - channel=0; - std::vector associations; - - AveragePoint tx_bytes_bw, - rx_bytes_bw, - tx_packets_bw, - rx_packets_bw, - tx_failed_pct, - tx_retries_pct, - tx_duration_pct; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - - struct APTimePoint { - uint64_t collisions = 0, - multicast = 0, - rx_bytes = 0, - rx_dropped = 0, - rx_errors = 0, - rx_packets = 0, - tx_bytes = 0, - tx_dropped = 0, - tx_errors = 0, - tx_packets = 0; - - double tx_bytes_bw = 0.0 , - rx_bytes_bw = 0.0 , - rx_dropped_pct = 0.0, - tx_dropped_pct = 0.0, - rx_packets_bw = 0.0, - tx_packets_bw = 0.0, - rx_errors_pct = 0.0 , - tx_errors_pct = 0.0; - - uint64_t tx_bytes_delta = 0, - rx_bytes_delta = 0 , - rx_dropped_delta = 0, - tx_dropped_delta = 0, - rx_packets_delta = 0, - tx_packets_delta = 0, - rx_errors_delta = 0, - tx_errors_delta = 0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct RadioTimePoint { - uint64_t band = 0, - channel_width = 0; - uint64_t active_ms = 0, - busy_ms = 0, - receive_ms = 0, - transmit_ms = 0, - tx_power = 0, - channel = 0; - int64_t temperature = 0, - noise = 0; - - double active_pct = 0.0 , - busy_pct = 0.0, - receive_pct = 0.0, - transmit_pct = 0.0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - - struct DeviceTimePoint { - std::string id; - std::string boardId; - uint64_t timestamp = 0; - APTimePoint ap_data; - std::vector ssid_data; - std::vector radio_data; - AnalyticsObjects::DeviceInfo device_info; - std::string serialNumber; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - - inline bool operator<(const DeviceTimePoint &rhs) const { - if(timestamp < rhs.timestamp) - return true; - if(timestamp > rhs.timestamp) - return false; - if(device_info.serialNumber < rhs.device_info.serialNumber) - return true; - return false; - } - - inline bool operator==(const DeviceTimePoint &rhs) const { - return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber; - } - - inline bool operator>(const DeviceTimePoint &rhs) const { - if(timestamp > rhs.timestamp) - return true; - if(timestamp < rhs.timestamp) - return false; - if(device_info.serialNumber > rhs.device_info.serialNumber) - return true; - return false; - } - - }; - - struct DeviceTimePointAnalysis { - uint64_t timestamp; - - AveragePoint noise; - AveragePoint temperature; - AveragePoint active_pct; - AveragePoint busy_pct; - AveragePoint receive_pct; - AveragePoint transmit_pct; - AveragePoint tx_power; - - AveragePoint tx_bytes_bw; - AveragePoint rx_bytes_bw; - AveragePoint rx_dropped_pct; - AveragePoint tx_dropped_pct; - AveragePoint rx_packets_bw; - AveragePoint tx_packets_bw; - AveragePoint rx_errors_pct; - AveragePoint tx_errors_pct; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - - }; - - struct DeviceTimePointList { - std::vector points; - std::vector stats; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct BandwidthAnalysisEntry { - uint64_t timestamp = 0; - - }; - - struct BandwidthAnalysis { - - }; - - struct AverageValueSigned { - int64_t peak=0, avg=0, low=0; - }; - - struct AverageValueUnsigned { - uint64_t peak=0, avg=0, low=0; - }; - - struct RadioAnalysis { - uint64_t timestamp=0; - AverageValueSigned noise, temperature; - AverageValueUnsigned active_ms, - busy_ms, - transmit_ms, - receive_ms; - }; - - struct DeviceTimePointStats { - uint64_t firstPoint=0; - uint64_t lastPoint=0; - uint64_t count=0; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct WifiClientRate { - uint32_t bitrate=0; - uint32_t chwidth=0; - uint16_t mcs=0; - uint16_t nss=0; - bool vht=false; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct WifiClientHistory { - uint64_t timestamp=Utils::Now(); - std::string station_id; - std::string bssid; - std::string ssid; - int64_t rssi=0; - uint32_t rx_bitrate=0; - uint32_t rx_chwidth=0; - uint16_t rx_mcs=0; - uint16_t rx_nss=0; - bool rx_vht=false; - uint32_t tx_bitrate=0; - uint32_t tx_chwidth=0; - uint16_t tx_mcs=0; - uint16_t tx_nss=0; - bool tx_vht=false; - uint64_t rx_bytes=0; - uint64_t tx_bytes=0; - uint64_t rx_duration=0; - uint64_t tx_duration=0; - uint64_t rx_packets=0; - uint64_t tx_packets=0; - std::string ipv4; - std::string ipv6; - uint64_t channel_width=0; - int64_t noise=0; - uint64_t tx_power=0; - uint64_t channel=0; - uint64_t active_ms=0; - uint64_t busy_ms=0; - uint64_t receive_ms=0; - std::string mode; - int64_t ack_signal=0; - int64_t ack_signal_avg=0; - uint64_t connected=0; - uint64_t inactive=0; - uint64_t tx_retries=0; - std::string venue_id; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - } - -} \ No newline at end of file + namespace AnalyticsObjects { + + struct Report { + uint64_t snapShot = 0; + + void reset(); + + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct VenueInfo { + OpenWifi::Types::UUID_t id; + std::string name; + std::string description; + uint64_t retention = 0; + uint64_t interval = 0; + bool monitorSubVenues = false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct BoardInfo { + ProvObjects::ObjectInfo info; + std::vector venueList; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + + inline bool operator<(const BoardInfo &bb) const { return info.id < bb.info.id; } + + inline bool operator==(const BoardInfo &bb) const { return info.id == bb.info.id; } + }; + + struct DeviceInfo { + std::string boardId; + std::string type; + std::string serialNumber; + std::string deviceType; + uint64_t lastContact = 0; + uint64_t lastPing = 0; + uint64_t lastState = 0; + std::string lastFirmware; + uint64_t lastFirmwareUpdate = 0; + uint64_t lastConnection = 0; + uint64_t lastDisconnection = 0; + uint64_t pings = 0; + uint64_t states = 0; + bool connected = false; + std::string connectionIp; + uint64_t associations_2g = 0; + uint64_t associations_5g = 0; + uint64_t associations_6g = 0; + uint64_t health = 0; + uint64_t lastHealth = 0; + std::string locale; + uint64_t uptime = 0; + double memory = 0.0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct DeviceInfoList { + std::vector devices; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum wifi_band { band_2g = 0, band_5g = 1, band_6g = 2 }; + + struct TIDstat_entry { + uint64_t rx_msdu = 0, tx_msdu = 0, tx_msdu_failed = 0, tx_msdu_retries = 0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct UE_rate { + uint64_t bitrate = 0; + uint64_t mcs = 0; + uint64_t nss = 0; + bool ht = false; + bool sgi = false; + uint64_t chwidth = 0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct AveragePoint { + double min = 0.0, max = 0.0, avg = 0.0; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct UETimePoint { + std::string station; + int64_t rssi = 0; + uint64_t tx_bytes = 0, rx_bytes = 0, tx_duration = 0, rx_packets = 0, tx_packets = 0, + tx_retries = 0, tx_failed = 0, connected = 0, inactive = 0; + + double tx_bytes_bw = 0.0, rx_bytes_bw = 0.0, tx_packets_bw = 0.0, rx_packets_bw = 0.0, + tx_failed_pct = 0.0, tx_retries_pct = 0.0, tx_duration_pct = 0.0; + + uint64_t tx_bytes_delta = 0, rx_bytes_delta = 0, tx_duration_delta = 0, + rx_packets_delta = 0, tx_packets_delta = 0, tx_retries_delta = 0, + tx_failed_delta = 0; + + UE_rate tx_rate, rx_rate; + std::vector tidstats; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum SSID_MODES { unknown = 0, ap, mesh, sta, wds_ap, wds_sta, wds_repeater }; + + inline SSID_MODES SSID_Mode(const std::string &m) { + if (m == "ap") + return ap; + if (m == "sta") + return sta; + if (m == "mesh") + return mesh; + if (m == "wds-ap") + return wds_ap; + if (m == "wds-sta") + return wds_sta; + if (m == "wds-repeater") + return wds_repeater; + return unknown; + } + + struct SSIDTimePoint { + std::string bssid, mode, ssid; + uint64_t band = 0, channel = 0; + std::vector associations; + + AveragePoint tx_bytes_bw, rx_bytes_bw, tx_packets_bw, rx_packets_bw, tx_failed_pct, + tx_retries_pct, tx_duration_pct; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct APTimePoint { + uint64_t collisions = 0, multicast = 0, rx_bytes = 0, rx_dropped = 0, rx_errors = 0, + rx_packets = 0, tx_bytes = 0, tx_dropped = 0, tx_errors = 0, tx_packets = 0; + + double tx_bytes_bw = 0.0, rx_bytes_bw = 0.0, rx_dropped_pct = 0.0, tx_dropped_pct = 0.0, + rx_packets_bw = 0.0, tx_packets_bw = 0.0, rx_errors_pct = 0.0, + tx_errors_pct = 0.0; + + uint64_t tx_bytes_delta = 0, rx_bytes_delta = 0, rx_dropped_delta = 0, + tx_dropped_delta = 0, rx_packets_delta = 0, tx_packets_delta = 0, + rx_errors_delta = 0, tx_errors_delta = 0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct RadioTimePoint { + uint64_t band = 0, channel_width = 0; + uint64_t active_ms = 0, busy_ms = 0, receive_ms = 0, transmit_ms = 0, tx_power = 0, + channel = 0; + int64_t temperature = 0, noise = 0; + + double active_pct = 0.0, busy_pct = 0.0, receive_pct = 0.0, transmit_pct = 0.0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct DeviceTimePoint { + std::string id; + std::string boardId; + uint64_t timestamp = 0; + APTimePoint ap_data; + std::vector ssid_data; + std::vector radio_data; + AnalyticsObjects::DeviceInfo device_info; + std::string serialNumber; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + + inline bool operator<(const DeviceTimePoint &rhs) const { + if (timestamp < rhs.timestamp) + return true; + if (timestamp > rhs.timestamp) + return false; + if (device_info.serialNumber < rhs.device_info.serialNumber) + return true; + return false; + } + + inline bool operator==(const DeviceTimePoint &rhs) const { + return timestamp == rhs.timestamp && + device_info.serialNumber == rhs.device_info.serialNumber; + } + + inline bool operator>(const DeviceTimePoint &rhs) const { + if (timestamp > rhs.timestamp) + return true; + if (timestamp < rhs.timestamp) + return false; + if (device_info.serialNumber > rhs.device_info.serialNumber) + return true; + return false; + } + }; + + struct DeviceTimePointAnalysis { + uint64_t timestamp; + + AveragePoint noise; + AveragePoint temperature; + AveragePoint active_pct; + AveragePoint busy_pct; + AveragePoint receive_pct; + AveragePoint transmit_pct; + AveragePoint tx_power; + + AveragePoint tx_bytes_bw; + AveragePoint rx_bytes_bw; + AveragePoint rx_dropped_pct; + AveragePoint tx_dropped_pct; + AveragePoint rx_packets_bw; + AveragePoint tx_packets_bw; + AveragePoint rx_errors_pct; + AveragePoint tx_errors_pct; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct DeviceTimePointList { + std::vector points; + std::vector stats; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct BandwidthAnalysisEntry { + uint64_t timestamp = 0; + }; + + struct BandwidthAnalysis {}; + + struct AverageValueSigned { + int64_t peak = 0, avg = 0, low = 0; + }; + + struct AverageValueUnsigned { + uint64_t peak = 0, avg = 0, low = 0; + }; + + struct RadioAnalysis { + uint64_t timestamp = 0; + AverageValueSigned noise, temperature; + AverageValueUnsigned active_ms, busy_ms, transmit_ms, receive_ms; + }; + + struct DeviceTimePointStats { + uint64_t firstPoint = 0; + uint64_t lastPoint = 0; + uint64_t count = 0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct WifiClientRate { + uint32_t bitrate = 0; + uint32_t chwidth = 0; + uint16_t mcs = 0; + uint16_t nss = 0; + bool vht = false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct WifiClientHistory { + uint64_t timestamp = Utils::Now(); + std::string station_id; + std::string bssid; + std::string ssid; + int64_t rssi = 0; + uint32_t rx_bitrate = 0; + uint32_t rx_chwidth = 0; + uint16_t rx_mcs = 0; + uint16_t rx_nss = 0; + bool rx_vht = false; + uint32_t tx_bitrate = 0; + uint32_t tx_chwidth = 0; + uint16_t tx_mcs = 0; + uint16_t tx_nss = 0; + bool tx_vht = false; + uint64_t rx_bytes = 0; + uint64_t tx_bytes = 0; + uint64_t rx_duration = 0; + uint64_t tx_duration = 0; + uint64_t rx_packets = 0; + uint64_t tx_packets = 0; + std::string ipv4; + std::string ipv6; + uint64_t channel_width = 0; + int64_t noise = 0; + uint64_t tx_power = 0; + uint64_t channel = 0; + uint64_t active_ms = 0; + uint64_t busy_ms = 0; + uint64_t receive_ms = 0; + std::string mode; + int64_t ack_signal = 0; + int64_t ack_signal_avg = 0; + uint64_t connected = 0; + uint64_t inactive = 0; + uint64_t tx_retries = 0; + std::string venue_id; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + } // namespace AnalyticsObjects + +} // namespace OpenWifi \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_CertObjects.cpp b/src/RESTObjects/RESTAPI_CertObjects.cpp index 6b30005..a1a9d6d 100644 --- a/src/RESTObjects/RESTAPI_CertObjects.cpp +++ b/src/RESTObjects/RESTAPI_CertObjects.cpp @@ -5,208 +5,208 @@ #include "RESTAPI_CertObjects.h" #include "framework/RESTAPI_utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::CertObjects { - void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"entity", entity); - field_to_json(Obj,"creator", creator); - field_to_json(Obj,"type", type); - field_to_json(Obj,"status", status); - field_to_json(Obj,"certificate", certificate); - field_to_json(Obj,"key", key); - field_to_json(Obj,"devid", devid); - field_to_json(Obj,"cas", cas); - field_to_json(Obj,"manufacturer", manufacturer); - field_to_json(Obj,"model", model); - field_to_json(Obj,"redirector", redirector); - field_to_json(Obj,"commonName", commonName); - field_to_json(Obj,"certificateId", certificateId); - field_to_json(Obj,"batch", batch); - field_to_json(Obj,"created", created); - field_to_json(Obj,"modified", modified); - field_to_json(Obj,"revoked", revoked); - field_to_json(Obj,"revokeCount", revokeCount); - field_to_json(Obj,"synched", synched); - field_to_json(Obj,"expiryDate", expiryDate); - } + void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "creator", creator); + field_to_json(Obj, "type", type); + field_to_json(Obj, "status", status); + field_to_json(Obj, "certificate", certificate); + field_to_json(Obj, "key", key); + field_to_json(Obj, "devid", devid); + field_to_json(Obj, "cas", cas); + field_to_json(Obj, "manufacturer", manufacturer); + field_to_json(Obj, "model", model); + field_to_json(Obj, "redirector", redirector); + field_to_json(Obj, "commonName", commonName); + field_to_json(Obj, "certificateId", certificateId); + field_to_json(Obj, "batch", batch); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "revoked", revoked); + field_to_json(Obj, "revokeCount", revokeCount); + field_to_json(Obj, "synched", synched); + field_to_json(Obj, "expiryDate", expiryDate); + } - bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"entity", entity); - field_from_json(Obj,"creator", creator); - field_from_json(Obj,"type", type); - field_from_json(Obj,"status", status); - field_from_json(Obj,"certificate", certificate); - field_from_json(Obj,"key", key); - field_from_json(Obj,"devid", devid); - field_from_json(Obj,"cas", cas); - field_from_json(Obj,"manufacturer", manufacturer); - field_from_json(Obj,"model", model); - field_from_json(Obj,"redirector", redirector); - field_from_json(Obj,"commonName", commonName); - field_from_json(Obj,"certificateId", certificateId); - field_from_json(Obj,"batch", batch); - field_from_json(Obj,"created", created); - field_from_json(Obj,"modified", modified); - field_from_json(Obj,"revoked", revoked); - field_from_json(Obj,"revokeCount", revokeCount); - field_from_json(Obj,"synched", synched); - field_from_json(Obj,"expiryDate", expiryDate); - return true; - } catch (...) { - } - return false; - } + bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "creator", creator); + field_from_json(Obj, "type", type); + field_from_json(Obj, "status", status); + field_from_json(Obj, "certificate", certificate); + field_from_json(Obj, "key", key); + field_from_json(Obj, "devid", devid); + field_from_json(Obj, "cas", cas); + field_from_json(Obj, "manufacturer", manufacturer); + field_from_json(Obj, "model", model); + field_from_json(Obj, "redirector", redirector); + field_from_json(Obj, "commonName", commonName); + field_from_json(Obj, "certificateId", certificateId); + field_from_json(Obj, "batch", batch); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "revoked", revoked); + field_from_json(Obj, "revokeCount", revokeCount); + field_from_json(Obj, "synched", synched); + field_from_json(Obj, "expiryDate", expiryDate); + return true; + } catch (...) { + } + return false; + } - void EntityEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"creator", creator); - field_to_json(Obj,"name", name); - field_to_json(Obj,"description", description); - field_to_json(Obj,"defaultRedirector", defaultRedirector); - field_to_json(Obj,"apiKey", apiKey); - field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); - field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); - field_to_json(Obj,"organization", organization); - field_to_json(Obj,"created", created); - field_to_json(Obj,"modified", modified); - field_to_json(Obj,"suspended", suspended); - field_to_json(Obj,"deleted", deleted); - field_to_json(Obj,"notes", notes); - } + void EntityEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "creator", creator); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "defaultRedirector", defaultRedirector); + field_to_json(Obj, "apiKey", apiKey); + field_to_json(Obj, "serverEnrollmentProfile", serverEnrollmentProfile); + field_to_json(Obj, "clientEnrollmentProfile", clientEnrollmentProfile); + field_to_json(Obj, "organization", organization); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "suspended", suspended); + field_to_json(Obj, "deleted", deleted); + field_to_json(Obj, "notes", notes); + } - bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"creator", creator); - field_from_json(Obj,"name", name); - field_from_json(Obj,"description", description); - field_from_json(Obj,"defaultRedirector", defaultRedirector); - field_from_json(Obj,"apiKey", apiKey); - field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); - field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); - field_from_json(Obj,"organization", organization); - field_from_json(Obj,"created", created); - field_from_json(Obj,"modified", modified); - field_from_json(Obj,"suspended", suspended); - field_from_json(Obj,"deleted", deleted); - field_from_json(Obj,"notes", notes); - return true; - } catch (...) { - } - return false; - } + bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "creator", creator); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "defaultRedirector", defaultRedirector); + field_from_json(Obj, "apiKey", apiKey); + field_from_json(Obj, "serverEnrollmentProfile", serverEnrollmentProfile); + field_from_json(Obj, "clientEnrollmentProfile", clientEnrollmentProfile); + field_from_json(Obj, "organization", organization); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "suspended", suspended); + field_from_json(Obj, "deleted", deleted); + field_from_json(Obj, "notes", notes); + return true; + } catch (...) { + } + return false; + } - void BatchEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"entity", entity); - field_to_json(Obj,"creator", creator); - field_to_json(Obj,"name", name); - field_to_json(Obj,"description", description); - field_to_json(Obj,"manufacturer", manufacturer); - field_to_json(Obj,"model", model); - field_to_json(Obj,"redirector", redirector); - field_to_json(Obj,"commonNames", commonNames); - field_to_json(Obj,"jobHistory", jobHistory); - field_to_json(Obj,"notes", notes); - field_to_json(Obj,"submitted", submitted); - field_to_json(Obj,"started", started); - field_to_json(Obj,"completed", completed); - field_to_json(Obj,"modified", modified); - } + void BatchEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "creator", creator); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "manufacturer", manufacturer); + field_to_json(Obj, "model", model); + field_to_json(Obj, "redirector", redirector); + field_to_json(Obj, "commonNames", commonNames); + field_to_json(Obj, "jobHistory", jobHistory); + field_to_json(Obj, "notes", notes); + field_to_json(Obj, "submitted", submitted); + field_to_json(Obj, "started", started); + field_to_json(Obj, "completed", completed); + field_to_json(Obj, "modified", modified); + } - bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"entity", entity); - field_from_json(Obj,"creator", creator); - field_from_json(Obj,"name", name); - field_from_json(Obj,"description", description); - field_from_json(Obj,"manufacturer", manufacturer); - field_from_json(Obj,"model", model); - field_from_json(Obj,"redirector", redirector); - field_from_json(Obj,"commonNames", commonNames); - field_from_json(Obj,"jobHistory", jobHistory); - field_from_json(Obj,"notes", notes); - field_from_json(Obj,"submitted", submitted); - field_from_json(Obj,"started", started); - field_from_json(Obj,"completed", completed); - field_from_json(Obj,"modified", modified); - return true; - } catch (...) { - } - return false; - } + bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "creator", creator); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "manufacturer", manufacturer); + field_from_json(Obj, "model", model); + field_from_json(Obj, "redirector", redirector); + field_from_json(Obj, "commonNames", commonNames); + field_from_json(Obj, "jobHistory", jobHistory); + field_from_json(Obj, "notes", notes); + field_from_json(Obj, "submitted", submitted); + field_from_json(Obj, "started", started); + field_from_json(Obj, "completed", completed); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void JobEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"entity", entity); - field_to_json(Obj,"creator", creator); - field_to_json(Obj,"batch", batch); - field_to_json(Obj,"commonNames", commonNames); - field_to_json(Obj,"completedNames", completedNames); - field_to_json(Obj,"errorNames", errorNames); - field_to_json(Obj,"status", status); - field_to_json(Obj,"command", command); - field_to_json(Obj,"parameters", parameters); - field_to_json(Obj,"submitted", submitted); - field_to_json(Obj,"started", started); - field_to_json(Obj,"completed", completed); - field_to_json(Obj,"requesterUsername", requesterUsername); - } + void JobEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "creator", creator); + field_to_json(Obj, "batch", batch); + field_to_json(Obj, "commonNames", commonNames); + field_to_json(Obj, "completedNames", completedNames); + field_to_json(Obj, "errorNames", errorNames); + field_to_json(Obj, "status", status); + field_to_json(Obj, "command", command); + field_to_json(Obj, "parameters", parameters); + field_to_json(Obj, "submitted", submitted); + field_to_json(Obj, "started", started); + field_to_json(Obj, "completed", completed); + field_to_json(Obj, "requesterUsername", requesterUsername); + } - bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"entity", entity); - field_from_json(Obj,"creator", creator); - field_from_json(Obj,"batch", batch); - field_from_json(Obj,"commonNames", commonNames); - field_from_json(Obj,"completedNames", completedNames); - field_from_json(Obj,"errorNames", errorNames); - field_from_json(Obj,"status", status); - field_from_json(Obj,"command", command); - field_from_json(Obj,"parameters", parameters); - field_from_json(Obj,"submitted", submitted); - field_from_json(Obj,"started", started); - field_from_json(Obj,"completed", completed); - field_from_json(Obj,"requesterUsername", requesterUsername); - return true; - } catch (...) { - } - return false; - } + bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "creator", creator); + field_from_json(Obj, "batch", batch); + field_from_json(Obj, "commonNames", commonNames); + field_from_json(Obj, "completedNames", completedNames); + field_from_json(Obj, "errorNames", errorNames); + field_from_json(Obj, "status", status); + field_from_json(Obj, "command", command); + field_from_json(Obj, "parameters", parameters); + field_from_json(Obj, "submitted", submitted); + field_from_json(Obj, "started", started); + field_from_json(Obj, "completed", completed); + field_from_json(Obj, "requesterUsername", requesterUsername); + return true; + } catch (...) { + } + return false; + } - void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "year", year); - field_to_json(Obj, "activeCerts", activeCerts); - field_to_json(Obj, "revokedCerts", revokedCerts); - } + void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "year", year); + field_to_json(Obj, "activeCerts", activeCerts); + field_to_json(Obj, "revokedCerts", revokedCerts); + } - void Dashboard::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"snapshot", snapshot); - field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts); - field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts); - field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization); - field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization); - field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors); - field_to_json(Obj,"deviceTypes", deviceTypes); - field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts); - field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear); - } + void Dashboard::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "snapshot", snapshot); + field_to_json(Obj, "numberOfIssuedCerts", numberOfIssuedCerts); + field_to_json(Obj, "numberOfRevokedCerts", numberOfRevokedCerts); + field_to_json(Obj, "activeCertsPerOrganization", activeCertsPerOrganization); + field_to_json(Obj, "revokedCertsPerOrganization", revokedCertsPerOrganization); + field_to_json(Obj, "numberOfRedirectors", numberOfRedirectors); + field_to_json(Obj, "deviceTypes", deviceTypes); + field_to_json(Obj, "monthlyNumberOfCerts", monthlyNumberOfCerts); + field_to_json(Obj, "monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear); + } - void Dashboard::reset() { - snapshot=0; - numberOfRevokedCerts = numberOfIssuedCerts = 0; - activeCertsPerOrganization.clear(); - revokedCertsPerOrganization.clear(); - numberOfRedirectors.clear(); - deviceTypes.clear(); - monthlyNumberOfCerts.clear(); - monthlyNumberOfCertsPerOrgPerYear.clear(); - } -} \ No newline at end of file + void Dashboard::reset() { + snapshot = 0; + numberOfRevokedCerts = numberOfIssuedCerts = 0; + activeCertsPerOrganization.clear(); + revokedCertsPerOrganization.clear(); + numberOfRedirectors.clear(); + deviceTypes.clear(); + monthlyNumberOfCerts.clear(); + monthlyNumberOfCertsPerOrgPerYear.clear(); + } +} // namespace OpenWifi::CertObjects \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_CertObjects.h b/src/RESTObjects/RESTAPI_CertObjects.h index 4baeafa..672116b 100644 --- a/src/RESTObjects/RESTAPI_CertObjects.h +++ b/src/RESTObjects/RESTAPI_CertObjects.h @@ -4,121 +4,121 @@ #pragma once -#include -#include "framework/OpenWifiTypes.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/OpenWifiTypes.h" +#include namespace OpenWifi::CertObjects { - struct CertificateEntry { - OpenWifi::Types::UUID_t id; - OpenWifi::Types::UUID_t entity; - OpenWifi::Types::UUID_t creator; - std::string type; - std::string status; - std::string certificate; - std::string key; - std::string devid; - std::string cas; - std::string manufacturer; - std::string model; - std::string redirector; - std::string commonName; - std::string certificateId; - OpenWifi::Types::UUID_t batch; - uint64_t created = 0; - uint64_t modified = 0; - uint64_t revoked = 0; - uint64_t revokeCount = 0; - uint64_t synched = 0; - uint64_t expiryDate = 0 ; + struct CertificateEntry { + OpenWifi::Types::UUID_t id; + OpenWifi::Types::UUID_t entity; + OpenWifi::Types::UUID_t creator; + std::string type; + std::string status; + std::string certificate; + std::string key; + std::string devid; + std::string cas; + std::string manufacturer; + std::string model; + std::string redirector; + std::string commonName; + std::string certificateId; + OpenWifi::Types::UUID_t batch; + uint64_t created = 0; + uint64_t modified = 0; + uint64_t revoked = 0; + uint64_t revokeCount = 0; + uint64_t synched = 0; + uint64_t expiryDate = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct EntityEntry { - OpenWifi::Types::UUID_t id; - OpenWifi::Types::UUID_t creator; - std::string name; - std::string description; - std::string defaultRedirector; - std::string apiKey; - std::string serverEnrollmentProfile; - std::string clientEnrollmentProfile; - std::string organization; - SecurityObjects::NoteInfoVec notes; - bool suspended=false; - bool deleted=false; - uint64_t created = 0 ; - uint64_t modified = 0 ; + struct EntityEntry { + OpenWifi::Types::UUID_t id; + OpenWifi::Types::UUID_t creator; + std::string name; + std::string description; + std::string defaultRedirector; + std::string apiKey; + std::string serverEnrollmentProfile; + std::string clientEnrollmentProfile; + std::string organization; + SecurityObjects::NoteInfoVec notes; + bool suspended = false; + bool deleted = false; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct BatchEntry { - OpenWifi::Types::UUID_t id; - OpenWifi::Types::UUID_t entity; - OpenWifi::Types::UUID_t creator; - std::string name; - std::string description; - std::string manufacturer; - std::string model; - std::string redirector; - std::vector commonNames; - std::vector jobHistory; - SecurityObjects::NoteInfoVec notes; - uint64_t submitted = 0 ; - uint64_t started = 0 ; - uint64_t completed = 0 ; - uint64_t modified = 0 ; + struct BatchEntry { + OpenWifi::Types::UUID_t id; + OpenWifi::Types::UUID_t entity; + OpenWifi::Types::UUID_t creator; + std::string name; + std::string description; + std::string manufacturer; + std::string model; + std::string redirector; + std::vector commonNames; + std::vector jobHistory; + SecurityObjects::NoteInfoVec notes; + uint64_t submitted = 0; + uint64_t started = 0; + uint64_t completed = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct JobEntry { - OpenWifi::Types::UUID_t id; - OpenWifi::Types::UUID_t entity; - OpenWifi::Types::UUID_t creator; - OpenWifi::Types::UUID_t batch; - std::string command; - OpenWifi::Types::StringVec commonNames; - OpenWifi::Types::StringVec completedNames; - OpenWifi::Types::StringVec errorNames; - Types::StringPairVec parameters; - std::string status; - uint64_t submitted=0; - uint64_t started=0; - uint64_t completed=0; - std::string requesterUsername; + struct JobEntry { + OpenWifi::Types::UUID_t id; + OpenWifi::Types::UUID_t entity; + OpenWifi::Types::UUID_t creator; + OpenWifi::Types::UUID_t batch; + std::string command; + OpenWifi::Types::StringVec commonNames; + OpenWifi::Types::StringVec completedNames; + OpenWifi::Types::StringVec errorNames; + Types::StringPairVec parameters; + std::string status; + uint64_t submitted = 0; + uint64_t started = 0; + uint64_t completed = 0; + std::string requesterUsername; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DashBoardYearlyStats { - uint64_t year=0; - OpenWifi::Types::Counted3DMapSII activeCerts; - OpenWifi::Types::Counted3DMapSII revokedCerts; + struct DashBoardYearlyStats { + uint64_t year = 0; + OpenWifi::Types::Counted3DMapSII activeCerts; + OpenWifi::Types::Counted3DMapSII revokedCerts; - void to_json(Poco::JSON::Object &Obj) const; - }; + void to_json(Poco::JSON::Object &Obj) const; + }; - struct Dashboard { - uint64_t snapshot=0; - uint64_t numberOfIssuedCerts=0; - uint64_t numberOfRevokedCerts=0; - OpenWifi::Types::CountedMap activeCertsPerOrganization; - OpenWifi::Types::CountedMap revokedCertsPerOrganization; - OpenWifi::Types::CountedMap numberOfRedirectors; - OpenWifi::Types::CountedMap deviceTypes; - OpenWifi::Types::CountedMap monthlyNumberOfCerts; - std::vector monthlyNumberOfCertsPerOrgPerYear; + struct Dashboard { + uint64_t snapshot = 0; + uint64_t numberOfIssuedCerts = 0; + uint64_t numberOfRevokedCerts = 0; + OpenWifi::Types::CountedMap activeCertsPerOrganization; + OpenWifi::Types::CountedMap revokedCertsPerOrganization; + OpenWifi::Types::CountedMap numberOfRedirectors; + OpenWifi::Types::CountedMap deviceTypes; + OpenWifi::Types::CountedMap monthlyNumberOfCerts; + std::vector monthlyNumberOfCertsPerOrgPerYear; - void to_json(Poco::JSON::Object &Obj) const; - void reset(); - }; + void to_json(Poco::JSON::Object &Obj) const; + void reset(); + }; -} \ No newline at end of file +} // namespace OpenWifi::CertObjects \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_FMSObjects.cpp b/src/RESTObjects/RESTAPI_FMSObjects.cpp index 5c42da9..ff46f83 100644 --- a/src/RESTObjects/RESTAPI_FMSObjects.cpp +++ b/src/RESTObjects/RESTAPI_FMSObjects.cpp @@ -6,305 +6,293 @@ #include "framework/RESTAPI_utils.h" #include "framework/utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::FMSObjects { - void Firmware::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "release", release); - field_to_json(Obj, "deviceType", deviceType); - field_to_json(Obj, "description", description); - field_to_json(Obj, "revision", revision); - field_to_json(Obj, "uri", uri); - field_to_json(Obj, "image", image); - field_to_json(Obj, "imageDate", imageDate); - field_to_json(Obj, "size", size); - field_to_json(Obj, "downloadCount", downloadCount); - field_to_json(Obj, "firmwareHash", firmwareHash); - field_to_json(Obj, "owner", owner); - field_to_json(Obj, "location", location); - field_to_json(Obj, "uploader", uploader); - field_to_json(Obj, "digest", digest); - field_to_json(Obj, "latest", latest); - field_to_json(Obj, "notes", notes); - field_to_json(Obj, "created", created); - }; + void Firmware::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "release", release); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "description", description); + field_to_json(Obj, "revision", revision); + field_to_json(Obj, "uri", uri); + field_to_json(Obj, "image", image); + field_to_json(Obj, "imageDate", imageDate); + field_to_json(Obj, "size", size); + field_to_json(Obj, "downloadCount", downloadCount); + field_to_json(Obj, "firmwareHash", firmwareHash); + field_to_json(Obj, "owner", owner); + field_to_json(Obj, "location", location); + field_to_json(Obj, "uploader", uploader); + field_to_json(Obj, "digest", digest); + field_to_json(Obj, "latest", latest); + field_to_json(Obj, "notes", notes); + field_to_json(Obj, "created", created); + }; - bool Firmware::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "release", release); - field_from_json(Obj, "deviceType", deviceType); - field_from_json(Obj, "description", description); - field_from_json(Obj, "revision", revision); - field_from_json(Obj, "uri", uri); - field_from_json(Obj, "image", image); - field_from_json(Obj, "imageDate", imageDate); - field_from_json(Obj, "size", size); - field_from_json(Obj, "downloadCount", downloadCount); - field_from_json(Obj, "firmwareHash", firmwareHash); - field_from_json(Obj, "owner", owner); - field_from_json(Obj, "location", location); - field_from_json(Obj, "uploader", uploader); - field_from_json(Obj, "digest", digest); - field_from_json(Obj, "latest", latest); - field_from_json(Obj, "notes", notes); - field_from_json(Obj, "created", created); - return true; - } catch (...) { + bool Firmware::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "release", release); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "description", description); + field_from_json(Obj, "revision", revision); + field_from_json(Obj, "uri", uri); + field_from_json(Obj, "image", image); + field_from_json(Obj, "imageDate", imageDate); + field_from_json(Obj, "size", size); + field_from_json(Obj, "downloadCount", downloadCount); + field_from_json(Obj, "firmwareHash", firmwareHash); + field_from_json(Obj, "owner", owner); + field_from_json(Obj, "location", location); + field_from_json(Obj, "uploader", uploader); + field_from_json(Obj, "digest", digest); + field_from_json(Obj, "latest", latest); + field_from_json(Obj, "notes", notes); + field_from_json(Obj, "created", created); + return true; + } catch (...) { + } + return true; + } - } - return true; - } + void FirmwareList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "firmwares", firmwares); + } - void FirmwareList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"firmwares",firmwares); - } + bool FirmwareList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "firmwares", firmwares); + return true; + } catch (...) { + } + return false; + } - bool FirmwareList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "firmwares", firmwares); - return true; - } catch (...) { + void DeviceType::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "manufacturer", manufacturer); + field_to_json(Obj, "model", model); + field_to_json(Obj, "policy", policy); + field_to_json(Obj, "notes", notes); + field_to_json(Obj, "lastUpdate", lastUpdate); + field_to_json(Obj, "created", created); + field_to_json(Obj, "id", id); + field_to_json(Obj, "id", id); + field_to_json(Obj, "id", id); + } - } - return false; - } + bool DeviceType::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "manufacturer", manufacturer); + field_from_json(Obj, "model", model); + field_from_json(Obj, "policy", policy); + field_from_json(Obj, "notes", notes); + field_from_json(Obj, "lastUpdate", lastUpdate); + field_from_json(Obj, "created", created); + field_from_json(Obj, "id", id); + field_from_json(Obj, "id", id); + field_from_json(Obj, "id", id); + return true; + } catch (...) { + } + return false; + } - void DeviceType::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "deviceType", deviceType); - field_to_json(Obj, "manufacturer", manufacturer); - field_to_json(Obj, "model", model); - field_to_json(Obj, "policy", policy); - field_to_json(Obj, "notes", notes); - field_to_json(Obj, "lastUpdate", lastUpdate); - field_to_json(Obj, "created", created); - field_to_json(Obj, "id", id); - field_to_json(Obj, "id", id); - field_to_json(Obj, "id", id); - } + void DeviceTypeList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "deviceTypes", deviceTypes); + } - bool DeviceType::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "deviceType", deviceType); - field_from_json(Obj, "manufacturer", manufacturer); - field_from_json(Obj, "model", model); - field_from_json(Obj, "policy", policy); - field_from_json(Obj, "notes", notes); - field_from_json(Obj, "lastUpdate", lastUpdate); - field_from_json(Obj, "created", created); - field_from_json(Obj, "id", id); - field_from_json(Obj, "id", id); - field_from_json(Obj, "id", id); - return true; - } catch (...) { + bool DeviceTypeList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "deviceTypes", deviceTypes); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void RevisionHistoryEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "fromRelease", fromRelease); + field_to_json(Obj, "toRelease", toRelease); + field_to_json(Obj, "commandUUID", commandUUID); + field_to_json(Obj, "revisionId", revisionId); + field_to_json(Obj, "upgraded", upgraded); + } - void DeviceTypeList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"deviceTypes", deviceTypes); - } + bool RevisionHistoryEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "fromRelease", fromRelease); + field_from_json(Obj, "toRelease", toRelease); + field_from_json(Obj, "commandUUID", commandUUID); + field_from_json(Obj, "revisionId", revisionId); + field_from_json(Obj, "upgraded", upgraded); + return true; + } catch (...) { + } + return false; + } - bool DeviceTypeList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"deviceTypes", deviceTypes); - return true; - } catch(...) { + void RevisionHistoryEntryList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "deviceTypes", history); + } - } - return false; - } + bool RevisionHistoryEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "deviceTypes", history); + return true; + } catch (...) { + } + return false; + } - void RevisionHistoryEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "serialNumber", serialNumber); - field_to_json(Obj, "fromRelease", fromRelease); - field_to_json(Obj, "toRelease", toRelease); - field_to_json(Obj, "commandUUID", commandUUID); - field_to_json(Obj, "revisionId", revisionId); - field_to_json(Obj, "upgraded", upgraded); - } + void FirmwareAgeDetails::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "latestId", latestId); + field_to_json(Obj, "image", image); + field_to_json(Obj, "imageDate", imageDate); + field_to_json(Obj, "revision", revision); + field_to_json(Obj, "uri", uri); + field_to_json(Obj, "age", age); + field_to_json(Obj, "latest", latest); + } - bool RevisionHistoryEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "serialNumber", serialNumber); - field_from_json(Obj, "fromRelease", fromRelease); - field_from_json(Obj, "toRelease", toRelease); - field_from_json(Obj, "commandUUID", commandUUID); - field_from_json(Obj, "revisionId", revisionId); - field_from_json(Obj, "upgraded", upgraded); - return true; - } catch(...) { + bool FirmwareAgeDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "latestId", latestId); + field_from_json(Obj, "image", image); + field_from_json(Obj, "imageDate", imageDate); + field_from_json(Obj, "revision", revision); + field_from_json(Obj, "uri", uri); + field_from_json(Obj, "age", age); + field_from_json(Obj, "latest", latest); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void DeviceConnectionInformation::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "revision", revision); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "endPoint", endPoint); + field_to_json(Obj, "lastUpdate", lastUpdate); + field_to_json(Obj, "status", status); + } - void RevisionHistoryEntryList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"deviceTypes", history); - } + bool DeviceConnectionInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "revision", revision); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "endPoint", endPoint); + field_from_json(Obj, "lastUpdate", lastUpdate); + field_from_json(Obj, "status", status); + return true; + } catch (...) { + } + return false; + } - bool RevisionHistoryEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"deviceTypes", history); - return true; - } catch(...) { + void DeviceReport::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "ouis", OUI_); + field_to_json(Obj, "revisions", Revisions_); + field_to_json(Obj, "deviceTypes", DeviceTypes_); + field_to_json(Obj, "status", Status_); + field_to_json(Obj, "endPoints", EndPoints_); + field_to_json(Obj, "usingLatest", UsingLatest_); + field_to_json(Obj, "unknownFirmwares", UnknownFirmwares_); + field_to_json(Obj, "snapshot", snapshot); + field_to_json(Obj, "numberOfDevices", numberOfDevices); + field_to_json(Obj, "totalSecondsOld", totalSecondsOld_); + } - } - return false; - } + void DeviceReport::reset() { + OUI_.clear(); + Revisions_.clear(); + DeviceTypes_.clear(); + Status_.clear(); + EndPoints_.clear(); + UsingLatest_.clear(); + UnknownFirmwares_.clear(); + totalSecondsOld_.clear(); + numberOfDevices = 0; + snapshot = Utils::Now(); + } - void FirmwareAgeDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"latestId", latestId); - field_to_json(Obj,"image", image); - field_to_json(Obj,"imageDate", imageDate); - field_to_json(Obj,"revision", revision); - field_to_json(Obj,"uri", uri); - field_to_json(Obj,"age", age); - field_to_json(Obj,"latest",latest); - } + bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { + try { - bool FirmwareAgeDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"latestId", latestId); - field_from_json(Obj,"image", image); - field_from_json(Obj,"imageDate", imageDate); - field_from_json(Obj,"revision", revision); - field_from_json(Obj,"uri", uri); - field_from_json(Obj,"age", age); - field_from_json(Obj,"latest", latest); - return true; - } catch(...) { + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void DeviceInformation::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "history", history); + field_to_json(Obj, "currentFirmware", currentFirmware); + field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); + field_to_json(Obj, "latestFirmware", latestFirmware); + field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); + field_to_json(Obj, "latestFirmwareAvailable", latestFirmwareAvailable); + field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI); + } - void DeviceConnectionInformation::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "serialNumber", serialNumber); - field_to_json(Obj, "revision", revision); - field_to_json(Obj, "deviceType", deviceType); - field_to_json(Obj, "endPoint", endPoint); - field_to_json(Obj, "lastUpdate", lastUpdate); - field_to_json(Obj, "status", status); - } + bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "history", history); + field_from_json(Obj, "currentFirmware", currentFirmware); + field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); + field_from_json(Obj, "latestFirmware", latestFirmware); + field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); + field_from_json(Obj, "latestFirmwareAvailable", latestFirmwareAvailable); + field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI); + return true; + } catch (...) { + } + return false; + } - bool DeviceConnectionInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "serialNumber", serialNumber); - field_from_json(Obj, "revision", revision); - field_from_json(Obj, "deviceType", deviceType); - field_from_json(Obj, "endPoint", endPoint); - field_from_json(Obj, "lastUpdate", lastUpdate); - field_from_json(Obj, "status", status); - return true; - } catch(...) { + void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "revision", revision); + field_to_json(Obj, "upgraded", upgraded); + } - } - return false; - } + bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "revision", revision); + field_from_json(Obj, "upgraded", upgraded); + return true; + } catch (...) { + } + return false; + } - void DeviceReport::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "ouis",OUI_); - field_to_json(Obj, "revisions", Revisions_); - field_to_json(Obj, "deviceTypes", DeviceTypes_); - field_to_json(Obj, "status", Status_); - field_to_json(Obj, "endPoints", EndPoints_); - field_to_json(Obj, "usingLatest", UsingLatest_); - field_to_json(Obj, "unknownFirmwares", UnknownFirmwares_); - field_to_json(Obj,"snapshot",snapshot); - field_to_json(Obj,"numberOfDevices",numberOfDevices); - field_to_json(Obj, "totalSecondsOld", totalSecondsOld_); - } + void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "devices", devices); + } - void DeviceReport::reset() { - OUI_.clear(); - Revisions_.clear(); - DeviceTypes_.clear(); - Status_.clear(); - EndPoints_.clear(); - UsingLatest_.clear(); - UnknownFirmwares_.clear(); - totalSecondsOld_.clear(); - numberOfDevices = 0 ; - snapshot = Utils::Now(); - } + bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "devices", devices); + return true; + } catch (...) { + } + return false; + } - bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { - try { - - return true; - } catch (...) { - - } - return false; - } - - void DeviceInformation::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "serialNumber",serialNumber); - field_to_json(Obj, "history", history); - field_to_json(Obj, "currentFirmware", currentFirmware); - field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); - field_to_json(Obj, "latestFirmware", latestFirmware); - field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); - field_to_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); - field_to_json(Obj, "latestFirmwareURI",latestFirmwareURI); - } - - bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "serialNumber",serialNumber); - field_from_json(Obj, "history", history); - field_from_json(Obj, "currentFirmware", currentFirmware); - field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); - field_from_json(Obj, "latestFirmware", latestFirmware); - field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); - field_from_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); - field_from_json(Obj, "latestFirmwareURI",latestFirmwareURI); - return true; - } catch(...) { - - } - return false; - } - - void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "serialNumber",serialNumber); - field_to_json(Obj, "revision", revision); - field_to_json(Obj, "upgraded", upgraded); - } - - bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "serialNumber",serialNumber); - field_from_json(Obj, "revision", revision); - field_from_json(Obj, "upgraded", upgraded); - return true; - } catch(...) { - - } - return false; - } - - void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "devices",devices); - } - - bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "devices",devices); - return true; - } catch(...) { - - } - return false; - } - -} +} // namespace OpenWifi::FMSObjects diff --git a/src/RESTObjects/RESTAPI_FMSObjects.h b/src/RESTObjects/RESTAPI_FMSObjects.h index 60aea5f..705ccc8 100644 --- a/src/RESTObjects/RESTAPI_FMSObjects.h +++ b/src/RESTObjects/RESTAPI_FMSObjects.h @@ -11,149 +11,149 @@ namespace OpenWifi::FMSObjects { - struct Firmware { - std::string id; - std::string release; - std::string deviceType; - std::string description; - std::string revision; - std::string uri; - std::string image; - uint64_t imageDate=0; - uint64_t size=0; - uint64_t downloadCount=0; - std::string firmwareHash; - std::string owner; - std::string location; - std::string uploader; - std::string digest; - bool latest=false; - SecurityObjects::NoteInfoVec notes; - uint64_t created=0; + struct Firmware { + std::string id; + std::string release; + std::string deviceType; + std::string description; + std::string revision; + std::string uri; + std::string image; + uint64_t imageDate = 0; + uint64_t size = 0; + uint64_t downloadCount = 0; + std::string firmwareHash; + std::string owner; + std::string location; + std::string uploader; + std::string digest; + bool latest = false; + SecurityObjects::NoteInfoVec notes; + uint64_t created = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector FirmwareVec; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector FirmwareVec; - struct FirmwareList { - FirmwareVec firmwares; + struct FirmwareList { + FirmwareVec firmwares; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceType { - std::string id; - std::string deviceType; - std::string manufacturer; - std::string model; - std::string policy; - SecurityObjects::NoteInfoVec notes; - uint64_t lastUpdate=0; - uint64_t created=0; + struct DeviceType { + std::string id; + std::string deviceType; + std::string manufacturer; + std::string model; + std::string policy; + SecurityObjects::NoteInfoVec notes; + uint64_t lastUpdate = 0; + uint64_t created = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector DeviceTypeVec; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector DeviceTypeVec; - struct DeviceTypeList { - DeviceTypeVec deviceTypes; + struct DeviceTypeList { + DeviceTypeVec deviceTypes; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct RevisionHistoryEntry { - std::string id; - std::string serialNumber; - std::string fromRelease; - std::string toRelease; - std::string commandUUID; - std::string revisionId; - uint64_t upgraded; + struct RevisionHistoryEntry { + std::string id; + std::string serialNumber; + std::string fromRelease; + std::string toRelease; + std::string commandUUID; + std::string revisionId; + uint64_t upgraded; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector RevisionHistoryEntryVec; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector RevisionHistoryEntryVec; - struct RevisionHistoryEntryList { - RevisionHistoryEntryVec history; + struct RevisionHistoryEntryList { + RevisionHistoryEntryVec history; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct FirmwareAgeDetails { - std::string latestId; - std::string image; - uint64_t imageDate; - std::string revision; - std::string uri; - uint64_t age=0; - bool latest=true; + struct FirmwareAgeDetails { + std::string latestId; + std::string image; + uint64_t imageDate; + std::string revision; + std::string uri; + uint64_t age = 0; + bool latest = true; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceConnectionInformation { - std::string serialNumber; - std::string revision; - std::string deviceType; - std::string endPoint; - uint64_t lastUpdate; - std::string status; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct DeviceConnectionInformation { + std::string serialNumber; + std::string revision; + std::string deviceType; + std::string endPoint; + uint64_t lastUpdate; + std::string status; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceReport { - uint64_t snapshot=0; - uint64_t numberOfDevices=0; - Types::CountedMap OUI_; - Types::CountedMap Revisions_; - Types::CountedMap DeviceTypes_; - Types::CountedMap Status_; - Types::CountedMap EndPoints_; - Types::CountedMap UsingLatest_; - Types::CountedMap UnknownFirmwares_; - Types::CountedMap totalSecondsOld_; - void to_json(Poco::JSON::Object &Obj) const; - void reset(); - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct DeviceReport { + uint64_t snapshot = 0; + uint64_t numberOfDevices = 0; + Types::CountedMap OUI_; + Types::CountedMap Revisions_; + Types::CountedMap DeviceTypes_; + Types::CountedMap Status_; + Types::CountedMap EndPoints_; + Types::CountedMap UsingLatest_; + Types::CountedMap UnknownFirmwares_; + Types::CountedMap totalSecondsOld_; + void to_json(Poco::JSON::Object &Obj) const; + void reset(); + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceInformation { - std::string serialNumber; - RevisionHistoryEntryList history; - std::string currentFirmware; - uint64_t currentFirmwareDate=0; - std::string latestFirmware; - uint64_t latestFirmwareDate=0; - bool latestFirmwareAvailable; - std::string latestFirmwareURI; + struct DeviceInformation { + std::string serialNumber; + RevisionHistoryEntryList history; + std::string currentFirmware; + uint64_t currentFirmwareDate = 0; + std::string latestFirmware; + uint64_t latestFirmwareDate = 0; + bool latestFirmwareAvailable; + std::string latestFirmwareURI; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceCurrentInfo { - std::string serialNumber; - std::string revision; - uint64_t upgraded=0; + struct DeviceCurrentInfo { + std::string serialNumber; + std::string revision; + uint64_t upgraded = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DeviceCurrentInfoList { - std::vector devices; + struct DeviceCurrentInfoList { + std::vector devices; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; -} +} // namespace OpenWifi::FMSObjects diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index 228dd0f..57ab524 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -10,7 +10,7 @@ #include "Poco/JSON/Stringifier.h" #include "Daemon.h" -#ifdef TIP_GATEWAY_SERVICE +#ifdef TIP_GATEWAY_SERVICE #include "AP_WS_Server.h" #include "CapabilitiesCache.h" #endif @@ -19,41 +19,41 @@ #include "framework/RESTAPI_utils.h" #include "framework/utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; -using OpenWifi::RESTAPI_utils::field_from_json; using OpenWifi::RESTAPI_utils::EmbedDocument; +using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::GWObjects { void Device::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"serialNumber", SerialNumber); + field_to_json(Obj, "serialNumber", SerialNumber); #ifdef TIP_GATEWAY_SERVICE - field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); + field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); #endif - field_to_json(Obj,"macAddress", MACAddress); - field_to_json(Obj,"manufacturer", Manufacturer); - field_to_json(Obj,"UUID", UUID); + field_to_json(Obj, "macAddress", MACAddress); + field_to_json(Obj, "manufacturer", Manufacturer); + field_to_json(Obj, "UUID", UUID); EmbedDocument("configuration", Obj, Configuration); - field_to_json(Obj,"notes", Notes); - field_to_json(Obj,"createdTimestamp", CreationTimestamp); - field_to_json(Obj,"lastConfigurationChange", LastConfigurationChange); - field_to_json(Obj,"lastConfigurationDownload", LastConfigurationDownload); - field_to_json(Obj,"lastFWUpdate", LastFWUpdate); - field_to_json(Obj,"owner", Owner); - field_to_json(Obj,"location", Location); - field_to_json(Obj,"venue", Venue); - field_to_json(Obj,"firmware", Firmware); - field_to_json(Obj,"compatible", Compatible); - field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy); - field_to_json(Obj,"devicePassword", DevicePassword); - field_to_json(Obj,"subscriber", subscriber); - field_to_json(Obj,"entity", entity); - field_to_json(Obj,"modified", modified); - field_to_json(Obj,"locale", locale); - field_to_json(Obj,"restrictedDevice", restrictedDevice); - field_to_json(Obj,"pendingConfiguration", pendingConfiguration); - field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); - field_to_json(Obj,"restrictionDetails", restrictionDetails); + field_to_json(Obj, "notes", Notes); + field_to_json(Obj, "createdTimestamp", CreationTimestamp); + field_to_json(Obj, "lastConfigurationChange", LastConfigurationChange); + field_to_json(Obj, "lastConfigurationDownload", LastConfigurationDownload); + field_to_json(Obj, "lastFWUpdate", LastFWUpdate); + field_to_json(Obj, "owner", Owner); + field_to_json(Obj, "location", Location); + field_to_json(Obj, "venue", Venue); + field_to_json(Obj, "firmware", Firmware); + field_to_json(Obj, "compatible", Compatible); + field_to_json(Obj, "fwUpdatePolicy", FWUpdatePolicy); + field_to_json(Obj, "devicePassword", DevicePassword); + field_to_json(Obj, "subscriber", subscriber); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "restrictedDevice", restrictedDevice); + field_to_json(Obj, "pendingConfiguration", pendingConfiguration); + field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd); + field_to_json(Obj, "restrictionDetails", restrictionDetails); } void Device::to_json_with_status(Poco::JSON::Object &Obj) const { @@ -65,39 +65,39 @@ namespace OpenWifi::GWObjects { if (AP_WS_Server()->GetState(SerialNumber, ConState)) { ConState.to_json(Obj); } else { - field_to_json(Obj,"ipAddress", ""); - field_to_json(Obj,"txBytes", (uint64_t) 0); - field_to_json(Obj,"rxBytes", (uint64_t )0); - field_to_json(Obj,"messageCount", (uint64_t )0); - field_to_json(Obj,"connected", false); - field_to_json(Obj,"lastContact", ""); - field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); - field_to_json(Obj,"associations_2G", (uint64_t) 0); - field_to_json(Obj,"associations_5G", (uint64_t) 0); - field_to_json(Obj,"associations_6G", (uint64_t) 0); + field_to_json(Obj, "ipAddress", ""); + field_to_json(Obj, "txBytes", (uint64_t)0); + field_to_json(Obj, "rxBytes", (uint64_t)0); + field_to_json(Obj, "messageCount", (uint64_t)0); + field_to_json(Obj, "connected", false); + field_to_json(Obj, "lastContact", ""); + field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); + field_to_json(Obj, "associations_2G", (uint64_t)0); + field_to_json(Obj, "associations_5G", (uint64_t)0); + field_to_json(Obj, "associations_6G", (uint64_t)0); } #endif } bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"serialNumber",SerialNumber); - field_from_json(Obj,"deviceType",DeviceType); - field_from_json(Obj,"macAddress",MACAddress); - field_from_json(Obj,"configuration",Configuration); - field_from_json(Obj,"notes",Notes); - field_from_json(Obj,"manufacturer",Manufacturer); - field_from_json(Obj,"owner",Owner); - field_from_json(Obj,"location",Location); - field_from_json(Obj,"venue",Venue); - field_from_json(Obj,"compatible",Compatible); - field_from_json(Obj,"subscriber", subscriber); - field_from_json(Obj,"entity", entity); - field_from_json(Obj,"locale", locale); - field_from_json(Obj,"restrictedDevice", restrictedDevice); - field_from_json(Obj,"pendingConfiguration", pendingConfiguration); - field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); - field_from_json(Obj,"restrictionDetails", restrictionDetails); + field_from_json(Obj, "serialNumber", SerialNumber); + field_from_json(Obj, "deviceType", DeviceType); + field_from_json(Obj, "macAddress", MACAddress); + field_from_json(Obj, "configuration", Configuration); + field_from_json(Obj, "notes", Notes); + field_from_json(Obj, "manufacturer", Manufacturer); + field_from_json(Obj, "owner", Owner); + field_from_json(Obj, "location", Location); + field_from_json(Obj, "venue", Venue); + field_from_json(Obj, "compatible", Compatible); + field_from_json(Obj, "subscriber", subscriber); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "restrictedDevice", restrictedDevice); + field_from_json(Obj, "pendingConfiguration", pendingConfiguration); + field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd); + field_from_json(Obj, "restrictionDetails", restrictionDetails); return true; } catch (const Poco::Exception &E) { } @@ -105,73 +105,74 @@ namespace OpenWifi::GWObjects { } void Device::Print() const { - std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType << " MACAddress:" << MACAddress << " Manufacturer:" - << Manufacturer << " " << Configuration << std::endl; + std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType + << " MACAddress:" << MACAddress << " Manufacturer:" << Manufacturer << " " + << Configuration << std::endl; } void Statistics::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("data", Obj, Data); - field_to_json(Obj,"UUID", UUID); - field_to_json(Obj,"recorded", Recorded); + field_to_json(Obj, "UUID", UUID); + field_to_json(Obj, "recorded", Recorded); } void Capabilities::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("capabilities", Obj, Capabilities); - field_to_json(Obj,"firstUpdate", FirstUpdate); - field_to_json(Obj,"lastUpdate", LastUpdate); + field_to_json(Obj, "firstUpdate", FirstUpdate); + field_to_json(Obj, "lastUpdate", LastUpdate); } void DeviceLog::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("data", Obj, Data); - field_to_json(Obj,"log", Log); - field_to_json(Obj,"severity", Severity); - field_to_json(Obj,"recorded", Recorded); - field_to_json(Obj,"logType", LogType); - field_to_json(Obj,"UUID", UUID); + field_to_json(Obj, "log", Log); + field_to_json(Obj, "severity", Severity); + field_to_json(Obj, "recorded", Recorded); + field_to_json(Obj, "logType", LogType); + field_to_json(Obj, "UUID", UUID); } void HealthCheck::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("values", Obj, Data); - field_to_json(Obj,"UUID", UUID); - field_to_json(Obj,"sanity", Sanity); - field_to_json(Obj,"recorded", Recorded); + field_to_json(Obj, "UUID", UUID); + field_to_json(Obj, "sanity", Sanity); + field_to_json(Obj, "recorded", Recorded); } void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("configuration", Obj, Configuration); - field_to_json(Obj,"name", Name); - field_to_json(Obj,"modelIds", Models); - field_to_json(Obj,"description", Description); - field_to_json(Obj,"created", Created); - field_to_json(Obj,"lastModified", LastModified); + field_to_json(Obj, "name", Name); + field_to_json(Obj, "modelIds", Models); + field_to_json(Obj, "description", Description); + field_to_json(Obj, "created", Created); + field_to_json(Obj, "lastModified", LastModified); } void CommandDetails::to_json(Poco::JSON::Object &Obj) const { EmbedDocument("details", Obj, Details); EmbedDocument("results", Obj, Results); - field_to_json(Obj,"UUID", UUID); - field_to_json(Obj,"serialNumber", SerialNumber); - field_to_json(Obj,"command", Command); - field_to_json(Obj,"errorText", ErrorText); - field_to_json(Obj,"submittedBy", SubmittedBy); - field_to_json(Obj,"status", Status); - field_to_json(Obj,"submitted", Submitted); - field_to_json(Obj,"executed", Executed); - field_to_json(Obj,"completed", Completed); - field_to_json(Obj,"when", RunAt); - field_to_json(Obj,"errorCode", ErrorCode); - field_to_json(Obj,"custom", Custom); - field_to_json(Obj,"waitingForFile", WaitingForFile); - field_to_json(Obj,"attachFile", AttachDate); - field_to_json(Obj,"executionTime", executionTime); + field_to_json(Obj, "UUID", UUID); + field_to_json(Obj, "serialNumber", SerialNumber); + field_to_json(Obj, "command", Command); + field_to_json(Obj, "errorText", ErrorText); + field_to_json(Obj, "submittedBy", SubmittedBy); + field_to_json(Obj, "status", Status); + field_to_json(Obj, "submitted", Submitted); + field_to_json(Obj, "executed", Executed); + field_to_json(Obj, "completed", Completed); + field_to_json(Obj, "when", RunAt); + field_to_json(Obj, "errorCode", ErrorCode); + field_to_json(Obj, "custom", Custom); + field_to_json(Obj, "waitingForFile", WaitingForFile); + field_to_json(Obj, "attachFile", AttachDate); + field_to_json(Obj, "executionTime", executionTime); } bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"name",Name); - field_from_json(Obj,"configuration",Configuration); - field_from_json(Obj,"modelIds",Models); - field_from_json(Obj,"description",Description); + field_from_json(Obj, "name", Name); + field_from_json(Obj, "configuration", Configuration); + field_from_json(Obj, "modelIds", Models); + field_from_json(Obj, "description", Description); return true; } catch (const Poco::Exception &E) { } @@ -179,18 +180,18 @@ namespace OpenWifi::GWObjects { } void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"serialNumber", serialNumber); - field_to_json(Obj,"author", author); - field_to_json(Obj,"reason", reason); - field_to_json(Obj,"created", created); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "author", author); + field_to_json(Obj, "reason", reason); + field_to_json(Obj, "created", created); } bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"serialNumber",serialNumber); - field_from_json(Obj,"author",author); - field_from_json(Obj,"reason",reason); - field_from_json(Obj,"created",created); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "author", author); + field_from_json(Obj, "reason", reason); + field_from_json(Obj, "created", created); return true; } catch (const Poco::Exception &E) { } @@ -198,53 +199,58 @@ namespace OpenWifi::GWObjects { } void ConnectionState::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"ipAddress", Address); - field_to_json(Obj,"txBytes", TX); - field_to_json(Obj,"rxBytes", RX); - field_to_json(Obj,"messageCount", MessageCount); - field_to_json(Obj,"UUID", UUID); - field_to_json(Obj,"connected", Connected); - field_to_json(Obj,"firmware", Firmware); - field_to_json(Obj,"lastContact", LastContact); - field_to_json(Obj,"associations_2G", Associations_2G); - field_to_json(Obj,"associations_5G", Associations_5G); - field_to_json(Obj,"associations_6G", Associations_6G); - field_to_json(Obj,"webSocketClients", webSocketClients); - field_to_json(Obj,"websocketPackets", websocketPackets); - field_to_json(Obj,"kafkaClients", kafkaClients); - field_to_json(Obj,"kafkaPackets", kafkaPackets); - field_to_json(Obj,"locale", locale); - field_to_json(Obj,"started", started); - field_to_json(Obj,"sessionId", sessionId); - field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); - field_to_json(Obj,"totalConnectionTime", Utils::Now() - started); - field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate); + field_to_json(Obj, "ipAddress", Address); + field_to_json(Obj, "txBytes", TX); + field_to_json(Obj, "rxBytes", RX); + field_to_json(Obj, "messageCount", MessageCount); + field_to_json(Obj, "UUID", UUID); + field_to_json(Obj, "connected", Connected); + field_to_json(Obj, "firmware", Firmware); + field_to_json(Obj, "lastContact", LastContact); + field_to_json(Obj, "associations_2G", Associations_2G); + field_to_json(Obj, "associations_5G", Associations_5G); + field_to_json(Obj, "associations_6G", Associations_6G); + field_to_json(Obj, "webSocketClients", webSocketClients); + field_to_json(Obj, "websocketPackets", websocketPackets); + field_to_json(Obj, "kafkaClients", kafkaClients); + field_to_json(Obj, "kafkaPackets", kafkaPackets); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "started", started); + field_to_json(Obj, "sessionId", sessionId); + field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime); + field_to_json(Obj, "totalConnectionTime", Utils::Now() - started); + field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate); - switch(VerifiedCertificate) { - case NO_CERTIFICATE: - field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; - case VALID_CERTIFICATE: - field_to_json(Obj,"verifiedCertificate", "VALID_CERTIFICATE"); break; - case MISMATCH_SERIAL: - field_to_json(Obj,"verifiedCertificate", "MISMATCH_SERIAL"); break; - case VERIFIED: - field_to_json(Obj,"verifiedCertificate", "VERIFIED"); break; - default: - field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; + switch (VerifiedCertificate) { + case NO_CERTIFICATE: + field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); + break; + case VALID_CERTIFICATE: + field_to_json(Obj, "verifiedCertificate", "VALID_CERTIFICATE"); + break; + case MISMATCH_SERIAL: + field_to_json(Obj, "verifiedCertificate", "MISMATCH_SERIAL"); + break; + case VERIFIED: + field_to_json(Obj, "verifiedCertificate", "VERIFIED"); + break; + default: + field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); + break; } } void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"averageConnectionTime", averageConnectionTime); - field_to_json(Obj,"connectedDevices", connectedDevices ); - field_to_json(Obj,"connectingDevices", connectingDevices ); + field_to_json(Obj, "averageConnectionTime", averageConnectionTime); + field_to_json(Obj, "connectedDevices", connectedDevices); + field_to_json(Obj, "connectingDevices", connectingDevices); } bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"averageConnectionTime", averageConnectionTime); - field_from_json(Obj,"connectedDevices", connectedDevices ); - field_from_json(Obj,"connectingDevices", connectingDevices ); + field_from_json(Obj, "averageConnectionTime", averageConnectionTime); + field_from_json(Obj, "connectedDevices", connectedDevices); + field_from_json(Obj, "connectingDevices", connectingDevices); return true; } catch (const Poco::Exception &E) { } @@ -252,37 +258,37 @@ namespace OpenWifi::GWObjects { } void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"serialNumber", SerialNumber); - field_to_json(Obj,"server", Server); - field_to_json(Obj,"port", Port); - field_to_json(Obj,"token",Token); - field_to_json(Obj,"timeout", TimeOut); - field_to_json(Obj,"connectionId",ConnectionId); - field_to_json(Obj,"commandUUID",CommandUUID); - field_to_json(Obj,"started", Started); - field_to_json(Obj,"viewport",ViewPort); - field_to_json(Obj,"password",DevicePassword); + field_to_json(Obj, "serialNumber", SerialNumber); + field_to_json(Obj, "server", Server); + field_to_json(Obj, "port", Port); + field_to_json(Obj, "token", Token); + field_to_json(Obj, "timeout", TimeOut); + field_to_json(Obj, "connectionId", ConnectionId); + field_to_json(Obj, "commandUUID", CommandUUID); + field_to_json(Obj, "started", Started); + field_to_json(Obj, "viewport", ViewPort); + field_to_json(Obj, "password", DevicePassword); } void Dashboard::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"commands",commands); - field_to_json(Obj,"upTimes",upTimes); - field_to_json(Obj,"memoryUsed",memoryUsed); - field_to_json(Obj,"load1",load1); - field_to_json(Obj,"load5",load5); - field_to_json(Obj,"load15",load15); - field_to_json(Obj,"vendors",vendors); - field_to_json(Obj,"status",status); - field_to_json(Obj,"deviceType",deviceType); - field_to_json(Obj,"healths",healths); - field_to_json(Obj,"certificates",certificates); - field_to_json(Obj,"lastContact",lastContact); - field_to_json(Obj,"associations",associations); - field_to_json(Obj,"snapshot",snapshot); - field_to_json(Obj,"numberOfDevices",numberOfDevices); + field_to_json(Obj, "commands", commands); + field_to_json(Obj, "upTimes", upTimes); + field_to_json(Obj, "memoryUsed", memoryUsed); + field_to_json(Obj, "load1", load1); + field_to_json(Obj, "load5", load5); + field_to_json(Obj, "load15", load15); + field_to_json(Obj, "vendors", vendors); + field_to_json(Obj, "status", status); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "healths", healths); + field_to_json(Obj, "certificates", certificates); + field_to_json(Obj, "lastContact", lastContact); + field_to_json(Obj, "associations", associations); + field_to_json(Obj, "snapshot", snapshot); + field_to_json(Obj, "numberOfDevices", numberOfDevices); } - void Dashboard::reset() { + void Dashboard::reset() { commands.clear(); upTimes.clear(); memoryUsed.clear(); @@ -296,38 +302,38 @@ namespace OpenWifi::GWObjects { certificates.clear(); lastContact.clear(); associations.clear(); - numberOfDevices = 0 ; + numberOfDevices = 0; snapshot = Utils::Now(); } - void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ - field_to_json(Obj,"deviceType", deviceType); - field_to_json(Obj,"capabilities", capabilities); + void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "capabilities", capabilities); }; void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"serialNumber",serialNumber); - field_to_json(Obj,"timeout",timeout); - field_to_json(Obj,"type",type); - field_to_json(Obj,"scriptId",scriptId); - field_to_json(Obj,"script",script); - field_to_json(Obj,"when",when); - field_to_json(Obj,"signature", signature); - field_to_json(Obj,"deferred", deferred); - field_to_json(Obj,"uri", uri); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "timeout", timeout); + field_to_json(Obj, "type", type); + field_to_json(Obj, "scriptId", scriptId); + field_to_json(Obj, "script", script); + field_to_json(Obj, "when", when); + field_to_json(Obj, "signature", signature); + field_to_json(Obj, "deferred", deferred); + field_to_json(Obj, "uri", uri); } bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"serialNumber",serialNumber); - field_from_json(Obj,"timeout",timeout); - field_from_json(Obj,"type",type); - field_from_json(Obj,"script",script); - field_from_json(Obj,"scriptId",scriptId); - field_from_json(Obj,"when",when); - field_from_json(Obj,"signature", signature); - field_from_json(Obj,"deferred", deferred); - field_from_json(Obj,"uri", uri); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "timeout", timeout); + field_from_json(Obj, "type", type); + field_from_json(Obj, "script", script); + field_from_json(Obj, "scriptId", scriptId); + field_from_json(Obj, "when", when); + field_from_json(Obj, "signature", signature); + field_from_json(Obj, "deferred", deferred); + field_from_json(Obj, "uri", uri); return true; } catch (const Poco::Exception &E) { } @@ -335,12 +341,12 @@ namespace OpenWifi::GWObjects { } void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"pools",pools); + field_to_json(Obj, "pools", pools); } bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"pools",pools); + field_from_json(Obj, "pools", pools); return true; } catch (const Poco::Exception &E) { } @@ -348,22 +354,22 @@ namespace OpenWifi::GWObjects { } void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"name",name); - field_to_json(Obj,"description",description); - field_to_json(Obj,"authConfig",authConfig); - field_to_json(Obj,"acctConfig",acctConfig); - field_to_json(Obj,"coaConfig",coaConfig); - field_to_json(Obj,"useByDefault",useByDefault); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "authConfig", authConfig); + field_to_json(Obj, "acctConfig", acctConfig); + field_to_json(Obj, "coaConfig", coaConfig); + field_to_json(Obj, "useByDefault", useByDefault); } bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"authConfig",authConfig); - field_from_json(Obj,"acctConfig",acctConfig); - field_from_json(Obj,"coaConfig",coaConfig); - field_from_json(Obj,"useByDefault",useByDefault); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "authConfig", authConfig); + field_from_json(Obj, "acctConfig", acctConfig); + field_from_json(Obj, "coaConfig", coaConfig); + field_from_json(Obj, "useByDefault", useByDefault); return true; } catch (const Poco::Exception &E) { } @@ -371,20 +377,20 @@ namespace OpenWifi::GWObjects { } void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"strategy",strategy); - field_to_json(Obj,"monitor",monitor); - field_to_json(Obj,"monitorMethod",monitorMethod); - field_to_json(Obj,"methodParameters",methodParameters); - field_to_json(Obj,"servers",servers); + field_to_json(Obj, "strategy", strategy); + field_to_json(Obj, "monitor", monitor); + field_to_json(Obj, "monitorMethod", monitorMethod); + field_to_json(Obj, "methodParameters", methodParameters); + field_to_json(Obj, "servers", servers); } bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"strategy",strategy); - field_from_json(Obj,"monitor",monitor); - field_from_json(Obj,"monitorMethod",monitorMethod); - field_from_json(Obj,"methodParameters",methodParameters); - field_from_json(Obj,"servers",servers); + field_from_json(Obj, "strategy", strategy); + field_from_json(Obj, "monitor", monitor); + field_from_json(Obj, "monitorMethod", monitorMethod); + field_from_json(Obj, "methodParameters", methodParameters); + field_from_json(Obj, "servers", servers); return true; } catch (const Poco::Exception &E) { } @@ -392,40 +398,40 @@ namespace OpenWifi::GWObjects { } void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"name",name); - field_to_json(Obj,"ip",ip); - field_to_json(Obj,"port",port); - field_to_json(Obj,"weight",weight); - field_to_json(Obj,"secret",secret); - field_to_json(Obj,"certificate",certificate); - field_to_json(Obj,"radsec",radsec); - field_to_json(Obj,"allowSelfSigned",allowSelfSigned); - field_to_json(Obj,"radsecPort",radsecPort); - field_to_json(Obj,"radsecSecret",radsecSecret); - field_to_json(Obj,"radsecCacerts",radsecCacerts); - field_to_json(Obj,"radsecCert",radsecCert); - field_to_json(Obj,"radsecKey",radsecKey); - field_to_json(Obj,"radsecRealms",radsecRealms); - field_to_json(Obj,"ignore",ignore); + field_to_json(Obj, "name", name); + field_to_json(Obj, "ip", ip); + field_to_json(Obj, "port", port); + field_to_json(Obj, "weight", weight); + field_to_json(Obj, "secret", secret); + field_to_json(Obj, "certificate", certificate); + field_to_json(Obj, "radsec", radsec); + field_to_json(Obj, "allowSelfSigned", allowSelfSigned); + field_to_json(Obj, "radsecPort", radsecPort); + field_to_json(Obj, "radsecSecret", radsecSecret); + field_to_json(Obj, "radsecCacerts", radsecCacerts); + field_to_json(Obj, "radsecCert", radsecCert); + field_to_json(Obj, "radsecKey", radsecKey); + field_to_json(Obj, "radsecRealms", radsecRealms); + field_to_json(Obj, "ignore", ignore); } bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"name",name); - field_from_json(Obj,"ip",ip); - field_from_json(Obj,"port",port); - field_from_json(Obj,"weight",weight); - field_from_json(Obj,"secret",secret); - field_from_json(Obj,"certificate",certificate); - field_from_json(Obj,"radsec",radsec); - field_from_json(Obj,"allowSelfSigned",allowSelfSigned); - field_from_json(Obj,"radsecSecret",radsecSecret); - field_from_json(Obj,"radsecPort",radsecPort); - field_from_json(Obj,"radsecCacerts",radsecCacerts); - field_from_json(Obj,"radsecCert",radsecCert); - field_from_json(Obj,"radsecKey",radsecKey); - field_from_json(Obj,"radsecRealms",radsecRealms); - field_from_json(Obj,"ignore",ignore); + field_from_json(Obj, "name", name); + field_from_json(Obj, "ip", ip); + field_from_json(Obj, "port", port); + field_from_json(Obj, "weight", weight); + field_from_json(Obj, "secret", secret); + field_from_json(Obj, "certificate", certificate); + field_from_json(Obj, "radsec", radsec); + field_from_json(Obj, "allowSelfSigned", allowSelfSigned); + field_from_json(Obj, "radsecSecret", radsecSecret); + field_from_json(Obj, "radsecPort", radsecPort); + field_from_json(Obj, "radsecCacerts", radsecCacerts); + field_from_json(Obj, "radsecCert", radsecCert); + field_from_json(Obj, "radsecKey", radsecKey); + field_from_json(Obj, "radsecRealms", radsecRealms); + field_from_json(Obj, "ignore", ignore); return true; } catch (const Poco::Exception &E) { } @@ -433,38 +439,38 @@ namespace OpenWifi::GWObjects { } void ScriptEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"name", name); - field_to_json(Obj,"description", description); - field_to_json(Obj,"uri", uri); - field_to_json(Obj,"content", content); - field_to_json(Obj,"version", version); - field_to_json(Obj,"type", type); - field_to_json(Obj,"created", created); - field_to_json(Obj,"modified", modified); - field_to_json(Obj,"author", author); - field_to_json(Obj,"restricted", restricted); - field_to_json(Obj,"deferred", deferred); - field_to_json(Obj,"timeout", timeout); - field_to_json(Obj,"defaultUploadURI", defaultUploadURI); + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "uri", uri); + field_to_json(Obj, "content", content); + field_to_json(Obj, "version", version); + field_to_json(Obj, "type", type); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "author", author); + field_to_json(Obj, "restricted", restricted); + field_to_json(Obj, "deferred", deferred); + field_to_json(Obj, "timeout", timeout); + field_to_json(Obj, "defaultUploadURI", defaultUploadURI); } bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"name", name); - field_from_json(Obj,"description", description); - field_from_json(Obj,"uri", uri); - field_from_json(Obj,"content", content); - field_from_json(Obj,"version", version); - field_from_json(Obj,"type", type); - field_from_json(Obj,"created", created); - field_from_json(Obj,"modified", modified); - field_from_json(Obj,"author", author); - field_from_json(Obj,"restricted", restricted); - field_from_json(Obj,"deferred", deferred); - field_from_json(Obj,"timeout", timeout); - field_from_json(Obj,"defaultUploadURI", defaultUploadURI); + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "uri", uri); + field_from_json(Obj, "content", content); + field_from_json(Obj, "version", version); + field_from_json(Obj, "type", type); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "author", author); + field_from_json(Obj, "restricted", restricted); + field_from_json(Obj, "deferred", deferred); + field_from_json(Obj, "timeout", timeout); + field_from_json(Obj, "defaultUploadURI", defaultUploadURI); return true; } catch (const Poco::Exception &E) { } @@ -472,12 +478,12 @@ namespace OpenWifi::GWObjects { } void ScriptEntryList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"scripts",scripts); + field_to_json(Obj, "scripts", scripts); } bool ScriptEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"scripts",scripts); + field_from_json(Obj, "scripts", scripts); return true; } catch (const Poco::Exception &E) { } @@ -485,63 +491,57 @@ namespace OpenWifi::GWObjects { } void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"vendor", vendor); - field_to_json(Obj,"algo", algo); + field_to_json(Obj, "vendor", vendor); + field_to_json(Obj, "algo", algo); } bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"vendor", vendor); - field_from_json(Obj,"algo", algo); + field_from_json(Obj, "vendor", vendor); + field_from_json(Obj, "algo", algo); return true; } catch (const Poco::Exception &E) { } return false; - } void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"dfs", dfs); - field_to_json(Obj,"ssh", ssh); - field_to_json(Obj,"rtty", rtty); - field_to_json(Obj,"tty", tty); - field_to_json(Obj,"developer", developer); - field_to_json(Obj,"upgrade", upgrade); - field_to_json(Obj,"commands", commands); - field_to_json(Obj,"country", country); - field_to_json(Obj,"key_info", key_info); + field_to_json(Obj, "dfs", dfs); + field_to_json(Obj, "ssh", ssh); + field_to_json(Obj, "rtty", rtty); + field_to_json(Obj, "tty", tty); + field_to_json(Obj, "developer", developer); + field_to_json(Obj, "upgrade", upgrade); + field_to_json(Obj, "commands", commands); + field_to_json(Obj, "country", country); + field_to_json(Obj, "key_info", key_info); } bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"dfs", dfs); - field_from_json(Obj,"ssh", ssh); - field_from_json(Obj,"rtty", rtty); - field_from_json(Obj,"tty", tty); - field_from_json(Obj,"developer", developer); - field_from_json(Obj,"upgrade", upgrade); - field_from_json(Obj,"commands", commands); - field_from_json(Obj,"country", country); - field_from_json(Obj,"key_info", key_info); + field_from_json(Obj, "dfs", dfs); + field_from_json(Obj, "ssh", ssh); + field_from_json(Obj, "rtty", rtty); + field_from_json(Obj, "tty", tty); + field_from_json(Obj, "developer", developer); + field_from_json(Obj, "upgrade", upgrade); + field_from_json(Obj, "commands", commands); + field_from_json(Obj, "country", country); + field_from_json(Obj, "key_info", key_info); return true; } catch (const Poco::Exception &E) { } return false; } - bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { - return (T.algo!=algo) || (T.vendor!=vendor); + bool DeviceRestrictionsKeyInfo::operator!=( + const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { + return (T.algo != algo) || (T.vendor != vendor); } bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { - return ( (T.dfs!=dfs) || - (T.rtty!=rtty) || - (T.upgrade!=upgrade) || - (T.commands != commands) || - (T.developer != developer) || - (T.ssh !=ssh) || - (T.key_info != key_info) || - (T.country != country) ); + return ((T.dfs != dfs) || (T.rtty != rtty) || (T.upgrade != upgrade) || + (T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) || + (T.key_info != key_info) || (T.country != country)); } -} - +} // namespace OpenWifi::GWObjects diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index 3e0e404..ed7b264 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -13,62 +13,57 @@ namespace OpenWifi::GWObjects { - enum CertificateValidation { - NO_CERTIFICATE, - VALID_CERTIFICATE, - MISMATCH_SERIAL, - VERIFIED - }; + enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED }; struct ConnectionState { - uint64_t MessageCount = 0 ; + uint64_t MessageCount = 0; std::string Address; - uint64_t UUID = 0 ; - uint64_t PendingUUID = 0 ; + uint64_t UUID = 0; + uint64_t PendingUUID = 0; uint64_t TX = 0, RX = 0; - uint64_t Associations_2G=0; - uint64_t Associations_5G=0; - uint64_t Associations_6G=0; + uint64_t Associations_2G = 0; + uint64_t Associations_5G = 0; + uint64_t Associations_6G = 0; bool Connected = false; - uint64_t LastContact=0; + uint64_t LastContact = 0; std::string Firmware; CertificateValidation VerifiedCertificate = NO_CERTIFICATE; - std::string Compatible; - uint64_t kafkaClients=0; - uint64_t webSocketClients=0; - uint64_t kafkaPackets=0; - uint64_t websocketPackets=0; - std::string locale; - uint64_t started=0; - uint64_t sessionId=0; - double connectionCompletionTime=0.0; - std::uint64_t certificateExpiryDate=0; + std::string Compatible; + uint64_t kafkaClients = 0; + uint64_t webSocketClients = 0; + uint64_t kafkaPackets = 0; + uint64_t websocketPackets = 0; + std::string locale; + uint64_t started = 0; + uint64_t sessionId = 0; + double connectionCompletionTime = 0.0; + std::uint64_t certificateExpiryDate = 0; void to_json(Poco::JSON::Object &Obj) const; }; struct DeviceRestrictionsKeyInfo { - std::string vendor; - std::string algo; + std::string vendor; + std::string algo; - bool operator !=(const DeviceRestrictionsKeyInfo &b) const; + bool operator!=(const DeviceRestrictionsKeyInfo &b) const; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; struct DeviceRestrictions { - bool dfs = false; - bool ssh = false; - bool rtty = false; - bool tty = false; - bool developer = false; - bool upgrade = false; - bool commands = false; - std::vector country; - DeviceRestrictionsKeyInfo key_info; + bool dfs = false; + bool ssh = false; + bool rtty = false; + bool tty = false; + bool developer = false; + bool upgrade = false; + bool commands = false; + std::vector country; + DeviceRestrictionsKeyInfo key_info; - bool operator !=(const DeviceRestrictions &D) const; + bool operator!=(const DeviceRestrictions &D) const; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); @@ -80,27 +75,27 @@ namespace OpenWifi::GWObjects { std::string MACAddress; std::string Manufacturer; std::string Configuration; - SecurityObjects::NoteInfoVec Notes; + SecurityObjects::NoteInfoVec Notes; std::string Owner; std::string Location; std::string Firmware; std::string Compatible; std::string FWUpdatePolicy; - uint64_t UUID = 0 ; - uint64_t CreationTimestamp = 0 ; - uint64_t LastConfigurationChange = 0 ; - uint64_t LastConfigurationDownload = 0 ; - uint64_t LastFWUpdate = 0 ; + uint64_t UUID = 0; + uint64_t CreationTimestamp = 0; + uint64_t LastConfigurationChange = 0; + uint64_t LastConfigurationDownload = 0; + uint64_t LastFWUpdate = 0; std::string Venue; std::string DevicePassword; std::string subscriber; std::string entity; - uint64_t modified=0; + uint64_t modified = 0; std::string locale; - bool restrictedDevice=false; + bool restrictedDevice = false; std::string pendingConfiguration; std::string pendingConfigurationCmd; - DeviceRestrictions restrictionDetails; + DeviceRestrictions restrictionDetails; void to_json(Poco::JSON::Object &Obj) const; void to_json_with_status(Poco::JSON::Object &Obj) const; @@ -119,26 +114,26 @@ namespace OpenWifi::GWObjects { struct Statistics { std::string SerialNumber; - uint64_t UUID = 0 ; + uint64_t UUID = 0; std::string Data; - uint64_t Recorded = 0; + uint64_t Recorded = 0; void to_json(Poco::JSON::Object &Obj) const; }; struct HealthCheck { std::string SerialNumber; - uint64_t UUID = 0 ; + uint64_t UUID = 0; std::string Data; - uint64_t Recorded = 0 ; - uint64_t Sanity = 0 ; + uint64_t Recorded = 0; + uint64_t Sanity = 0; void to_json(Poco::JSON::Object &Obj) const; }; struct Capabilities { std::string Capabilities; - uint64_t FirstUpdate = 0 ; - uint64_t LastUpdate = 0 ; - void to_json(Poco::JSON::Object &Obj) const; + uint64_t FirstUpdate = 0; + uint64_t LastUpdate = 0; + void to_json(Poco::JSON::Object &Obj) const; }; struct DeviceLog { @@ -155,11 +150,11 @@ namespace OpenWifi::GWObjects { std::string SerialNumber; std::string Log; std::string Data; - uint64_t Severity = 0 ; - uint64_t Recorded = 0 ; - uint64_t LogType = 0 ; - uint64_t UUID = 0 ; - void to_json(Poco::JSON::Object &Obj) const; + uint64_t Severity = 0; + uint64_t Recorded = 0; + uint64_t LogType = 0; + uint64_t UUID = 0; + void to_json(Poco::JSON::Object &Obj) const; }; struct DefaultConfiguration { @@ -167,10 +162,10 @@ namespace OpenWifi::GWObjects { std::string Configuration; Types::StringVec Models; std::string Description; - uint64_t Created; - uint64_t LastModified; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); + uint64_t Created; + uint64_t LastModified; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); }; struct CommandDetails { @@ -184,15 +179,15 @@ namespace OpenWifi::GWObjects { std::string ErrorText; uint64_t Submitted = time(nullptr); uint64_t Executed = 0; - uint64_t Completed = 0 ; - uint64_t RunAt = 0 ; - uint64_t ErrorCode = 0 ; - uint64_t Custom = 0 ; - uint64_t WaitingForFile = 0 ; - uint64_t AttachDate = 0 ; - uint64_t AttachSize = 0 ; + uint64_t Completed = 0; + uint64_t RunAt = 0; + uint64_t ErrorCode = 0; + uint64_t Custom = 0; + uint64_t WaitingForFile = 0; + uint64_t AttachDate = 0; + uint64_t AttachSize = 0; std::string AttachType; - double executionTime = 0.0; + double executionTime = 0.0; void to_json(Poco::JSON::Object &Obj) const; }; @@ -208,20 +203,20 @@ namespace OpenWifi::GWObjects { struct RttySessionDetails { std::string SerialNumber; std::string Server; - uint64_t Port = 0 ; + uint64_t Port = 0; std::string Token; - uint64_t TimeOut = 0 ; + uint64_t TimeOut = 0; std::string ConnectionId; - uint64_t Started = 0 ; + uint64_t Started = 0; std::string CommandUUID; - uint64_t ViewPort = 0 ; + uint64_t ViewPort = 0; std::string DevicePassword; void to_json(Poco::JSON::Object &Obj) const; }; struct Dashboard { - uint64_t snapshot = 0 ; - uint64_t numberOfDevices = 0 ; + uint64_t snapshot = 0; + uint64_t numberOfDevices = 0; Types::CountedMap commands; Types::CountedMap upTimes; Types::CountedMap memoryUsed; @@ -247,27 +242,27 @@ namespace OpenWifi::GWObjects { }; struct ScriptEntry { - std::string id; - std::string name; - std::string description; - std::string uri; - std::string content; - std::string version; - std::string type; - std::uint64_t created; - std::uint64_t modified; - std::string author; - Types::StringVec restricted; - bool deferred=false; - std::uint64_t timeout=30; - std::string defaultUploadURI; + std::string id; + std::string name; + std::string description; + std::string uri; + std::string content; + std::string version; + std::string type; + std::uint64_t created; + std::uint64_t modified; + std::string author; + Types::StringVec restricted; + bool deferred = false; + std::uint64_t timeout = 30; + std::string defaultUploadURI; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; struct ScriptEntryList { - std::vector scripts; + std::vector scripts; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); @@ -275,7 +270,7 @@ namespace OpenWifi::GWObjects { struct ScriptRequest { std::string serialNumber; - uint64_t timeout=30; + uint64_t timeout = 30; std::string type; std::string script; std::string scriptId; @@ -291,52 +286,52 @@ namespace OpenWifi::GWObjects { struct RadiusProxyServerEntry { std::string name; std::string ip; - uint16_t port=0; - uint64_t weight=0; + uint16_t port = 0; + uint64_t weight = 0; std::string secret; std::string certificate; - bool radsec=false; - bool allowSelfSigned=false; - uint16_t radsecPort=2083; + bool radsec = false; + bool allowSelfSigned = false; + uint16_t radsecPort = 2083; std::string radsecSecret; std::string radsecKey; std::string radsecCert; - std::vector radsecCacerts; - std::vector radsecRealms; - bool ignore=false; + std::vector radsecCacerts; + std::vector radsecRealms; + bool ignore = false; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; struct RadiusProxyServerConfig { - std::string strategy; - bool monitor=false; - std::string monitorMethod; - std::vector methodParameters; - std::vector servers; + std::string strategy; + bool monitor = false; + std::string monitorMethod; + std::vector methodParameters; + std::vector servers; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; - struct RadiusProxyPool { + struct RadiusProxyPool { std::string name; std::string description; - RadiusProxyServerConfig authConfig; - RadiusProxyServerConfig acctConfig; - RadiusProxyServerConfig coaConfig; - bool useByDefault=false; + RadiusProxyServerConfig authConfig; + RadiusProxyServerConfig acctConfig; + RadiusProxyServerConfig coaConfig; + bool useByDefault = false; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; struct RadiusProxyPoolList { - std::vector pools; + std::vector pools; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); }; -} +} // namespace OpenWifi::GWObjects diff --git a/src/RESTObjects/RESTAPI_OWLSobjects.cpp b/src/RESTObjects/RESTAPI_OWLSobjects.cpp index 15e5f0a..0a420b7 100644 --- a/src/RESTObjects/RESTAPI_OWLSobjects.cpp +++ b/src/RESTObjects/RESTAPI_OWLSobjects.cpp @@ -4,9 +4,9 @@ #include "framework/RESTAPI_utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; -using OpenWifi::RESTAPI_utils::field_from_json; using OpenWifi::RESTAPI_utils::EmbedDocument; +using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; #include "RESTAPI_OWLSobjects.h" @@ -14,97 +14,89 @@ using OpenWifi::RESTAPI_utils::EmbedDocument; namespace OpenWifi::OWLSObjects { - void SimulationDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"name", name); - field_to_json(Obj,"gateway", gateway); - field_to_json(Obj,"certificate", certificate); - field_to_json(Obj,"key", key); - field_to_json(Obj,"macPrefix", macPrefix); - field_to_json(Obj,"deviceType", deviceType); - field_to_json(Obj,"devices", devices); - field_to_json(Obj,"healthCheckInterval", healthCheckInterval); - field_to_json(Obj,"stateInterval", stateInterval); - field_to_json(Obj,"minAssociations", minAssociations); - field_to_json(Obj,"maxAssociations", maxAssociations); - field_to_json(Obj,"minClients", minClients); - field_to_json(Obj,"maxClients", maxClients); - field_to_json(Obj,"simulationLength", simulationLength); - field_to_json(Obj,"threads", threads); - field_to_json(Obj,"clientInterval", clientInterval); - field_to_json(Obj,"keepAlive", keepAlive); - field_to_json(Obj,"reconnectInterval", reconnectInterval); - field_to_json(Obj,"concurrentDevices", concurrentDevices); - } + void SimulationDetails::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "gateway", gateway); + field_to_json(Obj, "certificate", certificate); + field_to_json(Obj, "key", key); + field_to_json(Obj, "macPrefix", macPrefix); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "devices", devices); + field_to_json(Obj, "healthCheckInterval", healthCheckInterval); + field_to_json(Obj, "stateInterval", stateInterval); + field_to_json(Obj, "minAssociations", minAssociations); + field_to_json(Obj, "maxAssociations", maxAssociations); + field_to_json(Obj, "minClients", minClients); + field_to_json(Obj, "maxClients", maxClients); + field_to_json(Obj, "simulationLength", simulationLength); + field_to_json(Obj, "threads", threads); + field_to_json(Obj, "clientInterval", clientInterval); + field_to_json(Obj, "keepAlive", keepAlive); + field_to_json(Obj, "reconnectInterval", reconnectInterval); + field_to_json(Obj, "concurrentDevices", concurrentDevices); + } - bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id", id); - field_from_json(Obj,"name", name); - field_from_json(Obj,"gateway", gateway); - field_from_json(Obj,"certificate", certificate); - field_from_json(Obj,"key", key); - field_from_json(Obj,"macPrefix", macPrefix); - field_from_json(Obj,"deviceType", deviceType); - field_from_json(Obj,"devices", devices); - field_from_json(Obj,"healthCheckInterval", healthCheckInterval); - field_from_json(Obj,"stateInterval", stateInterval); - field_from_json(Obj,"minAssociations", minAssociations); - field_from_json(Obj,"maxAssociations", maxAssociations); - field_from_json(Obj,"minClients", minClients); - field_from_json(Obj,"maxClients", maxClients); - field_from_json(Obj,"simulationLength", simulationLength); - field_from_json(Obj,"threads", threads); - field_from_json(Obj,"clientInterval", clientInterval); - field_from_json(Obj,"keepAlive", keepAlive); - field_from_json(Obj,"reconnectInterval", reconnectInterval); - field_from_json(Obj,"concurrentDevices", concurrentDevices); - return true; - } catch(...) { + bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "gateway", gateway); + field_from_json(Obj, "certificate", certificate); + field_from_json(Obj, "key", key); + field_from_json(Obj, "macPrefix", macPrefix); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "devices", devices); + field_from_json(Obj, "healthCheckInterval", healthCheckInterval); + field_from_json(Obj, "stateInterval", stateInterval); + field_from_json(Obj, "minAssociations", minAssociations); + field_from_json(Obj, "maxAssociations", maxAssociations); + field_from_json(Obj, "minClients", minClients); + field_from_json(Obj, "maxClients", maxClients); + field_from_json(Obj, "simulationLength", simulationLength); + field_from_json(Obj, "threads", threads); + field_from_json(Obj, "clientInterval", clientInterval); + field_from_json(Obj, "keepAlive", keepAlive); + field_from_json(Obj, "reconnectInterval", reconnectInterval); + field_from_json(Obj, "concurrentDevices", concurrentDevices); + return true; + } catch (...) { + } + return false; + } - } - return false; - } + void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "list", list); + } - void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"list", list); - } + bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "list", list); + return true; + } catch (...) { + } + return false; + } - bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"list", list); - return true; - } catch(...) { + void SimulationStatus::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "simulationId", simulationId); + field_to_json(Obj, "state", state); + field_to_json(Obj, "tx", tx); + field_to_json(Obj, "rx", rx); + field_to_json(Obj, "msgsTx", msgsTx); + field_to_json(Obj, "msgsRx", msgsRx); + field_to_json(Obj, "liveDevices", liveDevices); + field_to_json(Obj, "timeToFullDevices", timeToFullDevices); + field_to_json(Obj, "startTime", startTime); + field_to_json(Obj, "endTime", endTime); + field_to_json(Obj, "errorDevices", errorDevices); + field_to_json(Obj, "owner", owner); + } - } - return false; - } + void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {} - void SimulationStatus::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"simulationId", simulationId); - field_to_json(Obj,"state", state); - field_to_json(Obj,"tx", tx); - field_to_json(Obj,"rx", rx); - field_to_json(Obj,"msgsTx", msgsTx); - field_to_json(Obj,"msgsRx", msgsRx); - field_to_json(Obj,"liveDevices", liveDevices); - field_to_json(Obj,"timeToFullDevices", timeToFullDevices); - field_to_json(Obj,"startTime", startTime); - field_to_json(Obj,"endTime", endTime); - field_to_json(Obj,"errorDevices", errorDevices); - field_to_json(Obj,"owner", owner); - } + bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { return true; } - void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const { - - } - - bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { - return true; - } - - void Dashboard::reset() { - - } -} + void Dashboard::reset() {} +} // namespace OpenWifi::OWLSObjects diff --git a/src/RESTObjects/RESTAPI_OWLSobjects.h b/src/RESTObjects/RESTAPI_OWLSobjects.h index 4dadcb6..92623cb 100644 --- a/src/RESTObjects/RESTAPI_OWLSobjects.h +++ b/src/RESTObjects/RESTAPI_OWLSobjects.h @@ -5,73 +5,70 @@ #ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H #define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H -#include #include "Poco/JSON/Object.h" +#include namespace OpenWifi::OWLSObjects { - struct SimulationDetails { - std::string id; - std::string name; - std::string gateway; - std::string certificate; - std::string key; - std::string macPrefix; - std::string deviceType; - uint64_t devices = 5; - uint64_t healthCheckInterval = 60; - uint64_t stateInterval = 60 ; - uint64_t minAssociations = 1; - uint64_t maxAssociations = 3; - uint64_t minClients = 1 ; - uint64_t maxClients = 3; - uint64_t simulationLength = 60 * 60; - uint64_t threads = 16; - uint64_t clientInterval = 1; - uint64_t keepAlive = 300; - uint64_t reconnectInterval = 30 ; - uint64_t concurrentDevices = 5; + struct SimulationDetails { + std::string id; + std::string name; + std::string gateway; + std::string certificate; + std::string key; + std::string macPrefix; + std::string deviceType; + uint64_t devices = 5; + uint64_t healthCheckInterval = 60; + uint64_t stateInterval = 60; + uint64_t minAssociations = 1; + uint64_t maxAssociations = 3; + uint64_t minClients = 1; + uint64_t maxClients = 3; + uint64_t simulationLength = 60 * 60; + uint64_t threads = 16; + uint64_t clientInterval = 1; + uint64_t keepAlive = 300; + uint64_t reconnectInterval = 30; + uint64_t concurrentDevices = 5; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SimulationDetailsList { - std::vector list; + struct SimulationDetailsList { + std::vector list; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SimulationStatus { - std::string id; - std::string simulationId; - std::string state; - uint64_t tx; - uint64_t rx; - uint64_t msgsTx; - uint64_t msgsRx; - uint64_t liveDevices; - uint64_t timeToFullDevices; - uint64_t startTime; - uint64_t endTime; - uint64_t errorDevices; - std::string owner; + struct SimulationStatus { + std::string id; + std::string simulationId; + std::string state; + uint64_t tx; + uint64_t rx; + uint64_t msgsTx; + uint64_t msgsRx; + uint64_t liveDevices; + uint64_t timeToFullDevices; + uint64_t startTime; + uint64_t endTime; + uint64_t errorDevices; + std::string owner; - void to_json(Poco::JSON::Object &Obj) const; - }; + void to_json(Poco::JSON::Object &Obj) const; + }; + struct Dashboard { + int O; - struct Dashboard { - int O; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + void reset(); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - void reset(); +} // namespace OpenWifi::OWLSObjects - }; - -} - - -#endif //UCENTRALSIM_RESTAPI_OWLSOBJECTS_H +#endif // UCENTRALSIM_RESTAPI_OWLSOBJECTS_H diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index c5387a8..533d0f4 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -6,1239 +6,1192 @@ // Arilia Wireless Inc. // - #include "RESTAPI_ProvObjects.h" -#include "framework/RESTAPI_utils.h" #include "framework/MicroServiceFuncs.h" +#include "framework/RESTAPI_utils.h" #include "framework/utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::ProvObjects { - void ObjectInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"name",name); - field_to_json(Obj,"description",description); - field_to_json(Obj,"created",created); - field_to_json(Obj,"modified",modified); - field_to_json(Obj,"notes",notes); - field_to_json(Obj,"tags",tags); - } - - bool ObjectInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"created",created); - field_from_json(Obj,"modified",modified); - field_from_json(Obj,"notes",notes); - field_from_json(Obj,"tags",tags); - return true; - } catch(...) { - - } - return false; - } - - void ManagementPolicyEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"users",users); - field_to_json( Obj,"resources",resources); - field_to_json( Obj,"access",access); - field_to_json( Obj,"policy",policy); - } - - bool ManagementPolicyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"users",users); - field_from_json( Obj,"resources",resources); - field_from_json( Obj,"access",access); - field_from_json( Obj,"policy",policy); - return true; - } catch(...) { - - } - return false; - } - - void ManagementPolicy::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json(Obj, "entries", entries); - field_to_json(Obj, "inUse", inUse); - field_to_json(Obj, "entity", entity); - } - - bool ManagementPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json(Obj, "entries", entries); - field_from_json(Obj, "inUse", inUse); - field_from_json(Obj, "entity", entity); - return true; - } catch(...) { - - } - return false; - } - - void Entity::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"parent",parent); - field_to_json( Obj,"venues",venues); - field_to_json( Obj,"children",children); - field_to_json( Obj,"contacts",contacts); - field_to_json( Obj,"locations",locations); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"deviceConfiguration",deviceConfiguration); - field_to_json( Obj,"devices",devices); - field_to_json( Obj,"deviceRules",deviceRules); - field_to_json( Obj,"sourceIP",sourceIP); - field_to_json( Obj,"variables", variables); - field_to_json( Obj,"managementPolicies", managementPolicies); - field_to_json( Obj,"managementRoles", managementRoles); - field_to_json( Obj,"maps", maps); - field_to_json( Obj,"configurations", configurations); - } - - bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"parent",parent); - field_from_json( Obj,"venues",venues); - field_from_json( Obj,"children",children); - field_from_json( Obj,"contacts",contacts); - field_from_json( Obj,"locations",locations); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"deviceConfiguration",deviceConfiguration); - field_from_json( Obj,"devices",devices); - field_from_json( Obj,"deviceRules",deviceRules); - field_from_json( Obj,"sourceIP",sourceIP); - field_from_json( Obj,"variables", variables); - field_from_json( Obj,"managementPolicies", managementPolicies); - field_from_json( Obj,"managementRoles", managementRoles); - field_from_json( Obj,"maps", maps); - field_from_json( Obj,"configurations", configurations); - return true; - } catch(...) { - - } - return false; - } - - void DiGraphEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"parent",parent); - field_to_json( Obj,"child",child); - } - - bool DiGraphEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"parent",parent); - field_from_json( Obj,"child",child); - return true; - } catch (...) { - - } - return false; - } - - void Venue::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"parent",parent); - field_to_json( Obj,"entity",entity); - field_to_json( Obj,"children",children); - field_to_json( Obj,"devices",devices); - field_to_json( Obj,"topology",topology); - field_to_json( Obj,"parent",parent); - field_to_json( Obj,"design",design); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"deviceConfiguration",deviceConfiguration); - field_to_json( Obj,"contacts",contacts); - field_to_json( Obj,"location",location); - field_to_json( Obj,"deviceRules",deviceRules); - field_to_json( Obj,"sourceIP",sourceIP); - field_to_json( Obj,"variables", variables); - field_to_json( Obj,"managementPolicies", managementPolicies); - field_to_json( Obj,"managementRoles", managementRoles); - field_to_json( Obj,"maps", maps); - field_to_json( Obj,"configurations", configurations); - field_to_json( Obj,"boards", boards); - } - - bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"parent",parent); - field_from_json( Obj,"entity",entity); - field_from_json( Obj,"children",children); - field_from_json( Obj,"devices",devices); - field_from_json( Obj,"topology",topology); - field_from_json( Obj,"parent",parent); - field_from_json( Obj,"design",design); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"deviceConfiguration",deviceConfiguration); - field_from_json( Obj,"contacts",contacts); - field_from_json( Obj,"location",location); - field_from_json( Obj,"deviceRules",deviceRules); - field_from_json( Obj,"sourceIP",sourceIP); - field_from_json( Obj,"variables", variables); - field_from_json( Obj,"managementPolicies", managementPolicies); - field_from_json( Obj,"managementRoles", managementRoles); - field_from_json( Obj,"maps", maps); - field_from_json( Obj,"configurations", configurations); - field_from_json( Obj,"boards", boards); - return true; - } catch (...) { - - } - return false; - } - - void Operator::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"managementRoles",managementRoles); - field_to_json( Obj,"deviceRules",deviceRules); - field_to_json( Obj,"variables",variables); - field_to_json( Obj,"defaultOperator",defaultOperator); - field_to_json( Obj,"sourceIP",sourceIP); - field_to_json( Obj,"registrationId",registrationId); - } - - bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"managementRoles",managementRoles); - field_from_json( Obj,"deviceRules",deviceRules); - field_from_json( Obj,"variables",variables); - field_from_json( Obj,"defaultOperator",defaultOperator); - field_from_json( Obj,"sourceIP",sourceIP); - field_from_json( Obj,"registrationId",registrationId); - return true; - } catch(...) { - } - return false; - } - - void OperatorList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"operators",operators); - } - - bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"operators",operators); - return true; - } catch(...) { - } - return false; - } - - void ServiceClass::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"operatorId",operatorId); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"cost",cost); - field_to_json( Obj,"currency",currency); - field_to_json( Obj,"period",period); - field_to_json( Obj,"billingCode",billingCode); - field_to_json( Obj,"variables",variables); - field_to_json( Obj,"defaultService",defaultService); - } - - bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"operatorId",operatorId); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"cost",cost); - field_from_json( Obj,"currency",currency); - field_from_json( Obj,"period",period); - field_from_json( Obj,"billingCode",billingCode); - field_from_json( Obj,"variables",variables); - field_from_json( Obj,"defaultService",defaultService); - return true; - } catch(...) { - } - return false; - - } - - void ServiceClassList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"serviceClasses",serviceClasses); - } - - bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"serviceClasses",serviceClasses); - return true; - } catch(...) { - } - return false; - } - - void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"id",id); - field_to_json( Obj,"entity",loginId); - field_to_json( Obj,"children",userType); - } - - bool UserInfoDigest::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"id",id); - field_from_json( Obj,"entity",loginId); - field_from_json( Obj,"children",userType); - return true; - } catch(...) { - } - return false; - } - - void ManagementRole::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"users",users); - field_to_json( Obj,"entity",entity); - field_to_json( Obj,"venue",venue); - } - - bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"users",users); - field_from_json( Obj,"entity",entity); - field_from_json( Obj,"venue",venue); - return true; - } catch(...) { - } - return false; - } - - void Location::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"type",OpenWifi::ProvObjects::to_string(type)); - field_to_json( Obj,"buildingName",buildingName); - field_to_json( Obj,"addressLines",addressLines); - field_to_json( Obj,"city",city); - field_to_json( Obj,"state",state); - field_to_json( Obj,"postal",postal); - field_to_json( Obj,"country",country); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"geoCode",geoCode); - field_to_json( Obj,"inUse",inUse); - field_to_json( Obj,"entity",entity); - field_to_json( Obj,"managementPolicy",managementPolicy); - } - - bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - std::string tmp_type; - field_from_json( Obj,"type", tmp_type); - type = location_from_string(tmp_type); - field_from_json( Obj,"buildingName",buildingName); - field_from_json( Obj,"addressLines",addressLines); - field_from_json( Obj,"city",city); - field_from_json( Obj,"state",state); - field_from_json( Obj,"postal",postal); - field_from_json( Obj,"country",country); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"geoCode",geoCode); - field_from_json( Obj,"inUse",inUse); - field_from_json( Obj,"entity",entity); - field_from_json( Obj,"managementPolicy",managementPolicy); - return true; - } catch (...) { - - } - return false; - } - - void OperatorLocation::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"type",type); - field_to_json( Obj,"buildingName",buildingName); - field_to_json( Obj,"addressLines",addressLines); - field_to_json( Obj,"city",city); - field_to_json( Obj,"state",state); - field_to_json( Obj,"postal",postal); - field_to_json( Obj,"country",country); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"geoCode",geoCode); - field_to_json( Obj,"operatorId",operatorId); - field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId); - field_to_json( Obj,"managementPolicy",managementPolicy); - } - - bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"type", type); - field_from_json( Obj,"buildingName",buildingName); - field_from_json( Obj,"addressLines",addressLines); - field_from_json( Obj,"city",city); - field_from_json( Obj,"state",state); - field_from_json( Obj,"postal",postal); - field_from_json( Obj,"country",country); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"geoCode",geoCode); - field_from_json( Obj,"operatorId",operatorId); - field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId); - field_from_json( Obj,"managementPolicy",managementPolicy); - return true; - } catch (...) { - - } - return false; - } - - void SubLocation::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"type",type); - field_to_json( Obj,"buildingName",buildingName); - field_to_json( Obj,"addressLines",addressLines); - field_to_json( Obj,"city",city); - field_to_json( Obj,"state",state); - field_to_json( Obj,"postal",postal); - field_to_json( Obj,"country",country); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"geoCode",geoCode); - } - - bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"type", type); - field_from_json( Obj,"buildingName",buildingName); - field_from_json( Obj,"addressLines",addressLines); - field_from_json( Obj,"city",city); - field_from_json( Obj,"state",state); - field_from_json( Obj,"postal",postal); - field_from_json( Obj,"country",country); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"geoCode",geoCode); - return true; - } catch (...) { - - } - return false; - } - - void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj, "locations", locations); - } - - bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj, "locations", locations); - return true; - } catch(...) { - - } - return false; - } - - void Contact::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"type", to_string(type)); - field_to_json( Obj,"title",title); - field_to_json( Obj,"salutation",salutation); - field_to_json( Obj,"firstname",firstname); - field_to_json( Obj,"lastname",lastname); - field_to_json( Obj,"initials",initials); - field_to_json( Obj,"visual",visual); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"primaryEmail",primaryEmail); - field_to_json( Obj,"secondaryEmail",secondaryEmail); - field_to_json( Obj,"accessPIN",accessPIN); - field_to_json( Obj,"inUse",inUse); - field_to_json( Obj,"entity",entity); - field_to_json( Obj,"managementPolicy",managementPolicy); - } - - bool Contact::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - std::string tmp_type; - field_from_json( Obj,"type", tmp_type); - type = contact_from_string(tmp_type); - field_from_json( Obj,"title",title); - field_from_json( Obj,"salutation",salutation); - field_from_json( Obj,"firstname",firstname); - field_from_json( Obj,"lastname",lastname); - field_from_json( Obj,"initials",initials); - field_from_json( Obj,"visual",visual); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"primaryEmail",primaryEmail); - field_from_json( Obj,"secondaryEmail",secondaryEmail); - field_from_json( Obj,"accessPIN",accessPIN); - field_from_json( Obj,"inUse",inUse); - field_from_json( Obj,"entity",entity); - field_from_json( Obj,"managementPolicy",managementPolicy); - return true; - } catch (...) { - - } - return false; - } - - void OperatorContact::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"type", type); - field_to_json( Obj,"title",title); - field_to_json( Obj,"salutation",salutation); - field_to_json( Obj,"firstname",firstname); - field_to_json( Obj,"lastname",lastname); - field_to_json( Obj,"initials",initials); - field_to_json( Obj,"visual",visual); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"primaryEmail",primaryEmail); - field_to_json( Obj,"secondaryEmail",secondaryEmail); - field_to_json( Obj,"accessPIN",accessPIN); - field_to_json( Obj,"operatorId",operatorId); - field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId); - field_to_json( Obj,"managementPolicy",managementPolicy); - } - - bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"type", type); - field_from_json( Obj,"title",title); - field_from_json( Obj,"salutation",salutation); - field_from_json( Obj,"firstname",firstname); - field_from_json( Obj,"lastname",lastname); - field_from_json( Obj,"initials",initials); - field_from_json( Obj,"visual",visual); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"primaryEmail",primaryEmail); - field_from_json( Obj,"secondaryEmail",secondaryEmail); - field_from_json( Obj,"accessPIN",accessPIN); - field_from_json( Obj,"operatorId",operatorId); - field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId); - field_from_json( Obj,"managementPolicy",managementPolicy); - return true; - } catch (...) { - - } - return false; - } - - void SubContact::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"type", type); - field_to_json( Obj,"title",title); - field_to_json( Obj,"salutation",salutation); - field_to_json( Obj,"firstname",firstname); - field_to_json( Obj,"lastname",lastname); - field_to_json( Obj,"initials",initials); - field_to_json( Obj,"visual",visual); - field_to_json( Obj,"mobiles",mobiles); - field_to_json( Obj,"phones",phones); - field_to_json( Obj,"primaryEmail",primaryEmail); - field_to_json( Obj,"secondaryEmail",secondaryEmail); - field_to_json( Obj,"accessPIN",accessPIN); - } - - bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"type", type); - field_from_json( Obj,"title",title); - field_from_json( Obj,"salutation",salutation); - field_from_json( Obj,"firstname",firstname); - field_from_json( Obj,"lastname",lastname); - field_from_json( Obj,"initials",initials); - field_from_json( Obj,"visual",visual); - field_from_json( Obj,"mobiles",mobiles); - field_from_json( Obj,"phones",phones); - field_from_json( Obj,"primaryEmail",primaryEmail); - field_from_json( Obj,"secondaryEmail",secondaryEmail); - field_from_json( Obj,"accessPIN",accessPIN); - return true; - } catch (...) { - - } - return false; - } - - void OperatorContactList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj, "contacts", contacts); - } - - bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj, "contacts", contacts); - return true; - } catch(...) { - - } - return false; - } - - void InventoryTag::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj, "serialNumber", serialNumber); - field_to_json( Obj, "venue", venue); - field_to_json( Obj, "entity", entity); - field_to_json( Obj, "subscriber", subscriber); - field_to_json( Obj, "deviceType", deviceType); - field_to_json( Obj, "qrCode", qrCode); - field_to_json( Obj, "geoCode", geoCode); - field_to_json( Obj, "location", location); - field_to_json( Obj, "contact", contact); - field_to_json( Obj, "deviceConfiguration",deviceConfiguration); - field_to_json( Obj,"deviceRules",deviceRules); - field_to_json( Obj, "managementPolicy",managementPolicy); - field_to_json( Obj, "state",state); - field_to_json( Obj, "devClass",devClass); - field_to_json( Obj, "locale",locale); - field_to_json( Obj, "realMacAddress",realMacAddress); - field_to_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); - } - - bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"serialNumber",serialNumber); - field_from_json( Obj,"venue",venue); - field_from_json( Obj,"entity",entity); - field_from_json( Obj,"subscriber",subscriber); - field_from_json( Obj,"deviceType",deviceType); - field_from_json( Obj,"qrCode", qrCode); - field_from_json( Obj,"geoCode",geoCode); - field_from_json( Obj,"location",location); - field_from_json( Obj,"contact",contact); - field_from_json( Obj,"deviceConfiguration",deviceConfiguration); - field_from_json( Obj,"deviceRules",deviceRules); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"state",state); - field_from_json( Obj,"devClass",devClass); - field_from_json( Obj,"locale",locale); - field_from_json( Obj,"realMacAddress",realMacAddress); - field_from_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); - return true; - } catch(...) { - - } - return false; - } - - void InventoryConfigApplyResult::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj, "appliedConfiguration", appliedConfiguration); - field_to_json( Obj, "warnings", warnings); - field_to_json( Obj, "errors", errors); - field_to_json( Obj, "errorCode", errorCode); - } - - bool InventoryConfigApplyResult::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj, "appliedConfiguration", appliedConfiguration); - field_from_json( Obj, "warnings", warnings); - field_from_json( Obj, "errors", errors); - field_from_json( Obj, "errorCode", errorCode); - return true; - } catch (...) { - - } - return false; - } - - void InventoryTagList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"taglist",taglist); - } - - bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"taglist",taglist); - return true; - } catch (...) { - - } - return false; - }; - - void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"name", name); - field_to_json( Obj,"description", description); - field_to_json( Obj,"weight", weight); - field_to_json( Obj,"configuration", configuration); - } - - bool DeviceConfigurationElement::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"name",name); - field_from_json( Obj,"description",description); - field_from_json( Obj,"weight",weight); - field_from_json( Obj,"configuration",configuration); - return true; - } catch(...) { - - } - return false; - } - - void DeviceConfiguration::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"managementPolicy",managementPolicy); - field_to_json( Obj,"deviceTypes",deviceTypes); - field_to_json( Obj,"subscriberOnly",subscriberOnly); - field_to_json( Obj,"entity", entity); - field_to_json( Obj,"venue", venue); - field_to_json( Obj,"subscriber", subscriber); - field_to_json( Obj,"configuration",configuration); - field_to_json( Obj,"inUse",inUse); - field_to_json( Obj,"variables",variables); - field_to_json( Obj,"deviceRules",deviceRules); - } - - bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"managementPolicy",managementPolicy); - field_from_json( Obj,"deviceTypes",deviceTypes); - field_from_json( Obj,"inUse",inUse); - field_from_json( Obj,"variables",variables); - field_from_json( Obj,"subscriberOnly",subscriberOnly); - field_from_json( Obj,"entity", entity); - field_from_json( Obj,"venue", venue); - field_from_json( Obj,"subscriber", subscriber); - field_from_json( Obj,"configuration",configuration); - field_from_json( Obj,"deviceRules",deviceRules); - return true; - } catch(...) { - - } - return false; - } - - void Report::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "snapshot", snapShot); - field_to_json(Obj, "devices", tenants); - }; - - void Report::reset() { - tenants.clear(); - } - - void ExpandedUseEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "uuid", uuid); - field_to_json(Obj, "name", name); - field_to_json(Obj, "description", description); - } - - bool ExpandedUseEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"uuid",uuid); - field_from_json( Obj,"name",name); - field_from_json( Obj,"description",description); - return true; - } catch(...) { - - } - return false; - } - - void ExpandedUseEntryList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "type", type); - field_to_json(Obj, "entries", entries); - } - - bool ExpandedUseEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"type",type); - field_from_json( Obj,"entries",entries); - return true; - } catch(...) { - - } - return false; - } - - void ExpandedUseEntryMapList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "entries", entries); - } - - bool ExpandedUseEntryMapList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"entries",entries); - return true; - } catch(...) { - - } - return false; - } - - void UuidList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "list", list); - } - - bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "list", list); - return true; - } catch(...) { - - } - return false; - } - - void ObjectACL::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "users", users); - field_to_json(Obj, "roles", roles); - field_to_json(Obj, "access", access); - } - - bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "users", users); - field_from_json(Obj, "roles", roles); - field_from_json(Obj, "access", access); - return true; - } catch(...) { - - } - return false; - } - - void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "list", list); - } - - bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "list", list); - return true; - } catch(...) { - - } - return false; - } - - void Map::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"data",data); - field_to_json( Obj,"entity",entity); - field_to_json( Obj,"creator",creator); - field_to_json( Obj,"visibility",visibility); - field_to_json( Obj,"access",access); - field_to_json( Obj,"managementPolicy", managementPolicy); - field_to_json( Obj,"venue", venue); - } - - bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - RESTAPI_utils::field_from_json( Obj,"data",data); - RESTAPI_utils::field_from_json( Obj,"entity",entity); - RESTAPI_utils::field_from_json( Obj,"creator",creator); - RESTAPI_utils::field_from_json( Obj,"visibility",visibility); - RESTAPI_utils::field_from_json( Obj,"access",access); - RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy); - RESTAPI_utils::field_from_json( Obj,"venue", venue); - return true; - } catch(...) { - - } - return false; - } - - void SerialNumberList::to_json(Poco::JSON::Object &Obj) const { - RESTAPI_utils::field_to_json( Obj,"serialNumbers",serialNumbers); - } - - bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - RESTAPI_utils::field_from_json( Obj,"serialNumbers",serialNumbers); - return true; - } catch(...) { - - } - return false; - } - - void MapList::to_json(Poco::JSON::Object &Obj) const { - RESTAPI_utils::field_to_json( Obj,"list",list); - } - - bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - RESTAPI_utils::field_from_json( Obj,"list",list); - return true; - } catch(...) { - - } - return false; - } - - void SignupEntry::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"email", email); - field_to_json( Obj,"userId", userId); - field_to_json( Obj,"macAddress", macAddress); - field_to_json( Obj,"serialNumber", serialNumber); - field_to_json( Obj,"submitted", submitted); - field_to_json( Obj,"completed", completed); - field_to_json( Obj,"status", status); - field_to_json( Obj,"error", error); - field_to_json( Obj,"statusCode", statusCode); - field_to_json( Obj,"deviceID", deviceID); - field_to_json( Obj,"registrationId",registrationId); - field_to_json( Obj,"operatorId",operatorId); - } - - bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"email", email); - field_from_json( Obj,"userId", userId); - field_from_json( Obj,"macAddress", macAddress); - field_from_json( Obj,"serialNumber", serialNumber); - field_from_json( Obj,"submitted", submitted); - field_from_json( Obj,"completed", completed); - field_from_json( Obj,"status", status); - field_from_json( Obj,"error", error); - field_from_json( Obj,"statusCode", statusCode); - field_from_json( Obj,"deviceID", deviceID); - field_from_json( Obj,"registrationId",registrationId); - field_from_json( Obj,"operatorId",operatorId); - return true; - } catch(...) { - - } - return false; - } - - void Variable::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"type", type); - field_to_json( Obj,"weight", weight); - field_to_json( Obj,"prefix", prefix); - field_to_json( Obj,"value", value); - } - - bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"type", type); - field_from_json( Obj,"weight", weight); - field_from_json( Obj,"prefix", prefix); - field_from_json( Obj,"value", value); - return true; - } catch(...) { - - } - return false; - } - - void VariableList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"variables", variables); - } - - bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"variables", variables); - return true; - } catch(...) { - - } - return false; - } - - void VariableBlock::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"variables", variables); - field_to_json( Obj,"entity", entity); - field_to_json( Obj,"venue", venue); - field_to_json( Obj,"subscriber", subscriber); - field_to_json( Obj,"inventory", inventory); - field_to_json( Obj,"configurations", configurations); - field_to_json( Obj,"managementPolicy", managementPolicy); - } - - bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"variables", variables); - field_from_json( Obj,"entity", entity); - field_from_json( Obj,"venue", venue); - field_from_json( Obj,"subscriber", subscriber); - field_from_json( Obj,"inventory", inventory); - field_from_json( Obj,"configurations", configurations); - field_from_json( Obj,"managementPolicy", managementPolicy); - return true; - } catch(...) { - } - return false; - } - - void VariableBlockList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"variableBlocks", variableBlocks); - } - - bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"variableBlocks", variableBlocks); - return true; - } catch(...) { - - } - return false; - } - - void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"configuration", configuration); - field_to_json( Obj,"rrm", rrm); - field_to_json( Obj,"firmwareRCOnly", firmwareRCOnly); - field_to_json( Obj,"firmwareUpgrade", firmwareUpgrade); - } - - bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"configuration", configuration); - field_from_json( Obj,"rrm", rrm); - field_from_json( Obj,"firmwareRCOnly", firmwareRCOnly); - field_from_json( Obj,"firmwareUpgrade", firmwareUpgrade); - return true; - } catch(...) { - - } - return false; - } - - void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const { - info.to_json(Obj); - field_to_json( Obj,"serialNumber", serialNumber); - field_to_json( Obj,"deviceType", deviceType); - field_to_json( Obj,"operatorId", operatorId); - field_to_json( Obj,"subscriberId", subscriberId); - field_to_json( Obj,"location", location); - field_to_json( Obj,"contact", contact); - field_to_json( Obj,"managementPolicy", managementPolicy); - field_to_json( Obj,"serviceClass", serviceClass); - field_to_json( Obj,"qrCode", qrCode); - field_to_json( Obj,"geoCode", geoCode); - field_to_json( Obj,"deviceRules",deviceRules); - field_to_json( Obj,"state", state); - field_to_json( Obj,"locale", locale); - field_to_json( Obj,"billingCode", billingCode); - field_to_json( Obj,"configuration", configuration); - field_to_json( Obj,"suspended", suspended); - field_to_json( Obj,"realMacAddress", realMacAddress); - } - - bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - info.from_json(Obj); - field_from_json( Obj,"serialNumber", serialNumber); - field_from_json( Obj,"deviceType", deviceType); - field_from_json( Obj,"operatorId", operatorId); - field_from_json( Obj,"subscriberId", subscriberId); - field_from_json( Obj,"location", location); - field_from_json( Obj,"contact", contact); - field_from_json( Obj,"managementPolicy", managementPolicy); - field_from_json( Obj,"serviceClass", serviceClass); - field_from_json( Obj,"qrCode", qrCode); - field_from_json( Obj,"geoCode", geoCode); - field_from_json( Obj,"deviceRules",deviceRules); - field_from_json( Obj,"state", state); - field_from_json( Obj,"locale", locale); - field_from_json( Obj,"billingCode", billingCode); - field_from_json( Obj,"configuration", configuration); - field_from_json( Obj,"suspended", suspended); - field_from_json( Obj,"realMacAddress", realMacAddress); - return true; - } catch(...) { - - } - return false; - } - - void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const { - field_to_json( Obj,"subscriberDevices", subscriberDevices); - } - - bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json( Obj,"subscriberDevices", subscriberDevices); - return true; - } catch(...) { - - } - return false; - } - - void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"name",name); - field_to_json(Obj,"description",description); - field_to_json(Obj,"devices",devices); - } - - bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"devices",devices); - return true; - } catch(...) { - - } - return false; - } - - bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { - uint64_t Now = Utils::Now(); - if(O->has("name")) - I.name = O->get("name").toString(); - - if(I.name.empty()) - return false; - - if(O->has("description")) - I.description = O->get("description").toString(); - SecurityObjects::MergeNotes(O,U,I.notes); - SecurityObjects::NoteInfoVec N; - for(auto &i:I.notes) { - if(i.note.empty()) - continue; - N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note}); - } - I.modified = Now; - return true; - } - - bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { - uint64_t Now = Utils::Now(); - if(O->has("name")) - I.name = O->get("name").toString(); - - if(I.name.empty()) - return false; - - if(O->has("description")) - I.description = O->get("description").toString(); - - SecurityObjects::NoteInfoVec N; - for(auto &i:I.notes) { - if(i.note.empty()) - continue; - N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note}); - } - I.notes = N; - I.modified = I.created = Now; - I.id = MicroServiceCreateUUID(); - - return true; - } - - bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) { - I.modified = I.created = Utils::Now(); - I.id = MicroServiceCreateUUID(); - return true; - } - - void DeviceRules::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"rcOnly",rcOnly); - field_to_json(Obj,"rrm",rrm); - field_to_json(Obj,"firmwareUpgrade",firmwareUpgrade); - } - - bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"rcOnly",rcOnly); - field_from_json(Obj,"rrm",rrm); - field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade); - return true; - } catch(...) { - - } - return false; - } - - void RRMAlgorithmDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"name",name); - field_to_json(Obj,"parameters",parameters); - } - - bool RRMAlgorithmDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"name",name); - field_from_json(Obj,"parameters",parameters); - return true; - } catch(...) { - - } - return false; - } - - void RRMDetails::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"vendor",vendor); - field_to_json(Obj,"schedule",schedule); - field_to_json(Obj,"algorithms",algorithms); - } - - bool RRMDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"vendor",vendor); - field_from_json(Obj,"schedule",schedule); - field_from_json(Obj,"algorithms",algorithms); - return true; - } catch(...) { - - } - return false; - } - - void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"source",source); - field_to_json(Obj,"reason",reason); - field_to_json(Obj,"parameterName",parameterName); - field_to_json(Obj,"parameterType",parameterType); - field_to_json(Obj,"parameterValue",parameterValue); - field_to_json(Obj,"modified",modified); - } - - bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"source",source); - field_from_json(Obj,"reason",reason); - field_from_json(Obj,"parameterName",parameterName); - field_from_json(Obj,"parameterType",parameterType); - field_from_json(Obj,"parameterValue",parameterValue); - field_from_json(Obj,"modified",modified); - return true; - } catch(...) { - - } - return false; - } - - void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"serialNumber",serialNumber); - field_to_json(Obj,"managementPolicy",managementPolicy); - field_to_json(Obj,"overrides",overrides); - } - - bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"serialNumber",serialNumber); - field_from_json(Obj,"managementPolicy",managementPolicy); - field_from_json(Obj,"overrides",overrides); - return true; - } catch(...) { - - } - return false; - } - -} - - + void ObjectInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "notes", notes); + field_to_json(Obj, "tags", tags); + } + + bool ObjectInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "notes", notes); + field_from_json(Obj, "tags", tags); + return true; + } catch (...) { + } + return false; + } + + void ManagementPolicyEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "users", users); + field_to_json(Obj, "resources", resources); + field_to_json(Obj, "access", access); + field_to_json(Obj, "policy", policy); + } + + bool ManagementPolicyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "users", users); + field_from_json(Obj, "resources", resources); + field_from_json(Obj, "access", access); + field_from_json(Obj, "policy", policy); + return true; + } catch (...) { + } + return false; + } + + void ManagementPolicy::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "entries", entries); + field_to_json(Obj, "inUse", inUse); + field_to_json(Obj, "entity", entity); + } + + bool ManagementPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "entries", entries); + field_from_json(Obj, "inUse", inUse); + field_from_json(Obj, "entity", entity); + return true; + } catch (...) { + } + return false; + } + + void Entity::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "parent", parent); + field_to_json(Obj, "venues", venues); + field_to_json(Obj, "children", children); + field_to_json(Obj, "contacts", contacts); + field_to_json(Obj, "locations", locations); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "deviceConfiguration", deviceConfiguration); + field_to_json(Obj, "devices", devices); + field_to_json(Obj, "deviceRules", deviceRules); + field_to_json(Obj, "sourceIP", sourceIP); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "managementPolicies", managementPolicies); + field_to_json(Obj, "managementRoles", managementRoles); + field_to_json(Obj, "maps", maps); + field_to_json(Obj, "configurations", configurations); + } + + bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "parent", parent); + field_from_json(Obj, "venues", venues); + field_from_json(Obj, "children", children); + field_from_json(Obj, "contacts", contacts); + field_from_json(Obj, "locations", locations); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "deviceConfiguration", deviceConfiguration); + field_from_json(Obj, "devices", devices); + field_from_json(Obj, "deviceRules", deviceRules); + field_from_json(Obj, "sourceIP", sourceIP); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "managementPolicies", managementPolicies); + field_from_json(Obj, "managementRoles", managementRoles); + field_from_json(Obj, "maps", maps); + field_from_json(Obj, "configurations", configurations); + return true; + } catch (...) { + } + return false; + } + + void DiGraphEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "parent", parent); + field_to_json(Obj, "child", child); + } + + bool DiGraphEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "parent", parent); + field_from_json(Obj, "child", child); + return true; + } catch (...) { + } + return false; + } + + void Venue::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "parent", parent); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "children", children); + field_to_json(Obj, "devices", devices); + field_to_json(Obj, "topology", topology); + field_to_json(Obj, "parent", parent); + field_to_json(Obj, "design", design); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "deviceConfiguration", deviceConfiguration); + field_to_json(Obj, "contacts", contacts); + field_to_json(Obj, "location", location); + field_to_json(Obj, "deviceRules", deviceRules); + field_to_json(Obj, "sourceIP", sourceIP); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "managementPolicies", managementPolicies); + field_to_json(Obj, "managementRoles", managementRoles); + field_to_json(Obj, "maps", maps); + field_to_json(Obj, "configurations", configurations); + field_to_json(Obj, "boards", boards); + } + + bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "parent", parent); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "children", children); + field_from_json(Obj, "devices", devices); + field_from_json(Obj, "topology", topology); + field_from_json(Obj, "parent", parent); + field_from_json(Obj, "design", design); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "deviceConfiguration", deviceConfiguration); + field_from_json(Obj, "contacts", contacts); + field_from_json(Obj, "location", location); + field_from_json(Obj, "deviceRules", deviceRules); + field_from_json(Obj, "sourceIP", sourceIP); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "managementPolicies", managementPolicies); + field_from_json(Obj, "managementRoles", managementRoles); + field_from_json(Obj, "maps", maps); + field_from_json(Obj, "configurations", configurations); + field_from_json(Obj, "boards", boards); + return true; + } catch (...) { + } + return false; + } + + void Operator::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "managementRoles", managementRoles); + field_to_json(Obj, "deviceRules", deviceRules); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "defaultOperator", defaultOperator); + field_to_json(Obj, "sourceIP", sourceIP); + field_to_json(Obj, "registrationId", registrationId); + } + + bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "managementRoles", managementRoles); + field_from_json(Obj, "deviceRules", deviceRules); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "defaultOperator", defaultOperator); + field_from_json(Obj, "sourceIP", sourceIP); + field_from_json(Obj, "registrationId", registrationId); + return true; + } catch (...) { + } + return false; + } + + void OperatorList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "operators", operators); + } + + bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "operators", operators); + return true; + } catch (...) { + } + return false; + } + + void ServiceClass::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "operatorId", operatorId); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "cost", cost); + field_to_json(Obj, "currency", currency); + field_to_json(Obj, "period", period); + field_to_json(Obj, "billingCode", billingCode); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "defaultService", defaultService); + } + + bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "operatorId", operatorId); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "cost", cost); + field_from_json(Obj, "currency", currency); + field_from_json(Obj, "period", period); + field_from_json(Obj, "billingCode", billingCode); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "defaultService", defaultService); + return true; + } catch (...) { + } + return false; + } + + void ServiceClassList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "serviceClasses", serviceClasses); + } + + bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serviceClasses", serviceClasses); + return true; + } catch (...) { + } + return false; + } + + void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "entity", loginId); + field_to_json(Obj, "children", userType); + } + + bool UserInfoDigest::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "entity", loginId); + field_from_json(Obj, "children", userType); + return true; + } catch (...) { + } + return false; + } + + void ManagementRole::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "users", users); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "venue", venue); + } + + bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "users", users); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "venue", venue); + return true; + } catch (...) { + } + return false; + } + + void Location::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "type", OpenWifi::ProvObjects::to_string(type)); + field_to_json(Obj, "buildingName", buildingName); + field_to_json(Obj, "addressLines", addressLines); + field_to_json(Obj, "city", city); + field_to_json(Obj, "state", state); + field_to_json(Obj, "postal", postal); + field_to_json(Obj, "country", country); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "geoCode", geoCode); + field_to_json(Obj, "inUse", inUse); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "managementPolicy", managementPolicy); + } + + bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + std::string tmp_type; + field_from_json(Obj, "type", tmp_type); + type = location_from_string(tmp_type); + field_from_json(Obj, "buildingName", buildingName); + field_from_json(Obj, "addressLines", addressLines); + field_from_json(Obj, "city", city); + field_from_json(Obj, "state", state); + field_from_json(Obj, "postal", postal); + field_from_json(Obj, "country", country); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "geoCode", geoCode); + field_from_json(Obj, "inUse", inUse); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "managementPolicy", managementPolicy); + return true; + } catch (...) { + } + return false; + } + + void OperatorLocation::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "type", type); + field_to_json(Obj, "buildingName", buildingName); + field_to_json(Obj, "addressLines", addressLines); + field_to_json(Obj, "city", city); + field_to_json(Obj, "state", state); + field_to_json(Obj, "postal", postal); + field_to_json(Obj, "country", country); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "geoCode", geoCode); + field_to_json(Obj, "operatorId", operatorId); + field_to_json(Obj, "subscriberDeviceId", subscriberDeviceId); + field_to_json(Obj, "managementPolicy", managementPolicy); + } + + bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "type", type); + field_from_json(Obj, "buildingName", buildingName); + field_from_json(Obj, "addressLines", addressLines); + field_from_json(Obj, "city", city); + field_from_json(Obj, "state", state); + field_from_json(Obj, "postal", postal); + field_from_json(Obj, "country", country); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "geoCode", geoCode); + field_from_json(Obj, "operatorId", operatorId); + field_from_json(Obj, "subscriberDeviceId", subscriberDeviceId); + field_from_json(Obj, "managementPolicy", managementPolicy); + return true; + } catch (...) { + } + return false; + } + + void SubLocation::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "buildingName", buildingName); + field_to_json(Obj, "addressLines", addressLines); + field_to_json(Obj, "city", city); + field_to_json(Obj, "state", state); + field_to_json(Obj, "postal", postal); + field_to_json(Obj, "country", country); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "geoCode", geoCode); + } + + bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "buildingName", buildingName); + field_from_json(Obj, "addressLines", addressLines); + field_from_json(Obj, "city", city); + field_from_json(Obj, "state", state); + field_from_json(Obj, "postal", postal); + field_from_json(Obj, "country", country); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "geoCode", geoCode); + return true; + } catch (...) { + } + return false; + } + + void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "locations", locations); + } + + bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "locations", locations); + return true; + } catch (...) { + } + return false; + } + + void Contact::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "type", to_string(type)); + field_to_json(Obj, "title", title); + field_to_json(Obj, "salutation", salutation); + field_to_json(Obj, "firstname", firstname); + field_to_json(Obj, "lastname", lastname); + field_to_json(Obj, "initials", initials); + field_to_json(Obj, "visual", visual); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "primaryEmail", primaryEmail); + field_to_json(Obj, "secondaryEmail", secondaryEmail); + field_to_json(Obj, "accessPIN", accessPIN); + field_to_json(Obj, "inUse", inUse); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "managementPolicy", managementPolicy); + } + + bool Contact::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + std::string tmp_type; + field_from_json(Obj, "type", tmp_type); + type = contact_from_string(tmp_type); + field_from_json(Obj, "title", title); + field_from_json(Obj, "salutation", salutation); + field_from_json(Obj, "firstname", firstname); + field_from_json(Obj, "lastname", lastname); + field_from_json(Obj, "initials", initials); + field_from_json(Obj, "visual", visual); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "primaryEmail", primaryEmail); + field_from_json(Obj, "secondaryEmail", secondaryEmail); + field_from_json(Obj, "accessPIN", accessPIN); + field_from_json(Obj, "inUse", inUse); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "managementPolicy", managementPolicy); + return true; + } catch (...) { + } + return false; + } + + void OperatorContact::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "type", type); + field_to_json(Obj, "title", title); + field_to_json(Obj, "salutation", salutation); + field_to_json(Obj, "firstname", firstname); + field_to_json(Obj, "lastname", lastname); + field_to_json(Obj, "initials", initials); + field_to_json(Obj, "visual", visual); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "primaryEmail", primaryEmail); + field_to_json(Obj, "secondaryEmail", secondaryEmail); + field_to_json(Obj, "accessPIN", accessPIN); + field_to_json(Obj, "operatorId", operatorId); + field_to_json(Obj, "subscriberDeviceId", subscriberDeviceId); + field_to_json(Obj, "managementPolicy", managementPolicy); + } + + bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "type", type); + field_from_json(Obj, "title", title); + field_from_json(Obj, "salutation", salutation); + field_from_json(Obj, "firstname", firstname); + field_from_json(Obj, "lastname", lastname); + field_from_json(Obj, "initials", initials); + field_from_json(Obj, "visual", visual); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "primaryEmail", primaryEmail); + field_from_json(Obj, "secondaryEmail", secondaryEmail); + field_from_json(Obj, "accessPIN", accessPIN); + field_from_json(Obj, "operatorId", operatorId); + field_from_json(Obj, "subscriberDeviceId", subscriberDeviceId); + field_from_json(Obj, "managementPolicy", managementPolicy); + return true; + } catch (...) { + } + return false; + } + + void SubContact::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "title", title); + field_to_json(Obj, "salutation", salutation); + field_to_json(Obj, "firstname", firstname); + field_to_json(Obj, "lastname", lastname); + field_to_json(Obj, "initials", initials); + field_to_json(Obj, "visual", visual); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "primaryEmail", primaryEmail); + field_to_json(Obj, "secondaryEmail", secondaryEmail); + field_to_json(Obj, "accessPIN", accessPIN); + } + + bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "title", title); + field_from_json(Obj, "salutation", salutation); + field_from_json(Obj, "firstname", firstname); + field_from_json(Obj, "lastname", lastname); + field_from_json(Obj, "initials", initials); + field_from_json(Obj, "visual", visual); + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "primaryEmail", primaryEmail); + field_from_json(Obj, "secondaryEmail", secondaryEmail); + field_from_json(Obj, "accessPIN", accessPIN); + return true; + } catch (...) { + } + return false; + } + + void OperatorContactList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "contacts", contacts); + } + + bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "contacts", contacts); + return true; + } catch (...) { + } + return false; + } + + void InventoryTag::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "venue", venue); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "subscriber", subscriber); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "qrCode", qrCode); + field_to_json(Obj, "geoCode", geoCode); + field_to_json(Obj, "location", location); + field_to_json(Obj, "contact", contact); + field_to_json(Obj, "deviceConfiguration", deviceConfiguration); + field_to_json(Obj, "deviceRules", deviceRules); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "state", state); + field_to_json(Obj, "devClass", devClass); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "realMacAddress", realMacAddress); + field_to_json(Obj, "doNotAllowOverrides", doNotAllowOverrides); + } + + bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "venue", venue); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "subscriber", subscriber); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "qrCode", qrCode); + field_from_json(Obj, "geoCode", geoCode); + field_from_json(Obj, "location", location); + field_from_json(Obj, "contact", contact); + field_from_json(Obj, "deviceConfiguration", deviceConfiguration); + field_from_json(Obj, "deviceRules", deviceRules); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "state", state); + field_from_json(Obj, "devClass", devClass); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "realMacAddress", realMacAddress); + field_from_json(Obj, "doNotAllowOverrides", doNotAllowOverrides); + return true; + } catch (...) { + } + return false; + } + + void InventoryConfigApplyResult::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "appliedConfiguration", appliedConfiguration); + field_to_json(Obj, "warnings", warnings); + field_to_json(Obj, "errors", errors); + field_to_json(Obj, "errorCode", errorCode); + } + + bool InventoryConfigApplyResult::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "appliedConfiguration", appliedConfiguration); + field_from_json(Obj, "warnings", warnings); + field_from_json(Obj, "errors", errors); + field_from_json(Obj, "errorCode", errorCode); + return true; + } catch (...) { + } + return false; + } + + void InventoryTagList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "taglist", taglist); + } + + bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "taglist", taglist); + return true; + } catch (...) { + } + return false; + }; + + void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "weight", weight); + field_to_json(Obj, "configuration", configuration); + } + + bool DeviceConfigurationElement::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "weight", weight); + field_from_json(Obj, "configuration", configuration); + return true; + } catch (...) { + } + return false; + } + + void DeviceConfiguration::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "deviceTypes", deviceTypes); + field_to_json(Obj, "subscriberOnly", subscriberOnly); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "venue", venue); + field_to_json(Obj, "subscriber", subscriber); + field_to_json(Obj, "configuration", configuration); + field_to_json(Obj, "inUse", inUse); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "deviceRules", deviceRules); + } + + bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "deviceTypes", deviceTypes); + field_from_json(Obj, "inUse", inUse); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "subscriberOnly", subscriberOnly); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "venue", venue); + field_from_json(Obj, "subscriber", subscriber); + field_from_json(Obj, "configuration", configuration); + field_from_json(Obj, "deviceRules", deviceRules); + return true; + } catch (...) { + } + return false; + } + + void Report::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "snapshot", snapShot); + field_to_json(Obj, "devices", tenants); + }; + + void Report::reset() { tenants.clear(); } + + void ExpandedUseEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + } + + bool ExpandedUseEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "uuid", uuid); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + return true; + } catch (...) { + } + return false; + } + + void ExpandedUseEntryList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "entries", entries); + } + + bool ExpandedUseEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "entries", entries); + return true; + } catch (...) { + } + return false; + } + + void ExpandedUseEntryMapList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "entries", entries); + } + + bool ExpandedUseEntryMapList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "entries", entries); + return true; + } catch (...) { + } + return false; + } + + void UuidList::to_json(Poco::JSON::Object &Obj) const { field_to_json(Obj, "list", list); } + + bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "list", list); + return true; + } catch (...) { + } + return false; + } + + void ObjectACL::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "users", users); + field_to_json(Obj, "roles", roles); + field_to_json(Obj, "access", access); + } + + bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "users", users); + field_from_json(Obj, "roles", roles); + field_from_json(Obj, "access", access); + return true; + } catch (...) { + } + return false; + } + + void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { field_to_json(Obj, "list", list); } + + bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "list", list); + return true; + } catch (...) { + } + return false; + } + + void Map::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "data", data); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "creator", creator); + field_to_json(Obj, "visibility", visibility); + field_to_json(Obj, "access", access); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "venue", venue); + } + + bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + RESTAPI_utils::field_from_json(Obj, "data", data); + RESTAPI_utils::field_from_json(Obj, "entity", entity); + RESTAPI_utils::field_from_json(Obj, "creator", creator); + RESTAPI_utils::field_from_json(Obj, "visibility", visibility); + RESTAPI_utils::field_from_json(Obj, "access", access); + RESTAPI_utils::field_from_json(Obj, "managementPolicy", managementPolicy); + RESTAPI_utils::field_from_json(Obj, "venue", venue); + return true; + } catch (...) { + } + return false; + } + + void SerialNumberList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj, "serialNumbers", serialNumbers); + } + + bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj, "serialNumbers", serialNumbers); + return true; + } catch (...) { + } + return false; + } + + void MapList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj, "list", list); + } + + bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj, "list", list); + return true; + } catch (...) { + } + return false; + } + + void SignupEntry::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "email", email); + field_to_json(Obj, "userId", userId); + field_to_json(Obj, "macAddress", macAddress); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "submitted", submitted); + field_to_json(Obj, "completed", completed); + field_to_json(Obj, "status", status); + field_to_json(Obj, "error", error); + field_to_json(Obj, "statusCode", statusCode); + field_to_json(Obj, "deviceID", deviceID); + field_to_json(Obj, "registrationId", registrationId); + field_to_json(Obj, "operatorId", operatorId); + } + + bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "email", email); + field_from_json(Obj, "userId", userId); + field_from_json(Obj, "macAddress", macAddress); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "submitted", submitted); + field_from_json(Obj, "completed", completed); + field_from_json(Obj, "status", status); + field_from_json(Obj, "error", error); + field_from_json(Obj, "statusCode", statusCode); + field_from_json(Obj, "deviceID", deviceID); + field_from_json(Obj, "registrationId", registrationId); + field_from_json(Obj, "operatorId", operatorId); + return true; + } catch (...) { + } + return false; + } + + void Variable::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "weight", weight); + field_to_json(Obj, "prefix", prefix); + field_to_json(Obj, "value", value); + } + + bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "weight", weight); + field_from_json(Obj, "prefix", prefix); + field_from_json(Obj, "value", value); + return true; + } catch (...) { + } + return false; + } + + void VariableList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "variables", variables); + } + + bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "variables", variables); + return true; + } catch (...) { + } + return false; + } + + void VariableBlock::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "venue", venue); + field_to_json(Obj, "subscriber", subscriber); + field_to_json(Obj, "inventory", inventory); + field_to_json(Obj, "configurations", configurations); + field_to_json(Obj, "managementPolicy", managementPolicy); + } + + bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "entity", entity); + field_from_json(Obj, "venue", venue); + field_from_json(Obj, "subscriber", subscriber); + field_from_json(Obj, "inventory", inventory); + field_from_json(Obj, "configurations", configurations); + field_from_json(Obj, "managementPolicy", managementPolicy); + return true; + } catch (...) { + } + return false; + } + + void VariableBlockList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "variableBlocks", variableBlocks); + } + + bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "variableBlocks", variableBlocks); + return true; + } catch (...) { + } + return false; + } + + void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "configuration", configuration); + field_to_json(Obj, "rrm", rrm); + field_to_json(Obj, "firmwareRCOnly", firmwareRCOnly); + field_to_json(Obj, "firmwareUpgrade", firmwareUpgrade); + } + + bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "configuration", configuration); + field_from_json(Obj, "rrm", rrm); + field_from_json(Obj, "firmwareRCOnly", firmwareRCOnly); + field_from_json(Obj, "firmwareUpgrade", firmwareUpgrade); + return true; + } catch (...) { + } + return false; + } + + void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "operatorId", operatorId); + field_to_json(Obj, "subscriberId", subscriberId); + field_to_json(Obj, "location", location); + field_to_json(Obj, "contact", contact); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "serviceClass", serviceClass); + field_to_json(Obj, "qrCode", qrCode); + field_to_json(Obj, "geoCode", geoCode); + field_to_json(Obj, "deviceRules", deviceRules); + field_to_json(Obj, "state", state); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "billingCode", billingCode); + field_to_json(Obj, "configuration", configuration); + field_to_json(Obj, "suspended", suspended); + field_to_json(Obj, "realMacAddress", realMacAddress); + } + + bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "operatorId", operatorId); + field_from_json(Obj, "subscriberId", subscriberId); + field_from_json(Obj, "location", location); + field_from_json(Obj, "contact", contact); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "serviceClass", serviceClass); + field_from_json(Obj, "qrCode", qrCode); + field_from_json(Obj, "geoCode", geoCode); + field_from_json(Obj, "deviceRules", deviceRules); + field_from_json(Obj, "state", state); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "billingCode", billingCode); + field_from_json(Obj, "configuration", configuration); + field_from_json(Obj, "suspended", suspended); + field_from_json(Obj, "realMacAddress", realMacAddress); + return true; + } catch (...) { + } + return false; + } + + void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "subscriberDevices", subscriberDevices); + } + + bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "subscriberDevices", subscriberDevices); + return true; + } catch (...) { + } + return false; + } + + void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "devices", devices); + } + + bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "devices", devices); + return true; + } catch (...) { + } + return false; + } + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, + ObjectInfo &I) { + uint64_t Now = Utils::Now(); + if (O->has("name")) + I.name = O->get("name").toString(); + + if (I.name.empty()) + return false; + + if (O->has("description")) + I.description = O->get("description").toString(); + SecurityObjects::MergeNotes(O, U, I.notes); + SecurityObjects::NoteInfoVec N; + for (auto &i : I.notes) { + if (i.note.empty()) + continue; + N.push_back( + SecurityObjects::NoteInfo{.created = Now, .createdBy = U.email, .note = i.note}); + } + I.modified = Now; + return true; + } + + bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, + ObjectInfo &I) { + uint64_t Now = Utils::Now(); + if (O->has("name")) + I.name = O->get("name").toString(); + + if (I.name.empty()) + return false; + + if (O->has("description")) + I.description = O->get("description").toString(); + + SecurityObjects::NoteInfoVec N; + for (auto &i : I.notes) { + if (i.note.empty()) + continue; + N.push_back( + SecurityObjects::NoteInfo{.created = Now, .createdBy = U.email, .note = i.note}); + } + I.notes = N; + I.modified = I.created = Now; + I.id = MicroServiceCreateUUID(); + + return true; + } + + bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) { + I.modified = I.created = Utils::Now(); + I.id = MicroServiceCreateUUID(); + return true; + } + + void DeviceRules::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "rcOnly", rcOnly); + field_to_json(Obj, "rrm", rrm); + field_to_json(Obj, "firmwareUpgrade", firmwareUpgrade); + } + + bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "rcOnly", rcOnly); + field_from_json(Obj, "rrm", rrm); + field_from_json(Obj, "firmwareUpgrade", firmwareUpgrade); + return true; + } catch (...) { + } + return false; + } + + void RRMAlgorithmDetails::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "name", name); + field_to_json(Obj, "parameters", parameters); + } + + bool RRMAlgorithmDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "name", name); + field_from_json(Obj, "parameters", parameters); + return true; + } catch (...) { + } + return false; + } + + void RRMDetails::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "vendor", vendor); + field_to_json(Obj, "schedule", schedule); + field_to_json(Obj, "algorithms", algorithms); + } + + bool RRMDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "vendor", vendor); + field_from_json(Obj, "schedule", schedule); + field_from_json(Obj, "algorithms", algorithms); + return true; + } catch (...) { + } + return false; + } + + void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "source", source); + field_to_json(Obj, "reason", reason); + field_to_json(Obj, "parameterName", parameterName); + field_to_json(Obj, "parameterType", parameterType); + field_to_json(Obj, "parameterValue", parameterValue); + field_to_json(Obj, "modified", modified); + } + + bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "source", source); + field_from_json(Obj, "reason", reason); + field_from_json(Obj, "parameterName", parameterName); + field_from_json(Obj, "parameterType", parameterType); + field_from_json(Obj, "parameterValue", parameterValue); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } + + void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "managementPolicy", managementPolicy); + field_to_json(Obj, "overrides", overrides); + } + + bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "managementPolicy", managementPolicy); + field_from_json(Obj, "overrides", overrides); + return true; + } catch (...) { + } + return false; + } + +} // namespace OpenWifi::ProvObjects diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 3c0ed3e..9f4edf3 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -12,710 +12,738 @@ namespace OpenWifi::ProvObjects { - enum FIRMWARE_UPGRADE_RULES { - dont_upgrade, - upgrade_inherit, - upgrade_release_only, - upgrade_latest - }; - - struct ObjectInfo { - Types::UUID_t id; - std::string name; - std::string description; - SecurityObjects::NoteInfoVec notes; - uint64_t created=0; - uint64_t modified=0; - Types::TagList tags; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct SerialNumberList { - Types::UUIDvec_t serialNumbers; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ManagementPolicyEntry { - Types::UUIDvec_t users; - Types::UUIDvec_t resources; - Types::StringVec access; - std::string policy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ManagementPolicy { - ObjectInfo info; - std::vector entries; - Types::StringVec inUse; - Types::UUID_t entity; - Types::UUID_t venue; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector ManagementPolicyVec; - - struct RRMAlgorithmDetails { - std::string name; - std::string parameters; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct RRMDetails { - std::string vendor; - std::string schedule; - std::vector algorithms; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct DeviceRules { - std::string rcOnly{"inherit"}; - std::string rrm{"inherit"}; - std::string firmwareUpgrade{"inherit"}; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct Entity { - ObjectInfo info; - Types::UUID_t parent; - Types::UUIDvec_t children; - Types::UUIDvec_t venues; - Types::UUIDvec_t contacts; // all contacts associated in this entity - Types::UUIDvec_t locations; // all locations associated in this entity - Types::UUID_t managementPolicy; - Types::UUIDvec_t deviceConfiguration; - Types::UUIDvec_t devices; - DeviceRules deviceRules; - Types::StringVec sourceIP; - Types::UUIDvec_t variables; - Types::UUIDvec_t managementPolicies; - Types::UUIDvec_t managementRoles; - Types::UUIDvec_t maps; - Types::UUIDvec_t configurations; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector EntityVec; - - struct DiGraphEntry { - Types::UUID_t parent; - Types::UUID_t child; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - typedef std::vector DiGraph; - - struct Venue { - ObjectInfo info; - Types::UUID_t entity; - Types::UUID_t parent; - Types::UUIDvec_t children; - Types::UUID_t managementPolicy; - Types::UUIDvec_t devices; - DiGraph topology; - std::string design; - Types::UUIDvec_t deviceConfiguration; - Types::UUIDvec_t contacts; - std::string location; - DeviceRules deviceRules; - Types::StringVec sourceIP; - Types::UUIDvec_t variables; - Types::UUIDvec_t configurations; - Types::UUIDvec_t maps; - Types::UUIDvec_t managementPolicies; - Types::UUIDvec_t managementRoles; - Types::UUIDvec_t boards; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector VenueVec; - - struct UserInfoDigest { - std::string id; - std::string loginId; - std::string userType; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ManagementRole { - ObjectInfo info; - Types::UUID_t managementPolicy; - Types::UUIDvec_t users; - Types::StringVec inUse; - Types::UUID_t entity; - Types::UUID_t venue; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector ManagementRoleVec; - - enum LocationType { - LT_SERVICE, LT_EQUIPMENT, LT_AUTO, LT_MANUAL, - LT_SPECIAL, LT_UNKNOWN, LT_CORPORATE - }; - - inline std::string to_string(LocationType L) { - switch(L) { - case LT_SERVICE: return "SERVICE"; - case LT_EQUIPMENT: return "EQUIPMENT"; - case LT_AUTO: return "AUTO"; - case LT_MANUAL: return "MANUAL"; - case LT_SPECIAL: return "SPECIAL"; - case LT_UNKNOWN: return "UNKNOWN"; - case LT_CORPORATE: return "CORPORATE"; - default: return "UNKNOWN"; - } - } - - inline LocationType location_from_string(const std::string &S) { - if(!Poco::icompare(S,"SERVICE")) - return LT_SERVICE; - else if(!Poco::icompare(S,"EQUIPMENT")) - return LT_EQUIPMENT; - else if(!Poco::icompare(S,"AUTO")) - return LT_AUTO; - else if(!Poco::icompare(S,"MANUAL")) - return LT_MANUAL; - else if(!Poco::icompare(S,"SPECIAL")) - return LT_SPECIAL; - else if(!Poco::icompare(S,"UNKNOWN")) - return LT_UNKNOWN; - else if(!Poco::icompare(S,"CORPORATE")) - return LT_CORPORATE; - return LT_UNKNOWN; - } - - struct Location { - ObjectInfo info; - LocationType type; - std::string buildingName; - Types::StringVec addressLines; - std::string city; - std::string state; - std::string postal; - std::string country; - Types::StringVec phones; - Types::StringVec mobiles; - std::string geoCode; - Types::StringVec inUse; - Types::UUID_t entity; - Types::UUID_t managementPolicy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector LocationVec; - - struct OperatorLocation { - ObjectInfo info; - std::string type; - std::string buildingName; - Types::StringVec addressLines; - std::string city; - std::string state; - std::string postal; - std::string country; - Types::StringVec phones; - Types::StringVec mobiles; - std::string geoCode; - Types::UUID_t operatorId; - Types::UUID_t subscriberDeviceId; - Types::UUID_t managementPolicy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector LocationVec; - - struct SubLocation { - std::string type; - std::string buildingName; - Types::StringVec addressLines; - std::string city; - std::string state; - std::string postal; - std::string country; - Types::StringVec phones; - Types::StringVec mobiles; - std::string geoCode; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct OperatorLocationList { - std::vector locations; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - - enum ContactType { - CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER, - CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN - }; - - inline std::string to_string(ContactType L) { - switch(L) { - case CT_SUBSCRIBER: return "SUBSCRIBER"; - case CT_USER: return "USER"; - case CT_INSTALLER: return "INSTALLER"; - case CT_CSR: return "CSR"; - case CT_MANAGER: return "MANAGER"; - case CT_BUSINESSOWNER: return "BUSINESSOWNER"; - case CT_TECHNICIAN: return "TECHNICIAN"; - case CT_CORPORATE: return "CORPORATE"; - case CT_UNKNOWN: return "UNKNOWN"; - default: return "UNKNOWN"; - } - } - - inline ContactType contact_from_string(const std::string &S) { - if(!Poco::icompare(S,"SUBSCRIBER")) - return CT_SUBSCRIBER; - else if(!Poco::icompare(S,"USER")) - return CT_USER; - else if(!Poco::icompare(S,"INSTALLER")) - return CT_INSTALLER; - else if(!Poco::icompare(S,"CSR")) - return CT_CSR; - else if(!Poco::icompare(S,"BUSINESSOWNER")) - return CT_BUSINESSOWNER; - else if(!Poco::icompare(S,"TECHNICIAN")) - return CT_TECHNICIAN; - else if(!Poco::icompare(S,"CORPORATE")) - return CT_CORPORATE; - else if(!Poco::icompare(S,"UNKNOWN")) - return CT_UNKNOWN; - return CT_UNKNOWN; - } - - struct Contact { - ObjectInfo info; - ContactType type=CT_USER; - std::string title; - std::string salutation; - std::string firstname; - std::string lastname; - std::string initials; - std::string visual; - Types::StringVec mobiles; - Types::StringVec phones; - std::string primaryEmail; - std::string secondaryEmail; - std::string accessPIN; - Types::StringVec inUse; - Types::UUID_t entity; - Types::UUID_t managementPolicy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector ContactVec; - - struct OperatorContact { - ObjectInfo info; - std::string type; - std::string title; - std::string salutation; - std::string firstname; - std::string lastname; - std::string initials; - std::string visual; - Types::StringVec mobiles; - Types::StringVec phones; - std::string primaryEmail; - std::string secondaryEmail; - std::string accessPIN; - Types::UUID_t operatorId; - Types::UUID_t subscriberDeviceId; - Types::UUID_t managementPolicy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct SubContact { - std::string type; - std::string title; - std::string salutation; - std::string firstname; - std::string lastname; - std::string initials; - std::string visual; - Types::StringVec mobiles; - Types::StringVec phones; - std::string primaryEmail; - std::string secondaryEmail; - std::string accessPIN; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct OperatorContactList { - std::vector contacts; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - typedef std::vector OperatorContactVec; - - struct DeviceConfigurationElement { - std::string name; - std::string description; - uint64_t weight; - std::string configuration; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector DeviceConfigurationElementVec; - - struct DeviceConfiguration { - ObjectInfo info; - Types::UUID_t managementPolicy; - Types::StringVec deviceTypes; - DeviceConfigurationElementVec configuration; - Types::StringVec inUse; - Types::UUIDvec_t variables; - DeviceRules deviceRules; - bool subscriberOnly=false; - std::string venue; - std::string entity; - std::string subscriber; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector DeviceConfigurationVec; - - - struct InventoryTag { - ObjectInfo info; - std::string serialNumber; - std::string venue; - std::string entity; - std::string subscriber; - std::string deviceType; - std::string qrCode; - std::string geoCode; - std::string location; - std::string contact; - std::string deviceConfiguration; - DeviceRules deviceRules; - Types::UUID_t managementPolicy; - std::string state; - std::string devClass; - std::string locale; - std::string realMacAddress; - bool doNotAllowOverrides=false; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - typedef std::vector InventoryTagVec; - - struct InventoryTagList { - InventoryTagVec taglist; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct InventoryConfigApplyResult { - std::string appliedConfiguration; - Types::StringVec errors; - Types::StringVec warnings; - uint64_t errorCode; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct Report { - uint64_t snapShot=0; - Types::CountedMap tenants; - - void reset(); - void to_json(Poco::JSON::Object &Obj) const; - }; - - struct ExpandedUseEntry { - std::string uuid; - std::string name; - std::string description; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ExpandedUseEntryList { - std::string type; - std::vector entries; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ExpandedUseEntryMapList { - std::vector entries; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct UuidList { - Types::UUIDvec_t list; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - enum ACLACCESS { - NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4 - }; - - struct ObjectACL { - UuidList users; - UuidList roles; - uint64_t access = (uint64_t) NONE; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ObjectACLList { - std::vector list; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct Map { - ObjectInfo info; - std::string data; - std::string entity; - std::string creator; - std::string visibility{"private"}; - ObjectACLList access; - Types::UUID_t managementPolicy; - std::string venue; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct MapList { - std::vector list; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - enum SignupStatusCodes { - SignupCreated = 0 , - SignupWaitingForEmail, - SignupWaitingForDevice, - SignupSuccess, - SignupFailure, - SignupCanceled, - SignupTimedOut - }; - - struct SignupEntry { - ObjectInfo info; - std::string email; - std::string userId; - std::string macAddress; - std::string serialNumber; - uint64_t submitted = 0 ; - uint64_t completed = 0 ; - std::string status; - uint64_t error=0; - uint64_t statusCode=0; - std::string deviceID; - std::string registrationId; - std::string operatorId; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct Variable { - std::string type; - uint64_t weight=0; - std::string prefix; - std::string value; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct VariableList { - std::vector variables; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct VariableBlock { - ObjectInfo info; - std::vector variables; - std::string entity; - std::string venue; - std::string subscriber; - std::string inventory; - Types::UUIDvec_t configurations; - Types::UUID_t managementPolicy; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct VariableBlockList { - std::vector variableBlocks; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct Operator { - ObjectInfo info; - Types::UUID_t managementPolicy; - Types::UUIDvec_t managementRoles; - DeviceRules deviceRules; - std::vector variables; - bool defaultOperator=false; - Types::StringVec sourceIP; - std::string registrationId; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct OperatorList { - std::vector operators; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct VenueDeviceList { - std::string id; - std::string name; - std::string description; - Types::UUIDvec_t devices; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ServiceClass { - ObjectInfo info; - Types::UUID_t operatorId; - Types::UUID_t managementPolicy; - double cost=0.0; - std::string currency; - std::string period; - std::string billingCode; - std::vector variables; - bool defaultService=false; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ServiceClassList { - std::vector serviceClasses; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ConfigurationDetails { - DeviceConfigurationElementVec configuration; - std::string rrm{"inherit"}; - std::string firmwareUpgrade{"inherit"}; - std::string firmwareRCOnly{"inherit"}; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct SubscriberDevice { - ObjectInfo info; - std::string serialNumber; - std::string deviceType; - Types::UUID_t operatorId; - Types::UUID_t subscriberId; - SubLocation location; - SubContact contact; - Types::UUID_t managementPolicy; - Types::UUID_t serviceClass; - std::string qrCode; - std::string geoCode; - DeviceRules deviceRules; - std::string state; - std::string locale; - std::string billingCode; - DeviceConfigurationElementVec configuration; - bool suspended=false; - std::string realMacAddress; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct SubscriberDeviceList { - std::vector subscriberDevices; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ConfigurationOverride { - std::string source; - std::string reason; - std::string parameterName; - std::string parameterType; - std::string parameterValue; - std::uint64_t modified; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - struct ConfigurationOverrideList { - std::string serialNumber; - Types::UUID_t managementPolicy; - std::vector overrides; - - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - - bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); - bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); - bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); -}; + enum FIRMWARE_UPGRADE_RULES { + dont_upgrade, + upgrade_inherit, + upgrade_release_only, + upgrade_latest + }; + + struct ObjectInfo { + Types::UUID_t id; + std::string name; + std::string description; + SecurityObjects::NoteInfoVec notes; + uint64_t created = 0; + uint64_t modified = 0; + Types::TagList tags; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct SerialNumberList { + Types::UUIDvec_t serialNumbers; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementPolicyEntry { + Types::UUIDvec_t users; + Types::UUIDvec_t resources; + Types::StringVec access; + std::string policy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementPolicy { + ObjectInfo info; + std::vector entries; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t venue; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ManagementPolicyVec; + + struct RRMAlgorithmDetails { + std::string name; + std::string parameters; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct RRMDetails { + std::string vendor; + std::string schedule; + std::vector algorithms; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct DeviceRules { + std::string rcOnly{"inherit"}; + std::string rrm{"inherit"}; + std::string firmwareUpgrade{"inherit"}; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct Entity { + ObjectInfo info; + Types::UUID_t parent; + Types::UUIDvec_t children; + Types::UUIDvec_t venues; + Types::UUIDvec_t contacts; // all contacts associated in this entity + Types::UUIDvec_t locations; // all locations associated in this entity + Types::UUID_t managementPolicy; + Types::UUIDvec_t deviceConfiguration; + Types::UUIDvec_t devices; + DeviceRules deviceRules; + Types::StringVec sourceIP; + Types::UUIDvec_t variables; + Types::UUIDvec_t managementPolicies; + Types::UUIDvec_t managementRoles; + Types::UUIDvec_t maps; + Types::UUIDvec_t configurations; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector EntityVec; + + struct DiGraphEntry { + Types::UUID_t parent; + Types::UUID_t child; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + typedef std::vector DiGraph; + + struct Venue { + ObjectInfo info; + Types::UUID_t entity; + Types::UUID_t parent; + Types::UUIDvec_t children; + Types::UUID_t managementPolicy; + Types::UUIDvec_t devices; + DiGraph topology; + std::string design; + Types::UUIDvec_t deviceConfiguration; + Types::UUIDvec_t contacts; + std::string location; + DeviceRules deviceRules; + Types::StringVec sourceIP; + Types::UUIDvec_t variables; + Types::UUIDvec_t configurations; + Types::UUIDvec_t maps; + Types::UUIDvec_t managementPolicies; + Types::UUIDvec_t managementRoles; + Types::UUIDvec_t boards; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector VenueVec; + + struct UserInfoDigest { + std::string id; + std::string loginId; + std::string userType; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementRole { + ObjectInfo info; + Types::UUID_t managementPolicy; + Types::UUIDvec_t users; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t venue; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ManagementRoleVec; + + enum LocationType { + LT_SERVICE, + LT_EQUIPMENT, + LT_AUTO, + LT_MANUAL, + LT_SPECIAL, + LT_UNKNOWN, + LT_CORPORATE + }; + + inline std::string to_string(LocationType L) { + switch (L) { + case LT_SERVICE: + return "SERVICE"; + case LT_EQUIPMENT: + return "EQUIPMENT"; + case LT_AUTO: + return "AUTO"; + case LT_MANUAL: + return "MANUAL"; + case LT_SPECIAL: + return "SPECIAL"; + case LT_UNKNOWN: + return "UNKNOWN"; + case LT_CORPORATE: + return "CORPORATE"; + default: + return "UNKNOWN"; + } + } + + inline LocationType location_from_string(const std::string &S) { + if (!Poco::icompare(S, "SERVICE")) + return LT_SERVICE; + else if (!Poco::icompare(S, "EQUIPMENT")) + return LT_EQUIPMENT; + else if (!Poco::icompare(S, "AUTO")) + return LT_AUTO; + else if (!Poco::icompare(S, "MANUAL")) + return LT_MANUAL; + else if (!Poco::icompare(S, "SPECIAL")) + return LT_SPECIAL; + else if (!Poco::icompare(S, "UNKNOWN")) + return LT_UNKNOWN; + else if (!Poco::icompare(S, "CORPORATE")) + return LT_CORPORATE; + return LT_UNKNOWN; + } + + struct Location { + ObjectInfo info; + LocationType type; + std::string buildingName; + Types::StringVec addressLines; + std::string city; + std::string state; + std::string postal; + std::string country; + Types::StringVec phones; + Types::StringVec mobiles; + std::string geoCode; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector LocationVec; + + struct OperatorLocation { + ObjectInfo info; + std::string type; + std::string buildingName; + Types::StringVec addressLines; + std::string city; + std::string state; + std::string postal; + std::string country; + Types::StringVec phones; + Types::StringVec mobiles; + std::string geoCode; + Types::UUID_t operatorId; + Types::UUID_t subscriberDeviceId; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector LocationVec; + + struct SubLocation { + std::string type; + std::string buildingName; + Types::StringVec addressLines; + std::string city; + std::string state; + std::string postal; + std::string country; + Types::StringVec phones; + Types::StringVec mobiles; + std::string geoCode; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct OperatorLocationList { + std::vector locations; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum ContactType { + CT_SUBSCRIBER, + CT_USER, + CT_INSTALLER, + CT_CSR, + CT_MANAGER, + CT_BUSINESSOWNER, + CT_TECHNICIAN, + CT_CORPORATE, + CT_UNKNOWN + }; + + inline std::string to_string(ContactType L) { + switch (L) { + case CT_SUBSCRIBER: + return "SUBSCRIBER"; + case CT_USER: + return "USER"; + case CT_INSTALLER: + return "INSTALLER"; + case CT_CSR: + return "CSR"; + case CT_MANAGER: + return "MANAGER"; + case CT_BUSINESSOWNER: + return "BUSINESSOWNER"; + case CT_TECHNICIAN: + return "TECHNICIAN"; + case CT_CORPORATE: + return "CORPORATE"; + case CT_UNKNOWN: + return "UNKNOWN"; + default: + return "UNKNOWN"; + } + } + + inline ContactType contact_from_string(const std::string &S) { + if (!Poco::icompare(S, "SUBSCRIBER")) + return CT_SUBSCRIBER; + else if (!Poco::icompare(S, "USER")) + return CT_USER; + else if (!Poco::icompare(S, "INSTALLER")) + return CT_INSTALLER; + else if (!Poco::icompare(S, "CSR")) + return CT_CSR; + else if (!Poco::icompare(S, "BUSINESSOWNER")) + return CT_BUSINESSOWNER; + else if (!Poco::icompare(S, "TECHNICIAN")) + return CT_TECHNICIAN; + else if (!Poco::icompare(S, "CORPORATE")) + return CT_CORPORATE; + else if (!Poco::icompare(S, "UNKNOWN")) + return CT_UNKNOWN; + return CT_UNKNOWN; + } + + struct Contact { + ObjectInfo info; + ContactType type = CT_USER; + std::string title; + std::string salutation; + std::string firstname; + std::string lastname; + std::string initials; + std::string visual; + Types::StringVec mobiles; + Types::StringVec phones; + std::string primaryEmail; + std::string secondaryEmail; + std::string accessPIN; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ContactVec; + + struct OperatorContact { + ObjectInfo info; + std::string type; + std::string title; + std::string salutation; + std::string firstname; + std::string lastname; + std::string initials; + std::string visual; + Types::StringVec mobiles; + Types::StringVec phones; + std::string primaryEmail; + std::string secondaryEmail; + std::string accessPIN; + Types::UUID_t operatorId; + Types::UUID_t subscriberDeviceId; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct SubContact { + std::string type; + std::string title; + std::string salutation; + std::string firstname; + std::string lastname; + std::string initials; + std::string visual; + Types::StringVec mobiles; + Types::StringVec phones; + std::string primaryEmail; + std::string secondaryEmail; + std::string accessPIN; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct OperatorContactList { + std::vector contacts; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + typedef std::vector OperatorContactVec; + + struct DeviceConfigurationElement { + std::string name; + std::string description; + uint64_t weight; + std::string configuration; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector DeviceConfigurationElementVec; + + struct DeviceConfiguration { + ObjectInfo info; + Types::UUID_t managementPolicy; + Types::StringVec deviceTypes; + DeviceConfigurationElementVec configuration; + Types::StringVec inUse; + Types::UUIDvec_t variables; + DeviceRules deviceRules; + bool subscriberOnly = false; + std::string venue; + std::string entity; + std::string subscriber; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector DeviceConfigurationVec; + + struct InventoryTag { + ObjectInfo info; + std::string serialNumber; + std::string venue; + std::string entity; + std::string subscriber; + std::string deviceType; + std::string qrCode; + std::string geoCode; + std::string location; + std::string contact; + std::string deviceConfiguration; + DeviceRules deviceRules; + Types::UUID_t managementPolicy; + std::string state; + std::string devClass; + std::string locale; + std::string realMacAddress; + bool doNotAllowOverrides = false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + typedef std::vector InventoryTagVec; + + struct InventoryTagList { + InventoryTagVec taglist; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct InventoryConfigApplyResult { + std::string appliedConfiguration; + Types::StringVec errors; + Types::StringVec warnings; + uint64_t errorCode; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct Report { + uint64_t snapShot = 0; + Types::CountedMap tenants; + + void reset(); + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct ExpandedUseEntry { + std::string uuid; + std::string name; + std::string description; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ExpandedUseEntryList { + std::string type; + std::vector entries; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ExpandedUseEntryMapList { + std::vector entries; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct UuidList { + Types::UUIDvec_t list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum ACLACCESS { NONE = 0, READ = 1, MODIFY = 2, CREATE = 3, DELETE = 4 }; + + struct ObjectACL { + UuidList users; + UuidList roles; + uint64_t access = (uint64_t)NONE; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ObjectACLList { + std::vector list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct Map { + ObjectInfo info; + std::string data; + std::string entity; + std::string creator; + std::string visibility{"private"}; + ObjectACLList access; + Types::UUID_t managementPolicy; + std::string venue; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct MapList { + std::vector list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum SignupStatusCodes { + SignupCreated = 0, + SignupWaitingForEmail, + SignupWaitingForDevice, + SignupSuccess, + SignupFailure, + SignupCanceled, + SignupTimedOut + }; + + struct SignupEntry { + ObjectInfo info; + std::string email; + std::string userId; + std::string macAddress; + std::string serialNumber; + uint64_t submitted = 0; + uint64_t completed = 0; + std::string status; + uint64_t error = 0; + uint64_t statusCode = 0; + std::string deviceID; + std::string registrationId; + std::string operatorId; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct Variable { + std::string type; + uint64_t weight = 0; + std::string prefix; + std::string value; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct VariableList { + std::vector variables; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct VariableBlock { + ObjectInfo info; + std::vector variables; + std::string entity; + std::string venue; + std::string subscriber; + std::string inventory; + Types::UUIDvec_t configurations; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct VariableBlockList { + std::vector variableBlocks; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct Operator { + ObjectInfo info; + Types::UUID_t managementPolicy; + Types::UUIDvec_t managementRoles; + DeviceRules deviceRules; + std::vector variables; + bool defaultOperator = false; + Types::StringVec sourceIP; + std::string registrationId; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct OperatorList { + std::vector operators; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct VenueDeviceList { + std::string id; + std::string name; + std::string description; + Types::UUIDvec_t devices; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ServiceClass { + ObjectInfo info; + Types::UUID_t operatorId; + Types::UUID_t managementPolicy; + double cost = 0.0; + std::string currency; + std::string period; + std::string billingCode; + std::vector variables; + bool defaultService = false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ServiceClassList { + std::vector serviceClasses; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ConfigurationDetails { + DeviceConfigurationElementVec configuration; + std::string rrm{"inherit"}; + std::string firmwareUpgrade{"inherit"}; + std::string firmwareRCOnly{"inherit"}; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct SubscriberDevice { + ObjectInfo info; + std::string serialNumber; + std::string deviceType; + Types::UUID_t operatorId; + Types::UUID_t subscriberId; + SubLocation location; + SubContact contact; + Types::UUID_t managementPolicy; + Types::UUID_t serviceClass; + std::string qrCode; + std::string geoCode; + DeviceRules deviceRules; + std::string state; + std::string locale; + std::string billingCode; + DeviceConfigurationElementVec configuration; + bool suspended = false; + std::string realMacAddress; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct SubscriberDeviceList { + std::vector subscriberDevices; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ConfigurationOverride { + std::string source; + std::string reason; + std::string parameterName; + std::string parameterType; + std::string parameterValue; + std::uint64_t modified; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ConfigurationOverrideList { + std::string serialNumber; + Types::UUID_t managementPolicy; + std::vector overrides; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, + ObjectInfo &I); + bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, + ObjectInfo &I); + bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); +}; // namespace OpenWifi::ProvObjects diff --git a/src/RESTObjects/RESTAPI_SecurityObjects.cpp b/src/RESTObjects/RESTAPI_SecurityObjects.cpp index c02df59..583de45 100644 --- a/src/RESTObjects/RESTAPI_SecurityObjects.cpp +++ b/src/RESTObjects/RESTAPI_SecurityObjects.cpp @@ -9,84 +9,106 @@ #include "Poco/JSON/Parser.h" #include "Poco/JSON/Stringifier.h" -#include "framework/RESTAPI_utils.h" #include "RESTAPI_SecurityObjects.h" +#include "framework/RESTAPI_utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::SecurityObjects { void AclTemplate::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"Read",Read_); - field_to_json(Obj,"ReadWrite",ReadWrite_); - field_to_json(Obj,"ReadWriteCreate",ReadWriteCreate_); - field_to_json(Obj,"Delete",Delete_); - field_to_json(Obj,"PortalLogin",PortalLogin_); + field_to_json(Obj, "Read", Read_); + field_to_json(Obj, "ReadWrite", ReadWrite_); + field_to_json(Obj, "ReadWriteCreate", ReadWriteCreate_); + field_to_json(Obj, "Delete", Delete_); + field_to_json(Obj, "PortalLogin", PortalLogin_); } ResourceAccessType ResourceAccessTypeFromString(const std::string &s) { - if(!Poco::icompare(s,"READ")) return READ; - if(!Poco::icompare(s,"MODIFY")) return MODIFY; - if(!Poco::icompare(s,"DELETE")) return DELETE; - if(!Poco::icompare(s,"CREATE")) return CREATE; - if(!Poco::icompare(s,"TEST")) return TEST; - if(!Poco::icompare(s,"MOVE")) return MOVE; + if (!Poco::icompare(s, "READ")) + return READ; + if (!Poco::icompare(s, "MODIFY")) + return MODIFY; + if (!Poco::icompare(s, "DELETE")) + return DELETE; + if (!Poco::icompare(s, "CREATE")) + return CREATE; + if (!Poco::icompare(s, "TEST")) + return TEST; + if (!Poco::icompare(s, "MOVE")) + return MOVE; return NONE; } - std::string ResourceAccessTypeToString(const ResourceAccessType & T) { - switch(T) { - case READ: return "READ"; - case MODIFY: return "MODIFY"; - case DELETE: return "DELETE"; - case CREATE: return "CREATE"; - case TEST: return "TEST"; - case MOVE: return "MOVE"; - default: return "NONE"; + std::string ResourceAccessTypeToString(const ResourceAccessType &T) { + switch (T) { + case READ: + return "READ"; + case MODIFY: + return "MODIFY"; + case DELETE: + return "DELETE"; + case CREATE: + return "CREATE"; + case TEST: + return "TEST"; + case MOVE: + return "MOVE"; + default: + return "NONE"; } } - USER_ROLE UserTypeFromString(const std::string &U) { - if (!Poco::icompare(U,"root")) - return ROOT; - else if (!Poco::icompare(U,"admin")) - return ADMIN; - else if (!Poco::icompare(U,"subscriber")) - return SUBSCRIBER; - else if (!Poco::icompare(U,"partner")) - return PARTNER; - else if (!Poco::icompare(U,"csr")) - return CSR; - else if (!Poco::icompare(U, "system")) - return SYSTEM; - else if (!Poco::icompare(U, "installer")) - return INSTALLER; - else if (!Poco::icompare(U, "noc")) - return NOC; - else if (!Poco::icompare(U, "accounting")) - return ACCOUNTING; - return UNKNOWN; - } + USER_ROLE UserTypeFromString(const std::string &U) { + if (!Poco::icompare(U, "root")) + return ROOT; + else if (!Poco::icompare(U, "admin")) + return ADMIN; + else if (!Poco::icompare(U, "subscriber")) + return SUBSCRIBER; + else if (!Poco::icompare(U, "partner")) + return PARTNER; + else if (!Poco::icompare(U, "csr")) + return CSR; + else if (!Poco::icompare(U, "system")) + return SYSTEM; + else if (!Poco::icompare(U, "installer")) + return INSTALLER; + else if (!Poco::icompare(U, "noc")) + return NOC; + else if (!Poco::icompare(U, "accounting")) + return ACCOUNTING; + return UNKNOWN; + } - std::string UserTypeToString(USER_ROLE U) { - switch(U) { - case ROOT: return "root"; - case ADMIN: return "admin"; - case SUBSCRIBER: return "subscriber"; - case PARTNER: return "partner"; - case CSR: return "csr"; - case SYSTEM: return "system"; - case INSTALLER: return "installer"; - case NOC: return "noc"; - case ACCOUNTING: return "accounting"; - case UNKNOWN: - default: - return "unknown"; - } - } + std::string UserTypeToString(USER_ROLE U) { + switch (U) { + case ROOT: + return "root"; + case ADMIN: + return "admin"; + case SUBSCRIBER: + return "subscriber"; + case PARTNER: + return "partner"; + case CSR: + return "csr"; + case SYSTEM: + return "system"; + case INSTALLER: + return "installer"; + case NOC: + return "noc"; + case ACCOUNTING: + return "accounting"; + case UNKNOWN: + default: + return "unknown"; + } + } - bool AclTemplate::from_json(const Poco::JSON::Object::Ptr &Obj) { + bool AclTemplate::from_json(const Poco::JSON::Object::Ptr &Obj) { try { field_from_json(Obj, "Read", Read_); field_from_json(Obj, "ReadWrite", ReadWrite_); @@ -94,27 +116,27 @@ namespace OpenWifi::SecurityObjects { field_from_json(Obj, "Delete", Delete_); field_from_json(Obj, "PortalLogin", PortalLogin_); return true; - } catch(...) { - std::cout << "Cannot parse: AclTemplate" << std::endl; + } catch (...) { + std::cout << "Cannot parse: AclTemplate" << std::endl; } return false; } - void WebToken::to_json(Poco::JSON::Object & Obj) const { - Poco::JSON::Object AclTemplateObj; + void WebToken::to_json(Poco::JSON::Object &Obj) const { + Poco::JSON::Object AclTemplateObj; acl_template_.to_json(AclTemplateObj); - field_to_json(Obj,"access_token",access_token_); - field_to_json(Obj,"refresh_token",refresh_token_); - field_to_json(Obj,"token_type",token_type_); - field_to_json(Obj,"expires_in",expires_in_); - field_to_json(Obj,"idle_timeout",idle_timeout_); - field_to_json(Obj,"created",created_); - field_to_json(Obj,"username",username_); - field_to_json(Obj,"userMustChangePassword",userMustChangePassword); - field_to_json(Obj,"errorCode", errorCode); - Obj.set("aclTemplate",AclTemplateObj); - field_to_json(Obj,"errorCode", errorCode); - field_to_json(Obj,"lastRefresh", lastRefresh_); + field_to_json(Obj, "access_token", access_token_); + field_to_json(Obj, "refresh_token", refresh_token_); + field_to_json(Obj, "token_type", token_type_); + field_to_json(Obj, "expires_in", expires_in_); + field_to_json(Obj, "idle_timeout", idle_timeout_); + field_to_json(Obj, "created", created_); + field_to_json(Obj, "username", username_); + field_to_json(Obj, "userMustChangePassword", userMustChangePassword); + field_to_json(Obj, "errorCode", errorCode); + Obj.set("aclTemplate", AclTemplateObj); + field_to_json(Obj, "errorCode", errorCode); + field_to_json(Obj, "lastRefresh", lastRefresh_); } bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -130,236 +152,235 @@ namespace OpenWifi::SecurityObjects { field_from_json(Obj, "idle_timeout", idle_timeout_); field_from_json(Obj, "created", created_); field_from_json(Obj, "username", username_); - field_from_json(Obj, "userMustChangePassword",userMustChangePassword); - field_from_json(Obj,"lastRefresh", lastRefresh_); + field_from_json(Obj, "userMustChangePassword", userMustChangePassword); + field_from_json(Obj, "lastRefresh", lastRefresh_); return true; } catch (...) { - std::cout << "Cannot parse: WebToken" << std::endl; + std::cout << "Cannot parse: WebToken" << std::endl; } return false; } void MobilePhoneNumber::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"number", number); - field_to_json(Obj,"verified", verified); - field_to_json(Obj,"primary", primary); + field_to_json(Obj, "number", number); + field_to_json(Obj, "verified", verified); + field_to_json(Obj, "primary", primary); } bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"number",number); - field_from_json(Obj,"verified",verified); - field_from_json(Obj,"primary",primary); - return true; - } catch (...) { - std::cout << "Cannot parse: MobilePhoneNumber" << std::endl; - } - return false; + try { + field_from_json(Obj, "number", number); + field_from_json(Obj, "verified", verified); + field_from_json(Obj, "primary", primary); + return true; + } catch (...) { + std::cout << "Cannot parse: MobilePhoneNumber" << std::endl; + } + return false; }; void MfaAuthInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"enabled", enabled); - field_to_json(Obj,"method", method); + field_to_json(Obj, "enabled", enabled); + field_to_json(Obj, "method", method); } bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"enabled",enabled); - field_from_json(Obj,"method",method); - return true; - } catch (...) { - std::cout << "Cannot parse: MfaAuthInfo" << std::endl; - } - return false; + try { + field_from_json(Obj, "enabled", enabled); + field_from_json(Obj, "method", method); + return true; + } catch (...) { + std::cout << "Cannot parse: MfaAuthInfo" << std::endl; + } + return false; } void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "mobiles", mobiles); - field_to_json(Obj, "mfa", mfa); - field_to_json(Obj, "authenticatorSecret", authenticatorSecret); + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "mfa", mfa); + field_to_json(Obj, "authenticatorSecret", authenticatorSecret); } bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "mobiles",mobiles); - field_from_json(Obj, "mfa",mfa); - field_from_json(Obj, "authenticatorSecret", authenticatorSecret); - return true; - } catch (...) { - std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl; - } - return false; + try { + field_from_json(Obj, "mobiles", mobiles); + field_from_json(Obj, "mfa", mfa); + field_from_json(Obj, "authenticatorSecret", authenticatorSecret); + return true; + } catch (...) { + std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl; + } + return false; } - void MFAChallengeRequest::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "uuid", uuid); - field_to_json(Obj, "question", question); - field_to_json(Obj, "created", created); - field_to_json(Obj, "method", method); - } + void MFAChallengeRequest::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "question", question); + field_to_json(Obj, "created", created); + field_to_json(Obj, "method", method); + } - bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"uuid",uuid); - field_from_json(Obj,"question",question); - field_from_json(Obj,"created",created); - field_from_json(Obj,"method",method); - return true; - } catch (...) { - std::cout << "Cannot parse: MFAChallengeRequest" << std::endl; - } - return false; + bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "uuid", uuid); + field_from_json(Obj, "question", question); + field_from_json(Obj, "created", created); + field_from_json(Obj, "method", method); + return true; + } catch (...) { + std::cout << "Cannot parse: MFAChallengeRequest" << std::endl; + } + return false; }; - void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "uuid", uuid); - field_to_json(Obj, "answer", answer); - } + void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "answer", answer); + } - bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"uuid",uuid); - field_from_json(Obj,"answer",answer); - return true; - } catch (...) { - std::cout << "Cannot parse: MFAChallengeResponse" << std::endl; - } - return false; + bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "uuid", uuid); + field_from_json(Obj, "answer", answer); + return true; + } catch (...) { + std::cout << "Cannot parse: MFAChallengeResponse" << std::endl; + } + return false; + } - } + void UserInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "avatar", avatar); + field_to_json(Obj, "email", email); + field_to_json(Obj, "validated", validated); + field_to_json(Obj, "validationEmail", validationEmail); + field_to_json(Obj, "validationDate", validationDate); + field_to_json(Obj, "creationDate", creationDate); + field_to_json(Obj, "validationURI", validationURI); + field_to_json(Obj, "changePassword", changePassword); + field_to_json(Obj, "lastLogin", lastLogin); + field_to_json(Obj, "currentLoginURI", currentLoginURI); + field_to_json(Obj, "lastPasswordChange", lastPasswordChange); + field_to_json(Obj, "lastEmailCheck", lastEmailCheck); + field_to_json(Obj, "waitingForEmailCheck", waitingForEmailCheck); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "notes", notes); + field_to_json(Obj, "location", location); + field_to_json(Obj, "owner", owner); + field_to_json(Obj, "suspended", suspended); + field_to_json(Obj, "blackListed", blackListed); + field_to_json(Obj, "userRole", userRole, UserTypeToString); + field_to_json(Obj, "userTypeProprietaryInfo", userTypeProprietaryInfo); + field_to_json(Obj, "securityPolicy", securityPolicy); + field_to_json(Obj, "securityPolicyChange", securityPolicyChange); + field_to_json(Obj, "currentPassword", currentPassword); + field_to_json(Obj, "lastPasswords", lastPasswords); + field_to_json(Obj, "oauthType", oauthType); + field_to_json(Obj, "oauthUserInfo", oauthUserInfo); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "signingUp", signingUp); + }; - void UserInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"name",name); - field_to_json(Obj,"description", description); - field_to_json(Obj,"avatar", avatar); - field_to_json(Obj,"email", email); - field_to_json(Obj,"validated", validated); - field_to_json(Obj,"validationEmail", validationEmail); - field_to_json(Obj,"validationDate", validationDate); - field_to_json(Obj,"creationDate", creationDate); - field_to_json(Obj,"validationURI", validationURI); - field_to_json(Obj,"changePassword", changePassword); - field_to_json(Obj,"lastLogin", lastLogin); - field_to_json(Obj,"currentLoginURI", currentLoginURI); - field_to_json(Obj,"lastPasswordChange", lastPasswordChange); - field_to_json(Obj,"lastEmailCheck", lastEmailCheck); - field_to_json(Obj,"waitingForEmailCheck", waitingForEmailCheck); - field_to_json(Obj,"locale", locale); - field_to_json(Obj,"notes", notes); - field_to_json(Obj,"location", location); - field_to_json(Obj,"owner", owner); - field_to_json(Obj,"suspended", suspended); - field_to_json(Obj,"blackListed", blackListed); - field_to_json(Obj,"userRole", userRole, UserTypeToString); - field_to_json(Obj,"userTypeProprietaryInfo", userTypeProprietaryInfo); - field_to_json(Obj,"securityPolicy", securityPolicy); - field_to_json(Obj,"securityPolicyChange", securityPolicyChange); - field_to_json(Obj,"currentPassword",currentPassword); - field_to_json(Obj,"lastPasswords",lastPasswords); - field_to_json(Obj,"oauthType",oauthType); - field_to_json(Obj,"oauthUserInfo",oauthUserInfo); - field_to_json(Obj,"modified",modified); - field_to_json(Obj,"signingUp",signingUp); - }; + bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "avatar", avatar); + field_from_json(Obj, "email", email); + field_from_json(Obj, "validationEmail", validationEmail); + field_from_json(Obj, "validationURI", validationURI); + field_from_json(Obj, "currentLoginURI", currentLoginURI); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "notes", notes); + field_from_json(Obj, "location", location); + field_from_json(Obj, "owner", owner); + field_from_json(Obj, "userRole", userRole, UserTypeFromString); + field_from_json(Obj, "securityPolicy", securityPolicy); + field_from_json(Obj, "userTypeProprietaryInfo", userTypeProprietaryInfo); + field_from_json(Obj, "validationDate", validationDate); + field_from_json(Obj, "creationDate", creationDate); + field_from_json(Obj, "lastLogin", lastLogin); + field_from_json(Obj, "lastPasswordChange", lastPasswordChange); + field_from_json(Obj, "lastEmailCheck", lastEmailCheck); + field_from_json(Obj, "securityPolicyChange", securityPolicyChange); + field_from_json(Obj, "validated", validated); + field_from_json(Obj, "changePassword", changePassword); + field_from_json(Obj, "waitingForEmailCheck", waitingForEmailCheck); + field_from_json(Obj, "suspended", suspended); + field_from_json(Obj, "blackListed", blackListed); + field_from_json(Obj, "currentPassword", currentPassword); + field_from_json(Obj, "lastPasswords", lastPasswords); + field_from_json(Obj, "oauthType", oauthType); + field_from_json(Obj, "oauthUserInfo", oauthUserInfo); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "signingUp", signingUp); + return true; + } catch (const Poco::Exception &E) { + std::cout << "Cannot parse: UserInfo" << std::endl; + } + return false; + }; - bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"avatar",avatar); - field_from_json(Obj,"email",email); - field_from_json(Obj,"validationEmail",validationEmail); - field_from_json(Obj,"validationURI",validationURI); - field_from_json(Obj,"currentLoginURI",currentLoginURI); - field_from_json(Obj,"locale",locale); - field_from_json(Obj,"notes",notes); - field_from_json(Obj,"location", location); - field_from_json(Obj,"owner", owner); - field_from_json(Obj,"userRole",userRole, UserTypeFromString); - field_from_json(Obj,"securityPolicy",securityPolicy); - field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo); - field_from_json(Obj,"validationDate",validationDate); - field_from_json(Obj,"creationDate",creationDate); - field_from_json(Obj,"lastLogin",lastLogin); - field_from_json(Obj,"lastPasswordChange",lastPasswordChange); - field_from_json(Obj,"lastEmailCheck",lastEmailCheck); - field_from_json(Obj,"securityPolicyChange",securityPolicyChange); - field_from_json(Obj,"validated",validated); - field_from_json(Obj,"changePassword",changePassword); - field_from_json(Obj,"waitingForEmailCheck",waitingForEmailCheck); - field_from_json(Obj,"suspended",suspended); - field_from_json(Obj,"blackListed",blackListed); - field_from_json(Obj,"currentPassword",currentPassword); - field_from_json(Obj,"lastPasswords",lastPasswords); - field_from_json(Obj,"oauthType",oauthType); - field_from_json(Obj,"oauthUserInfo",oauthUserInfo); - field_from_json(Obj,"modified",modified); - field_from_json(Obj,"signingUp",signingUp); - return true; - } catch (const Poco::Exception &E) { - std::cout << "Cannot parse: UserInfo" << std::endl; - } - return false; - }; + void UserInfoList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "users", users); + } - void UserInfoList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"users",users); - } - - bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"users",users); - return true; - } catch (...) { - std::cout << "Cannot parse: InternalServiceInfo" << std::endl; - } - return false; - } + bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "users", users); + return true; + } catch (...) { + std::cout << "Cannot parse: InternalServiceInfo" << std::endl; + } + return false; + } void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"privateURI",privateURI); - field_to_json(Obj,"publicURI",publicURI); - field_to_json(Obj,"token",token); + field_to_json(Obj, "privateURI", privateURI); + field_to_json(Obj, "publicURI", publicURI); + field_to_json(Obj, "token", token); }; bool InternalServiceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"privateURI",privateURI); - field_from_json(Obj,"publicURI",publicURI); - field_from_json(Obj,"token",token); + field_from_json(Obj, "privateURI", privateURI); + field_from_json(Obj, "publicURI", publicURI); + field_from_json(Obj, "token", token); return true; } catch (...) { - std::cout << "Cannot parse: InternalServiceInfo" << std::endl; + std::cout << "Cannot parse: InternalServiceInfo" << std::endl; } return false; }; void InternalSystemServices::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"key",key); - field_to_json(Obj,"version",version); - field_to_json(Obj,"services",services); + field_to_json(Obj, "key", key); + field_to_json(Obj, "version", version); + field_to_json(Obj, "services", services); }; - bool InternalSystemServices::from_json(const Poco::JSON::Object::Ptr &Obj) { + bool InternalSystemServices::from_json(const Poco::JSON::Object::Ptr &Obj) { try { field_from_json(Obj, "key", key); field_from_json(Obj, "version", version); field_from_json(Obj, "services", services); return true; - } catch(...) { - std::cout << "Cannot parse: InternalSystemServices" << std::endl; + } catch (...) { + std::cout << "Cannot parse: InternalSystemServices" << std::endl; } return false; }; void SystemEndpoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"type",type); - field_to_json(Obj,"id",id); - field_to_json(Obj,"vendor",vendor); - field_to_json(Obj,"uri",uri); - field_to_json(Obj,"authenticationType",authenticationType); + field_to_json(Obj, "type", type); + field_to_json(Obj, "id", id); + field_to_json(Obj, "vendor", vendor); + field_to_json(Obj, "uri", uri); + field_to_json(Obj, "authenticationType", authenticationType); }; bool SystemEndpoint::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -371,31 +392,31 @@ namespace OpenWifi::SecurityObjects { field_from_json(Obj, "authenticationType", authenticationType); return true; } catch (...) { - std::cout << "Cannot parse: SystemEndpoint" << std::endl; + std::cout << "Cannot parse: SystemEndpoint" << std::endl; } return false; }; void SystemEndpointList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"endpoints",endpoints); + field_to_json(Obj, "endpoints", endpoints); } - bool SystemEndpointList::from_json(const Poco::JSON::Object::Ptr &Obj) { + bool SystemEndpointList::from_json(const Poco::JSON::Object::Ptr &Obj) { try { field_from_json(Obj, "endpoints", endpoints); return true; } catch (...) { - std::cout << "Cannot parse: SystemEndpointList" << std::endl; + std::cout << "Cannot parse: SystemEndpointList" << std::endl; } return false; } void UserInfoAndPolicy::to_json(Poco::JSON::Object &Obj) const { - Poco::JSON::Object UI, TI; + Poco::JSON::Object UI, TI; userinfo.to_json(UI); webtoken.to_json(TI); - Obj.set("tokenInfo",TI); - Obj.set("userInfo",UI); + Obj.set("tokenInfo", TI); + Obj.set("userInfo", UI); } bool UserInfoAndPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -403,91 +424,97 @@ namespace OpenWifi::SecurityObjects { field_from_json(Obj, "tokenInfo", webtoken); field_from_json(Obj, "userInfo", userinfo); return true; - } catch(...) { - std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl; + } catch (...) { + std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl; } return false; } void NoteInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"created", created); - field_to_json(Obj,"createdBy", createdBy); - field_to_json(Obj,"note", note); + field_to_json(Obj, "created", created); + field_to_json(Obj, "createdBy", createdBy); + field_to_json(Obj, "note", note); } bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"created",created); - field_from_json(Obj,"createdBy",createdBy); - field_from_json(Obj,"note", note); + field_from_json(Obj, "created", created); + field_from_json(Obj, "createdBy", createdBy); + field_from_json(Obj, "note", note); return true; - } catch(...) { - std::cout << "Cannot parse: NoteInfo" << std::endl; + } catch (...) { + std::cout << "Cannot parse: NoteInfo" << std::endl; } return false; } - bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes) { - try { - if(Obj->has("notes") && Obj->isArray("notes")) { - SecurityObjects::NoteInfoVec NIV; - NIV = RESTAPI_utils::to_object_array(Obj->get("notes").toString()); - for(auto const &i:NIV) { - SecurityObjects::NoteInfo ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; - Notes.push_back(ii); - } - } - return true; - } catch(...) { - std::cout << "Cannot parse: MergeNotes" << std::endl; - } - return false; + bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec &Notes) { + try { + if (Obj->has("notes") && Obj->isArray("notes")) { + SecurityObjects::NoteInfoVec NIV; + NIV = RESTAPI_utils::to_object_array( + Obj->get("notes").toString()); + for (auto const &i : NIV) { + SecurityObjects::NoteInfo ii{.created = (uint64_t)Utils::Now(), + .createdBy = UInfo.email, + .note = i.note}; + Notes.push_back(ii); + } + } + return true; + } catch (...) { + std::cout << "Cannot parse: MergeNotes" << std::endl; + } + return false; } - bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) { - for(auto const &i:NewNotes) { - SecurityObjects::NoteInfo ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; - ExistingNotes.push_back(ii); - } - return true; + bool MergeNotes(const NoteInfoVec &NewNotes, const UserInfo &UInfo, + NoteInfoVec &ExistingNotes) { + for (auto const &i : NewNotes) { + SecurityObjects::NoteInfo ii{ + .created = (uint64_t)Utils::Now(), .createdBy = UInfo.email, .note = i.note}; + ExistingNotes.push_back(ii); + } + return true; } void ProfileAction::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"resource", resource); - field_to_json(Obj,"access", access, ResourceAccessTypeToString); + field_to_json(Obj, "resource", resource); + field_to_json(Obj, "access", access, ResourceAccessTypeToString); } bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"resource",resource); - field_from_json(Obj,"access",access,ResourceAccessTypeFromString ); + field_from_json(Obj, "resource", resource); + field_from_json(Obj, "access", access, + ResourceAccessTypeFromString); return true; - } catch(...) { - std::cout << "Cannot parse: ProfileAction" << std::endl; + } catch (...) { + std::cout << "Cannot parse: ProfileAction" << std::endl; } return false; } void SecurityProfile::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id", id); - field_to_json(Obj,"name", name); - field_to_json(Obj,"description", description); - field_to_json(Obj,"policy", policy); - field_to_json(Obj,"role", role); - field_to_json(Obj,"notes", notes); + field_to_json(Obj, "id", id); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "policy", policy); + field_to_json(Obj, "role", role); + field_to_json(Obj, "notes", notes); } bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"name",name); - field_from_json(Obj,"description",description); - field_from_json(Obj,"policy",policy); - field_from_json(Obj,"role",role); - field_from_json(Obj,"notes",notes); + field_from_json(Obj, "id", id); + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "policy", policy); + field_from_json(Obj, "role", role); + field_from_json(Obj, "notes", notes); return true; - } catch(...) { - std::cout << "Cannot parse: SecurityProfile" << std::endl; + } catch (...) { + std::cout << "Cannot parse: SecurityProfile" << std::endl; } return false; } @@ -498,201 +525,200 @@ namespace OpenWifi::SecurityObjects { bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"profiles",profiles); + field_from_json(Obj, "profiles", profiles); return true; - } catch(...) { - std::cout << "Cannot parse: SecurityProfileList" << std::endl; + } catch (...) { + std::cout << "Cannot parse: SecurityProfileList" << std::endl; } return false; } - void ActionLink::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"action",action); - field_to_json(Obj,"userId",userId); - field_to_json(Obj,"actionTemplate",actionTemplate); - field_to_json(Obj,"variables",variables); - field_to_json(Obj,"locale",locale); - field_to_json(Obj,"message",message); - field_to_json(Obj,"sent",sent); - field_to_json(Obj,"created",created); - field_to_json(Obj,"expires",expires); - field_to_json(Obj,"completed",completed); - field_to_json(Obj,"canceled",canceled); - field_to_json(Obj,"userAction",userAction); + void ActionLink::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "action", action); + field_to_json(Obj, "userId", userId); + field_to_json(Obj, "actionTemplate", actionTemplate); + field_to_json(Obj, "variables", variables); + field_to_json(Obj, "locale", locale); + field_to_json(Obj, "message", message); + field_to_json(Obj, "sent", sent); + field_to_json(Obj, "created", created); + field_to_json(Obj, "expires", expires); + field_to_json(Obj, "completed", completed); + field_to_json(Obj, "canceled", canceled); + field_to_json(Obj, "userAction", userAction); } - bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"action",action); - field_from_json(Obj,"userId",userId); - field_from_json(Obj,"actionTemplate",actionTemplate); - field_from_json(Obj,"variables",variables); - field_from_json(Obj,"locale",locale); - field_from_json(Obj,"message",message); - field_from_json(Obj,"sent",sent); - field_from_json(Obj,"created",created); - field_from_json(Obj,"expires",expires); - field_from_json(Obj,"completed",completed); - field_from_json(Obj,"canceled",canceled); - field_from_json(Obj,"userAction",userAction); - return true; - } catch(...) { - std::cout << "Cannot parse: ActionLink" << std::endl; - } - return false; + bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "action", action); + field_from_json(Obj, "userId", userId); + field_from_json(Obj, "actionTemplate", actionTemplate); + field_from_json(Obj, "variables", variables); + field_from_json(Obj, "locale", locale); + field_from_json(Obj, "message", message); + field_from_json(Obj, "sent", sent); + field_from_json(Obj, "created", created); + field_from_json(Obj, "expires", expires); + field_from_json(Obj, "completed", completed); + field_from_json(Obj, "canceled", canceled); + field_from_json(Obj, "userAction", userAction); + return true; + } catch (...) { + std::cout << "Cannot parse: ActionLink" << std::endl; + } + return false; } - void Preferences::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"modified",modified); - field_to_json(Obj,"data",data); + void Preferences::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "data", data); } - bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"modified",modified); - field_from_json(Obj,"data",data); - return true; - } catch(...) { - std::cout << "Cannot parse: Preferences" << std::endl; - } - return false; + bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "data", data); + return true; + } catch (...) { + std::cout << "Cannot parse: Preferences" << std::endl; + } + return false; } - void SubMfaConfig::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"id",id); - field_to_json(Obj,"type",type); - field_to_json(Obj,"sms",sms); - field_to_json(Obj,"email",email); + void SubMfaConfig::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "type", type); + field_to_json(Obj, "sms", sms); + field_to_json(Obj, "email", email); } - bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"id",id); - field_from_json(Obj,"type",type); - field_from_json(Obj,"sms",sms); - field_from_json(Obj,"email",email); - return true; - } catch(...) { - std::cout << "Cannot parse: SubMfaConfig" << std::endl; - } - return false; + bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "type", type); + field_from_json(Obj, "sms", sms); + field_from_json(Obj, "email", email); + return true; + } catch (...) { + std::cout << "Cannot parse: SubMfaConfig" << std::endl; + } + return false; } - void Token::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"token",token); - field_to_json(Obj,"refreshToken",refreshToken); - field_to_json(Obj,"tokenType",tokenType); - field_to_json(Obj,"userName",userName); - field_to_json(Obj,"created",created); - field_to_json(Obj,"expires",expires); - field_to_json(Obj,"idleTimeout",idleTimeout); - field_to_json(Obj,"revocationDate",revocationDate); - field_to_json(Obj,"lastRefresh", lastRefresh); - } + void Token::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "token", token); + field_to_json(Obj, "refreshToken", refreshToken); + field_to_json(Obj, "tokenType", tokenType); + field_to_json(Obj, "userName", userName); + field_to_json(Obj, "created", created); + field_to_json(Obj, "expires", expires); + field_to_json(Obj, "idleTimeout", idleTimeout); + field_to_json(Obj, "revocationDate", revocationDate); + field_to_json(Obj, "lastRefresh", lastRefresh); + } - bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj,"token",token); - field_from_json(Obj,"refreshToken",refreshToken); - field_from_json(Obj,"tokenType",tokenType); - field_from_json(Obj,"userName",userName); - field_from_json(Obj,"created",created); - field_from_json(Obj,"expires",expires); - field_from_json(Obj,"idleTimeout",idleTimeout); - field_from_json(Obj,"revocationDate",revocationDate); - field_from_json(Obj,"lastRefresh", lastRefresh); - return true; - } catch(...) { - std::cout << "Cannot parse: Token" << std::endl; - } - return false; - } + bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "token", token); + field_from_json(Obj, "refreshToken", refreshToken); + field_from_json(Obj, "tokenType", tokenType); + field_from_json(Obj, "userName", userName); + field_from_json(Obj, "created", created); + field_from_json(Obj, "expires", expires); + field_from_json(Obj, "idleTimeout", idleTimeout); + field_from_json(Obj, "revocationDate", revocationDate); + field_from_json(Obj, "lastRefresh", lastRefresh); + return true; + } catch (...) { + std::cout << "Cannot parse: Token" << std::endl; + } + return false; + } - void LoginRecordInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"sessionId",sessionId); - field_to_json(Obj,"userId",userId); - field_to_json(Obj,"email",email); - field_to_json(Obj,"login",login); - field_to_json(Obj,"logout",logout); - } + void LoginRecordInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "sessionId", sessionId); + field_to_json(Obj, "userId", userId); + field_to_json(Obj, "email", email); + field_to_json(Obj, "login", login); + field_to_json(Obj, "logout", logout); + } - void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "service", service); - field_to_json(Obj, "access", access); - } + void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "service", service); + field_to_json(Obj, "access", access); + } - bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "service", service); - field_from_json(Obj, "access", access); - return true; - } catch(...) { - std::cout << "Cannot parse: Token" << std::endl; - } - return false; - } + bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "service", service); + field_from_json(Obj, "access", access); + return true; + } catch (...) { + std::cout << "Cannot parse: Token" << std::endl; + } + return false; + } - void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "acls", acls); - } + void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "acls", acls); + } - bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "acls", acls); - return true; - } catch(...) { - std::cout << "Cannot parse: Token" << std::endl; - } - return false; - } + bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "acls", acls); + return true; + } catch (...) { + std::cout << "Cannot parse: Token" << std::endl; + } + return false; + } - void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "userUuid", userUuid); - field_to_json(Obj, "name", name); - field_to_json(Obj, "apiKey", apiKey); - field_to_json(Obj, "salt", salt); - field_to_json(Obj, "description", description); - field_to_json(Obj, "expiresOn", expiresOn); - field_to_json(Obj, "rights", rights); - field_to_json(Obj, "lastUse", lastUse); - } + void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "userUuid", userUuid); + field_to_json(Obj, "name", name); + field_to_json(Obj, "apiKey", apiKey); + field_to_json(Obj, "salt", salt); + field_to_json(Obj, "description", description); + field_to_json(Obj, "expiresOn", expiresOn); + field_to_json(Obj, "rights", rights); + field_to_json(Obj, "lastUse", lastUse); + } - bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "userUuid", userUuid); - field_from_json(Obj, "name", name); - field_from_json(Obj, "apiKey", apiKey); - field_from_json(Obj, "salt", salt); - field_from_json(Obj, "description", description); - field_from_json(Obj, "expiresOn", expiresOn); - field_from_json(Obj, "rights", rights); - field_from_json(Obj, "lastUse", lastUse); - return true; - } catch(...) { - std::cout << "Cannot parse: Token" << std::endl; - } - return false; - } + bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "userUuid", userUuid); + field_from_json(Obj, "name", name); + field_from_json(Obj, "apiKey", apiKey); + field_from_json(Obj, "salt", salt); + field_from_json(Obj, "description", description); + field_from_json(Obj, "expiresOn", expiresOn); + field_from_json(Obj, "rights", rights); + field_from_json(Obj, "lastUse", lastUse); + return true; + } catch (...) { + std::cout << "Cannot parse: Token" << std::endl; + } + return false; + } - void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "apiKeys", apiKeys); - } + void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "apiKeys", apiKeys); + } - bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "apiKeys", apiKeys); - return true; - } catch(...) { - std::cout << "Cannot parse: Token" << std::endl; - } - return false; - } - -} + bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "apiKeys", apiKeys); + return true; + } catch (...) { + std::cout << "Cannot parse: Token" << std::endl; + } + return false; + } +} // namespace OpenWifi::SecurityObjects diff --git a/src/RESTObjects/RESTAPI_SecurityObjects.h b/src/RESTObjects/RESTAPI_SecurityObjects.h index a804128..649fb49 100644 --- a/src/RESTObjects/RESTAPI_SecurityObjects.h +++ b/src/RESTObjects/RESTAPI_SecurityObjects.h @@ -8,361 +8,364 @@ #pragma once -#include -#include -#include "framework/OpenWifiTypes.h" -#include "Poco/JSON/Object.h" #include "Poco/Data/LOB.h" #include "Poco/Data/LOBStream.h" +#include "Poco/JSON/Object.h" +#include "framework/OpenWifiTypes.h" #include "framework/utils.h" +#include +#include namespace OpenWifi { - uint64_t Now(); - namespace SecurityObjects { - - typedef std::string USER_ID_TYPE; + uint64_t Now(); + namespace SecurityObjects { - struct AclTemplate { - bool Read_ = true; - bool ReadWrite_ = true; - bool ReadWriteCreate_ = true; - bool Delete_ = true; - bool PortalLogin_ = true; + typedef std::string USER_ID_TYPE; - AclTemplate() noexcept = default; + struct AclTemplate { + bool Read_ = true; + bool ReadWrite_ = true; + bool ReadWriteCreate_ = true; + bool Delete_ = true; + bool PortalLogin_ = true; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + AclTemplate() noexcept = default; - static_assert( std::is_nothrow_move_constructible_v ); + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct WebToken { - std::string access_token_; - std::string refresh_token_; - std::string id_token_; - std::string token_type_; - std::string username_; - bool userMustChangePassword=false; - uint64_t errorCode=0; - uint64_t expires_in_=0; - uint64_t idle_timeout_=0; - AclTemplate acl_template_; - uint64_t created_=0; - uint64_t lastRefresh_=0; + static_assert(std::is_nothrow_move_constructible_v); - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct WebToken { + std::string access_token_; + std::string refresh_token_; + std::string id_token_; + std::string token_type_; + std::string username_; + bool userMustChangePassword = false; + uint64_t errorCode = 0; + uint64_t expires_in_ = 0; + uint64_t idle_timeout_ = 0; + AclTemplate acl_template_; + uint64_t created_ = 0; + uint64_t lastRefresh_ = 0; - enum USER_ROLE { - UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING, PARTNER - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - USER_ROLE UserTypeFromString(const std::string &U); - std::string UserTypeToString(USER_ROLE U); + enum USER_ROLE { + UNKNOWN, + ROOT, + ADMIN, + SUBSCRIBER, + CSR, + SYSTEM, + INSTALLER, + NOC, + ACCOUNTING, + PARTNER + }; - struct NoteInfo { - uint64_t created=0; // = Utils::Now(); - std::string createdBy; - std::string note; + USER_ROLE UserTypeFromString(const std::string &U); + std::string UserTypeToString(USER_ROLE U); - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector NoteInfoVec; + struct NoteInfo { + uint64_t created = 0; // = Utils::Now(); + std::string createdBy; + std::string note; - struct MobilePhoneNumber { - std::string number; - bool verified = false; - bool primary = false; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector NoteInfoVec; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct MobilePhoneNumber { + std::string number; + bool verified = false; + bool primary = false; - struct MfaAuthInfo { - bool enabled = false; - std::string method; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct MfaAuthInfo { + bool enabled = false; + std::string method; - struct UserLoginLoginExtensions { - std::vector mobiles; - struct MfaAuthInfo mfa; - std::string authenticatorSecret; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct UserLoginLoginExtensions { + std::vector mobiles; + struct MfaAuthInfo mfa; + std::string authenticatorSecret; - struct MFAChallengeRequest { - std::string uuid; - std::string question; - std::string method; - uint64_t created = Utils::Now(); + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct MFAChallengeRequest { + std::string uuid; + std::string question; + std::string method; + uint64_t created = Utils::Now(); - struct MFAChallengeResponse { - std::string uuid; - std::string answer; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct MFAChallengeResponse { + std::string uuid; + std::string answer; - struct UserInfo { - std::string id; - std::string name; - std::string description; - std::string avatar; - std::string email; - bool validated = false; - std::string validationEmail; - uint64_t validationDate = 0; - uint64_t creationDate = 0; - std::string validationURI; - bool changePassword = false; - uint64_t lastLogin = 0; - std::string currentLoginURI; - uint64_t lastPasswordChange = 0; - uint64_t lastEmailCheck = 0; - bool waitingForEmailCheck = false; - std::string locale; - NoteInfoVec notes; - std::string location; - std::string owner; - bool suspended = false; - bool blackListed = false; - USER_ROLE userRole; - UserLoginLoginExtensions userTypeProprietaryInfo; - std::string securityPolicy; - uint64_t securityPolicyChange = 0 ; - std::string currentPassword; - OpenWifi::Types::StringVec lastPasswords; - std::string oauthType; - std::string oauthUserInfo; - uint64_t modified; - std::string signingUp; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector UserInfoVec; + struct UserInfo { + std::string id; + std::string name; + std::string description; + std::string avatar; + std::string email; + bool validated = false; + std::string validationEmail; + uint64_t validationDate = 0; + uint64_t creationDate = 0; + std::string validationURI; + bool changePassword = false; + uint64_t lastLogin = 0; + std::string currentLoginURI; + uint64_t lastPasswordChange = 0; + uint64_t lastEmailCheck = 0; + bool waitingForEmailCheck = false; + std::string locale; + NoteInfoVec notes; + std::string location; + std::string owner; + bool suspended = false; + bool blackListed = false; + USER_ROLE userRole; + UserLoginLoginExtensions userTypeProprietaryInfo; + std::string securityPolicy; + uint64_t securityPolicyChange = 0; + std::string currentPassword; + OpenWifi::Types::StringVec lastPasswords; + std::string oauthType; + std::string oauthUserInfo; + uint64_t modified; + std::string signingUp; - struct UserInfoList { - std::vector users; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector UserInfoVec; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct UserInfoList { + std::vector users; - // bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); - bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); - bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes); + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct InternalServiceInfo { - std::string privateURI; - std::string publicURI; - std::string token; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector InternalServiceInfoVec; + // bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & + // Notes); + bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec &Notes); + bool MergeNotes(const NoteInfoVec &NewNotes, const UserInfo &UInfo, + NoteInfoVec &ExistingNotes); - struct InternalSystemServices { - std::string key; - std::string version; - InternalServiceInfoVec services; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct InternalServiceInfo { + std::string privateURI; + std::string publicURI; + std::string token; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector InternalServiceInfoVec; - struct SystemEndpoint { - std::string type; - uint64_t id = 0; - std::string vendor{"OpenWiFi"}; - std::string uri; - std::string authenticationType{"internal_v1"}; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector SystemEndpointVec; + struct InternalSystemServices { + std::string key; + std::string version; + InternalServiceInfoVec services; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SystemEndpointList { - SystemEndpointVec endpoints; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct SystemEndpoint { + std::string type; + uint64_t id = 0; + std::string vendor{"OpenWiFi"}; + std::string uri; + std::string authenticationType{"internal_v1"}; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector SystemEndpointVec; - struct UserInfoAndPolicy { - WebToken webtoken; - UserInfo userinfo; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::map UserInfoCache; + struct SystemEndpointList { + SystemEndpointVec endpoints; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - enum ResourceAccessType { - NONE, - READ, - MODIFY, - DELETE, - CREATE, - TEST, - MOVE - }; + struct UserInfoAndPolicy { + WebToken webtoken; + UserInfo userinfo; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::map UserInfoCache; - ResourceAccessType ResourceAccessTypeFromString(const std::string &s); - std::string ResourceAccessTypeToString(const ResourceAccessType & T); + enum ResourceAccessType { NONE, READ, MODIFY, DELETE, CREATE, TEST, MOVE }; - struct ProfileAction { - std::string resource; - ResourceAccessType access; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector ProfileActionVec; + ResourceAccessType ResourceAccessTypeFromString(const std::string &s); + std::string ResourceAccessTypeToString(const ResourceAccessType &T); - struct SecurityProfile { - uint64_t id=0; - std::string name; - std::string description; - ProfileActionVec policy; - std::string role; - NoteInfoVec notes; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; - typedef std::vector SecurityProfileVec; + struct ProfileAction { + std::string resource; + ResourceAccessType access; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ProfileActionVec; - struct SecurityProfileList { - SecurityProfileVec profiles; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct SecurityProfile { + uint64_t id = 0; + std::string name; + std::string description; + ProfileActionVec policy; + std::string role; + NoteInfoVec notes; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector SecurityProfileVec; - enum LinkActions { - FORGOT_PASSWORD=1, - VERIFY_EMAIL, - SUB_FORGOT_PASSWORD, - SUB_VERIFY_EMAIL, - SUB_SIGNUP, - EMAIL_INVITATION - }; + struct SecurityProfileList { + SecurityProfileVec profiles; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct ActionLink { - std::string id; - uint64_t action; - std::string userId; - std::string actionTemplate; - Types::StringPairVec variables; - std::string locale; - std::string message; - uint64_t sent=0; - uint64_t created=Utils::Now(); - uint64_t expires=0; - uint64_t completed=0; - uint64_t canceled=0; - bool userAction=true; + enum LinkActions { + FORGOT_PASSWORD = 1, + VERIFY_EMAIL, + SUB_FORGOT_PASSWORD, + SUB_VERIFY_EMAIL, + SUB_SIGNUP, + EMAIL_INVITATION + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct ActionLink { + std::string id; + uint64_t action; + std::string userId; + std::string actionTemplate; + Types::StringPairVec variables; + std::string locale; + std::string message; + uint64_t sent = 0; + uint64_t created = Utils::Now(); + uint64_t expires = 0; + uint64_t completed = 0; + uint64_t canceled = 0; + bool userAction = true; - struct Preferences { - std::string id; - uint64_t modified; - Types::StringPairVec data; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SubMfaConfig { - std::string id; - std::string type; - std::string sms; - std::string email; + struct Preferences { + std::string id; + uint64_t modified; + Types::StringPairVec data; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct SubMfaConfig { + std::string id; + std::string type; + std::string sms; + std::string email; - struct Token { - std::string token; - std::string refreshToken; - std::string tokenType; - std::string userName; - uint64_t created=0; - uint64_t expires=0; - uint64_t idleTimeout=0; - uint64_t revocationDate=0; - uint64_t lastRefresh=0; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct Token { + std::string token; + std::string refreshToken; + std::string tokenType; + std::string userName; + uint64_t created = 0; + uint64_t expires = 0; + uint64_t idleTimeout = 0; + uint64_t revocationDate = 0; + uint64_t lastRefresh = 0; - struct Avatar { - std::string id; - std::string type; - uint64_t created=0; - std::string name; - Poco::Data::BLOB avatar; - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct LoginRecordInfo { - std::string sessionId; - std::string userId; - std::string email; - uint64_t login=0; - uint64_t logout=0; + struct Avatar { + std::string id; + std::string type; + uint64_t created = 0; + std::string name; + Poco::Data::BLOB avatar; + }; - void to_json(Poco::JSON::Object &Obj) const; - }; + struct LoginRecordInfo { + std::string sessionId; + std::string userId; + std::string email; + uint64_t login = 0; + uint64_t logout = 0; - struct ApiKeyAccessRight { - std::string service; - std::string access; + void to_json(Poco::JSON::Object &Obj) const; + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct ApiKeyAccessRight { + std::string service; + std::string access; - struct ApiKeyAccessRightList { - std::vector acls; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct ApiKeyAccessRightList { + std::vector acls; - struct ApiKeyEntry { - Types::UUID_t id; - Types::UUID_t userUuid; - std::string name; - std::string description; - std::string apiKey; - std::string salt; - std::uint64_t created; - std::uint64_t expiresOn=0; - ApiKeyAccessRightList rights; - std::uint64_t lastUse=0; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct ApiKeyEntry { + Types::UUID_t id; + Types::UUID_t userUuid; + std::string name; + std::string description; + std::string apiKey; + std::string salt; + std::uint64_t created; + std::uint64_t expiresOn = 0; + ApiKeyAccessRightList rights; + std::uint64_t lastUse = 0; - struct ApiKeyEntryList { - std::vector apiKeys; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + struct ApiKeyEntryList { + std::vector apiKeys; - } -} + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + } // namespace SecurityObjects +} // namespace OpenWifi diff --git a/src/RESTObjects/RESTAPI_SubObjects.cpp b/src/RESTObjects/RESTAPI_SubObjects.cpp index a362b15..fabd513 100644 --- a/src/RESTObjects/RESTAPI_SubObjects.cpp +++ b/src/RESTObjects/RESTAPI_SubObjects.cpp @@ -5,598 +5,598 @@ #include "RESTAPI_SubObjects.h" #include "framework/RESTAPI_utils.h" -using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_from_json; +using OpenWifi::RESTAPI_utils::field_to_json; namespace OpenWifi::SubObjects { - void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "enableLEDS", enableLEDS); - field_to_json(Obj, "type", type); - field_to_json(Obj, "subnet", subnet); - field_to_json(Obj, "subnetMask", subnetMask); - field_to_json(Obj, "startIP", startIP); - field_to_json(Obj, "endIP", endIP); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - field_to_json(Obj, "subnetV6", subnetV6); - field_to_json(Obj, "subnetMaskV6", subnetMaskV6); - field_to_json(Obj, "startIPV6", startIPV6); - field_to_json(Obj, "endIPV6", endIPV6); - } + void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "enableLEDS", enableLEDS); + field_to_json(Obj, "type", type); + field_to_json(Obj, "subnet", subnet); + field_to_json(Obj, "subnetMask", subnetMask); + field_to_json(Obj, "startIP", startIP); + field_to_json(Obj, "endIP", endIP); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "subnetV6", subnetV6); + field_to_json(Obj, "subnetMaskV6", subnetMaskV6); + field_to_json(Obj, "startIPV6", startIPV6); + field_to_json(Obj, "endIPV6", endIPV6); + } - bool HomeDeviceMode::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "enableLEDS", enableLEDS); - field_from_json(Obj, "type", type); - field_from_json(Obj, "subnet", subnet); - field_from_json(Obj, "subnetMask", subnetMask); - field_from_json(Obj, "startIP", startIP); - field_from_json(Obj, "endIP", endIP); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - field_from_json(Obj, "subnetV6", subnetV6); - field_from_json(Obj, "subnetMaskV6", subnetMaskV6); - field_from_json(Obj, "startIPV6", startIPV6); - field_from_json(Obj, "endIPV6", endIPV6); - return true; - } catch (...) { - } - return false; - } + bool HomeDeviceMode::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "enableLEDS", enableLEDS); + field_from_json(Obj, "type", type); + field_from_json(Obj, "subnet", subnet); + field_from_json(Obj, "subnetMask", subnetMask); + field_from_json(Obj, "startIP", startIP); + field_from_json(Obj, "endIP", endIP); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "subnetV6", subnetV6); + field_from_json(Obj, "subnetMaskV6", subnetMaskV6); + field_from_json(Obj, "startIPV6", startIPV6); + field_from_json(Obj, "endIPV6", endIPV6); + return true; + } catch (...) { + } + return false; + } - void IPReservation::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "nickname", nickname); - field_to_json(Obj, "ipAddress", ipAddress); - field_to_json(Obj, "macAddress", macAddress); - } + void IPReservation::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "nickname", nickname); + field_to_json(Obj, "ipAddress", ipAddress); + field_to_json(Obj, "macAddress", macAddress); + } - bool IPReservation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "nickname", nickname); - field_from_json(Obj, "ipAddress", ipAddress); - field_from_json(Obj, "macAddress", macAddress); - return true; - } catch (...) { - } - return false; - } + bool IPReservation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "nickname", nickname); + field_from_json(Obj, "ipAddress", ipAddress); + field_from_json(Obj, "macAddress", macAddress); + return true; + } catch (...) { + } + return false; + } - void IPReservationList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "reservations", reservations); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void IPReservationList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "reservations", reservations); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool IPReservationList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "reservations", reservations); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool IPReservationList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "reservations", reservations); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void DnsConfiguration::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "ISP", ISP); - field_to_json(Obj, "custom", custom); - field_to_json(Obj, "primary", primary); - field_to_json(Obj, "secondary", secondary); - field_to_json(Obj, "primaryV6", primaryV6); - field_to_json(Obj, "secondaryV6", secondaryV6); - } + void DnsConfiguration::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "ISP", ISP); + field_to_json(Obj, "custom", custom); + field_to_json(Obj, "primary", primary); + field_to_json(Obj, "secondary", secondary); + field_to_json(Obj, "primaryV6", primaryV6); + field_to_json(Obj, "secondaryV6", secondaryV6); + } - bool DnsConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "ISP", ISP); - field_from_json(Obj, "custom", custom); - field_from_json(Obj, "primary", primary); - field_from_json(Obj, "secondary", secondary); - field_from_json(Obj, "primaryV6", primaryV6); - field_from_json(Obj, "secondaryV6", secondaryV6); - return true; - } catch (...) { - } - return false; - } + bool DnsConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "ISP", ISP); + field_from_json(Obj, "custom", custom); + field_from_json(Obj, "primary", primary); + field_from_json(Obj, "secondary", secondary); + field_from_json(Obj, "primaryV6", primaryV6); + field_from_json(Obj, "secondaryV6", secondaryV6); + return true; + } catch (...) { + } + return false; + } - void InternetConnection::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "type", type); - field_to_json(Obj, "username", username); - field_to_json(Obj, "password", password); - field_to_json(Obj, "ipAddress", ipAddress); - field_to_json(Obj, "subnetMask", subnetMask); - field_to_json(Obj, "defaultGateway", defaultGateway); - field_to_json(Obj, "sendHostname", sendHostname); - field_to_json(Obj, "primaryDns", primaryDns); - field_to_json(Obj, "secondaryDns", secondaryDns); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - field_to_json(Obj, "ipV6Support", ipV6Support); - field_to_json(Obj, "ipAddressV6", ipAddressV6); - field_to_json(Obj, "subnetMaskV6", subnetMaskV6); - field_to_json(Obj, "defaultGatewayV6", defaultGatewayV6); - field_to_json(Obj, "primaryDnsV6", primaryDnsV6); - field_to_json(Obj, "secondaryDnsV6", secondaryDnsV6); - } + void InternetConnection::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "username", username); + field_to_json(Obj, "password", password); + field_to_json(Obj, "ipAddress", ipAddress); + field_to_json(Obj, "subnetMask", subnetMask); + field_to_json(Obj, "defaultGateway", defaultGateway); + field_to_json(Obj, "sendHostname", sendHostname); + field_to_json(Obj, "primaryDns", primaryDns); + field_to_json(Obj, "secondaryDns", secondaryDns); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "ipV6Support", ipV6Support); + field_to_json(Obj, "ipAddressV6", ipAddressV6); + field_to_json(Obj, "subnetMaskV6", subnetMaskV6); + field_to_json(Obj, "defaultGatewayV6", defaultGatewayV6); + field_to_json(Obj, "primaryDnsV6", primaryDnsV6); + field_to_json(Obj, "secondaryDnsV6", secondaryDnsV6); + } - bool InternetConnection::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "type", type); - field_from_json(Obj, "username", username); - field_from_json(Obj, "password", password); - field_from_json(Obj, "ipAddress", ipAddress); - field_from_json(Obj, "subnetMask", subnetMask); - field_from_json(Obj, "defaultGateway", defaultGateway); - field_from_json(Obj, "sendHostname", sendHostname); - field_from_json(Obj, "primaryDns", primaryDns); - field_from_json(Obj, "secondaryDns", secondaryDns); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - field_from_json(Obj, "ipV6Support", ipV6Support); - field_from_json(Obj, "ipAddressV6", ipAddressV6); - field_from_json(Obj, "subnetMaskV6", subnetMaskV6); - field_from_json(Obj, "defaultGatewayV6", defaultGatewayV6); - field_from_json(Obj, "primaryDnsV6", primaryDnsV6); - field_from_json(Obj, "secondaryDnsV6", secondaryDnsV6); - return true; - } catch (...) { - } - return false; - } + bool InternetConnection::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "username", username); + field_from_json(Obj, "password", password); + field_from_json(Obj, "ipAddress", ipAddress); + field_from_json(Obj, "subnetMask", subnetMask); + field_from_json(Obj, "defaultGateway", defaultGateway); + field_from_json(Obj, "sendHostname", sendHostname); + field_from_json(Obj, "primaryDns", primaryDns); + field_from_json(Obj, "secondaryDns", secondaryDns); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "ipV6Support", ipV6Support); + field_from_json(Obj, "ipAddressV6", ipAddressV6); + field_from_json(Obj, "subnetMaskV6", subnetMaskV6); + field_from_json(Obj, "defaultGatewayV6", defaultGatewayV6); + field_from_json(Obj, "primaryDnsV6", primaryDnsV6); + field_from_json(Obj, "secondaryDnsV6", secondaryDnsV6); + return true; + } catch (...) { + } + return false; + } - void WifiNetwork::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "type", type); - field_to_json(Obj, "name", name); - field_to_json(Obj, "password", password); - field_to_json(Obj, "encryption", encryption); - field_to_json(Obj, "bands", bands); - } + void WifiNetwork::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "name", name); + field_to_json(Obj, "password", password); + field_to_json(Obj, "encryption", encryption); + field_to_json(Obj, "bands", bands); + } - bool WifiNetwork::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "type", type); - field_from_json(Obj, "name", name); - field_from_json(Obj, "password", password); - field_from_json(Obj, "encryption", encryption); - field_from_json(Obj, "bands", bands); - return true; - } catch (...) { - } - return false; - } + bool WifiNetwork::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "name", name); + field_from_json(Obj, "password", password); + field_from_json(Obj, "encryption", encryption); + field_from_json(Obj, "bands", bands); + return true; + } catch (...) { + } + return false; + } - void WifiNetworkList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "wifiNetworks", wifiNetworks); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void WifiNetworkList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "wifiNetworks", wifiNetworks); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool WifiNetworkList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "wifiNetworks", wifiNetworks); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool WifiNetworkList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "wifiNetworks", wifiNetworks); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void AccessTime::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "day", day); - field_to_json(Obj, "rangeList", rangeList); - } + void AccessTime::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "day", day); + field_to_json(Obj, "rangeList", rangeList); + } - bool AccessTime::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "day", day); - field_from_json(Obj, "rangeList", rangeList); - return true; - } catch (...) { - } - return false; - } + bool AccessTime::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "day", day); + field_from_json(Obj, "rangeList", rangeList); + return true; + } catch (...) { + } + return false; + } - void AccessTimes::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "schedule", schedule); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void AccessTimes::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "schedule", schedule); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool AccessTimes::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "schedule", schedule); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool AccessTimes::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "schedule", schedule); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "name", name); - field_to_json(Obj, "description", description); - field_to_json(Obj, "macAddress", macAddress); - field_to_json(Obj, "manufacturer", manufacturer); - field_to_json(Obj, "firstContact", firstContact); - field_to_json(Obj, "lastContact", lastContact); - field_to_json(Obj, "group", group); - field_to_json(Obj, "icon", icon); - field_to_json(Obj, "suspended", suspended); - field_to_json(Obj, "ip", ip); - field_to_json(Obj, "schedule", schedule); - } + void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + field_to_json(Obj, "macAddress", macAddress); + field_to_json(Obj, "manufacturer", manufacturer); + field_to_json(Obj, "firstContact", firstContact); + field_to_json(Obj, "lastContact", lastContact); + field_to_json(Obj, "group", group); + field_to_json(Obj, "icon", icon); + field_to_json(Obj, "suspended", suspended); + field_to_json(Obj, "ip", ip); + field_to_json(Obj, "schedule", schedule); + } - bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "name", name); - field_from_json(Obj, "description", description); - field_from_json(Obj, "macAddress", macAddress); - field_from_json(Obj, "manufacturer", manufacturer); - field_from_json(Obj, "firstContact", firstContact); - field_from_json(Obj, "lastContact", lastContact); - field_from_json(Obj, "group", group); - field_from_json(Obj, "icon", icon); - field_from_json(Obj, "suspended", suspended); - field_from_json(Obj, "ip", ip); - field_from_json(Obj, "schedule", schedule); - return true; - } catch (...) { - } - return false; - } + bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "name", name); + field_from_json(Obj, "description", description); + field_from_json(Obj, "macAddress", macAddress); + field_from_json(Obj, "manufacturer", manufacturer); + field_from_json(Obj, "firstContact", firstContact); + field_from_json(Obj, "lastContact", lastContact); + field_from_json(Obj, "group", group); + field_from_json(Obj, "icon", icon); + field_from_json(Obj, "suspended", suspended); + field_from_json(Obj, "ip", ip); + field_from_json(Obj, "schedule", schedule); + return true; + } catch (...) { + } + return false; + } - void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "devices", devices); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "devices", devices); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "devices", devices); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "devices", devices); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void Association::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "name", name); - field_to_json(Obj, "ssid", ssid); - field_to_json(Obj, "macAddress", macAddress); - field_to_json(Obj, "rssi", rssi); - field_to_json(Obj, "power", power); - field_to_json(Obj, "ipv4", ipv4); - field_to_json(Obj, "ipv6", ipv6); - field_to_json(Obj, "tx", tx); - field_to_json(Obj, "rx", rx); - field_to_json(Obj, "manufacturer", manufacturer); - } + void Association::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "name", name); + field_to_json(Obj, "ssid", ssid); + field_to_json(Obj, "macAddress", macAddress); + field_to_json(Obj, "rssi", rssi); + field_to_json(Obj, "power", power); + field_to_json(Obj, "ipv4", ipv4); + field_to_json(Obj, "ipv6", ipv6); + field_to_json(Obj, "tx", tx); + field_to_json(Obj, "rx", rx); + field_to_json(Obj, "manufacturer", manufacturer); + } - bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "name", name); - field_from_json(Obj, "ssid", ssid); - field_from_json(Obj, "macAddress", macAddress); - field_from_json(Obj, "rssi", rssi); - field_from_json(Obj, "power", power); - field_from_json(Obj, "ipv4", ipv4); - field_from_json(Obj, "ipv6", ipv6); - field_from_json(Obj, "tx", tx); - field_from_json(Obj, "rx", rx); - field_from_json(Obj, "manufacturer", manufacturer); - return true; - } catch (...) { - } - return false; - } + bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "name", name); + field_from_json(Obj, "ssid", ssid); + field_from_json(Obj, "macAddress", macAddress); + field_from_json(Obj, "rssi", rssi); + field_from_json(Obj, "power", power); + field_from_json(Obj, "ipv4", ipv4); + field_from_json(Obj, "ipv6", ipv6); + field_from_json(Obj, "tx", tx); + field_from_json(Obj, "rx", rx); + field_from_json(Obj, "manufacturer", manufacturer); + return true; + } catch (...) { + } + return false; + } - void AssociationList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "associations", associations); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void AssociationList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "associations", associations); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool AssociationList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "associations", associations); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool AssociationList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "associations", associations); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void Client::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "macAddress", macAddress); - field_to_json(Obj, "speed", speed); - field_to_json(Obj, "mode", mode); - field_to_json(Obj, "ipv4", ipv4); - field_to_json(Obj, "ipv6", ipv6); - field_to_json(Obj, "tx", tx); - field_to_json(Obj, "rx", rx); - field_to_json(Obj, "manufacturer", manufacturer); - } + void Client::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "macAddress", macAddress); + field_to_json(Obj, "speed", speed); + field_to_json(Obj, "mode", mode); + field_to_json(Obj, "ipv4", ipv4); + field_to_json(Obj, "ipv6", ipv6); + field_to_json(Obj, "tx", tx); + field_to_json(Obj, "rx", rx); + field_to_json(Obj, "manufacturer", manufacturer); + } - bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "macAddress", macAddress); - field_from_json(Obj, "speed", speed); - field_from_json(Obj, "mode", mode); - field_from_json(Obj, "ipv4", ipv4); - field_from_json(Obj, "ipv6", ipv6); - field_from_json(Obj, "tx", tx); - field_from_json(Obj, "rx", rx); - field_from_json(Obj, "manufacturer", manufacturer); - return true; - } catch (...) { - } - return false; - } + bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "macAddress", macAddress); + field_from_json(Obj, "speed", speed); + field_from_json(Obj, "mode", mode); + field_from_json(Obj, "ipv4", ipv4); + field_from_json(Obj, "ipv6", ipv6); + field_from_json(Obj, "tx", tx); + field_from_json(Obj, "rx", rx); + field_from_json(Obj, "manufacturer", manufacturer); + return true; + } catch (...) { + } + return false; + } - void ClientList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "clients", clients); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void ClientList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "clients", clients); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool ClientList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "clients", clients); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool ClientList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "clients", clients); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void Location::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "buildingName", buildingName); - field_to_json(Obj, "addressLines", addressLines); - field_to_json(Obj, "city", city); - field_to_json(Obj, "state", state); - field_to_json(Obj, "postal", postal); - field_to_json(Obj, "country", country); - field_to_json(Obj, "phones", phones); - field_to_json(Obj, "mobiles", mobiles); - } + void Location::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "buildingName", buildingName); + field_to_json(Obj, "addressLines", addressLines); + field_to_json(Obj, "city", city); + field_to_json(Obj, "state", state); + field_to_json(Obj, "postal", postal); + field_to_json(Obj, "country", country); + field_to_json(Obj, "phones", phones); + field_to_json(Obj, "mobiles", mobiles); + } - bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "buildingName", buildingName); - field_from_json(Obj, "addressLines", addressLines); - field_from_json(Obj, "city", city); - field_from_json(Obj, "state", state); - field_from_json(Obj, "postal", postal); - field_from_json(Obj, "country", country); - field_from_json(Obj, "phones", phones); - field_from_json(Obj, "mobiles", mobiles); - return true; - } catch (...) { - } - return false; - } + bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "buildingName", buildingName); + field_from_json(Obj, "addressLines", addressLines); + field_from_json(Obj, "city", city); + field_from_json(Obj, "state", state); + field_from_json(Obj, "postal", postal); + field_from_json(Obj, "country", country); + field_from_json(Obj, "phones", phones); + field_from_json(Obj, "mobiles", mobiles); + return true; + } catch (...) { + } + return false; + } - void RadioHE::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "multipleBSSID", multipleBSSID); - field_to_json(Obj, "ema", ema); - field_to_json(Obj, "bssColor", bssColor); - } + void RadioHE::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "multipleBSSID", multipleBSSID); + field_to_json(Obj, "ema", ema); + field_to_json(Obj, "bssColor", bssColor); + } - bool RadioHE::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "multipleBSSID", multipleBSSID); - field_from_json(Obj, "ema", ema); - field_from_json(Obj, "bssColor", bssColor); - return true; - } catch (...) { - } - return false; - } + bool RadioHE::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "multipleBSSID", multipleBSSID); + field_from_json(Obj, "ema", ema); + field_from_json(Obj, "bssColor", bssColor); + return true; + } catch (...) { + } + return false; + } - void RadioRates::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "beacon", beacon); - field_to_json(Obj, "multicast", multicast); - } + void RadioRates::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "beacon", beacon); + field_to_json(Obj, "multicast", multicast); + } - bool RadioRates::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "beacon", beacon); - field_from_json(Obj, "multicast", multicast); - return true; - } catch (...) { - } - return false; - } + bool RadioRates::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "beacon", beacon); + field_from_json(Obj, "multicast", multicast); + return true; + } catch (...) { + } + return false; + } - void RadioInformation::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "band", band); - field_to_json(Obj, "bandwidth", bandwidth); - field_to_json(Obj, "channel", channel); - field_to_json(Obj, "country", country); - field_to_json(Obj, "channelMode", channelMode); - field_to_json(Obj, "channelWidth", channelWidth); - field_to_json(Obj, "requireMode", requireMode); - field_to_json(Obj, "txpower", txpower); - field_to_json(Obj, "legacyRates", legacyRates); - field_to_json(Obj, "beaconInterval", beaconInterval); - field_to_json(Obj, "dtimPeriod", dtimPeriod); - field_to_json(Obj, "maximumClients", maximumClients); - field_to_json(Obj, "rates", rates); - field_to_json(Obj, "he", he); - field_to_json(Obj, "rawInfo", rawInfo); - field_to_json(Obj, "allowDFS", allowDFS); - field_to_json(Obj, "mimo", mimo); - } + void RadioInformation::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "band", band); + field_to_json(Obj, "bandwidth", bandwidth); + field_to_json(Obj, "channel", channel); + field_to_json(Obj, "country", country); + field_to_json(Obj, "channelMode", channelMode); + field_to_json(Obj, "channelWidth", channelWidth); + field_to_json(Obj, "requireMode", requireMode); + field_to_json(Obj, "txpower", txpower); + field_to_json(Obj, "legacyRates", legacyRates); + field_to_json(Obj, "beaconInterval", beaconInterval); + field_to_json(Obj, "dtimPeriod", dtimPeriod); + field_to_json(Obj, "maximumClients", maximumClients); + field_to_json(Obj, "rates", rates); + field_to_json(Obj, "he", he); + field_to_json(Obj, "rawInfo", rawInfo); + field_to_json(Obj, "allowDFS", allowDFS); + field_to_json(Obj, "mimo", mimo); + } - bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "band", band); - field_from_json(Obj, "bandwidth", bandwidth); - field_from_json(Obj, "channel", channel); - field_from_json(Obj, "country", country); - field_from_json(Obj, "channelMode", channelMode); - field_from_json(Obj, "channelWidth", channelWidth); - field_from_json(Obj, "requireMode", requireMode); - field_from_json(Obj, "txpower", txpower); - field_from_json(Obj, "legacyRates", legacyRates); - field_from_json(Obj, "beaconInterval", beaconInterval); - field_from_json(Obj, "dtimPeriod", dtimPeriod); - field_from_json(Obj, "maximumClients", maximumClients); - field_from_json(Obj, "rates", rates); - field_from_json(Obj, "he", he); - field_from_json(Obj, "rawInfo", rawInfo); - field_from_json(Obj, "allowDFS", allowDFS); - field_from_json(Obj, "mimo", mimo); - return true; - } catch (...) { - } - return false; - } + bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "band", band); + field_from_json(Obj, "bandwidth", bandwidth); + field_from_json(Obj, "channel", channel); + field_from_json(Obj, "country", country); + field_from_json(Obj, "channelMode", channelMode); + field_from_json(Obj, "channelWidth", channelWidth); + field_from_json(Obj, "requireMode", requireMode); + field_from_json(Obj, "txpower", txpower); + field_from_json(Obj, "legacyRates", legacyRates); + field_from_json(Obj, "beaconInterval", beaconInterval); + field_from_json(Obj, "dtimPeriod", dtimPeriod); + field_from_json(Obj, "maximumClients", maximumClients); + field_from_json(Obj, "rates", rates); + field_from_json(Obj, "he", he); + field_from_json(Obj, "rawInfo", rawInfo); + field_from_json(Obj, "allowDFS", allowDFS); + field_from_json(Obj, "mimo", mimo); + return true; + } catch (...) { + } + return false; + } - void AccessPoint::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "macAddress", macAddress); - field_to_json(Obj, "serialNumber", serialNumber); - field_to_json(Obj, "name", name); - field_to_json(Obj, "deviceType", deviceType); - field_to_json(Obj, "subscriberDevices", subscriberDevices); - field_to_json(Obj, "ipReservations", ipReservations); - field_to_json(Obj, "address", address); - field_to_json(Obj, "wifiNetworks", wifiNetworks); - field_to_json(Obj, "internetConnection", internetConnection); - field_to_json(Obj, "deviceMode", deviceMode); - field_to_json(Obj, "dnsConfiguration", dnsConfiguration); - field_to_json(Obj, "radios", radios); - field_to_json(Obj, "automaticUpgrade", automaticUpgrade); - field_to_json(Obj, "configurationUUID", configurationUUID); - field_to_json(Obj, "currentFirmware", currentFirmware); - field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); - field_to_json(Obj, "latestFirmware", latestFirmware); - field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); - field_to_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); - field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI); - } + void AccessPoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "macAddress", macAddress); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "name", name); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "subscriberDevices", subscriberDevices); + field_to_json(Obj, "ipReservations", ipReservations); + field_to_json(Obj, "address", address); + field_to_json(Obj, "wifiNetworks", wifiNetworks); + field_to_json(Obj, "internetConnection", internetConnection); + field_to_json(Obj, "deviceMode", deviceMode); + field_to_json(Obj, "dnsConfiguration", dnsConfiguration); + field_to_json(Obj, "radios", radios); + field_to_json(Obj, "automaticUpgrade", automaticUpgrade); + field_to_json(Obj, "configurationUUID", configurationUUID); + field_to_json(Obj, "currentFirmware", currentFirmware); + field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); + field_to_json(Obj, "latestFirmware", latestFirmware); + field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); + field_to_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); + field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI); + } - bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "macAddress", macAddress); - field_from_json(Obj, "serialNumber", serialNumber); - field_from_json(Obj, "name", name); - field_from_json(Obj, "deviceType", deviceType); - field_from_json(Obj, "subscriberDevices", subscriberDevices); - field_from_json(Obj, "ipReservations", ipReservations); - field_from_json(Obj, "address", address); - field_from_json(Obj, "wifiNetworks", wifiNetworks); - field_from_json(Obj, "internetConnection", internetConnection); - field_from_json(Obj, "deviceMode", deviceMode); - field_from_json(Obj, "dnsConfiguration", dnsConfiguration); - field_from_json(Obj, "radios", radios); - field_from_json(Obj, "automaticUpgrade", automaticUpgrade); - field_from_json(Obj, "configurationUUID", configurationUUID); - field_from_json(Obj, "currentFirmware", currentFirmware); - field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); - field_from_json(Obj, "latestFirmware", latestFirmware); - field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); - field_from_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); - field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI); - return true; - } catch (...) { - } - return false; - } + bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "macAddress", macAddress); + field_from_json(Obj, "serialNumber", serialNumber); + field_from_json(Obj, "name", name); + field_from_json(Obj, "deviceType", deviceType); + field_from_json(Obj, "subscriberDevices", subscriberDevices); + field_from_json(Obj, "ipReservations", ipReservations); + field_from_json(Obj, "address", address); + field_from_json(Obj, "wifiNetworks", wifiNetworks); + field_from_json(Obj, "internetConnection", internetConnection); + field_from_json(Obj, "deviceMode", deviceMode); + field_from_json(Obj, "dnsConfiguration", dnsConfiguration); + field_from_json(Obj, "radios", radios); + field_from_json(Obj, "automaticUpgrade", automaticUpgrade); + field_from_json(Obj, "configurationUUID", configurationUUID); + field_from_json(Obj, "currentFirmware", currentFirmware); + field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); + field_from_json(Obj, "latestFirmware", latestFirmware); + field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); + field_from_json(Obj, "newFirmwareAvailable", newFirmwareAvailable); + field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI); + return true; + } catch (...) { + } + return false; + } - void AccessPointList::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "list", list); - } + void AccessPointList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "list", list); + } - bool AccessPointList::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "list", list); - return true; - } catch (...) { - } - return false; - } + bool AccessPointList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "list", list); + return true; + } catch (...) { + } + return false; + } - void SubscriberInfo::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "id", id); - field_to_json(Obj, "userId", userId); - field_to_json(Obj, "firstName", firstName); - field_to_json(Obj, "initials", initials); - field_to_json(Obj, "lastName", lastName); - field_to_json(Obj, "phoneNumber", phoneNumber); - field_to_json(Obj, "secondaryEmail", secondaryEmail); - field_to_json(Obj, "accessPoints", accessPoints); - field_to_json(Obj, "serviceAddress", serviceAddress); - field_to_json(Obj, "billingAddress", billingAddress); - field_to_json(Obj, "created", created); - field_to_json(Obj, "modified", modified); - } + void SubscriberInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "id", id); + field_to_json(Obj, "userId", userId); + field_to_json(Obj, "firstName", firstName); + field_to_json(Obj, "initials", initials); + field_to_json(Obj, "lastName", lastName); + field_to_json(Obj, "phoneNumber", phoneNumber); + field_to_json(Obj, "secondaryEmail", secondaryEmail); + field_to_json(Obj, "accessPoints", accessPoints); + field_to_json(Obj, "serviceAddress", serviceAddress); + field_to_json(Obj, "billingAddress", billingAddress); + field_to_json(Obj, "created", created); + field_to_json(Obj, "modified", modified); + } - bool SubscriberInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "id", id); - field_from_json(Obj, "userId", userId); - field_from_json(Obj, "firstName", firstName); - field_from_json(Obj, "initials", initials); - field_from_json(Obj, "lastName", lastName); - field_from_json(Obj, "phoneNumber", phoneNumber); - field_from_json(Obj, "secondaryEmail", secondaryEmail); - field_from_json(Obj, "accessPoints", accessPoints); - field_from_json(Obj, "serviceAddress", serviceAddress); - field_from_json(Obj, "billingAddress", billingAddress); - field_from_json(Obj, "created", created); - field_from_json(Obj, "modified", modified); - return true; - } catch (...) { - } - return false; - } + bool SubscriberInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "id", id); + field_from_json(Obj, "userId", userId); + field_from_json(Obj, "firstName", firstName); + field_from_json(Obj, "initials", initials); + field_from_json(Obj, "lastName", lastName); + field_from_json(Obj, "phoneNumber", phoneNumber); + field_from_json(Obj, "secondaryEmail", secondaryEmail); + field_from_json(Obj, "accessPoints", accessPoints); + field_from_json(Obj, "serviceAddress", serviceAddress); + field_from_json(Obj, "billingAddress", billingAddress); + field_from_json(Obj, "created", created); + field_from_json(Obj, "modified", modified); + return true; + } catch (...) { + } + return false; + } - void StatsEntry::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "timestamp", timestamp); - field_to_json(Obj, "tx", tx); - field_to_json(Obj, "rx", rx); - } + void StatsEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "timestamp", timestamp); + field_to_json(Obj, "tx", tx); + field_to_json(Obj, "rx", rx); + } - bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "timestamp", timestamp); - field_from_json(Obj, "tx", tx); - field_from_json(Obj, "rx", rx); - return true; - } catch (...) { - } - return false; - } + bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "timestamp", timestamp); + field_from_json(Obj, "tx", tx); + field_from_json(Obj, "rx", rx); + return true; + } catch (...) { + } + return false; + } - void StatsBlock::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj, "modified", modified); - field_to_json(Obj, "external", external); - field_to_json(Obj, "internal", internal); - } + void StatsBlock::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "modified", modified); + field_to_json(Obj, "external", external); + field_to_json(Obj, "internal", internal); + } - bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - field_from_json(Obj, "modified", modified); - field_from_json(Obj, "external", external); - field_from_json(Obj, "internal", internal); - return true; - } catch (...) { - } - return false; - } -} \ No newline at end of file + bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "modified", modified); + field_from_json(Obj, "external", external); + field_from_json(Obj, "internal", internal); + return true; + } catch (...) { + } + return false; + } +} // namespace OpenWifi::SubObjects \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_SubObjects.h b/src/RESTObjects/RESTAPI_SubObjects.h index e586af9..64d9941 100644 --- a/src/RESTObjects/RESTAPI_SubObjects.h +++ b/src/RESTObjects/RESTAPI_SubObjects.h @@ -11,312 +11,312 @@ namespace OpenWifi::SubObjects { - struct HomeDeviceMode { - bool enableLEDS = true; - std::string type; // bridge, manual, automatic - std::string subnet; - std::string subnetMask; - std::string startIP; - std::string endIP; - uint64_t created = 0 ; - uint64_t modified = 0 ; - std::string subnetV6; - int subnetMaskV6=0; - std::string startIPV6; - std::string endIPV6; - std::string leaseTime; + struct HomeDeviceMode { + bool enableLEDS = true; + std::string type; // bridge, manual, automatic + std::string subnet; + std::string subnetMask; + std::string startIP; + std::string endIP; + uint64_t created = 0; + uint64_t modified = 0; + std::string subnetV6; + int subnetMaskV6 = 0; + std::string startIPV6; + std::string endIPV6; + std::string leaseTime; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct IPReservation { - std::string nickname; - std::string ipAddress; - std::string macAddress; + struct IPReservation { + std::string nickname; + std::string ipAddress; + std::string macAddress; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct IPReservationList { - std::string id; - std::vector reservations; - uint64_t created = 0 ; - uint64_t modified = 0 ; + struct IPReservationList { + std::string id; + std::vector reservations; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct DnsConfiguration { - bool ISP=false; - bool custom=false; - std::string primary; - std::string secondary; - std::string primaryV6; - std::string secondaryV6; + struct DnsConfiguration { + bool ISP = false; + bool custom = false; + std::string primary; + std::string secondary; + std::string primaryV6; + std::string secondaryV6; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct InternetConnection { - std::string type; // automatic, pppoe, manual - std::string username; - std::string password; - std::string ipAddress; - std::string subnetMask; - std::string defaultGateway; - bool sendHostname = true; - std::string primaryDns; - std::string secondaryDns; - uint64_t created=0; - uint64_t modified=0; - bool ipV6Support=false; - std::string ipAddressV6; - int subnetMaskV6=0; - std::string defaultGatewayV6; - std::string primaryDnsV6; - std::string secondaryDnsV6; + struct InternetConnection { + std::string type; // automatic, pppoe, manual + std::string username; + std::string password; + std::string ipAddress; + std::string subnetMask; + std::string defaultGateway; + bool sendHostname = true; + std::string primaryDns; + std::string secondaryDns; + uint64_t created = 0; + uint64_t modified = 0; + bool ipV6Support = false; + std::string ipAddressV6; + int subnetMaskV6 = 0; + std::string defaultGatewayV6; + std::string primaryDnsV6; + std::string secondaryDnsV6; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct WifiNetwork { - std::string type; // main, guest - std::string name; - std::string password; - std::string encryption; - std::vector bands; + struct WifiNetwork { + std::string type; // main, guest + std::string name; + std::string password; + std::string encryption; + std::vector bands; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct WifiNetworkList { - std::vector wifiNetworks; - uint64_t created=0; - uint64_t modified=0; + struct WifiNetworkList { + std::vector wifiNetworks; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct AccessTime { - std::string day; - std::vector rangeList; + struct AccessTime { + std::string day; + std::vector rangeList; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct AccessTimes { - std::vector schedule; - uint64_t created=0; - uint64_t modified=0; + struct AccessTimes { + std::vector schedule; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SubscriberDevice { - std::string name; - std::string description; - std::string macAddress; - std::string manufacturer; - uint64_t firstContact=0; - uint64_t lastContact=0; - std::string group; - std::string icon; - bool suspended=false; - std::string ip; - std::vector schedule; + struct SubscriberDevice { + std::string name; + std::string description; + std::string macAddress; + std::string manufacturer; + uint64_t firstContact = 0; + uint64_t lastContact = 0; + std::string group; + std::string icon; + bool suspended = false; + std::string ip; + std::vector schedule; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SubscriberDeviceList { - std::vector devices; - uint64_t created=0; - uint64_t modified=0; + struct SubscriberDeviceList { + std::vector devices; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct Association { - std::string name; - std::string ssid; - std::string macAddress; - int rssi=0; - int power=0; - std::string ipv4; - std::string ipv6; - uint64_t tx=0; - uint64_t rx=0; - std::string manufacturer; + struct Association { + std::string name; + std::string ssid; + std::string macAddress; + int rssi = 0; + int power = 0; + std::string ipv4; + std::string ipv6; + uint64_t tx = 0; + uint64_t rx = 0; + std::string manufacturer; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct AssociationList { - std::vector associations; - uint64_t created=0; - uint64_t modified=0; + struct AssociationList { + std::vector associations; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct Client { - std::string macAddress; - std::string speed; - std::string mode; - std::string ipv4; - std::string ipv6; - uint64_t tx=0; - uint64_t rx=0; - std::string manufacturer; + struct Client { + std::string macAddress; + std::string speed; + std::string mode; + std::string ipv4; + std::string ipv6; + uint64_t tx = 0; + uint64_t rx = 0; + std::string manufacturer; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct ClientList { - std::vector clients; - uint64_t created=0; - uint64_t modified=0; + struct ClientList { + std::vector clients; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct Location { - std::string buildingName; - std::vector addressLines; - std::string city; - std::string state; - std::string postal; - std::string country; - std::vector phones; - std::vector mobiles; + struct Location { + std::string buildingName; + std::vector addressLines; + std::string city; + std::string state; + std::string postal; + std::string country; + std::vector phones; + std::vector mobiles; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct RadioHE { - bool multipleBSSID = false; - bool ema = false; - uint64_t bssColor = 64; + struct RadioHE { + bool multipleBSSID = false; + bool ema = false; + uint64_t bssColor = 64; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct RadioRates { - uint64_t beacon = 6000; - uint64_t multicast = 24000; + struct RadioRates { + uint64_t beacon = 6000; + uint64_t multicast = 24000; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct RadioInformation { - std::string band; - uint64_t bandwidth; - uint64_t channel = 0 ; - std::string country; - std::string channelMode{"HE"}; - uint64_t channelWidth = 80; - std::string requireMode; - uint64_t txpower=0; - bool legacyRates = false; - uint64_t beaconInterval = 100; - uint64_t dtimPeriod = 2; - uint64_t maximumClients = 64; - RadioRates rates; - RadioHE he; - bool allowDFS=false; - std::string mimo; - std::vector rawInfo; + struct RadioInformation { + std::string band; + uint64_t bandwidth; + uint64_t channel = 0; + std::string country; + std::string channelMode{"HE"}; + uint64_t channelWidth = 80; + std::string requireMode; + uint64_t txpower = 0; + bool legacyRates = false; + uint64_t beaconInterval = 100; + uint64_t dtimPeriod = 2; + uint64_t maximumClients = 64; + RadioRates rates; + RadioHE he; + bool allowDFS = false; + std::string mimo; + std::vector rawInfo; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct AccessPoint { - std::string id; - std::string macAddress; - std::string serialNumber; - std::string name; - std::string deviceType; - SubscriberDeviceList subscriberDevices; - IPReservationList ipReservations; - Location address; - WifiNetworkList wifiNetworks; - InternetConnection internetConnection; - HomeDeviceMode deviceMode; - DnsConfiguration dnsConfiguration; - std::vector radios; - bool automaticUpgrade = true; - std::string configurationUUID; - std::string currentFirmware; - uint64_t currentFirmwareDate; - std::string latestFirmware; - uint64_t latestFirmwareDate; - bool newFirmwareAvailable; - std::string latestFirmwareURI; + struct AccessPoint { + std::string id; + std::string macAddress; + std::string serialNumber; + std::string name; + std::string deviceType; + SubscriberDeviceList subscriberDevices; + IPReservationList ipReservations; + Location address; + WifiNetworkList wifiNetworks; + InternetConnection internetConnection; + HomeDeviceMode deviceMode; + DnsConfiguration dnsConfiguration; + std::vector radios; + bool automaticUpgrade = true; + std::string configurationUUID; + std::string currentFirmware; + uint64_t currentFirmwareDate; + std::string latestFirmware; + uint64_t latestFirmwareDate; + bool newFirmwareAvailable; + std::string latestFirmwareURI; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct AccessPointList { - std::vector list; + struct AccessPointList { + std::vector list; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct SubscriberInfo { - std::string id; - std::string userId; - std::string firstName; - std::string initials; - std::string lastName; - std::string phoneNumber; - std::string secondaryEmail; - AccessPointList accessPoints; - Location serviceAddress; - Location billingAddress; - uint64_t created = 0; - uint64_t modified = 0; + struct SubscriberInfo { + std::string id; + std::string userId; + std::string firstName; + std::string initials; + std::string lastName; + std::string phoneNumber; + std::string secondaryEmail; + AccessPointList accessPoints; + Location serviceAddress; + Location billingAddress; + uint64_t created = 0; + uint64_t modified = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct StatsEntry { - uint64_t timestamp=0; - uint64_t tx=0; - uint64_t rx=0; + struct StatsEntry { + uint64_t timestamp = 0; + uint64_t tx = 0; + uint64_t rx = 0; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - struct StatsBlock { - uint64_t modified=0; - std::vector external, internal; + struct StatsBlock { + uint64_t modified = 0; + std::vector external, internal; - void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; -} + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; +} // namespace OpenWifi::SubObjects -#endif //OWSUB_RESTAPI_SUBOBJECTS_H +#endif // OWSUB_RESTAPI_SUBOBJECTS_H diff --git a/src/SMSSender.cpp b/src/SMSSender.cpp index 46f764f..1e50af8 100644 --- a/src/SMSSender.cpp +++ b/src/SMSSender.cpp @@ -2,87 +2,88 @@ // Created by stephane bourque on 2021-10-09. // +#include "SMSSender.h" #include "MFAServer.h" #include "SMS_provider_aws.h" #include "SMS_provider_twilio.h" -#include "SMSSender.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - int SMSSender::Start() { - Enabled_ = MicroServiceConfigGetBool("smssender.enabled",false); - if(Enabled_) { - Provider_ = MicroServiceConfigGetString("smssender.provider","aws"); - if(Provider_=="aws") { - ProviderImpl_ = std::make_unique(Logger()); - } else if(Provider_=="twilio") { - ProviderImpl_ = std::make_unique(Logger()); - } - Enabled_ = ProviderImpl_->Initialize(); - } + int SMSSender::Start() { + Enabled_ = MicroServiceConfigGetBool("smssender.enabled", false); + if (Enabled_) { + Provider_ = MicroServiceConfigGetString("smssender.provider", "aws"); + if (Provider_ == "aws") { + ProviderImpl_ = std::make_unique(Logger()); + } else if (Provider_ == "twilio") { + ProviderImpl_ = std::make_unique(Logger()); + } + Enabled_ = ProviderImpl_->Initialize(); + } - return 0; - } + return 0; + } - void SMSSender::Stop() { - } + void SMSSender::Stop() {} - void SMSSender::CleanCache() { - uint64_t Now=OpenWifi::Now(); - for(auto i=begin(Cache_);i!=end(Cache_);) { - if((Now-i->Created)>300) - i = Cache_.erase(i); - else - ++i; - } - } + void SMSSender::CleanCache() { + uint64_t Now = OpenWifi::Now(); + for (auto i = begin(Cache_); i != end(Cache_);) { + if ((Now - i->Created) > 300) + i = Cache_.erase(i); + else + ++i; + } + } - bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) { - std::lock_guard G(Mutex_); - if(!Enabled_) - return false; - CleanCache(); - uint64_t Now=OpenWifi::Now(); - auto Challenge = MFAServer::MakeChallenge(); - Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now}); - std::string Message = "Please enter the following code on your login screen: " + Challenge; - return ProviderImpl_->Send(Number, Message); - } + bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) { + std::lock_guard G(Mutex_); + if (!Enabled_) + return false; + CleanCache(); + uint64_t Now = OpenWifi::Now(); + auto Challenge = MFAServer::MakeChallenge(); + Cache_.emplace_back(SMSValidationCacheEntry{ + .Number = Number, .Code = Challenge, .UserName = UserName, .Created = Now}); + std::string Message = "Please enter the following code on your login screen: " + Challenge; + return ProviderImpl_->Send(Number, Message); + } - bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) { - std::lock_guard G(Mutex_); + bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) { + std::lock_guard G(Mutex_); - if(!Enabled_) - return false; + if (!Enabled_) + return false; - for(const auto &i:Cache_) { - if(i.Number==Number && i.UserName==UserName) - return i.Validated; - } - return false; - } + for (const auto &i : Cache_) { + if (i.Number == Number && i.UserName == UserName) + return i.Validated; + } + return false; + } - bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) { - std::lock_guard G(Mutex_); + bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, + const std::string &UserName) { + std::lock_guard G(Mutex_); - if(!Enabled_) - return false; + if (!Enabled_) + return false; - for(auto &i:Cache_) { - if(i.Code==Code && i.Number==Number && i.UserName==UserName) { - i.Validated=true; - return true; - } - } - return false; - } + for (auto &i : Cache_) { + if (i.Code == Code && i.Number == Number && i.UserName == UserName) { + i.Validated = true; + return true; + } + } + return false; + } - bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) { - if(!Enabled_) { - poco_information(Logger(),"SMS has not been enabled. Messages cannot be sent."); - return false; - } - return ProviderImpl_->Send(PhoneNumber,Message); - } -} \ No newline at end of file + bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) { + if (!Enabled_) { + poco_information(Logger(), "SMS has not been enabled. Messages cannot be sent."); + return false; + } + return ProviderImpl_->Send(PhoneNumber, Message); + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/SMSSender.h b/src/SMSSender.h index ea647e3..26a996b 100644 --- a/src/SMSSender.h +++ b/src/SMSSender.h @@ -5,51 +5,49 @@ #pragma once #include -#include #include +#include -#include "framework/SubSystemServer.h" #include "SMS_provider.h" +#include "framework/SubSystemServer.h" namespace OpenWifi { - struct SMSValidationCacheEntry { - std::string Number; - std::string Code; - std::string UserName; - uint64_t Created = OpenWifi::Now(); - bool Validated = false; - }; + struct SMSValidationCacheEntry { + std::string Number; + std::string Code; + std::string UserName; + uint64_t Created = OpenWifi::Now(); + bool Validated = false; + }; - class SMSSender : public SubSystemServer { - public: - static SMSSender *instance() { - static auto *instance_ = new SMSSender; - return instance_; - } + class SMSSender : public SubSystemServer { + public: + static SMSSender *instance() { + static auto *instance_ = new SMSSender; + return instance_; + } - int Start() final; - void Stop() final; - bool Enabled() const { return Enabled_; } - bool StartValidation(const std::string &Number, const std::string &UserName); - bool CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName); - bool IsNumberValid(const std::string &Number, const std::string &UserName); - [[nodiscard]] bool Send(const std::string &PhoneNumber, const std::string &Message); - private: - std::string Provider_; - bool Enabled_=false; - std::vector Cache_; - std::unique_ptr ProviderImpl_; + int Start() final; + void Stop() final; + bool Enabled() const { return Enabled_; } + bool StartValidation(const std::string &Number, const std::string &UserName); + bool CompleteValidation(const std::string &Number, const std::string &Code, + const std::string &UserName); + bool IsNumberValid(const std::string &Number, const std::string &UserName); + [[nodiscard]] bool Send(const std::string &PhoneNumber, const std::string &Message); - SMSSender() noexcept: - SubSystemServer("SMSSender", "SMS-SVR", "smssender.aws") - { - } + private: + std::string Provider_; + bool Enabled_ = false; + std::vector Cache_; + std::unique_ptr ProviderImpl_; - bool SendAWS(const std::string &PhoneNumber, const std::string &Message); - void CleanCache(); + SMSSender() noexcept : SubSystemServer("SMSSender", "SMS-SVR", "smssender.aws") {} - }; - inline SMSSender * SMSSender() { return SMSSender::instance(); } + bool SendAWS(const std::string &PhoneNumber, const std::string &Message); + void CleanCache(); + }; + inline SMSSender *SMSSender() { return SMSSender::instance(); } -} +} // namespace OpenWifi diff --git a/src/SMS_provider.h b/src/SMS_provider.h index 1d1f423..3ccab49 100644 --- a/src/SMS_provider.h +++ b/src/SMS_provider.h @@ -8,17 +8,17 @@ #include "Poco/Logger.h" namespace OpenWifi { - class SMS_provider { - public: - virtual bool Initialize() = 0 ; - virtual bool Start() = 0 ; - virtual bool Stop() = 0 ; - virtual bool Running() = 0 ; - virtual bool Send(const std::string &Number, const std::string &Message) = 0; - virtual ~SMS_provider() {}; - private: - }; -} + class SMS_provider { + public: + virtual bool Initialize() = 0; + virtual bool Start() = 0; + virtual bool Stop() = 0; + virtual bool Running() = 0; + virtual bool Send(const std::string &Number, const std::string &Message) = 0; + virtual ~SMS_provider(){}; + private: + }; +} // namespace OpenWifi -#endif //OWSEC_SMS_PROVIDER_H +#endif // OWSEC_SMS_PROVIDER_H diff --git a/src/SMS_provider_aws.cpp b/src/SMS_provider_aws.cpp index 9e4a6d3..8ee9d4f 100644 --- a/src/SMS_provider_aws.cpp +++ b/src/SMS_provider_aws.cpp @@ -8,61 +8,55 @@ #include #include -#include "framework/MicroServiceFuncs.h" #include "fmt/format.h" +#include "framework/MicroServiceFuncs.h" namespace OpenWifi { - bool SMS_provider_aws::Initialize() { - SecretKey_ = MicroServiceConfigGetString("smssender.aws.secretkey",""); - AccessKey_ = MicroServiceConfigGetString("smssender.aws.accesskey",""); - Region_ = MicroServiceConfigGetString("smssender.aws.region",""); + bool SMS_provider_aws::Initialize() { + SecretKey_ = MicroServiceConfigGetString("smssender.aws.secretkey", ""); + AccessKey_ = MicroServiceConfigGetString("smssender.aws.accesskey", ""); + Region_ = MicroServiceConfigGetString("smssender.aws.region", ""); - if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) { - poco_debug(Logger(),"SMSSender is disabled. Please provide key, secret, and region."); - return false; - } - Running_=true; - AwsConfig_.region = Region_; - AwsCreds_.SetAWSAccessKeyId(AccessKey_.c_str()); - AwsCreds_.SetAWSSecretKey(SecretKey_.c_str()); - return true; - } + if (SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) { + poco_debug(Logger(), "SMSSender is disabled. Please provide key, secret, and region."); + return false; + } + Running_ = true; + AwsConfig_.region = Region_; + AwsCreds_.SetAWSAccessKeyId(AccessKey_.c_str()); + AwsCreds_.SetAWSSecretKey(SecretKey_.c_str()); + return true; + } - bool SMS_provider_aws::Start() { - return true; - } + bool SMS_provider_aws::Start() { return true; } - bool SMS_provider_aws::Stop() { - return true; - } + bool SMS_provider_aws::Stop() { return true; } - bool SMS_provider_aws::Running() { - return Running_; - } + bool SMS_provider_aws::Running() { return Running_; } - bool SMS_provider_aws::Send(const std::string &PhoneNumber, const std::string &Message) { - if(!Running_) - return false; + bool SMS_provider_aws::Send(const std::string &PhoneNumber, const std::string &Message) { + if (!Running_) + return false; - try { - Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_); - Aws::SNS::Model::PublishRequest psms_req; - psms_req.SetMessage(Message.c_str()); - psms_req.SetPhoneNumber(PhoneNumber.c_str()); + try { + Aws::SNS::SNSClient sns(AwsCreds_, AwsConfig_); + Aws::SNS::Model::PublishRequest psms_req; + psms_req.SetMessage(Message.c_str()); + psms_req.SetPhoneNumber(PhoneNumber.c_str()); - auto psms_out = sns.Publish(psms_req); - if (psms_out.IsSuccess()) { - poco_debug(Logger(),fmt::format("SMS sent to {}",PhoneNumber)); - return true; - } - std::string ErrMsg{psms_out.GetError().GetMessage()}; - poco_debug(Logger(),fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg)); - return false; - } catch (...) { + auto psms_out = sns.Publish(psms_req); + if (psms_out.IsSuccess()) { + poco_debug(Logger(), fmt::format("SMS sent to {}", PhoneNumber)); + return true; + } + std::string ErrMsg{psms_out.GetError().GetMessage()}; + poco_debug(Logger(), fmt::format("SMS NOT sent to {}: {}", PhoneNumber, ErrMsg)); + return false; + } catch (...) { + } + poco_debug(Logger(), + fmt::format("SMS NOT sent to {}: failure in SMS service", PhoneNumber)); + return false; + } - } - poco_debug(Logger(),fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber)); - return false; - } - -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/SMS_provider_aws.h b/src/SMS_provider_aws.h index 2d6377f..421fb96 100644 --- a/src/SMS_provider_aws.h +++ b/src/SMS_provider_aws.h @@ -5,29 +5,30 @@ #pragma once #include -#include #include +#include #include "SMS_provider.h" namespace OpenWifi { - class SMS_provider_aws : public SMS_provider { - public: - explicit SMS_provider_aws(Poco::Logger &L) : Logger_(L) {} - ~SMS_provider_aws() {}; - bool Initialize() final ; - bool Start() final ; - bool Stop() final ; - bool Send(const std::string &Number, const std::string &Message) final; - bool Running() final; - inline Poco::Logger & Logger() { return Logger_; } - private: - bool Running_=false; - Poco::Logger &Logger_; - std::string SecretKey_; - std::string AccessKey_; - std::string Region_; - Aws::Client::ClientConfiguration AwsConfig_; - Aws::Auth::AWSCredentials AwsCreds_; - }; -} + class SMS_provider_aws : public SMS_provider { + public: + explicit SMS_provider_aws(Poco::Logger &L) : Logger_(L) {} + ~SMS_provider_aws(){}; + bool Initialize() final; + bool Start() final; + bool Stop() final; + bool Send(const std::string &Number, const std::string &Message) final; + bool Running() final; + inline Poco::Logger &Logger() { return Logger_; } + + private: + bool Running_ = false; + Poco::Logger &Logger_; + std::string SecretKey_; + std::string AccessKey_; + std::string Region_; + Aws::Client::ClientConfiguration AwsConfig_; + Aws::Auth::AWSCredentials AwsCreds_; + }; +} // namespace OpenWifi diff --git a/src/SMS_provider_twilio.cpp b/src/SMS_provider_twilio.cpp index f893b4b..6fb4d09 100644 --- a/src/SMS_provider_twilio.cpp +++ b/src/SMS_provider_twilio.cpp @@ -4,75 +4,72 @@ #include "SMS_provider_twilio.h" -#include "Poco/Net/HTTPBasicCredentials.h" -#include "Poco/URI.h" #include "Poco/Net/HTMLForm.h" -#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPBasicCredentials.h" #include "Poco/Net/HTTPResponse.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/URI.h" -#include "framework/MicroServiceFuncs.h" #include "fmt/format.h" +#include "framework/MicroServiceFuncs.h" namespace OpenWifi { - bool SMS_provider_twilio::Initialize() { - Sid_ = MicroServiceConfigGetString("smssender.twilio.sid",""); - Token_ = MicroServiceConfigGetString("smssender.twilio.token",""); - PhoneNumber_ = MicroServiceConfigGetString("smssender.twilio.phonenumber",""); + bool SMS_provider_twilio::Initialize() { + Sid_ = MicroServiceConfigGetString("smssender.twilio.sid", ""); + Token_ = MicroServiceConfigGetString("smssender.twilio.token", ""); + PhoneNumber_ = MicroServiceConfigGetString("smssender.twilio.phonenumber", ""); - if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) { - poco_debug(Logger(),"SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER."); - return false; - } - Running_=true; - Uri_ = "https://api.twilio.com/2010-04-01/Accounts/" + Sid_ + "/Messages.json"; - return true; - } + if (Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) { + poco_debug(Logger(), + "SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER."); + return false; + } + Running_ = true; + Uri_ = "https://api.twilio.com/2010-04-01/Accounts/" + Sid_ + "/Messages.json"; + return true; + } - bool SMS_provider_twilio::Start() { - return true; - } + bool SMS_provider_twilio::Start() { return true; } - bool SMS_provider_twilio::Stop() { - return true; - } + bool SMS_provider_twilio::Stop() { return true; } - bool SMS_provider_twilio::Running() { - return Running_; - } + bool SMS_provider_twilio::Running() { return Running_; } - bool SMS_provider_twilio::Send(const std::string &PhoneNumber, const std::string &Message) { - if(!Running_) - return false; + bool SMS_provider_twilio::Send(const std::string &PhoneNumber, const std::string &Message) { + if (!Running_) + return false; - Poco::Net::HTTPBasicCredentials Creds(Sid_,Token_); - Poco::URI uri(Uri_); - Poco::Net::HTMLForm form; + Poco::Net::HTTPBasicCredentials Creds(Sid_, Token_); + Poco::URI uri(Uri_); + Poco::Net::HTMLForm form; - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1); - Creds.authenticate(req); + Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, uri.getPath(), + Poco::Net::HTTPMessage::HTTP_1_1); + Creds.authenticate(req); - Poco::JSON::Object RObj; + Poco::JSON::Object RObj; - form.add("To", PhoneNumber); - form.add("From", PhoneNumber_); - form.add("Body", Message); + form.add("To", PhoneNumber); + form.add("From", PhoneNumber_); + form.add("Body", Message); - form.prepareSubmit(req); - std::ostream& ostr = session.sendRequest(req); - form.write(ostr); + form.prepareSubmit(req); + std::ostream &ostr = session.sendRequest(req); + form.write(ostr); - Poco::Net::HTTPResponse res; - std::istream& rs = session.receiveResponse(res); + Poco::Net::HTTPResponse res; + std::istream &rs = session.receiveResponse(res); - if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { - poco_information(Logger(),fmt::format("Message sent to {}", PhoneNumber)); - return true; - } else { - std::ostringstream os; - Poco::StreamCopier::copyStream(rs,os); - poco_information(Logger(),fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str())); - return false; - } - } -} \ No newline at end of file + if (res.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + poco_information(Logger(), fmt::format("Message sent to {}", PhoneNumber)); + return true; + } else { + std::ostringstream os; + Poco::StreamCopier::copyStream(rs, os); + poco_information(Logger(), + fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str())); + return false; + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/SMS_provider_twilio.h b/src/SMS_provider_twilio.h index 00214f9..eadb405 100644 --- a/src/SMS_provider_twilio.h +++ b/src/SMS_provider_twilio.h @@ -8,24 +8,25 @@ #include "SMS_provider.h" namespace OpenWifi { - class SMS_provider_twilio : public SMS_provider { - public: - explicit SMS_provider_twilio(Poco::Logger &L) : Logger_(L) {} - ~SMS_provider_twilio() {}; - bool Initialize() final ; - bool Start() final ; - bool Stop() final ; - bool Send(const std::string &Number, const std::string &Message) final; - bool Running() final; - inline Poco::Logger & Logger() { return Logger_; } - private: - bool Running_=false; - Poco::Logger &Logger_; - std::string Sid_; - std::string Token_; - std::string PhoneNumber_; - std::string Uri_; - }; -} + class SMS_provider_twilio : public SMS_provider { + public: + explicit SMS_provider_twilio(Poco::Logger &L) : Logger_(L) {} + ~SMS_provider_twilio(){}; + bool Initialize() final; + bool Start() final; + bool Stop() final; + bool Send(const std::string &Number, const std::string &Message) final; + bool Running() final; + inline Poco::Logger &Logger() { return Logger_; } -#endif //OWSEC_SMS_PROVIDER_TWILIO_H + private: + bool Running_ = false; + Poco::Logger &Logger_; + std::string Sid_; + std::string Token_; + std::string PhoneNumber_; + std::string Uri_; + }; +} // namespace OpenWifi + +#endif // OWSEC_SMS_PROVIDER_TWILIO_H diff --git a/src/SMTPMailerService.cpp b/src/SMTPMailerService.cpp index 7bc2232..74e6007 100644 --- a/src/SMTPMailerService.cpp +++ b/src/SMTPMailerService.cpp @@ -2,231 +2,239 @@ // Created by stephane bourque on 2021-06-17. // +#include "Poco/Exception.h" +#include "Poco/Net/Context.h" #include "Poco/Net/MailMessage.h" #include "Poco/Net/MailRecipient.h" +#include "Poco/Net/NetException.h" #include "Poco/Net/SMTPClientSession.h" +#include "Poco/Net/SSLManager.h" #include "Poco/Net/SecureSMTPClientSession.h" #include "Poco/Net/StringPartSource.h" -#include "Poco/Exception.h" -#include "Poco/Net/SSLManager.h" -#include "Poco/Net/Context.h" -#include "Poco/Net/NetException.h" -#include "SMTPMailerService.h" #include "AuthService.h" +#include "SMTPMailerService.h" +#include "fmt/format.h" #include "framework/MicroServiceFuncs.h" #include "framework/utils.h" -#include "fmt/format.h" namespace OpenWifi { - void SMTPMailerService::LoadMyConfig() { - Enabled_ = MicroServiceConfigGetBool("mailer.enabled",false); - if(Enabled_) { - MailHost_ = MicroServiceConfigGetString("mailer.hostname",""); - SenderLoginUserName_ = MicroServiceConfigGetString("mailer.username",""); - SenderLoginPassword_ = MicroServiceConfigGetString("mailer.password",""); - Sender_ = MicroServiceConfigGetString("mailer.sender",""); - LoginMethod_ = MicroServiceConfigGetString("mailer.loginmethod",""); - MailHostPort_ = MicroServiceConfigGetInt("mailer.port", 587); - TemplateDir_ = MicroServiceConfigPath("mailer.templates", MicroServiceDataDirectory()); - MailRetry_ = MicroServiceConfigGetInt("mailer.retry",2*60); - MailAbandon_ = MicroServiceConfigGetInt("mailer.abandon",2*60*60); - UseHTML_ = MicroServiceConfigGetBool("mailer.html",false); - Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty()); - LogoFilename = AuthService()->GetLogoAssetURI(); - SubLogoFilename = AuthService()->GetSubLogoAssetURI(); - } - } + void SMTPMailerService::LoadMyConfig() { + Enabled_ = MicroServiceConfigGetBool("mailer.enabled", false); + if (Enabled_) { + MailHost_ = MicroServiceConfigGetString("mailer.hostname", ""); + SenderLoginUserName_ = MicroServiceConfigGetString("mailer.username", ""); + SenderLoginPassword_ = MicroServiceConfigGetString("mailer.password", ""); + Sender_ = MicroServiceConfigGetString("mailer.sender", ""); + LoginMethod_ = MicroServiceConfigGetString("mailer.loginmethod", ""); + MailHostPort_ = MicroServiceConfigGetInt("mailer.port", 587); + TemplateDir_ = MicroServiceConfigPath("mailer.templates", MicroServiceDataDirectory()); + MailRetry_ = MicroServiceConfigGetInt("mailer.retry", 2 * 60); + MailAbandon_ = MicroServiceConfigGetInt("mailer.abandon", 2 * 60 * 60); + UseHTML_ = MicroServiceConfigGetBool("mailer.html", false); + Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && + !SenderLoginUserName_.empty()); + LogoFilename = AuthService()->GetLogoAssetURI(); + SubLogoFilename = AuthService()->GetSubLogoAssetURI(); + } + } - void SMTPMailerService::AddUserVars(MessageAttributes & Attrs) { - Attrs[USER_HELPER_EMAIL] = AuthService()->HelperEmail(); - Attrs[USER_SYSTEM_LOGIN] = AuthService()->SystemLoginSite(); - Attrs[USER_HELPER_SITE] = AuthService()->HelperSite(); - Attrs[GLOBAL_USER_HELPER_EMAIL] = AuthService()->GlobalHelperEmail(); - Attrs[USER_SIGNATURE] = AuthService()->UserSignature(); - } + void SMTPMailerService::AddUserVars(MessageAttributes &Attrs) { + Attrs[USER_HELPER_EMAIL] = AuthService()->HelperEmail(); + Attrs[USER_SYSTEM_LOGIN] = AuthService()->SystemLoginSite(); + Attrs[USER_HELPER_SITE] = AuthService()->HelperSite(); + Attrs[GLOBAL_USER_HELPER_EMAIL] = AuthService()->GlobalHelperEmail(); + Attrs[USER_SIGNATURE] = AuthService()->UserSignature(); + } - void SMTPMailerService::AddSubVars(MessageAttributes & Attrs) { - Attrs[SUB_HELPER_EMAIL] = AuthService()->SubHelperEmail(); - Attrs[SUB_SYSTEM_LOGIN] = AuthService()->SubSystemLoginSite(); - Attrs[SUB_HELPER_SITE] = AuthService()->SubHelperSite(); - Attrs[GLOBAL_SUB_HELPER_EMAIL] = AuthService()->GlobalSubHelperEmail(); - Attrs[SUB_SIGNATURE] = AuthService()->SubSignature(); - } + void SMTPMailerService::AddSubVars(MessageAttributes &Attrs) { + Attrs[SUB_HELPER_EMAIL] = AuthService()->SubHelperEmail(); + Attrs[SUB_SYSTEM_LOGIN] = AuthService()->SubSystemLoginSite(); + Attrs[SUB_HELPER_SITE] = AuthService()->SubHelperSite(); + Attrs[GLOBAL_SUB_HELPER_EMAIL] = AuthService()->GlobalSubHelperEmail(); + Attrs[SUB_SIGNATURE] = AuthService()->SubSignature(); + } - int SMTPMailerService::Start() { - LoadMyConfig(); - SenderThr_.start(*this); - return 0; - } + int SMTPMailerService::Start() { + LoadMyConfig(); + SenderThr_.start(*this); + return 0; + } - void SMTPMailerService::Stop() { - Running_ = false; - SenderThr_.wakeUp(); - SenderThr_.join(); - } + void SMTPMailerService::Stop() { + Running_ = false; + SenderThr_.wakeUp(); + SenderThr_.join(); + } - void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) { - MicroServiceLoadConfigurationFile(); - poco_information(Logger(),"Reinitializing."); - LoadMyConfig(); - } + void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) { + MicroServiceLoadConfigurationFile(); + poco_information(Logger(), "Reinitializing."); + LoadMyConfig(); + } - bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs, bool Subscriber) { - std::lock_guard G(Mutex_); - PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(), - .LastTry=0, - .Sent=0, - .TemplateName=Name, - .Attrs=Attrs, - .Subscriber=Subscriber}); - return true; - } + bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, + const std::string &Name, const MessageAttributes &Attrs, + bool Subscriber) { + std::lock_guard G(Mutex_); + PendingMessages_.push_back(MessageEvent{.Posted = OpenWifi::Now(), + .LastTry = 0, + .Sent = 0, + .TemplateName = Name, + .Attrs = Attrs, + .Subscriber = Subscriber}); + return true; + } - void SMTPMailerService::run() { - Running_ = true; - Utils::SetThreadName("smtp-mailer"); - while(Running_) { + void SMTPMailerService::run() { + Running_ = true; + Utils::SetThreadName("smtp-mailer"); + while (Running_) { - Poco::Thread::trySleep(10000); - if(!Running_) - break; - { - std::lock_guard G(Mutex_); - Messages_.splice(Messages_.end(),PendingMessages_); - } + Poco::Thread::trySleep(10000); + if (!Running_) + break; + { + std::lock_guard G(Mutex_); + Messages_.splice(Messages_.end(), PendingMessages_); + } - for(auto i=Messages_.begin();i!=Messages_.end();) { - if(!Running_) - break; - auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second; - uint64_t now = OpenWifi::Now(); - if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) { - switch(SendIt(*i)) { - case MessageSendStatus::msg_sent: { - poco_information(Logger(),fmt::format("Attempting to deliver for mail '{}'.", Recipient)); - i = Messages_.erase(i); - } break; - case MessageSendStatus::msg_not_sent_but_resend: { - poco_information(Logger(),fmt::format("Mail for '{}' was not. We will retry later.", Recipient)); - i->LastTry = now; - ++i; - } break; - case MessageSendStatus::msg_not_sent_but_do_not_resend: { - poco_information(Logger(),fmt::format("Mail for '{}' will not be sent. Check email address", Recipient)); - i = Messages_.erase(i); - } break; - } - } else if ((now-i->Posted)>MailAbandon_) { - poco_information(Logger(),fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient)); - i = Messages_.erase(i); - } else { - ++i; - } - } - } - } + for (auto i = Messages_.begin(); i != Messages_.end();) { + if (!Running_) + break; + auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second; + uint64_t now = OpenWifi::Now(); + if ((i->LastTry == 0 || (now - i->LastTry) > MailRetry_)) { + switch (SendIt(*i)) { + case MessageSendStatus::msg_sent: { + poco_information( + Logger(), + fmt::format("Attempting to deliver for mail '{}'.", Recipient)); + i = Messages_.erase(i); + } break; + case MessageSendStatus::msg_not_sent_but_resend: { + poco_information( + Logger(), + fmt::format("Mail for '{}' was not. We will retry later.", Recipient)); + i->LastTry = now; + ++i; + } break; + case MessageSendStatus::msg_not_sent_but_do_not_resend: { + poco_information( + Logger(), + fmt::format("Mail for '{}' will not be sent. Check email address", + Recipient)); + i = Messages_.erase(i); + } break; + } + } else if ((now - i->Posted) > MailAbandon_) { + poco_information( + Logger(), fmt::format("Mail for '{}' has timed out and will not be sent.", + Recipient)); + i = Messages_.erase(i); + } else { + ++i; + } + } + } + } - void FillVariables(const MessageAttributes &Attrs, Types::StringPairVec &R) { - for(const auto &[Variable,Value]:Attrs) { - R.push_back(std::make_pair(MessageAttributeToVar(Variable),Value)); - } - } + void FillVariables(const MessageAttributes &Attrs, Types::StringPairVec &R) { + for (const auto &[Variable, Value] : Attrs) { + R.push_back(std::make_pair(MessageAttributeToVar(Variable), Value)); + } + } - MessageSendStatus SMTPMailerService::SendIt(const MessageEvent &Msg) { + MessageSendStatus SMTPMailerService::SendIt(const MessageEvent &Msg) { - std::string Recipient; + std::string Recipient; - try - { - auto H1 = Msg.Attrs.find(SENDER); - std::string TheSender; - if(H1!=Msg.Attrs.end()) { - TheSender = H1->second ; - } else { - TheSender = Sender_ ; - } + try { + auto H1 = Msg.Attrs.find(SENDER); + std::string TheSender; + if (H1 != Msg.Attrs.end()) { + TheSender = H1->second; + } else { + TheSender = Sender_; + } - auto Message = std::make_unique(); + auto Message = std::make_unique(); - Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second; - Message->setSender( TheSender ); - Message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient)); - Message->setSubject(Msg.Attrs.find(SUBJECT)->second); - Message->setContentType("multipart/alternative"); + Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second; + Message->setSender(TheSender); + Message->addRecipient( + Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient)); + Message->setSubject(Msg.Attrs.find(SUBJECT)->second); + Message->setContentType("multipart/alternative"); - poco_information(Logger(),fmt::format("Sending message to:{} from {}",Recipient,TheSender)); + poco_information(Logger(), + fmt::format("Sending message to:{} from {}", Recipient, TheSender)); - if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) { - std::string Content = Msg.Attrs.find(TEXT)->second; - Message->addContent(new Poco::Net::StringPartSource(Content)); - } else { - for(const auto &format:{"txt","html"}) { - std::string Content = Utils::LoadFile(TemplateDir_ + Msg.TemplateName + "." + format ); - Types::StringPairVec Variables; - FillVariables(Msg.Attrs, Variables); - Utils::ReplaceVariables(Content, Variables); - Message->addContent( - new Poco::Net::StringPartSource(Content, (strcmp(format,"html") == 0 ? "text/html" : "text/plain") )); - } - } + if (Msg.Attrs.find(TEXT) != Msg.Attrs.end()) { + std::string Content = Msg.Attrs.find(TEXT)->second; + Message->addContent(new Poco::Net::StringPartSource(Content)); + } else { + for (const auto &format : {"txt", "html"}) { + std::string Content = + Utils::LoadFile(TemplateDir_ + Msg.TemplateName + "." + format); + Types::StringPairVec Variables; + FillVariables(Msg.Attrs, Variables); + Utils::ReplaceVariables(Content, Variables); + Message->addContent(new Poco::Net::StringPartSource( + Content, (strcmp(format, "html") == 0 ? "text/html" : "text/plain"))); + } + } - /* - auto Logo = Msg.Attrs.find(LOGO); - if(Logo!=Msg.Attrs.end()) { - std::cout << "... >" << Logo->second << std::endl; - try { - Poco::File LogoFile( Msg.Subscriber ? AuthService::GetSubLogoAssetFileName() : AuthService::GetLogoAssetFileName ()); - std::ifstream IF(LogoFile.path()); - std::ostringstream OS; - Poco::StreamCopier::copyStream(IF, OS); - Message->addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png")); - } catch (...) { - poco_warning(Logger(),fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName())); - } - } - */ + /* + auto Logo = Msg.Attrs.find(LOGO); + if(Logo!=Msg.Attrs.end()) { + std::cout << "... >" << Logo->second << std::endl; + try { + Poco::File LogoFile( Msg.Subscriber ? + AuthService::GetSubLogoAssetFileName() : AuthService::GetLogoAssetFileName ()); + std::ifstream IF(LogoFile.path()); + std::ostringstream OS; + Poco::StreamCopier::copyStream(IF, OS); + Message->addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), + "image/png")); } catch (...) { poco_warning(Logger(),fmt::format("Cannot add '{}' logo + in email",AuthService::GetLogoAssetFileName())); + } + } + */ - Poco::SharedPtr ptrHandler_ = new Poco::Net::AcceptCertificateHandler(false); + Poco::SharedPtr ptrHandler_ = + new Poco::Net::AcceptCertificateHandler(false); - Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_); - auto ptrContext = Poco::AutoPtr - (new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "", - Poco::Net::Context::VERIFY_RELAXED, 9, true, - "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH")); - Poco::Net::SSLManager::instance().initializeClient(nullptr, - ptrHandler_, - ptrContext); - session.login(); - session.startTLS(ptrContext); - session.login(MailHost_, - Poco::Net::SecureSMTPClientSession::AUTH_LOGIN, - SenderLoginUserName_, - SenderLoginPassword_ - ); -/* std::ofstream of(MicroServiceDataDirectory()+"/message.txt",std::ios_base::out|std::ios_base::trunc); - Message->write(of); - of.close(); -*/ - session.sendMessage(*Message); - session.close(); - return MessageSendStatus::msg_sent; - } - catch (const Poco::Net::SMTPException &S) { - Logger().log(S); - return MessageSendStatus::msg_not_sent_but_do_not_resend; - } - catch (const Poco::Exception& E) - { - Logger().log(E); - return MessageSendStatus::msg_not_sent_but_resend; - } - catch (const std::exception &E) { - poco_warning(Logger(),fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what())); - return MessageSendStatus::msg_not_sent_but_do_not_resend; - } - } + Poco::Net::SecureSMTPClientSession session(MailHost_, MailHostPort_); + auto ptrContext = Poco::AutoPtr(new Poco::Net::Context( + Poco::Net::Context::CLIENT_USE, "", "", "", Poco::Net::Context::VERIFY_RELAXED, 9, + true, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH")); + Poco::Net::SSLManager::instance().initializeClient(nullptr, ptrHandler_, ptrContext); + session.login(); + session.startTLS(ptrContext); + session.login(MailHost_, Poco::Net::SecureSMTPClientSession::AUTH_LOGIN, + SenderLoginUserName_, SenderLoginPassword_); + /* std::ofstream + of(MicroServiceDataDirectory()+"/message.txt",std::ios_base::out|std::ios_base::trunc); + Message->write(of); + of.close(); + */ + session.sendMessage(*Message); + session.close(); + return MessageSendStatus::msg_sent; + } catch (const Poco::Net::SMTPException &S) { + Logger().log(S); + return MessageSendStatus::msg_not_sent_but_do_not_resend; + } catch (const Poco::Exception &E) { + Logger().log(E); + return MessageSendStatus::msg_not_sent_but_resend; + } catch (const std::exception &E) { + poco_warning(Logger(), + fmt::format("Cannot send message to:{}, error: {}", Recipient, E.what())); + return MessageSendStatus::msg_not_sent_but_do_not_resend; + } + } -} +} // namespace OpenWifi diff --git a/src/SMTPMailerService.h b/src/SMTPMailerService.h index a88ddb9..3004770 100644 --- a/src/SMTPMailerService.h +++ b/src/SMTPMailerService.h @@ -5,155 +5,150 @@ #pragma once #include "Poco/File.h" -#include "Poco/Net/InvalidCertificateHandler.h" #include "Poco/Net/AcceptCertificateHandler.h" +#include "Poco/Net/InvalidCertificateHandler.h" #include "framework/SubSystemServer.h" namespace OpenWifi { - enum MESSAGE_ATTRIBUTES { - RECIPIENT_EMAIL, - RECIPIENT_FIRST_NAME, - RECIPIENT_LAST_NAME, - RECIPIENT_INITIALS, - RECIPIENT_FULL_NAME, - RECIPIENT_SALUTATION, - ACTION_LINK, - SUBJECT, - TEMPLATE_TXT, - TEMPLATE_HTML, - LOGO, - TEXT, - CHALLENGE_CODE, - SENDER, - ACTION_LINK_HTML, - USER_HELPER_EMAIL, - SUB_HELPER_EMAIL, - GLOBAL_USER_HELPER_EMAIL, - GLOBAL_SUB_HELPER_EMAIL, - USER_HELPER_SITE, - SUB_HELPER_SITE, - USER_SYSTEM_LOGIN, - SUB_SYSTEM_LOGIN, - USER_SIGNATURE, - SUB_SIGNATURE, - TRANSFER_REQUESTER, - TRANSFER_ENTITY, - ORIGINAL_REDIRECTOR, - NEW_REDIRECTOR, - TRANSFER_REASON, - SERIAL_NUMBER, - ORIGINAL_ENTITY_NAME, - UUID - }; + enum MESSAGE_ATTRIBUTES { + RECIPIENT_EMAIL, + RECIPIENT_FIRST_NAME, + RECIPIENT_LAST_NAME, + RECIPIENT_INITIALS, + RECIPIENT_FULL_NAME, + RECIPIENT_SALUTATION, + ACTION_LINK, + SUBJECT, + TEMPLATE_TXT, + TEMPLATE_HTML, + LOGO, + TEXT, + CHALLENGE_CODE, + SENDER, + ACTION_LINK_HTML, + USER_HELPER_EMAIL, + SUB_HELPER_EMAIL, + GLOBAL_USER_HELPER_EMAIL, + GLOBAL_SUB_HELPER_EMAIL, + USER_HELPER_SITE, + SUB_HELPER_SITE, + USER_SYSTEM_LOGIN, + SUB_SYSTEM_LOGIN, + USER_SIGNATURE, + SUB_SIGNATURE, + TRANSFER_REQUESTER, + TRANSFER_ENTITY, + ORIGINAL_REDIRECTOR, + NEW_REDIRECTOR, + TRANSFER_REASON, + SERIAL_NUMBER, + ORIGINAL_ENTITY_NAME, + UUID + }; - static const std::map - MessageAttributeMap{ - { RECIPIENT_EMAIL,"RECIPIENT_EMAIL"}, - { RECIPIENT_FIRST_NAME, "RECIPIENT_FIRST_NAME"}, - { RECIPIENT_LAST_NAME, "RECIPIENT_LAST_NAME"}, - { RECIPIENT_INITIALS, "RECIPIENT_INITIALS"}, - { RECIPIENT_FULL_NAME, "RECIPIENT_FULL_NAME"}, - { RECIPIENT_SALUTATION, "RECIPIENT_SALUTATION"}, - { ACTION_LINK, "ACTION_LINK"}, - { SUBJECT, "SUBJECT"}, - { TEMPLATE_TXT, "TEMPLATE_TXT"}, - { TEMPLATE_HTML, "TEMPLATE_HTML"}, - { LOGO, "LOGO"}, - { TEXT, "TEXT"}, - { CHALLENGE_CODE, "CHALLENGE_CODE"}, - { SENDER, "SENDER"}, - { ACTION_LINK_HTML, "SUB_SYSTEM_LOGIN"}, - { USER_HELPER_EMAIL, "USER_HELPER_EMAIL"}, - { SUB_HELPER_EMAIL, "SUB_HELPER_EMAIL"}, - { GLOBAL_USER_HELPER_EMAIL, "GLOBAL_USER_HELPER_EMAIL"}, - { GLOBAL_SUB_HELPER_EMAIL, "GLOBAL_SUB_HELPER_EMAIL"}, - { USER_HELPER_SITE, "USER_HELPER_SITE"}, - { SUB_HELPER_SITE, "SUB_USER_HELPER_SITE"}, - { USER_SYSTEM_LOGIN, "USER_SYSTEM_LOGIN"}, - { SUB_SYSTEM_LOGIN, "SUB_SYSTEM_LOGIN"}, - { USER_SIGNATURE, "USER_SIGNATURE" }, - { SUB_SIGNATURE, "SUB_USER_SIGNATURE"}, - { TRANSFER_REQUESTER, "TRANSFER_REQUESTER" }, - { TRANSFER_ENTITY, "TRANSFER_ENTITY"}, - { ORIGINAL_REDIRECTOR, "ORIGINAL_REDIRECTOR"}, - { NEW_REDIRECTOR, "NEW_REDIRECTOR" }, - { TRANSFER_REASON, "TRANSFER_REASON"}, - { SERIAL_NUMBER, "SERIAL_NUMBER"}, - { ORIGINAL_ENTITY_NAME, "ORIGINAL_ENTITY_NAME"}, - { UUID, "UUID" } - }; + static const std::map MessageAttributeMap{ + {RECIPIENT_EMAIL, "RECIPIENT_EMAIL"}, + {RECIPIENT_FIRST_NAME, "RECIPIENT_FIRST_NAME"}, + {RECIPIENT_LAST_NAME, "RECIPIENT_LAST_NAME"}, + {RECIPIENT_INITIALS, "RECIPIENT_INITIALS"}, + {RECIPIENT_FULL_NAME, "RECIPIENT_FULL_NAME"}, + {RECIPIENT_SALUTATION, "RECIPIENT_SALUTATION"}, + {ACTION_LINK, "ACTION_LINK"}, + {SUBJECT, "SUBJECT"}, + {TEMPLATE_TXT, "TEMPLATE_TXT"}, + {TEMPLATE_HTML, "TEMPLATE_HTML"}, + {LOGO, "LOGO"}, + {TEXT, "TEXT"}, + {CHALLENGE_CODE, "CHALLENGE_CODE"}, + {SENDER, "SENDER"}, + {ACTION_LINK_HTML, "SUB_SYSTEM_LOGIN"}, + {USER_HELPER_EMAIL, "USER_HELPER_EMAIL"}, + {SUB_HELPER_EMAIL, "SUB_HELPER_EMAIL"}, + {GLOBAL_USER_HELPER_EMAIL, "GLOBAL_USER_HELPER_EMAIL"}, + {GLOBAL_SUB_HELPER_EMAIL, "GLOBAL_SUB_HELPER_EMAIL"}, + {USER_HELPER_SITE, "USER_HELPER_SITE"}, + {SUB_HELPER_SITE, "SUB_USER_HELPER_SITE"}, + {USER_SYSTEM_LOGIN, "USER_SYSTEM_LOGIN"}, + {SUB_SYSTEM_LOGIN, "SUB_SYSTEM_LOGIN"}, + {USER_SIGNATURE, "USER_SIGNATURE"}, + {SUB_SIGNATURE, "SUB_USER_SIGNATURE"}, + {TRANSFER_REQUESTER, "TRANSFER_REQUESTER"}, + {TRANSFER_ENTITY, "TRANSFER_ENTITY"}, + {ORIGINAL_REDIRECTOR, "ORIGINAL_REDIRECTOR"}, + {NEW_REDIRECTOR, "NEW_REDIRECTOR"}, + {TRANSFER_REASON, "TRANSFER_REASON"}, + {SERIAL_NUMBER, "SERIAL_NUMBER"}, + {ORIGINAL_ENTITY_NAME, "ORIGINAL_ENTITY_NAME"}, + {UUID, "UUID"}}; - inline const std::string & MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) { - static const std::string EmptyString{}; - auto E = MessageAttributeMap.find(Attr); - if(E == MessageAttributeMap.end()) - return EmptyString; - return E->second; - } - typedef std::map MessageAttributes; + inline const std::string &MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) { + static const std::string EmptyString{}; + auto E = MessageAttributeMap.find(Attr); + if (E == MessageAttributeMap.end()) + return EmptyString; + return E->second; + } + typedef std::map MessageAttributes; - enum class MessageSendStatus { - msg_sent, - msg_not_sent_but_resend, - msg_not_sent_but_do_not_resend - }; + enum class MessageSendStatus { + msg_sent, + msg_not_sent_but_resend, + msg_not_sent_but_do_not_resend + }; - class SMTPMailerService : public SubSystemServer, Poco::Runnable { - public: - static SMTPMailerService *instance() { - static auto * instance_ = new SMTPMailerService; - return instance_; - } + class SMTPMailerService : public SubSystemServer, Poco::Runnable { + public: + static SMTPMailerService *instance() { + static auto *instance_ = new SMTPMailerService; + return instance_; + } - struct MessageEvent { - uint64_t Posted=0; - uint64_t LastTry=0; - uint64_t Sent=0; - std::string TemplateName; - MessageAttributes Attrs; - bool Subscriber=false; - }; + struct MessageEvent { + uint64_t Posted = 0; + uint64_t LastTry = 0; + uint64_t Sent = 0; + std::string TemplateName; + MessageAttributes Attrs; + bool Subscriber = false; + }; - void run() override; - int Start() override; - void Stop() override; + void run() override; + int Start() override; + void Stop() override; - bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs, bool Subscriber); - MessageSendStatus SendIt(const MessageEvent &Msg); - void LoadMyConfig(); - void reinitialize(Poco::Util::Application &self) override; - bool Enabled() const { return Enabled_; } + bool SendMessage(const std::string &Recipient, const std::string &Name, + const MessageAttributes &Attrs, bool Subscriber); + MessageSendStatus SendIt(const MessageEvent &Msg); + void LoadMyConfig(); + void reinitialize(Poco::Util::Application &self) override; + bool Enabled() const { return Enabled_; } - void AddUserVars(MessageAttributes & Attrs); - void AddSubVars(MessageAttributes & Attrs); + void AddUserVars(MessageAttributes &Attrs); + void AddSubVars(MessageAttributes &Attrs); - private: - std::string MailHost_; - std::string Sender_; - uint32_t MailHostPort_=25; - uint64_t MailRetry_=2*60; - uint64_t MailAbandon_=2*60*20; - std::string SenderLoginUserName_; - std::string SenderLoginPassword_; - std::string LoginMethod_ = "login"; - std::string TemplateDir_; - std::list Messages_; - std::list PendingMessages_; - Poco::Thread SenderThr_; - std::atomic_bool Running_=false; - bool Enabled_=false; - bool UseHTML_=false; - std::string LogoFilename; - std::string SubLogoFilename; + private: + std::string MailHost_; + std::string Sender_; + uint32_t MailHostPort_ = 25; + uint64_t MailRetry_ = 2 * 60; + uint64_t MailAbandon_ = 2 * 60 * 20; + std::string SenderLoginUserName_; + std::string SenderLoginPassword_; + std::string LoginMethod_ = "login"; + std::string TemplateDir_; + std::list Messages_; + std::list PendingMessages_; + Poco::Thread SenderThr_; + std::atomic_bool Running_ = false; + bool Enabled_ = false; + bool UseHTML_ = false; + std::string LogoFilename; + std::string SubLogoFilename; - SMTPMailerService() noexcept: - SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer") - { - } - }; - - inline SMTPMailerService * SMTPMailerService() { return SMTPMailerService::instance(); } -} + SMTPMailerService() noexcept : SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer") {} + }; + inline SMTPMailerService *SMTPMailerService() { return SMTPMailerService::instance(); } +} // namespace OpenWifi diff --git a/src/SecretStore.cpp b/src/SecretStore.cpp index 64b009a..373f1d4 100644 --- a/src/SecretStore.cpp +++ b/src/SecretStore.cpp @@ -2,91 +2,92 @@ // Created by stephane bourque on 2023-01-25. // -#include #include "SecretStore.h" -#include #include #include +#include +#include namespace OpenWifi { - int SecretStore::Start() { - std::lock_guard G(Mutex_); - ReadStore(); - return 0; - } + int SecretStore::Start() { + std::lock_guard G(Mutex_); + ReadStore(); + return 0; + } - void SecretStore::Stop() { - std::lock_guard G(Mutex_); - SaveStore(); - } + void SecretStore::Stop() { + std::lock_guard G(Mutex_); + SaveStore(); + } - void SecretStore::ReadStore() { - Poco::File StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); - if(StoreFileName.exists() && StoreFileName.isFile()) { - try { - std::ostringstream OS; - std::ifstream IF(StoreFileName.path().c_str()); - Poco::StreamCopier::copyStream(IF, OS); - Poco::JSON::Parser P; - auto Doc = P.parse(OS.str()).extract(); - if(Doc->isArray("secrets")) { - auto Secrets = Doc->getArray("secrets"); - for(const auto &secret:*Secrets) { - const auto &entry = secret.extract(); - if(entry->has("key") && entry->has("value")) { - Store_[entry->get("key")] = entry->get("value").toString(); - } - } - } - } catch (const Poco::Exception &E) { - Logger().log(E); - } - } - } + void SecretStore::ReadStore() { + Poco::File StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); + if (StoreFileName.exists() && StoreFileName.isFile()) { + try { + std::ostringstream OS; + std::ifstream IF(StoreFileName.path().c_str()); + Poco::StreamCopier::copyStream(IF, OS); + Poco::JSON::Parser P; + auto Doc = P.parse(OS.str()).extract(); + if (Doc->isArray("secrets")) { + auto Secrets = Doc->getArray("secrets"); + for (const auto &secret : *Secrets) { + const auto &entry = secret.extract(); + if (entry->has("key") && entry->has("value")) { + Store_[entry->get("key")] = entry->get("value").toString(); + } + } + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } + } + } - void SecretStore::SaveStore() { - Poco::JSON::Object StoreJSON; - Poco::JSON::Array Secrets; + void SecretStore::SaveStore() { + Poco::JSON::Object StoreJSON; + Poco::JSON::Array Secrets; - for(const auto &[key,value]:Store_) { - Poco::JSON::Object Entry; - Entry.set("key", key); - Entry.set("value", value); - Secrets.add(Entry); - } + for (const auto &[key, value] : Store_) { + Poco::JSON::Object Entry; + Entry.set("key", key); + Entry.set("value", value); + Secrets.add(Entry); + } - StoreJSON.set("secrets",Secrets); - Poco::File StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); - std::ofstream OF(StoreFileName.path(),std::ios_base::trunc); - StoreJSON.stringify(OF); - } + StoreJSON.set("secrets", Secrets); + Poco::File StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); + std::ofstream OF(StoreFileName.path(), std::ios_base::trunc); + StoreJSON.stringify(OF); + } - bool SecretStore::Get(const std::string & key, std::string & value, const std::string & default_value) { - std::lock_guard G(Mutex_); + bool SecretStore::Get(const std::string &key, std::string &value, + const std::string &default_value) { + std::lock_guard G(Mutex_); - auto It = Store_.find(key); - if(It!=end(Store_)) { - value = It->second; - return true; - } else { - value = default_value; - return false; - } - } + auto It = Store_.find(key); + if (It != end(Store_)) { + value = It->second; + return true; + } else { + value = default_value; + return false; + } + } - void SecretStore::Set(const std::string & key, const std::string & value ) { - std::lock_guard G(Mutex_); + void SecretStore::Set(const std::string &key, const std::string &value) { + std::lock_guard G(Mutex_); - Store_[key] = value; - SaveStore(); - } + Store_[key] = value; + SaveStore(); + } - void SecretStore::Remove(const std::string & key) { - std::lock_guard G(Mutex_); + void SecretStore::Remove(const std::string &key) { + std::lock_guard G(Mutex_); - Store_.erase(key); - SaveStore(); - } + Store_.erase(key); + SaveStore(); + } -} // OpenWifi \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/SecretStore.h b/src/SecretStore.h index b605d52..7611507 100644 --- a/src/SecretStore.h +++ b/src/SecretStore.h @@ -8,34 +8,30 @@ namespace OpenWifi { - class SecretStore : public SubSystemServer { - public: + class SecretStore : public SubSystemServer { + public: + using SecretStoreType = std::map; + static SecretStore *instance() { + static auto *instance_ = new SecretStore; + return instance_; + } - using SecretStoreType = std::map; - static SecretStore *instance() { - static auto *instance_ = new SecretStore; - return instance_; - } + int Start() final; + void Stop() final; + void ReadStore(); + void SaveStore(); + bool Get(const std::string &key, std::string &value, const std::string &default_value); + void Set(const std::string &key, const std::string &value); + void Remove(const std::string &key); + inline SecretStoreType Store() { + std::lock_guard G(Mutex_); + return Store_; + } - int Start() final; - void Stop() final; - void ReadStore(); - void SaveStore(); - bool Get(const std::string & key, std::string & value, const std::string & default_value); - void Set(const std::string & key, const std::string & value ); - void Remove(const std::string &key); - inline SecretStoreType Store() { - std::lock_guard G(Mutex_); - return Store_; - } + private: + SecretStoreType Store_; + SecretStore() noexcept : SubSystemServer("SecretStore", "SECRET-SVR", "secret.store") {} + }; + inline SecretStore *SecretStore() { return SecretStore::instance(); } - private: - SecretStoreType Store_; - SecretStore() noexcept: - SubSystemServer("SecretStore", "SECRET-SVR", "secret.store") - { - } - }; - inline SecretStore * SecretStore() { return SecretStore::instance(); } - -} // OpenWifi +} // namespace OpenWifi diff --git a/src/SpecialUserHelpers.h b/src/SpecialUserHelpers.h index 82c612c..d7b01ac 100644 --- a/src/SpecialUserHelpers.h +++ b/src/SpecialUserHelpers.h @@ -10,30 +10,32 @@ namespace OpenWifi { - namespace SpecialUserHelpers { - static inline std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"}; + namespace SpecialUserHelpers { + static inline std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"}; - inline bool InitializeDefaultUser() { - SecurityObjects::UserInfo U; - bool DefaultUserCreated = false; + inline bool InitializeDefaultUser() { + SecurityObjects::UserInfo U; + bool DefaultUserCreated = false; - AppServiceRegistry().Get("defaultusercreated", DefaultUserCreated); - if (!StorageService()->UserDB().GetUserById(NewDefaultUseridStockUUID, U) && !DefaultUserCreated) { - U.currentPassword = MicroServiceConfigGetString("authentication.default.password", ""); - U.lastPasswords.push_back(U.currentPassword); - U.email = MicroServiceConfigGetString("authentication.default.username", ""); - U.id = NewDefaultUseridStockUUID; - U.userRole = SecurityObjects::ROOT; - U.creationDate = OpenWifi::Now(); - U.validated = true; - U.name = "Default User"; - U.description = "Default user should be deleted."; - U.changePassword = true; - StorageService()->UserDB().CreateUser("SYSTEM", U, true); - AppServiceRegistry().Set("defaultusercreated", true); - return true; - } - return false; - } - } -} \ No newline at end of file + AppServiceRegistry().Get("defaultusercreated", DefaultUserCreated); + if (!StorageService()->UserDB().GetUserById(NewDefaultUseridStockUUID, U) && + !DefaultUserCreated) { + U.currentPassword = + MicroServiceConfigGetString("authentication.default.password", ""); + U.lastPasswords.push_back(U.currentPassword); + U.email = MicroServiceConfigGetString("authentication.default.username", ""); + U.id = NewDefaultUseridStockUUID; + U.userRole = SecurityObjects::ROOT; + U.creationDate = OpenWifi::Now(); + U.validated = true; + U.name = "Default User"; + U.description = "Default user should be deleted."; + U.changePassword = true; + StorageService()->UserDB().CreateUser("SYSTEM", U, true); + AppServiceRegistry().Set("defaultusercreated", true); + return true; + } + return false; + } + } // namespace SpecialUserHelpers +} // namespace OpenWifi \ No newline at end of file diff --git a/src/StorageService.cpp b/src/StorageService.cpp index 854ca80..947dc27 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -13,72 +13,84 @@ namespace OpenWifi { - int StorageService::Start() { - std::lock_guard Guard(Mutex_); - poco_information(Logger(),"Starting..."); + int StorageService::Start() { + std::lock_guard Guard(Mutex_); + poco_information(Logger(), "Starting..."); StorageClass::Start(); - UserCache_ = std::make_unique(64,1200000,true); - SubCache_ = std::make_unique(2048,1200000,false); - UserTokenCache_ = std::make_unique(64,1200000, true); - SubTokenCache_ = std::make_unique(2048,1200000,false); + UserCache_ = std::make_unique(64, 1200000, true); + SubCache_ = std::make_unique(2048, 1200000, false); + UserTokenCache_ = std::make_unique(64, 1200000, true); + SubTokenCache_ = std::make_unique(2048, 1200000, false); - UserDB_ = std::make_unique("Users", "usr", dbType_,*Pool_, Logger(), UserCache_.get(), true); - SubDB_ = std::make_unique("Subscribers", "sub", dbType_,*Pool_, Logger(), SubCache_.get(), false); - UserTokenDB_ = std::make_unique("Tokens", "tok", dbType_,*Pool_, Logger(), UserTokenCache_.get(), true); - SubTokenDB_ = std::make_unique("SubTokens", "stk", dbType_,*Pool_, Logger(), SubTokenCache_.get(), false); + UserDB_ = std::make_unique("Users", "usr", dbType_, *Pool_, Logger(), + UserCache_.get(), true); + SubDB_ = std::make_unique("Subscribers", "sub", dbType_, *Pool_, + Logger(), SubCache_.get(), false); + UserTokenDB_ = std::make_unique( + "Tokens", "tok", dbType_, *Pool_, Logger(), UserTokenCache_.get(), true); + SubTokenDB_ = std::make_unique( + "SubTokens", "stk", dbType_, *Pool_, Logger(), SubTokenCache_.get(), false); - PreferencesDB_ = std::make_unique("Preferences", "pre", dbType_,*Pool_, Logger()); - SubPreferencesDB_ = std::make_unique("SubPreferences", "prs", dbType_,*Pool_, Logger()); - ActionLinksDB_ = std::make_unique("Actions", "act", dbType_,*Pool_, Logger()); - AvatarDB_ = std::make_unique("Avatars2", "ava", dbType_,*Pool_, Logger()); - SubAvatarDB_ = std::make_unique("SubAvatars", "avs", dbType_,*Pool_, Logger()); - LoginDB_ = std::make_unique("Logins", "lin", dbType_,*Pool_, Logger()); - SubLoginDB_ = std::make_unique("SubLogins", "lis", dbType_,*Pool_, Logger()); - ApiKeyDB_ = std::make_unique("ApiKeys", "api", dbType_,*Pool_, Logger()); + PreferencesDB_ = std::make_unique("Preferences", "pre", dbType_, + *Pool_, Logger()); + SubPreferencesDB_ = std::make_unique("SubPreferences", "prs", + dbType_, *Pool_, Logger()); + ActionLinksDB_ = + std::make_unique("Actions", "act", dbType_, *Pool_, Logger()); + AvatarDB_ = + std::make_unique("Avatars2", "ava", dbType_, *Pool_, Logger()); + SubAvatarDB_ = + std::make_unique("SubAvatars", "avs", dbType_, *Pool_, Logger()); + LoginDB_ = std::make_unique("Logins", "lin", dbType_, *Pool_, Logger()); + SubLoginDB_ = + std::make_unique("SubLogins", "lis", dbType_, *Pool_, Logger()); + ApiKeyDB_ = + std::make_unique("ApiKeys", "api", dbType_, *Pool_, Logger()); - UserDB_->Create(); - SubDB_->Create(); - UserTokenDB_->Create(); - SubTokenDB_->Create(); - ActionLinksDB_->Create(); - PreferencesDB_->Create(); - SubPreferencesDB_->Create(); - AvatarDB_->Create(); - SubAvatarDB_->Create(); - LoginDB_->Create(); - ApiKeyDB_->Create(); - SubLoginDB_->Create(); + UserDB_->Create(); + SubDB_->Create(); + UserTokenDB_->Create(); + SubTokenDB_->Create(); + ActionLinksDB_->Create(); + PreferencesDB_->Create(); + SubPreferencesDB_->Create(); + AvatarDB_->Create(); + SubAvatarDB_->Create(); + LoginDB_->Create(); + ApiKeyDB_->Create(); + SubLoginDB_->Create(); OpenWifi::SpecialUserHelpers::InitializeDefaultUser(); - Archivercallback_ = std::make_unique>(Archiver_,&Archiver::onTimer); - Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes + Archivercallback_ = + std::make_unique>(Archiver_, &Archiver::onTimer); + Timer_.setStartInterval(5 * 60 * 1000); // first run in 5 minutes Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours Timer_.start(*Archivercallback_, MicroServiceTimerPool()); return 0; - } + } - void StorageService::Stop() { - poco_information(Logger(),"Stopping..."); - Timer_.stop(); - StorageClass::Stop(); - poco_information(Logger(),"Stopped..."); - } + void StorageService::Stop() { + poco_information(Logger(), "Stopping..."); + Timer_.stop(); + StorageClass::Stop(); + poco_information(Logger(), "Stopped..."); + } - void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) { - Utils::SetThreadName("strg-arch"); - Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER"); - logger.information("Squiggy the DB: removing old tokens."); - StorageService()->SubTokenDB().CleanExpiredTokens(); - StorageService()->UserTokenDB().CleanExpiredTokens(); - logger.information("Squiggy the DB: removing old actionLinks."); - StorageService()->ActionLinksDB().CleanOldActionLinks(); - logger.information("Squiggy the DB: removing old expired API Keys."); - StorageService()->ActionLinksDB().CleanOldActionLinks(); - } + void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) { + Utils::SetThreadName("strg-arch"); + Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER"); + logger.information("Squiggy the DB: removing old tokens."); + StorageService()->SubTokenDB().CleanExpiredTokens(); + StorageService()->UserTokenDB().CleanExpiredTokens(); + logger.information("Squiggy the DB: removing old actionLinks."); + StorageService()->ActionLinksDB().CleanOldActionLinks(); + logger.information("Squiggy the DB: removing old expired API Keys."); + StorageService()->ActionLinksDB().CleanOldActionLinks(); + } -} -// namespace \ No newline at end of file +} // namespace OpenWifi + // namespace \ No newline at end of file diff --git a/src/StorageService.h b/src/StorageService.h index e37ebd2..aa90619 100644 --- a/src/StorageService.h +++ b/src/StorageService.h @@ -8,77 +8,76 @@ #pragma once +#include "AuthService.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" #include "framework/StorageClass.h" -#include "AuthService.h" #include "Poco/Timer.h" -#include "storage/orm_users.h" -#include "storage/orm_tokens.h" -#include "storage/orm_preferences.h" #include "storage/orm_actionLinks.h" +#include "storage/orm_apikeys.h" #include "storage/orm_avatar.h" #include "storage/orm_logins.h" -#include "storage/orm_apikeys.h" +#include "storage/orm_preferences.h" +#include "storage/orm_tokens.h" +#include "storage/orm_users.h" namespace OpenWifi { - class Archiver { - public: - void onTimer(Poco::Timer & timer); - private: - }; - - class StorageService : public StorageClass { - public: - - static auto instance() { - static auto instance_ = new StorageService; - return instance_; - } - - int Start() override; - void Stop() override; - - OpenWifi::BaseUserDB & UserDB() { return *UserDB_; } - OpenWifi::BaseUserDB & SubDB() { return *SubDB_; } - OpenWifi::BaseTokenDB & UserTokenDB() { return *UserTokenDB_; } - OpenWifi::BaseTokenDB & SubTokenDB() { return *SubTokenDB_; } - OpenWifi::PreferencesDB & PreferencesDB() { return *PreferencesDB_; } - OpenWifi::PreferencesDB & SubPreferencesDB() { return *SubPreferencesDB_; } - OpenWifi::ActionLinkDB & ActionLinksDB() { return *ActionLinksDB_; } - OpenWifi::AvatarDB & AvatarDB() { return *AvatarDB_; } - OpenWifi::AvatarDB & SubAvatarDB() { return *SubAvatarDB_; } - OpenWifi::LoginDB & LoginDB() { return *LoginDB_; } - OpenWifi::LoginDB & SubLoginDB() { return *SubLoginDB_; } - OpenWifi::ApiKeyDB & ApiKeyDB() { return *ApiKeyDB_; } + class Archiver { + public: + void onTimer(Poco::Timer &timer); private: + }; - std::unique_ptr UserDB_; - std::unique_ptr SubDB_; - std::unique_ptr UserTokenDB_; - std::unique_ptr SubTokenDB_; - std::unique_ptr PreferencesDB_; - std::unique_ptr SubPreferencesDB_; - std::unique_ptr ActionLinksDB_; - std::unique_ptr AvatarDB_; - std::unique_ptr SubAvatarDB_; - std::unique_ptr LoginDB_; - std::unique_ptr SubLoginDB_; - std::unique_ptr ApiKeyDB_; + class StorageService : public StorageClass { + public: + static auto instance() { + static auto instance_ = new StorageService; + return instance_; + } - std::unique_ptr UserCache_; - std::unique_ptr SubCache_; - std::unique_ptr UserTokenCache_; - std::unique_ptr SubTokenCache_; + int Start() override; + void Stop() override; - Poco::Timer Timer_; - Archiver Archiver_; - std::unique_ptr> Archivercallback_; - }; + OpenWifi::BaseUserDB &UserDB() { return *UserDB_; } + OpenWifi::BaseUserDB &SubDB() { return *SubDB_; } + OpenWifi::BaseTokenDB &UserTokenDB() { return *UserTokenDB_; } + OpenWifi::BaseTokenDB &SubTokenDB() { return *SubTokenDB_; } + OpenWifi::PreferencesDB &PreferencesDB() { return *PreferencesDB_; } + OpenWifi::PreferencesDB &SubPreferencesDB() { return *SubPreferencesDB_; } + OpenWifi::ActionLinkDB &ActionLinksDB() { return *ActionLinksDB_; } + OpenWifi::AvatarDB &AvatarDB() { return *AvatarDB_; } + OpenWifi::AvatarDB &SubAvatarDB() { return *SubAvatarDB_; } + OpenWifi::LoginDB &LoginDB() { return *LoginDB_; } + OpenWifi::LoginDB &SubLoginDB() { return *SubLoginDB_; } + OpenWifi::ApiKeyDB &ApiKeyDB() { return *ApiKeyDB_; } - inline auto StorageService() { return StorageService::instance(); }; + private: + std::unique_ptr UserDB_; + std::unique_ptr SubDB_; + std::unique_ptr UserTokenDB_; + std::unique_ptr SubTokenDB_; + std::unique_ptr PreferencesDB_; + std::unique_ptr SubPreferencesDB_; + std::unique_ptr ActionLinksDB_; + std::unique_ptr AvatarDB_; + std::unique_ptr SubAvatarDB_; + std::unique_ptr LoginDB_; + std::unique_ptr SubLoginDB_; + std::unique_ptr ApiKeyDB_; -} // namespace + std::unique_ptr UserCache_; + std::unique_ptr SubCache_; + std::unique_ptr UserTokenCache_; + std::unique_ptr SubTokenCache_; + + Poco::Timer Timer_; + Archiver Archiver_; + std::unique_ptr> Archivercallback_; + }; + + inline auto StorageService() { return StorageService::instance(); }; + +} // namespace OpenWifi diff --git a/src/TotpCache.h b/src/TotpCache.h index 524ee62..571d16c 100644 --- a/src/TotpCache.h +++ b/src/TotpCache.h @@ -5,161 +5,165 @@ #pragma once #include "seclibs/cpptotp/bytes.h" -#include "seclibs/qrcode/qrcodegen.hpp" #include "seclibs/cpptotp/otp.h" +#include "seclibs/qrcode/qrcodegen.hpp" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - class TotpCache : public SubSystemServer { - public: + class TotpCache : public SubSystemServer { + public: + struct Entry { + bool Subscriber = false; + uint64_t Start = 0; + uint64_t Done = 0; + uint64_t Verifications = 0; + std::string Secret; + std::string QRCode; + std::string LastCode; + }; - struct Entry { - bool Subscriber=false; - uint64_t Start = 0; - uint64_t Done = 0 ; - uint64_t Verifications = 0 ; - std::string Secret; - std::string QRCode; - std::string LastCode; - }; + static auto instance() { + static auto instance = new TotpCache; + return instance; + } - static auto instance() { - static auto instance = new TotpCache; - return instance; - } + static std::string GenerateSecret(uint Size, std::string &Base32Secret) { + std::string R; - static std::string GenerateSecret(uint Size, std::string & Base32Secret) { - std::string R; + for (; Size; Size--) { + R += (char)MicroServiceRandom(33, 127); + } + Base32Secret = + CppTotp::Bytes::toBase32(CppTotp::Bytes::ByteString{(const u_char *)R.c_str()}); + return R; + } - for(;Size;Size--) { - R += (char) MicroServiceRandom(33,127); - } - Base32Secret = CppTotp::Bytes::toBase32( CppTotp::Bytes::ByteString{ (const u_char *)R.c_str()}); - return R; - } + std::string GenerateQRCode(const std::string &Secret, const std::string &email) { + std::string uri{"otpauth://totp/" + Issuer_ + ":" + email + "?secret=" + Secret + + "&issuer=" + Issuer_}; - std::string GenerateQRCode(const std::string &Secret, const std::string &email) { - std::string uri{ - "otpauth://totp/" + Issuer_ + ":" + - email + "?secret=" + Secret + "&issuer=" + Issuer_ - }; + qrcodegen::QrCode qr0 = + qrcodegen::QrCode::encodeText(uri.c_str(), qrcodegen::QrCode::Ecc::MEDIUM); + std::string svg = qrcodegen::toSvgString(qr0, 4); // See QrCodeGeneratorDemo + return svg; + } - qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText(uri.c_str(), qrcodegen::QrCode::Ecc::MEDIUM); - std::string svg = qrcodegen::toSvgString(qr0, 4); // See QrCodeGeneratorDemo - return svg; - } + static bool ValidateCode(const std::string &Secret, const std::string &Code, + std::string &Expecting) { + uint64_t Now = OpenWifi::Now(); + uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{(const u_char *)Secret.c_str()}, + Now, 0, 30, 6); + char buffer[16]{0}; + snprintf(buffer, 7, "%06u", p); + Expecting = std::string(buffer); + return Code == Expecting; + } - static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) { - uint64_t Now = OpenWifi::Now(); - uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6); - char buffer[16]{0}; - snprintf(buffer,7,"%06u",p); - Expecting = std::string(buffer); - return Code == Expecting; - } + int Start() override { + Issuer_ = MicroServiceConfigGetString("totp.issuer", "OpenWiFi"); + return 0; + }; - int Start() override { - Issuer_ = MicroServiceConfigGetString("totp.issuer","OpenWiFi"); - return 0; - }; + void Stop() override{ - void Stop() override { + }; - }; + inline bool StartValidation(const SecurityObjects::UserInfo &User, bool Subscriber, + std::string &QRCode, bool Reset) { + auto Hint = Cache_.find(User.id); + if (Hint != Cache_.end() && Hint->second.Subscriber == Subscriber) { + if (Reset) { + std::string Base32Secret; + Hint->second.Subscriber = Subscriber; + Hint->second.Start = OpenWifi::Now(); + Hint->second.Done = 0; + Hint->second.Verifications = 0; + Hint->second.Secret = GenerateSecret(20, Base32Secret); + Hint->second.QRCode = QRCode = GenerateQRCode(Base32Secret, User.email); + Hint->second.LastCode.clear(); + } else { + QRCode = Hint->second.QRCode; + } + return true; + } - inline bool StartValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & QRCode, bool Reset) { - auto Hint = Cache_.find(User.id); - if(Hint!=Cache_.end() && Hint->second.Subscriber==Subscriber) { - if(Reset) { - std::string Base32Secret; - Hint->second.Subscriber = Subscriber; - Hint->second.Start = OpenWifi::Now(); - Hint->second.Done = 0; - Hint->second.Verifications = 0; - Hint->second.Secret = GenerateSecret(20,Base32Secret); - Hint->second.QRCode = QRCode = GenerateQRCode(Base32Secret, User.email); - Hint->second.LastCode.clear(); - } else { - QRCode = Hint->second.QRCode; - } - return true; - } + std::string Base32Secret; + auto Secret = GenerateSecret(20, Base32Secret); + QRCode = GenerateQRCode(Base32Secret, User.email); - std::string Base32Secret; - auto Secret = GenerateSecret(20, Base32Secret); - QRCode = GenerateQRCode(Base32Secret, User.email); + Entry E{.Subscriber = Subscriber, + .Start = OpenWifi::Now(), + .Done = 0, + .Verifications = 0, + .Secret = Secret, + .QRCode = QRCode, + .LastCode = ""}; + Cache_[User.id] = E; + return true; + } - Entry E{ .Subscriber = Subscriber, - .Start = OpenWifi::Now(), - .Done = 0, - .Verifications = 0, - .Secret = Secret, - .QRCode = QRCode, - .LastCode = "" - }; - Cache_[User.id] = E; - return true; - } + inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, + const std::string &Code, uint64_t &NextIndex, + bool &MoreCodes, RESTAPI::Errors::msg &Error) { + auto Hint = Cache_.find(User.id); + uint64_t Now = OpenWifi::Now(); + if (Hint != Cache_.end() && Subscriber == Hint->second.Subscriber && + (Now - Hint->second.Start) < (15 * 60)) { + std::string Expecting; + if (NextIndex == 1 && Hint->second.Verifications == 0 && + ValidateCode(Hint->second.Secret, Code, Expecting)) { + NextIndex++; + Hint->second.Verifications++; + MoreCodes = true; + Hint->second.LastCode = Code; + return true; + } else if (NextIndex == 2 && Hint->second.Verifications == 1 && + Code != Hint->second.LastCode && + ValidateCode(Hint->second.Secret, Code, Expecting)) { + MoreCodes = false; + Hint->second.Done = Now; + return true; + } else { + if (!ValidateCode(Hint->second.Secret, Code, Expecting)) { + Error = RESTAPI::Errors::TOTInvalidCode; + return false; + } else if (NextIndex != 1 && NextIndex != 2) { + Error = RESTAPI::Errors::TOTInvalidIndex; + return false; + } else if (Code == Hint->second.LastCode) { + Error = RESTAPI::Errors::TOTRepeatedCode; + return false; + } + Error = RESTAPI::Errors::TOTInvalidProtocol; + return false; + } + } else { + Error = RESTAPI::Errors::TOTNoSession; + } + return false; + } - inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code, - uint64_t &NextIndex, bool &MoreCodes, RESTAPI::Errors::msg & Error ) { - auto Hint = Cache_.find(User.id); - uint64_t Now = OpenWifi::Now(); - if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) { - std::string Expecting; - if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) { - NextIndex++; - Hint->second.Verifications++; - MoreCodes = true; - Hint->second.LastCode = Code; - return true; - } else if (NextIndex == 2 && Hint->second.Verifications == 1 && Code != Hint->second.LastCode && - ValidateCode(Hint->second.Secret, Code, Expecting) ) { - MoreCodes = false; - Hint->second.Done = Now; - return true; - } else { - if(!ValidateCode(Hint->second.Secret, Code, Expecting)) { - Error = RESTAPI::Errors::TOTInvalidCode; - return false; - } else if(NextIndex!=1 && NextIndex != 2) { - Error = RESTAPI::Errors::TOTInvalidIndex; - return false; - } else if(Code == Hint->second.LastCode) { - Error = RESTAPI::Errors::TOTRepeatedCode; - return false; - } - Error = RESTAPI::Errors::TOTInvalidProtocol; - return false; - } - } else { - Error = RESTAPI::Errors::TOTNoSession; - } - return false; - } + inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, + std::string &Secret) { + auto Hint = Cache_.find(User.id); + uint64_t Now = OpenWifi::Now(); + if (Hint != Cache_.end() && Subscriber == Hint->second.Subscriber && + (Now - Hint->second.Start) < (15 * 60) && Hint->second.Done != 0) { + Secret = Hint->second.Secret; + Cache_.erase(Hint); + return true; + } + return false; + } - inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) { - auto Hint = Cache_.find(User.id); - uint64_t Now = OpenWifi::Now(); - if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) { - Secret = Hint->second.Secret; - Cache_.erase(Hint); - return true; - } - return false; - } + private: + std::map Cache_; + std::string Issuer_; - private: - std::map Cache_; - std::string Issuer_; + TotpCache() noexcept : SubSystemServer("TOTP-system", "TOTP-SVR", "totp") {} + }; - TotpCache() noexcept: - SubSystemServer("TOTP-system", "TOTP-SVR", "totp") { - } - - }; - - inline auto TotpCache() { return TotpCache::instance(); } -} + inline auto TotpCache() { return TotpCache::instance(); } +} // namespace OpenWifi diff --git a/src/framework/ALBserver.cpp b/src/framework/ALBserver.cpp index 5e2bf47..1a08503 100644 --- a/src/framework/ALBserver.cpp +++ b/src/framework/ALBserver.cpp @@ -4,17 +4,19 @@ #include "ALBserver.h" -#include "framework/utils.h" -#include "framework/MicroServiceFuncs.h" #include "fmt/format.h" +#include "framework/MicroServiceFuncs.h" +#include "framework/utils.h" namespace OpenWifi { - void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) { + void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request, + Poco::Net::HTTPServerResponse &Response) { Utils::SetThreadName("alb-request"); try { - if((id_ % 100) == 0) { - Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_)); + if ((id_ % 100) == 0) { + Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", + Request.clientAddress().toString(), id_)); } Response.setChunkedTransferEncoding(true); Response.setContentType("text/html"); @@ -26,31 +28,27 @@ namespace OpenWifi { std::ostream &Answer = Response.send(); Answer << "process Alive and kicking!"; } catch (...) { - } } - ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L): - Logger_(L) { - } + ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {} - ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) { + ALBRequestHandler * + ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) { if (request.getURI() == "/") return new ALBRequestHandler(Logger_, req_id_++); else return nullptr; } - ALBHealthCheckServer::ALBHealthCheckServer() : - SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") - { - } + ALBHealthCheckServer::ALBHealthCheckServer() + : SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") {} int ALBHealthCheckServer::Start() { - if(MicroServiceConfigGetBool("alb.enable",false)) { - poco_information(Logger(),"Starting..."); - Running_=true; - Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); + if (MicroServiceConfigGetBool("alb.enable", false)) { + poco_information(Logger(), "Starting..."); + Running_ = true; + Port_ = (int)MicroServiceConfigGetInt("alb.port", 15015); Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard( Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6 : Poco::Net::AddressFamily::IPv4)); @@ -60,7 +58,8 @@ namespace OpenWifi { Socket_ = std::make_unique(SockAddr, Port_); auto Params = new Poco::Net::HTTPServerParams; Params->setName("ws:alb"); - Server_ = std::make_unique(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); + Server_ = std::make_unique( + new ALBRequestHandlerFactory(Logger()), *Socket_, Params); Server_->start(); } @@ -68,10 +67,10 @@ namespace OpenWifi { } void ALBHealthCheckServer::Stop() { - poco_information(Logger(),"Stopping..."); - if(Running_) + poco_information(Logger(), "Stopping..."); + if (Running_) Server_->stopAll(true); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/ALBserver.h b/src/framework/ALBserver.h index 6316818..6599ac8 100644 --- a/src/framework/ALBserver.h +++ b/src/framework/ALBserver.h @@ -7,35 +7,34 @@ #include "framework/SubSystemServer.h" #include "Poco/Net/HTTPRequestHandler.h" -#include "Poco/Net/HTTPServerRequest.h" -#include "Poco/Net/HTTPServerResponse.h" #include "Poco/Net/HTTPRequestHandlerFactory.h" #include "Poco/Net/HTTPServer.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" namespace OpenWifi { - class ALBRequestHandler: public Poco::Net::HTTPRequestHandler { + class ALBRequestHandler : public Poco::Net::HTTPRequestHandler { public: - explicit ALBRequestHandler(Poco::Logger & L, uint64_t id) - : Logger_(L), id_(id) { - } + explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {} - void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override; + void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request, + Poco::Net::HTTPServerResponse &Response) override; private: - Poco::Logger & Logger_; - uint64_t id_; + Poco::Logger &Logger_; + uint64_t id_; }; - class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory - { + class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory { public: - explicit ALBRequestHandlerFactory(Poco::Logger & L); - ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override; + explicit ALBRequestHandlerFactory(Poco::Logger &L); + ALBRequestHandler * + createRequestHandler(const Poco::Net::HTTPServerRequest &request) override; private: - Poco::Logger &Logger_; - inline static std::atomic_uint64_t req_id_=1; + Poco::Logger &Logger_; + inline static std::atomic_uint64_t req_id_ = 1; }; class ALBHealthCheckServer : public SubSystemServer { @@ -51,13 +50,12 @@ namespace OpenWifi { void Stop() override; private: - std::unique_ptr Server_; - std::unique_ptr Socket_; - int Port_ = 0; - mutable std::atomic_bool Running_=false; + std::unique_ptr Server_; + std::unique_ptr Socket_; + int Port_ = 0; + mutable std::atomic_bool Running_ = false; }; inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); } } // namespace OpenWifi - diff --git a/src/framework/API_Proxy.h b/src/framework/API_Proxy.h index a6a402a..dcb6f06 100644 --- a/src/framework/API_Proxy.h +++ b/src/framework/API_Proxy.h @@ -4,96 +4,94 @@ #pragma once -#include "Poco/Logger.h" #include "Poco/JSON/Parser.h" +#include "Poco/Logger.h" +#include "Poco/Net/HTTPSClientSession.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Net/HTTPServerResponse.h" -#include "Poco/Net/HTTPSClientSession.h" #include "Poco/URI.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - inline void API_Proxy( Poco::Logger &Logger, - Poco::Net::HTTPServerRequest *Request, - Poco::Net::HTTPServerResponse *Response, - const char * ServiceType, - const char * PathRewrite, - uint64_t msTimeout_ = 10000 ) { - try { - auto Services = MicroServiceGetServices(ServiceType); - for(auto const &Svc:Services) { - Poco::URI SourceURI(Request->getURI()); - Poco::URI DestinationURI(Svc.PrivateEndPoint); - DestinationURI.setPath(PathRewrite); - DestinationURI.setQuery(SourceURI.getQuery()); + inline void API_Proxy(Poco::Logger &Logger, Poco::Net::HTTPServerRequest *Request, + Poco::Net::HTTPServerResponse *Response, const char *ServiceType, + const char *PathRewrite, uint64_t msTimeout_ = 10000) { + try { + auto Services = MicroServiceGetServices(ServiceType); + for (auto const &Svc : Services) { + Poco::URI SourceURI(Request->getURI()); + Poco::URI DestinationURI(Svc.PrivateEndPoint); + DestinationURI.setPath(PathRewrite); + DestinationURI.setQuery(SourceURI.getQuery()); - // std::cout << " Source: " << SourceURI.toString() << std::endl; - // std::cout << "Destination: " << DestinationURI.toString() << std::endl; + // std::cout << " Source: " << SourceURI.toString() << std::endl; + // std::cout << "Destination: " << DestinationURI.toString() << std::endl; - Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort()); - Session.setKeepAlive(true); - Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000)); - Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(), - DestinationURI.getPathAndQuery(), - Poco::Net::HTTPMessage::HTTP_1_1); - if(Request->has("Authorization")) { - ProxyRequest.add("Authorization", Request->get("Authorization")); - } else { - ProxyRequest.add("X-API-KEY", Svc.AccessKey); - ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); - } + Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), + DestinationURI.getPort()); + Session.setKeepAlive(true); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(), + DestinationURI.getPathAndQuery(), + Poco::Net::HTTPMessage::HTTP_1_1); + if (Request->has("Authorization")) { + ProxyRequest.add("Authorization", Request->get("Authorization")); + } else { + ProxyRequest.add("X-API-KEY", Svc.AccessKey); + ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); + } - if(Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) { - Session.sendRequest(ProxyRequest); - Poco::Net::HTTPResponse ProxyResponse; - Session.receiveResponse(ProxyResponse); - Response->setStatus(ProxyResponse.getStatus()); - Response->send(); - return; - } else { - Poco::JSON::Parser P; - std::stringstream SS; - try { - auto Body = P.parse(Request->stream()).extract(); - Poco::JSON::Stringifier::condense(Body,SS); - SS << "\r\n\r\n"; - } catch(const Poco::Exception &E) { - Logger.log(E); - } + if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) { + Session.sendRequest(ProxyRequest); + Poco::Net::HTTPResponse ProxyResponse; + Session.receiveResponse(ProxyResponse); + Response->setStatus(ProxyResponse.getStatus()); + Response->send(); + return; + } else { + Poco::JSON::Parser P; + std::stringstream SS; + try { + auto Body = P.parse(Request->stream()).extract(); + Poco::JSON::Stringifier::condense(Body, SS); + SS << "\r\n\r\n"; + } catch (const Poco::Exception &E) { + Logger.log(E); + } - if(SS.str().empty()) { - Session.sendRequest(ProxyRequest); - } else { - ProxyRequest.setContentType("application/json"); - ProxyRequest.setContentLength(SS.str().size()); - std::ostream & os = Session.sendRequest(ProxyRequest); - os << SS.str() ; - } + if (SS.str().empty()) { + Session.sendRequest(ProxyRequest); + } else { + ProxyRequest.setContentType("application/json"); + ProxyRequest.setContentLength(SS.str().size()); + std::ostream &os = Session.sendRequest(ProxyRequest); + os << SS.str(); + } - Poco::Net::HTTPResponse ProxyResponse; - std::stringstream SSR; - try { - std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse); - Poco::JSON::Parser P2; - auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract(); - Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR); - Response->setContentType("application/json"); - Response->setContentLength(SSR.str().size()); - Response->setStatus(ProxyResponse.getStatus()); - Response->sendBuffer(SSR.str().c_str(),SSR.str().size()); - return; - } catch( const Poco::Exception & E) { + Poco::Net::HTTPResponse ProxyResponse; + std::stringstream SSR; + try { + std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse); + Poco::JSON::Parser P2; + auto ProxyResponseBody = + P2.parse(ProxyResponseStream).extract(); + Poco::JSON::Stringifier::condense(ProxyResponseBody, SSR); + Response->setContentType("application/json"); + Response->setContentLength(SSR.str().size()); + Response->setStatus(ProxyResponse.getStatus()); + Response->sendBuffer(SSR.str().c_str(), SSR.str().size()); + return; + } catch (const Poco::Exception &E) { + } + Response->setStatus(ProxyResponse.getStatus()); + Response->send(); + return; + } + } - } - Response->setStatus(ProxyResponse.getStatus()); - Response->send(); - return; - } - } - - } catch (const Poco::Exception &E) { - Logger.log(E); - } - } -} \ No newline at end of file + } catch (const Poco::Exception &E) { + Logger.log(E); + } + } +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/AppServiceRegistry.h b/src/framework/AppServiceRegistry.h index 0466df7..4855c67 100644 --- a/src/framework/AppServiceRegistry.h +++ b/src/framework/AppServiceRegistry.h @@ -4,13 +4,13 @@ #pragma once -#include #include #include #include +#include -#include "Poco/StreamCopier.h" #include "Poco/File.h" +#include "Poco/StreamCopier.h" #include "framework/MicroServiceFuncs.h" @@ -18,7 +18,6 @@ namespace OpenWifi { - class AppServiceRegistry { public: AppServiceRegistry() { @@ -26,9 +25,9 @@ namespace OpenWifi { Poco::File F(FileName); try { - if(F.exists()) { - std::ostringstream OS; - std::ifstream IF(FileName); + if (F.exists()) { + std::ostringstream OS; + std::ifstream IF(FileName); Poco::StreamCopier::copyStream(IF, OS); Registry_ = nlohmann::json::parse(OS.str()); } @@ -37,55 +36,53 @@ namespace OpenWifi { } } - static AppServiceRegistry & instance() { - static auto instance_= new AppServiceRegistry; + static AppServiceRegistry &instance() { + static auto instance_ = new AppServiceRegistry; return *instance_; } - inline ~AppServiceRegistry() { - Save(); - } + inline ~AppServiceRegistry() { Save(); } inline void Save() { - std::istringstream IS( to_string(Registry_)); - std::ofstream OF; - OF.open(FileName,std::ios::binary | std::ios::trunc); + std::istringstream IS(to_string(Registry_)); + std::ofstream OF; + OF.open(FileName, std::ios::binary | std::ios::trunc); Poco::StreamCopier::copyStream(IS, OF); } - inline void Set(const char *Key, uint64_t Value ) { + inline void Set(const char *Key, uint64_t Value) { Registry_[Key] = Value; Save(); } - inline void Set(const char *Key, const std::string &Value ) { + inline void Set(const char *Key, const std::string &Value) { Registry_[Key] = Value; Save(); } - inline void Set(const char *Key, bool Value ) { + inline void Set(const char *Key, bool Value) { Registry_[Key] = Value; Save(); } - inline bool Get(const char *Key, bool & Value ) { - if(Registry_[Key].is_boolean()) { + inline bool Get(const char *Key, bool &Value) { + if (Registry_[Key].is_boolean()) { Value = Registry_[Key].get(); return true; } return false; } - inline bool Get(const char *Key, uint64_t & Value ) { - if(Registry_[Key].is_number_unsigned()) { + inline bool Get(const char *Key, uint64_t &Value) { + if (Registry_[Key].is_number_unsigned()) { Value = Registry_[Key].get(); return true; } return false; } - inline bool Get(const char *Key, std::string & Value ) { - if(Registry_[Key].is_string()) { + inline bool Get(const char *Key, std::string &Value) { + if (Registry_[Key].is_string()) { Value = Registry_[Key].get(); return true; } @@ -93,10 +90,10 @@ namespace OpenWifi { } private: - std::string FileName; - nlohmann::json Registry_; + std::string FileName; + nlohmann::json Registry_; }; inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/AuthClient.cpp b/src/framework/AuthClient.cpp index 24c498d..3f2e1c3 100644 --- a/src/framework/AuthClient.cpp +++ b/src/framework/AuthClient.cpp @@ -4,41 +4,40 @@ #include "Poco/Net/HTTPServerResponse.h" +#include "fmt/format.h" #include "framework/AuthClient.h" #include "framework/MicroServiceNames.h" #include "framework/OpenAPIRequests.h" #include "framework/utils.h" -#include "fmt/format.h" namespace OpenWifi { - bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken, - SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool Sub) { + bool AuthClient::RetrieveTokenInformation(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired, bool &Contacted, + bool Sub) { try { Types::StringPairVec QueryData; - QueryData.push_back(std::make_pair("token",SessionToken)); - std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken)); - OpenAPIRequestGet Req( uSERVICE_SECURITY, + QueryData.push_back(std::make_pair("token", SessionToken)); + std::string AlternateURIForLogging = fmt::format( + "{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", + Utils::SanitizeToken(SessionToken)); + OpenAPIRequestGet Req(uSERVICE_SECURITY, Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", - QueryData, - 10000, - AlternateURIForLogging - ); + QueryData, 10000, AlternateURIForLogging); Poco::JSON::Object::Ptr Response; auto StatusCode = Req.Do(Response); - if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { + if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { Contacted = false; return false; } Contacted = true; - if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { - if(Response->has("tokenInfo") && Response->has("userInfo")) { + if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_OK) { + if (Response->has("tokenInfo") && Response->has("userInfo")) { UInfo.from_json(Response); - if(IsTokenExpired(UInfo.webtoken)) { + if (IsTokenExpired(UInfo.webtoken)) { Expired = true; return false; } @@ -50,18 +49,19 @@ namespace OpenWifi { } } } catch (...) { - poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); + poco_error(Logger(), fmt::format("Failed to retrieve token={} for TID={}", + Utils::SanitizeToken(SessionToken), TID)); } Expired = false; return false; } - bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool Sub) { + bool AuthClient::IsAuthorized(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool Sub) { auto User = Cache_.get(SessionToken); - if(!User.isNull()) { - if(IsTokenExpired(User->webtoken)) { + if (!User.isNull()) { + if (IsTokenExpired(User->webtoken)) { Expired = true; Cache_.remove(SessionToken); return false; @@ -73,57 +73,60 @@ namespace OpenWifi { return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub); } - bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken, - SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, [[maybe_unused]] bool & Suspended) { - try { - Types::StringPairVec QueryData; - QueryData.push_back(std::make_pair("apikey",SessionToken)); - std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken)); - OpenAPIRequestGet Req( uSERVICE_SECURITY, - "/api/v1/validateApiKey" , - QueryData, - 10000, - AlternateURIForLogging); - Poco::JSON::Object::Ptr Response; + bool AuthClient::RetrieveApiKeyInformation(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired, bool &Contacted, + [[maybe_unused]] bool &Suspended) { + try { + Types::StringPairVec QueryData; + QueryData.push_back(std::make_pair("apikey", SessionToken)); + std::string AlternateURIForLogging = + fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken)); + OpenAPIRequestGet Req(uSERVICE_SECURITY, "/api/v1/validateApiKey", QueryData, 10000, + AlternateURIForLogging); + Poco::JSON::Object::Ptr Response; - auto StatusCode = Req.Do(Response); - if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { - Contacted = false; - return false; - } + auto StatusCode = Req.Do(Response); + if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { + Contacted = false; + return false; + } - Contacted = true; - if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { - if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) { - UInfo.from_json(Response); - Expired = false; - ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")}); - return true; - } else { - return false; - } - } - } catch (...) { - poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); - } - Expired = false; - return false; - } + Contacted = true; + if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_OK) { + if (Response->has("tokenInfo") && Response->has("userInfo") && + Response->has("expiresOn")) { + UInfo.from_json(Response); + Expired = false; + ApiKeyCache_.update(SessionToken, + ApiKeyCacheEntry{.UserInfo = UInfo, + .ExpiresOn = Response->get("expiresOn")}); + return true; + } else { + return false; + } + } + } catch (...) { + poco_error(Logger(), fmt::format("Failed to retrieve api key={} for TID={}", + Utils::SanitizeToken(SessionToken), TID)); + } + Expired = false; + return false; + } - bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo, - std::uint64_t TID, bool &Expired, bool &Contacted, bool & Suspended) { - auto User = ApiKeyCache_.get(SessionToken); - if (!User.isNull()) { - if(User->ExpiresOn < Utils::Now()) { - Expired = false; - UInfo = User->UserInfo; - return true; - } + bool AuthClient::IsValidApiKey(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool &Suspended) { + auto User = ApiKeyCache_.get(SessionToken); + if (!User.isNull()) { + if (User->ExpiresOn < Utils::Now()) { + Expired = false; + UInfo = User->UserInfo; + return true; + } ApiKeyCache_.remove(SessionToken); - } - return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted, Suspended); - } + } + return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted, Suspended); + } } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/AuthClient.h b/src/framework/AuthClient.h index 0ff4f6c..706dff8 100644 --- a/src/framework/AuthClient.h +++ b/src/framework/AuthClient.h @@ -4,9 +4,9 @@ #pragma once -#include "framework/SubSystemServer.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "Poco/ExpireLRUCache.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/SubSystemServer.h" #include "framework/utils.h" namespace OpenWifi { @@ -14,66 +14,59 @@ namespace OpenWifi { class AuthClient : public SubSystemServer { public: - explicit AuthClient() noexcept: - SubSystemServer("Authentication", "AUTH-CLNT", "authentication") - { - } + explicit AuthClient() noexcept + : SubSystemServer("Authentication", "AUTH-CLNT", "authentication") {} static auto instance() { static auto instance_ = new AuthClient; return instance_; } - struct ApiKeyCacheEntry { - OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo; - std::uint64_t ExpiresOn; - }; + struct ApiKeyCacheEntry { + OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo; + std::uint64_t ExpiresOn; + }; - inline int Start() override { - return 0; - } + inline int Start() override { return 0; } inline void Stop() override { - poco_information(Logger(),"Stopping..."); - std::lock_guard G(Mutex_); + poco_information(Logger(), "Stopping..."); + std::lock_guard G(Mutex_); Cache_.clear(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } inline void RemovedCachedToken(const std::string &Token) { Cache_.remove(Token); - ApiKeyCache_.remove(Token); + ApiKeyCache_.remove(Token); } inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) { - return ((T.expires_in_+T.created_) < Utils::Now()); + return ((T.expires_in_ + T.created_) < Utils::Now()); } - bool RetrieveTokenInformation(const std::string & SessionToken, - SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool Sub=false); + bool RetrieveTokenInformation(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool Sub = false); - bool RetrieveApiKeyInformation(const std::string & SessionToken, - SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool & Suspended); + bool RetrieveApiKeyInformation(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool &Suspended); - bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool Sub = false); + bool IsAuthorized(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool Sub = false); - bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, - std::uint64_t TID, - bool & Expired, bool & Contacted, bool & Suspended) ; + bool IsValidApiKey(const std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, + bool &Expired, bool &Contacted, bool &Suspended); private: - - Poco::ExpireLRUCache Cache_{512,1200000 }; - Poco::ExpireLRUCache ApiKeyCache_{512,1200000 }; + Poco::ExpireLRUCache Cache_{ + 512, 1200000}; + Poco::ExpireLRUCache ApiKeyCache_{512, 1200000}; }; inline auto AuthClient() { return AuthClient::instance(); } } // namespace OpenWifi - diff --git a/src/framework/CIDR.h b/src/framework/CIDR.h index 0d40f52..3a7fd92 100644 --- a/src/framework/CIDR.h +++ b/src/framework/CIDR.h @@ -21,13 +21,13 @@ namespace OpenWifi::CIDR { } static bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) { - #ifdef __linux__ +#ifdef __linux__ const uint32_t *a = address.s6_addr32; const uint32_t *n = network.s6_addr32; - #else +#else const uint32_t *a = address.__u6_addr.__u6_addr32; const uint32_t *n = network.__u6_addr.__u6_addr32; - #endif +#endif int bits_whole, bits_incomplete; bits_whole = bits >> 5; // number of whole u32 bits_incomplete = bits & 0x1F; // number of bits in incomplete u32 @@ -152,4 +152,4 @@ namespace OpenWifi::CIDR { [[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) { return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange); } -} \ No newline at end of file +} // namespace OpenWifi::CIDR \ No newline at end of file diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index 0a194cb..85ba6b3 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -2,8 +2,8 @@ // Created by stephane bourque on 2021-09-14. // -#include #include +#include #include #include "ConfigurationValidator.h" @@ -17,14 +17,15 @@ #include "fmt/format.h" #include -#include +#include #include #include +#include #include -#include static const std::string GitUCentralJSONSchemaFile{ - "https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json"}; + "https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/" + "ucentral.schema.json"}; static std::string DefaultUCentralSchema = R"foo( @@ -3184,7 +3185,6 @@ static std::string DefaultUCentralSchema = R"foo( )foo"; - static inline bool IsIPv4(const std::string &value) { Poco::Net::IPAddress A; return ((Poco::Net::IPAddress::tryParse(value, A) && A.family() == Poco::Net::IPAddress::IPv4)); @@ -3242,57 +3242,68 @@ bool ExternalValijsonFormatChecker(const std::string &format, const std::string if (format == "uc-cidr4") { if (IsCIDRv4(value)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv4 block",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid CIDR IPv4 block", value)); } else if (format == "uc-cidr6") { if (IsCIDRv6(value)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv6 block",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid CIDR IPv6 block", value)); } else if (format == "uc-cidr") { if (IsCIDR(value)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid CIDR block",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid CIDR block", value)); } else if (format == "uc-mac") { if (std::regex_match(value, mac_regex)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid MAC address",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid MAC address", value)); } else if (format == "uc-timeout") { if (std::regex_match(value, uc_timeout_regex)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid timeout value",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid timeout value", value)); } else if (format == "uc-host") { if (IsIP(value)) return true; if (std::regex_match(value, host_regex)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid hostname",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid hostname", value)); } else if (format == "fqdn" || format == "uc-fqdn") { if (std::regex_match(value, host_regex)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid FQDN",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid FQDN", value)); } else if (format == "uc-base64") { std::string s{value}; Poco::trimInPlace(s); if ((s.size() % 4 == 0) && std::regex_match(s, b64_regex)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid base 64 value",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid base 64 value", value)); } else if (format == "uri") { try { Poco::URI uri(value); return true; } catch (...) { } - if(results) results->pushError(context,fmt::format("{} is not a valid URL",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid URL", value)); } else if (format == "uc-portrange") { try { if (IsPortRangeIsValid(value)) return true; } catch (...) { } - if(results) results->pushError(context,fmt::format("{} is not a valid post range",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid post range", value)); } else if (format == "ip") { if (IsIP(value)) return true; - if(results) results->pushError(context,fmt::format("{} is not a valid IP address",value)); + if (results) + results->pushError(context, fmt::format("{} is not a valid IP address", value)); } return true; } @@ -3304,9 +3315,7 @@ namespace OpenWifi { return 0; } - void ConfigurationValidator::Stop() { - - } + void ConfigurationValidator::Stop() {} bool ConfigurationValidator::SetSchema(const std::string &SchemaStr) { try { @@ -3318,9 +3327,9 @@ namespace OpenWifi { SchemaParser_->populateSchema(*PocoJsonAdapter_, *RootSchema_); Initialized_ = Working_ = true; return true; - } catch(const Poco::Exception &E) { + } catch (const Poco::Exception &E) { Logger().log(E); - } catch(...) { + } catch (...) { Logger().error("Validation schema is invalid, falling back."); } return false; @@ -3331,7 +3340,7 @@ namespace OpenWifi { return; std::string GitSchema; - if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) { + if (MicroServiceConfigGetBool("ucentral.datamodel.internal", true)) { SetSchema(DefaultUCentralSchema); poco_information(Logger(), "Using uCentral validation from built-in default."); return; @@ -3339,34 +3348,35 @@ namespace OpenWifi { try { auto GitURI = - MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile); - if(Utils::wgets(GitURI, GitSchema) && SetSchema(GitSchema)) { - poco_information(Logger(),"Using uCentral data model validation schema from GIT."); + MicroServiceConfigGetString("ucentral.datamodel.uri", GitUCentralJSONSchemaFile); + if (Utils::wgets(GitURI, GitSchema) && SetSchema(GitSchema)) { + poco_information(Logger(), "Using uCentral data model validation schema from GIT."); + return; + } else { + std::string FileName{MicroServiceDataDirectory() + "/ucentral.schema.json"}; + std::ifstream input(FileName); + std::stringstream schema_file; + schema_file << input.rdbuf(); + input.close(); + if (SetSchema(schema_file.str())) { + poco_information( + Logger(), "Using uCentral data model validation schema from local file."); return; - } else { - std::string FileName{ MicroServiceDataDirectory() + "/ucentral.schema.json" }; - std::ifstream input(FileName); - std::stringstream schema_file; - schema_file << input.rdbuf(); - input.close(); - if(SetSchema(schema_file.str())) { - poco_information(Logger(), - "Using uCentral data model validation schema from local file."); - return; - } } + } } catch (const Poco::Exception &E) { } catch (...) { - } SetSchema(DefaultUCentralSchema); - poco_information(Logger(),"Using uCentral data model validation schema from built-in default."); + poco_information(Logger(), + "Using uCentral data model validation schema from built-in default."); } - bool ConfigurationValidator::Validate(const std::string &C, std::vector &Errors, bool Strict) { - if(Working_) { - try { + bool ConfigurationValidator::Validate(const std::string &C, std::vector &Errors, + bool Strict) { + if (Working_) { + try { Poco::JSON::Parser P; auto Doc = P.parse(C).extract(); valijson::adapters::PocoJsonAdapter Tester(Doc); @@ -3375,27 +3385,28 @@ namespace OpenWifi { if (Validator.validate(*RootSchema_, Tester, &Results)) { return true; } - for(const auto &error:Results) { + for (const auto &error : Results) { Errors.push_back(error.description); } return false; - } catch(const Poco::Exception &E) { + } catch (const Poco::Exception &E) { Logger().log(E); - } catch(const std::exception &E) { - Logger().warning(fmt::format("Error wile validating a configuration (1): {}", E.what())); - } catch(...) { + } catch (const std::exception &E) { + Logger().warning( + fmt::format("Error wile validating a configuration (1): {}", E.what())); + } catch (...) { Logger().warning("Error wile validating a configuration (2)"); - } - } - if(Strict) + } + } + if (Strict) return false; - return true; - } + return true; + } - void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) { - poco_information(Logger(),"Reinitializing."); - Working_ = Initialized_ = false; - Init(); - } + void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) { + poco_information(Logger(), "Reinitializing."); + Working_ = Initialized_ = false; + Init(); + } -} +} // namespace OpenWifi diff --git a/src/framework/ConfigurationValidator.h b/src/framework/ConfigurationValidator.h index 77e4df9..58ef180 100644 --- a/src/framework/ConfigurationValidator.h +++ b/src/framework/ConfigurationValidator.h @@ -7,43 +7,43 @@ #include "framework/SubSystemServer.h" #include -#include -#include -#include -#include #include #include +#include +#include +#include +#include namespace OpenWifi { - class ConfigurationValidator : public SubSystemServer { - public: + class ConfigurationValidator : public SubSystemServer { + public: + static auto instance() { + static auto instance_ = new ConfigurationValidator; + return instance_; + } - static auto instance() { - static auto instance_ = new ConfigurationValidator; - return instance_; - } + bool Validate(const std::string &C, std::vector &Errors, bool Strict); + int Start() override; + void Stop() override; + void reinitialize(Poco::Util::Application &self) override; - bool Validate(const std::string &C, std::vector &Errors, bool Strict); - int Start() override; - void Stop() override; - void reinitialize(Poco::Util::Application &self) override; + private: + bool Initialized_ = false; + bool Working_ = false; + void Init(); + std::unique_ptr RootSchema_; + std::unique_ptr SchemaParser_; + std::unique_ptr PocoJsonAdapter_; + Poco::JSON::Object::Ptr SchemaDocPtr_; + bool SetSchema(const std::string &SchemaStr); - private: - bool Initialized_=false; - bool Working_=false; - void Init(); - std::unique_ptr RootSchema_; - std::unique_ptr SchemaParser_; - std::unique_ptr PocoJsonAdapter_; - Poco::JSON::Object::Ptr SchemaDocPtr_; - bool SetSchema(const std::string &SchemaStr); - - ConfigurationValidator(): - SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") { - } - }; - - inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); } - inline bool ValidateUCentralConfiguration(const std::string &C, std::vector &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); } -} + ConfigurationValidator() + : SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {} + }; + inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); } + inline bool ValidateUCentralConfiguration(const std::string &C, std::vector &Error, + bool strict) { + return ConfigurationValidator::instance()->Validate(C, Error, strict); + } +} // namespace OpenWifi diff --git a/src/framework/CountryCodes.h b/src/framework/CountryCodes.h index 92a002a..282c1f4 100644 --- a/src/framework/CountryCodes.h +++ b/src/framework/CountryCodes.h @@ -4,268 +4,266 @@ #pragma once -#include #include #include +#include namespace OpenWifi { - - struct CountryInfo { - std::string code; - std::string name; - }; - - inline static const std::vector CountryCodes { - { .code= "US", .name= "United States" }, - { .code= "GB", .name= "United Kingdom" }, - { .code= "CA", .name= "Canada" }, - { .code= "AF", .name= "Afghanistan" }, - { .code= "AX", .name= "Aland Islands" }, - { .code= "AL", .name= "Albania" }, - { .code= "DZ", .name= "Algeria" }, - { .code= "AS", .name= "American Samoa" }, - { .code= "AD", .name= "Andorra" }, - { .code= "AO", .name= "Angola" }, - { .code= "AI", .name= "Anguilla" }, - { .code= "AQ", .name= "Antarctica" }, - { .code= "AG", .name= "Antigua And Barbuda" }, - { .code= "AR", .name= "Argentina" }, - { .code= "AM", .name= "Armenia" }, - { .code= "AN", .name= "Netherlands Antilles" }, - { .code= "AW", .name= "Aruba" }, - { .code= "AU", .name= "Australia" }, - { .code= "AT", .name= "Austria" }, - { .code= "AZ", .name= "Azerbaijan" }, - { .code= "BS", .name= "Bahamas" }, - { .code= "BH", .name= "Bahrain" }, - { .code= "BD", .name= "Bangladesh" }, - { .code= "BB", .name= "Barbados" }, - { .code= "BY", .name= "Belarus" }, - { .code= "BE", .name= "Belgium" }, - { .code= "BZ", .name= "Belize" }, - { .code= "BJ", .name= "Benin" }, - { .code= "BM", .name= "Bermuda" }, - { .code= "BT", .name= "Bhutan" }, - { .code= "BO", .name= "Bolivia" }, - { .code= "BA", .name= "Bosnia And Herzegovina" }, - { .code= "BW", .name= "Botswana" }, - { .code= "BV", .name= "Bouvet Island" }, - { .code= "BR", .name= "Brazil" }, - { .code= "IO", .name= "British Indian Ocean Territory" }, - { .code= "BN", .name= "Brunei Darussalam" }, - { .code= "BG", .name= "Bulgaria" }, - { .code= "BF", .name= "Burkina Faso" }, - { .code= "BI", .name= "Burundi" }, - { .code= "KH", .name= "Cambodia" }, - { .code= "CM", .name= "Cameroon" }, - { .code= "CA", .name= "Canada" }, - { .code= "CV", .name= "Cape Verde" }, - { .code= "KY", .name= "Cayman Islands" }, - { .code= "CF", .name= "Central African Republic" }, - { .code= "TD", .name= "Chad" }, - { .code= "CL", .name= "Chile" }, - { .code= "CN", .name= "China" }, - { .code= "CX", .name= "Christmas Island" }, - { .code= "CC", .name= "Cocos (Keeling) Islands" }, - { .code= "CO", .name= "Colombia" }, - { .code= "KM", .name= "Comoros" }, - { .code= "CG", .name= "Congo" }, - { .code= "CD", .name= "Congo, Democratic Republic" }, - { .code= "CK", .name= "Cook Islands" }, - { .code= "CR", .name= "Costa Rica" }, - { .code= "CI", .name= "Cote D\"Ivoire" }, - { .code= "HR", .name= "Croatia" }, - { .code= "CU", .name= "Cuba" }, - { .code= "CY", .name= "Cyprus" }, - { .code= "CZ", .name= "Czech Republic" }, - { .code= "DK", .name= "Denmark" }, - { .code= "DJ", .name= "Djibouti" }, - { .code= "DM", .name= "Dominica" }, - { .code= "DO", .name= "Dominican Republic" }, - { .code= "EC", .name= "Ecuador" }, - { .code= "EG", .name= "Egypt" }, - { .code= "SV", .name= "El Salvador" }, - { .code= "GQ", .name= "Equatorial Guinea" }, - { .code= "ER", .name= "Eritrea" }, - { .code= "EE", .name= "Estonia" }, - { .code= "ET", .name= "Ethiopia" }, - { .code= "FK", .name= "Falkland Islands (Malvinas)" }, - { .code= "FO", .name= "Faroe Islands" }, - { .code= "FJ", .name= "Fiji" }, - { .code= "FI", .name= "Finland" }, - { .code= "FR", .name= "France" }, - { .code= "GF", .name= "French Guiana" }, - { .code= "PF", .name= "French Polynesia" }, - { .code= "TF", .name= "French Southern Territories" }, - { .code= "GA", .name= "Gabon" }, - { .code= "GM", .name= "Gambia" }, - { .code= "GE", .name= "Georgia" }, - { .code= "DE", .name= "Germany" }, - { .code= "GH", .name= "Ghana" }, - { .code= "GI", .name= "Gibraltar" }, - { .code= "GR", .name= "Greece" }, - { .code= "GL", .name= "Greenland" }, - { .code= "GD", .name= "Grenada" }, - { .code= "GP", .name= "Guadeloupe" }, - { .code= "GU", .name= "Guam" }, - { .code= "GT", .name= "Guatemala" }, - { .code= "GG", .name= "Guernsey" }, - { .code= "GN", .name= "Guinea" }, - { .code= "GW", .name= "Guinea-Bissau" }, - { .code= "GY", .name= "Guyana" }, - { .code= "HT", .name= "Haiti" }, - { .code= "HM", .name= "Heard Island & Mcdonald Islands" }, - { .code= "VA", .name= "Holy See (Vatican City State)" }, - { .code= "HN", .name= "Honduras" }, - { .code= "HK", .name= "Hong Kong" }, - { .code= "HU", .name= "Hungary" }, - { .code= "IS", .name= "Iceland" }, - { .code= "IN", .name= "India" }, - { .code= "ID", .name= "Indonesia" }, - { .code= "IR", .name= "Iran, Islamic Republic Of" }, - { .code= "IQ", .name= "Iraq" }, - { .code= "IE", .name= "Ireland" }, - { .code= "IM", .name= "Isle Of Man" }, - { .code= "IL", .name= "Israel" }, - { .code= "IT", .name= "Italy" }, - { .code= "JM", .name= "Jamaica" }, - { .code= "JP", .name= "Japan" }, - { .code= "JE", .name= "Jersey" }, - { .code= "JO", .name= "Jordan" }, - { .code= "KZ", .name= "Kazakhstan" }, - { .code= "KE", .name= "Kenya" }, - { .code= "KI", .name= "Kiribati" }, - { .code= "KR", .name= "Korea" }, - { .code= "KW", .name= "Kuwait" }, - { .code= "KG", .name= "Kyrgyzstan" }, - { .code= "LA", .name= "Lao People\"s Democratic Republic" }, - { .code= "LV", .name= "Latvia" }, - { .code= "LB", .name= "Lebanon" }, - { .code= "LS", .name= "Lesotho" }, - { .code= "LR", .name= "Liberia" }, - { .code= "LY", .name= "Libyan Arab Jamahiriya" }, - { .code= "LI", .name= "Liechtenstein" }, - { .code= "LT", .name= "Lithuania" }, - { .code= "LU", .name= "Luxembourg" }, - { .code= "MO", .name= "Macao" }, - { .code= "MK", .name= "Macedonia" }, - { .code= "MG", .name= "Madagascar" }, - { .code= "MW", .name= "Malawi" }, - { .code= "MY", .name= "Malaysia" }, - { .code= "MV", .name= "Maldives" }, - { .code= "ML", .name= "Mali" }, - { .code= "MT", .name= "Malta" }, - { .code= "MH", .name= "Marshall Islands" }, - { .code= "MQ", .name= "Martinique" }, - { .code= "MR", .name= "Mauritania" }, - { .code= "MU", .name= "Mauritius" }, - { .code= "YT", .name= "Mayotte" }, - { .code= "MX", .name= "Mexico" }, - { .code= "FM", .name= "Micronesia, Federated States Of" }, - { .code= "MD", .name= "Moldova" }, - { .code= "MC", .name= "Monaco" }, - { .code= "MN", .name= "Mongolia" }, - { .code= "ME", .name= "Montenegro" }, - { .code= "MS", .name= "Montserrat" }, - { .code= "MA", .name= "Morocco" }, - { .code= "MZ", .name= "Mozambique" }, - { .code= "MM", .name= "Myanmar" }, - { .code= "NA", .name= "Namibia" }, - { .code= "NR", .name= "Nauru" }, - { .code= "NP", .name= "Nepal" }, - { .code= "NL", .name= "Netherlands" }, - { .code= "AN", .name= "Netherlands Antilles" }, - { .code= "NC", .name= "New Caledonia" }, - { .code= "NZ", .name= "New Zealand" }, - { .code= "NI", .name= "Nicaragua" }, - { .code= "NE", .name= "Niger" }, - { .code= "NG", .name= "Nigeria" }, - { .code= "NU", .name= "Niue" }, - { .code= "NF", .name= "Norfolk Island" }, - { .code= "MP", .name= "Northern Mariana Islands" }, - { .code= "NO", .name= "Norway" }, - { .code= "OM", .name= "Oman" }, - { .code= "PK", .name= "Pakistan" }, - { .code= "PW", .name= "Palau" }, - { .code= "PS", .name= "Palestinian Territory, Occupied" }, - { .code= "PA", .name= "Panama" }, - { .code= "PG", .name= "Papua New Guinea" }, - { .code= "PY", .name= "Paraguay" }, - { .code= "PE", .name= "Peru" }, - { .code= "PH", .name= "Philippines" }, - { .code= "PN", .name= "Pitcairn" }, - { .code= "PL", .name= "Poland" }, - { .code= "PT", .name= "Portugal" }, - { .code= "PR", .name= "Puerto Rico" }, - { .code= "QA", .name= "Qatar" }, - { .code= "RE", .name= "Reunion" }, - { .code= "RO", .name= "Romania" }, - { .code= "RU", .name= "Russian Federation" }, - { .code= "RW", .name= "Rwanda" }, - { .code= "BL", .name= "Saint Barthelemy" }, - { .code= "SH", .name= "Saint Helena" }, - { .code= "KN", .name= "Saint Kitts And Nevis" }, - { .code= "LC", .name= "Saint Lucia" }, - { .code= "MF", .name= "Saint Martin" }, - { .code= "PM", .name= "Saint Pierre And Miquelon" }, - { .code= "VC", .name= "Saint Vincent And Grenadines" }, - { .code= "WS", .name= "Samoa" }, - { .code= "SM", .name= "San Marino" }, - { .code= "ST", .name= "Sao Tome And Principe" }, - { .code= "SA", .name= "Saudi Arabia" }, - { .code= "SN", .name= "Senegal" }, - { .code= "RS", .name= "Serbia" }, - { .code= "SC", .name= "Seychelles" }, - { .code= "SL", .name= "Sierra Leone" }, - { .code= "SG", .name= "Singapore" }, - { .code= "SK", .name= "Slovakia" }, - { .code= "SI", .name= "Slovenia" }, - { .code= "SB", .name= "Solomon Islands" }, - { .code= "SO", .name= "Somalia" }, - { .code= "ZA", .name= "South Africa" }, - { .code= "GS", .name= "South Georgia And Sandwich Isl." }, - { .code= "ES", .name= "Spain" }, - { .code= "LK", .name= "Sri Lanka" }, - { .code= "SD", .name= "Sudan" }, - { .code= "SR", .name= "Suriname" }, - { .code= "SJ", .name= "Svalbard And Jan Mayen" }, - { .code= "SZ", .name= "Swaziland" }, - { .code= "SE", .name= "Sweden" }, - { .code= "CH", .name= "Switzerland" }, - { .code= "SY", .name= "Syrian Arab Republic" }, - { .code= "TW", .name= "Taiwan" }, - { .code= "TJ", .name= "Tajikistan" }, - { .code= "TZ", .name= "Tanzania" }, - { .code= "TH", .name= "Thailand" }, - { .code= "TL", .name= "Timor-Leste" }, - { .code= "TG", .name= "Togo" }, - { .code= "TK", .name= "Tokelau" }, - { .code= "TO", .name= "Tonga" }, - { .code= "TT", .name= "Trinidad And Tobago" }, - { .code= "TN", .name= "Tunisia" }, - { .code= "TR", .name= "Turkey" }, - { .code= "TM", .name= "Turkmenistan" }, - { .code= "TC", .name= "Turks And Caicos Islands" }, - { .code= "TV", .name= "Tuvalu" }, - { .code= "UG", .name= "Uganda" }, - { .code= "UA", .name= "Ukraine" }, - { .code= "AE", .name= "United Arab Emirates" }, - { .code= "GB", .name= "United Kingdom" }, - { .code= "US", .name= "United States" }, - { .code= "UM", .name= "United States Outlying Islands" }, - { .code= "UY", .name= "Uruguay" }, - { .code= "UZ", .name= "Uzbekistan" }, - { .code= "VU", .name= "Vanuatu" }, - { .code= "VE", .name= "Venezuela" }, - { .code= "VN", .name= "Viet Nam" }, - { .code= "VG", .name= "Virgin Islands, British" }, - { .code= "VI", .name= "Virgin Islands, U.S." }, - { .code= "WF", .name= "Wallis And Futuna" }, - { .code= "EH", .name= "Western Sahara" }, - { .code= "YE", .name= "Yemen" }, - { .code= "ZM", .name= "Zambia" }, - { .code= "ZW", .name= "Zimbabwe" } - }; -} + struct CountryInfo { + std::string code; + std::string name; + }; + inline static const std::vector CountryCodes{ + {.code = "US", .name = "United States"}, + {.code = "GB", .name = "United Kingdom"}, + {.code = "CA", .name = "Canada"}, + {.code = "AF", .name = "Afghanistan"}, + {.code = "AX", .name = "Aland Islands"}, + {.code = "AL", .name = "Albania"}, + {.code = "DZ", .name = "Algeria"}, + {.code = "AS", .name = "American Samoa"}, + {.code = "AD", .name = "Andorra"}, + {.code = "AO", .name = "Angola"}, + {.code = "AI", .name = "Anguilla"}, + {.code = "AQ", .name = "Antarctica"}, + {.code = "AG", .name = "Antigua And Barbuda"}, + {.code = "AR", .name = "Argentina"}, + {.code = "AM", .name = "Armenia"}, + {.code = "AN", .name = "Netherlands Antilles"}, + {.code = "AW", .name = "Aruba"}, + {.code = "AU", .name = "Australia"}, + {.code = "AT", .name = "Austria"}, + {.code = "AZ", .name = "Azerbaijan"}, + {.code = "BS", .name = "Bahamas"}, + {.code = "BH", .name = "Bahrain"}, + {.code = "BD", .name = "Bangladesh"}, + {.code = "BB", .name = "Barbados"}, + {.code = "BY", .name = "Belarus"}, + {.code = "BE", .name = "Belgium"}, + {.code = "BZ", .name = "Belize"}, + {.code = "BJ", .name = "Benin"}, + {.code = "BM", .name = "Bermuda"}, + {.code = "BT", .name = "Bhutan"}, + {.code = "BO", .name = "Bolivia"}, + {.code = "BA", .name = "Bosnia And Herzegovina"}, + {.code = "BW", .name = "Botswana"}, + {.code = "BV", .name = "Bouvet Island"}, + {.code = "BR", .name = "Brazil"}, + {.code = "IO", .name = "British Indian Ocean Territory"}, + {.code = "BN", .name = "Brunei Darussalam"}, + {.code = "BG", .name = "Bulgaria"}, + {.code = "BF", .name = "Burkina Faso"}, + {.code = "BI", .name = "Burundi"}, + {.code = "KH", .name = "Cambodia"}, + {.code = "CM", .name = "Cameroon"}, + {.code = "CA", .name = "Canada"}, + {.code = "CV", .name = "Cape Verde"}, + {.code = "KY", .name = "Cayman Islands"}, + {.code = "CF", .name = "Central African Republic"}, + {.code = "TD", .name = "Chad"}, + {.code = "CL", .name = "Chile"}, + {.code = "CN", .name = "China"}, + {.code = "CX", .name = "Christmas Island"}, + {.code = "CC", .name = "Cocos (Keeling) Islands"}, + {.code = "CO", .name = "Colombia"}, + {.code = "KM", .name = "Comoros"}, + {.code = "CG", .name = "Congo"}, + {.code = "CD", .name = "Congo, Democratic Republic"}, + {.code = "CK", .name = "Cook Islands"}, + {.code = "CR", .name = "Costa Rica"}, + {.code = "CI", .name = "Cote D\"Ivoire"}, + {.code = "HR", .name = "Croatia"}, + {.code = "CU", .name = "Cuba"}, + {.code = "CY", .name = "Cyprus"}, + {.code = "CZ", .name = "Czech Republic"}, + {.code = "DK", .name = "Denmark"}, + {.code = "DJ", .name = "Djibouti"}, + {.code = "DM", .name = "Dominica"}, + {.code = "DO", .name = "Dominican Republic"}, + {.code = "EC", .name = "Ecuador"}, + {.code = "EG", .name = "Egypt"}, + {.code = "SV", .name = "El Salvador"}, + {.code = "GQ", .name = "Equatorial Guinea"}, + {.code = "ER", .name = "Eritrea"}, + {.code = "EE", .name = "Estonia"}, + {.code = "ET", .name = "Ethiopia"}, + {.code = "FK", .name = "Falkland Islands (Malvinas)"}, + {.code = "FO", .name = "Faroe Islands"}, + {.code = "FJ", .name = "Fiji"}, + {.code = "FI", .name = "Finland"}, + {.code = "FR", .name = "France"}, + {.code = "GF", .name = "French Guiana"}, + {.code = "PF", .name = "French Polynesia"}, + {.code = "TF", .name = "French Southern Territories"}, + {.code = "GA", .name = "Gabon"}, + {.code = "GM", .name = "Gambia"}, + {.code = "GE", .name = "Georgia"}, + {.code = "DE", .name = "Germany"}, + {.code = "GH", .name = "Ghana"}, + {.code = "GI", .name = "Gibraltar"}, + {.code = "GR", .name = "Greece"}, + {.code = "GL", .name = "Greenland"}, + {.code = "GD", .name = "Grenada"}, + {.code = "GP", .name = "Guadeloupe"}, + {.code = "GU", .name = "Guam"}, + {.code = "GT", .name = "Guatemala"}, + {.code = "GG", .name = "Guernsey"}, + {.code = "GN", .name = "Guinea"}, + {.code = "GW", .name = "Guinea-Bissau"}, + {.code = "GY", .name = "Guyana"}, + {.code = "HT", .name = "Haiti"}, + {.code = "HM", .name = "Heard Island & Mcdonald Islands"}, + {.code = "VA", .name = "Holy See (Vatican City State)"}, + {.code = "HN", .name = "Honduras"}, + {.code = "HK", .name = "Hong Kong"}, + {.code = "HU", .name = "Hungary"}, + {.code = "IS", .name = "Iceland"}, + {.code = "IN", .name = "India"}, + {.code = "ID", .name = "Indonesia"}, + {.code = "IR", .name = "Iran, Islamic Republic Of"}, + {.code = "IQ", .name = "Iraq"}, + {.code = "IE", .name = "Ireland"}, + {.code = "IM", .name = "Isle Of Man"}, + {.code = "IL", .name = "Israel"}, + {.code = "IT", .name = "Italy"}, + {.code = "JM", .name = "Jamaica"}, + {.code = "JP", .name = "Japan"}, + {.code = "JE", .name = "Jersey"}, + {.code = "JO", .name = "Jordan"}, + {.code = "KZ", .name = "Kazakhstan"}, + {.code = "KE", .name = "Kenya"}, + {.code = "KI", .name = "Kiribati"}, + {.code = "KR", .name = "Korea"}, + {.code = "KW", .name = "Kuwait"}, + {.code = "KG", .name = "Kyrgyzstan"}, + {.code = "LA", .name = "Lao People\"s Democratic Republic"}, + {.code = "LV", .name = "Latvia"}, + {.code = "LB", .name = "Lebanon"}, + {.code = "LS", .name = "Lesotho"}, + {.code = "LR", .name = "Liberia"}, + {.code = "LY", .name = "Libyan Arab Jamahiriya"}, + {.code = "LI", .name = "Liechtenstein"}, + {.code = "LT", .name = "Lithuania"}, + {.code = "LU", .name = "Luxembourg"}, + {.code = "MO", .name = "Macao"}, + {.code = "MK", .name = "Macedonia"}, + {.code = "MG", .name = "Madagascar"}, + {.code = "MW", .name = "Malawi"}, + {.code = "MY", .name = "Malaysia"}, + {.code = "MV", .name = "Maldives"}, + {.code = "ML", .name = "Mali"}, + {.code = "MT", .name = "Malta"}, + {.code = "MH", .name = "Marshall Islands"}, + {.code = "MQ", .name = "Martinique"}, + {.code = "MR", .name = "Mauritania"}, + {.code = "MU", .name = "Mauritius"}, + {.code = "YT", .name = "Mayotte"}, + {.code = "MX", .name = "Mexico"}, + {.code = "FM", .name = "Micronesia, Federated States Of"}, + {.code = "MD", .name = "Moldova"}, + {.code = "MC", .name = "Monaco"}, + {.code = "MN", .name = "Mongolia"}, + {.code = "ME", .name = "Montenegro"}, + {.code = "MS", .name = "Montserrat"}, + {.code = "MA", .name = "Morocco"}, + {.code = "MZ", .name = "Mozambique"}, + {.code = "MM", .name = "Myanmar"}, + {.code = "NA", .name = "Namibia"}, + {.code = "NR", .name = "Nauru"}, + {.code = "NP", .name = "Nepal"}, + {.code = "NL", .name = "Netherlands"}, + {.code = "AN", .name = "Netherlands Antilles"}, + {.code = "NC", .name = "New Caledonia"}, + {.code = "NZ", .name = "New Zealand"}, + {.code = "NI", .name = "Nicaragua"}, + {.code = "NE", .name = "Niger"}, + {.code = "NG", .name = "Nigeria"}, + {.code = "NU", .name = "Niue"}, + {.code = "NF", .name = "Norfolk Island"}, + {.code = "MP", .name = "Northern Mariana Islands"}, + {.code = "NO", .name = "Norway"}, + {.code = "OM", .name = "Oman"}, + {.code = "PK", .name = "Pakistan"}, + {.code = "PW", .name = "Palau"}, + {.code = "PS", .name = "Palestinian Territory, Occupied"}, + {.code = "PA", .name = "Panama"}, + {.code = "PG", .name = "Papua New Guinea"}, + {.code = "PY", .name = "Paraguay"}, + {.code = "PE", .name = "Peru"}, + {.code = "PH", .name = "Philippines"}, + {.code = "PN", .name = "Pitcairn"}, + {.code = "PL", .name = "Poland"}, + {.code = "PT", .name = "Portugal"}, + {.code = "PR", .name = "Puerto Rico"}, + {.code = "QA", .name = "Qatar"}, + {.code = "RE", .name = "Reunion"}, + {.code = "RO", .name = "Romania"}, + {.code = "RU", .name = "Russian Federation"}, + {.code = "RW", .name = "Rwanda"}, + {.code = "BL", .name = "Saint Barthelemy"}, + {.code = "SH", .name = "Saint Helena"}, + {.code = "KN", .name = "Saint Kitts And Nevis"}, + {.code = "LC", .name = "Saint Lucia"}, + {.code = "MF", .name = "Saint Martin"}, + {.code = "PM", .name = "Saint Pierre And Miquelon"}, + {.code = "VC", .name = "Saint Vincent And Grenadines"}, + {.code = "WS", .name = "Samoa"}, + {.code = "SM", .name = "San Marino"}, + {.code = "ST", .name = "Sao Tome And Principe"}, + {.code = "SA", .name = "Saudi Arabia"}, + {.code = "SN", .name = "Senegal"}, + {.code = "RS", .name = "Serbia"}, + {.code = "SC", .name = "Seychelles"}, + {.code = "SL", .name = "Sierra Leone"}, + {.code = "SG", .name = "Singapore"}, + {.code = "SK", .name = "Slovakia"}, + {.code = "SI", .name = "Slovenia"}, + {.code = "SB", .name = "Solomon Islands"}, + {.code = "SO", .name = "Somalia"}, + {.code = "ZA", .name = "South Africa"}, + {.code = "GS", .name = "South Georgia And Sandwich Isl."}, + {.code = "ES", .name = "Spain"}, + {.code = "LK", .name = "Sri Lanka"}, + {.code = "SD", .name = "Sudan"}, + {.code = "SR", .name = "Suriname"}, + {.code = "SJ", .name = "Svalbard And Jan Mayen"}, + {.code = "SZ", .name = "Swaziland"}, + {.code = "SE", .name = "Sweden"}, + {.code = "CH", .name = "Switzerland"}, + {.code = "SY", .name = "Syrian Arab Republic"}, + {.code = "TW", .name = "Taiwan"}, + {.code = "TJ", .name = "Tajikistan"}, + {.code = "TZ", .name = "Tanzania"}, + {.code = "TH", .name = "Thailand"}, + {.code = "TL", .name = "Timor-Leste"}, + {.code = "TG", .name = "Togo"}, + {.code = "TK", .name = "Tokelau"}, + {.code = "TO", .name = "Tonga"}, + {.code = "TT", .name = "Trinidad And Tobago"}, + {.code = "TN", .name = "Tunisia"}, + {.code = "TR", .name = "Turkey"}, + {.code = "TM", .name = "Turkmenistan"}, + {.code = "TC", .name = "Turks And Caicos Islands"}, + {.code = "TV", .name = "Tuvalu"}, + {.code = "UG", .name = "Uganda"}, + {.code = "UA", .name = "Ukraine"}, + {.code = "AE", .name = "United Arab Emirates"}, + {.code = "GB", .name = "United Kingdom"}, + {.code = "US", .name = "United States"}, + {.code = "UM", .name = "United States Outlying Islands"}, + {.code = "UY", .name = "Uruguay"}, + {.code = "UZ", .name = "Uzbekistan"}, + {.code = "VU", .name = "Vanuatu"}, + {.code = "VE", .name = "Venezuela"}, + {.code = "VN", .name = "Viet Nam"}, + {.code = "VG", .name = "Virgin Islands, British"}, + {.code = "VI", .name = "Virgin Islands, U.S."}, + {.code = "WF", .name = "Wallis And Futuna"}, + {.code = "EH", .name = "Western Sahara"}, + {.code = "YE", .name = "Yemen"}, + {.code = "ZM", .name = "Zambia"}, + {.code = "ZW", .name = "Zimbabwe"}}; + +} // namespace OpenWifi diff --git a/src/framework/EventBusManager.cpp b/src/framework/EventBusManager.cpp index 967ca58..ef182bf 100644 --- a/src/framework/EventBusManager.cpp +++ b/src/framework/EventBusManager.cpp @@ -4,45 +4,46 @@ #include "framework/EventBusManager.h" #include "framework/KafkaManager.h" -#include "framework/utils.h" #include "framework/MicroServiceFuncs.h" +#include "framework/utils.h" namespace OpenWifi { - EventBusManager::EventBusManager(Poco::Logger &L) : - Logger_(L) { - } + EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {} void EventBusManager::run() { Running_ = true; Utils::SetThreadName("fmwk:EventMgr"); auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN); - KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); - while(Running_) { + KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg, + false); + while (Running_) { Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer()); - if(!Running_) + if (!Running_) break; Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE); - KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); + KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), + Msg, false); } Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE); - KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false); + KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg, + false); }; void EventBusManager::Start() { - poco_information(Logger(),"Starting..."); - if(KafkaManager()->Enabled()) { + poco_information(Logger(), "Starting..."); + if (KafkaManager()->Enabled()) { Thread_.start(*this); } } void EventBusManager::Stop() { - if(KafkaManager()->Enabled()) { - poco_information(Logger(),"Stopping..."); + if (KafkaManager()->Enabled()) { + poco_information(Logger(), "Stopping..."); Running_ = false; Thread_.wakeUp(); Thread_.join(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } } diff --git a/src/framework/EventBusManager.h b/src/framework/EventBusManager.h index 4b57d20..9a7316e 100644 --- a/src/framework/EventBusManager.h +++ b/src/framework/EventBusManager.h @@ -4,8 +4,8 @@ #pragma once -#include "Poco/Runnable.h" #include "Poco/Logger.h" +#include "Poco/Runnable.h" #include "Poco/Thread.h" namespace OpenWifi { @@ -16,13 +16,12 @@ namespace OpenWifi { void run() final; void Start(); void Stop(); - inline Poco::Logger & Logger() { return Logger_; } + inline Poco::Logger &Logger() { return Logger_; } private: - mutable std::atomic_bool Running_ = false; - Poco::Thread Thread_; - Poco::Logger &Logger_; + mutable std::atomic_bool Running_ = false; + Poco::Thread Thread_; + Poco::Logger &Logger_; }; } // namespace OpenWifi - diff --git a/src/framework/KafkaManager.cpp b/src/framework/KafkaManager.cpp index 5733c93..af37a8d 100644 --- a/src/framework/KafkaManager.cpp +++ b/src/framework/KafkaManager.cpp @@ -4,251 +4,260 @@ #include "KafkaManager.h" -#include "framework/MicroServiceFuncs.h" #include "fmt/format.h" +#include "framework/MicroServiceFuncs.h" namespace OpenWifi { - void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) { - switch ((cppkafka::LogLevel) level) { + void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int level, + const std::string &facility, const std::string &message) { + switch ((cppkafka::LogLevel)level) { case cppkafka::LogLevel::LogNotice: { - poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_notice(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; case cppkafka::LogLevel::LogDebug: { - poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_debug(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; case cppkafka::LogLevel::LogInfo: { - poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_information(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; case cppkafka::LogLevel::LogWarning: { - poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_warning(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; case cppkafka::LogLevel::LogAlert: case cppkafka::LogLevel::LogCrit: { - poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_critical(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; case cppkafka::LogLevel::LogErr: case cppkafka::LogLevel::LogEmerg: default: { - poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); - } - break; + poco_error(KafkaManager()->Logger(), + fmt::format("kafka-log: facility: {} message: {}", facility, message)); + } break; } } - inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) { - poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason)); + inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int error, + const std::string &reason) { + poco_error(KafkaManager()->Logger(), + fmt::format("kafka-error: {}, reason: {}", error, reason)); } - inline void AddKafkaSecurity(cppkafka::Configuration & Config) { - auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location",""); - auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location",""); - auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location",""); - auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password",""); + inline void AddKafkaSecurity(cppkafka::Configuration &Config) { + auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location", ""); + auto Certificate = + MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location", ""); + auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location", ""); + auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password", ""); - if(CA.empty() || Certificate.empty() || Key.empty()) + if (CA.empty() || Certificate.empty() || Key.empty()) return; Config.set("ssl.ca.location", CA); Config.set("ssl.certificate.location", Certificate); Config.set("ssl.key.location", Key); - if(!Password.empty()) + if (!Password.empty()) Config.set("ssl.key.password", Password); } - - void KafkaManager::initialize(Poco::Util::Application & self) { + void KafkaManager::initialize(Poco::Util::Application &self) { SubSystemServer::initialize(self); - KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false); + KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable", false); } inline void KafkaProducer::run() { - Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel()); - poco_information(Logger_,"Starting..."); + Poco::Logger &Logger_ = + Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel()); + poco_information(Logger_, "Starting..."); Utils::SetThreadName("Kafka:Prod"); - cppkafka::Configuration Config({ - { "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") }, - { "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") } - }); + cppkafka::Configuration Config( + {{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")}, + {"metadata.broker.list", + MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}}); AddKafkaSecurity(Config); Config.set_log_callback(KafkaLoggerFun); Config.set_error_callback(KafkaErrorFun); - KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" + - std::to_string(MicroServiceID()) + - R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() + - R"lit(" } , "payload" : )lit" ; + KafkaManager()->SystemInfoWrapper_ = + R"lit({ "system" : { "id" : )lit" + std::to_string(MicroServiceID()) + + R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() + + R"lit(" } , "payload" : )lit"; - cppkafka::Producer Producer(Config); + cppkafka::Producer Producer(Config); Running_ = true; - Poco::AutoPtr Note(Queue_.waitDequeueNotification()); - while(Note && Running_) { + Poco::AutoPtr Note(Queue_.waitDequeueNotification()); + while (Note && Running_) { try { auto Msg = dynamic_cast(Note.get()); if (Msg != nullptr) { - Producer.produce( - cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload())); + Producer.produce(cppkafka::MessageBuilder(Msg->Topic()) + .key(Msg->Key()) + .payload(Msg->Payload())); } } catch (const cppkafka::HandleException &E) { - poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what())); - } catch( const Poco::Exception &E) { + poco_warning(Logger_, + fmt::format("Caught a Kafka exception (producer): {}", E.what())); + } catch (const Poco::Exception &E) { Logger_.log(E); } catch (...) { - poco_error(Logger_,"std::exception"); + poco_error(Logger_, "std::exception"); } Note = Queue_.waitDequeueNotification(); } - poco_information(Logger_,"Stopped..."); + poco_information(Logger_, "Stopped..."); } inline void KafkaConsumer::run() { Utils::SetThreadName("Kafka:Cons"); - Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel()); + Poco::Logger &Logger_ = + Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel()); - poco_information(Logger_,"Starting..."); + poco_information(Logger_, "Starting..."); - cppkafka::Configuration Config({ - { "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") }, - { "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") }, - { "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") }, - { "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) }, - { "auto.offset.reset", "latest" } , - { "enable.partition.eof", false } - }); + cppkafka::Configuration Config( + {{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")}, + {"metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}, + {"group.id", MicroServiceConfigGetString("openwifi.kafka.group.id", "")}, + {"enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false)}, + {"auto.offset.reset", "latest"}, + {"enable.partition.eof", false}}); AddKafkaSecurity(Config); Config.set_log_callback(KafkaLoggerFun); Config.set_error_callback(KafkaErrorFun); - cppkafka::TopicConfiguration topic_config = { - { "auto.offset.reset", "smallest" } - }; + cppkafka::TopicConfiguration topic_config = {{"auto.offset.reset", "smallest"}}; // Now configure it to be the default topic config Config.set_default_topic_configuration(topic_config); cppkafka::Consumer Consumer(Config); - Consumer.set_assignment_callback([&](cppkafka::TopicPartitionList& partitions) { - if(!partitions.empty()) { - poco_information(Logger_,fmt::format("Partition assigned: {}...", - partitions.front().get_partition())); + Consumer.set_assignment_callback([&](cppkafka::TopicPartitionList &partitions) { + if (!partitions.empty()) { + poco_information(Logger_, fmt::format("Partition assigned: {}...", + partitions.front().get_partition())); } }); - Consumer.set_revocation_callback([&](const cppkafka::TopicPartitionList& partitions) { - if(!partitions.empty()) { - poco_information(Logger_,fmt::format("Partition revocation: {}...", - partitions.front().get_partition())); + Consumer.set_revocation_callback([&](const cppkafka::TopicPartitionList &partitions) { + if (!partitions.empty()) { + poco_information(Logger_, fmt::format("Partition revocation: {}...", + partitions.front().get_partition())); } }); - bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false); - auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize",20); + bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false); + auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 20); - Types::StringVec Topics; + Types::StringVec Topics; KafkaManager()->Topics(Topics); Consumer.subscribe(Topics); Running_ = true; - while(Running_) { + while (Running_) { try { - std::vector MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100)); - for(auto const &Msg:MsgVec) { + std::vector MsgVec = + Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100)); + for (auto const &Msg : MsgVec) { if (!Msg) continue; if (Msg.get_error()) { if (!Msg.is_eof()) { - poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string())); + poco_error(Logger_, + fmt::format("Error: {}", Msg.get_error().to_string())); } - if(!AutoCommit) + if (!AutoCommit) Consumer.async_commit(Msg); continue; } - KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() ); + KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(), Msg.get_payload()); if (!AutoCommit) Consumer.async_commit(Msg); } } catch (const cppkafka::HandleException &E) { - poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what())); + poco_warning(Logger_, + fmt::format("Caught a Kafka exception (consumer): {}", E.what())); } catch (const Poco::Exception &E) { Logger_.log(E); } catch (...) { - poco_error(Logger_,"std::exception"); + poco_error(Logger_, "std::exception"); } } Consumer.unsubscribe(); - poco_information(Logger_,"Stopped..."); + poco_information(Logger_, "Stopped..."); } void KafkaProducer::Start() { - if(!Running_) { - Running_=true; + if (!Running_) { + Running_ = true; Worker_.start(*this); } } void KafkaProducer::Stop() { - if(Running_) { - Running_=false; + if (Running_) { + Running_ = false; Queue_.wakeUpAll(); Worker_.join(); } } - void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) { - std::lock_guard G(Mutex_); - Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload)); + void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, + const std::string &Payload) { + std::lock_guard G(Mutex_); + Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload)); } void KafkaConsumer::Start() { - if(!Running_) { - Running_=true; + if (!Running_) { + Running_ = true; Worker_.start(*this); } } void KafkaConsumer::Stop() { - if(Running_) { - Running_=false; + if (Running_) { + Running_ = false; Worker_.wakeUp(); Worker_.join(); } } void KafkaDispatcher::Start() { - if(!Running_) { - Running_=true; + if (!Running_) { + Running_ = true; Worker_.start(*this); } } void KafkaDispatcher::Stop() { - if(Running_) { - Running_=false; + if (Running_) { + Running_ = false; Queue_.wakeUpAll(); Worker_.join(); } } - auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { + auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, + Types::TopicNotifyFunction &F) { std::lock_guard G(Mutex_); auto It = Notifiers_.find(Topic); - if(It == Notifiers_.end()) { + if (It == Notifiers_.end()) { Types::TopicNotifyFunctionList L; - L.emplace(L.end(),std::make_pair(F,FunctionId_)); + L.emplace(L.end(), std::make_pair(F, FunctionId_)); Notifiers_[Topic] = std::move(L); } else { - It->second.emplace(It->second.end(),std::make_pair(F,FunctionId_)); + It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_)); } return FunctionId_++; } @@ -256,110 +265,114 @@ namespace OpenWifi { void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) { std::lock_guard G(Mutex_); auto It = Notifiers_.find(Topic); - if(It != Notifiers_.end()) { - Types::TopicNotifyFunctionList & L = It->second; - for(auto it=L.begin(); it!=L.end(); it++) - if(it->second == Id) { + if (It != Notifiers_.end()) { + Types::TopicNotifyFunctionList &L = It->second; + for (auto it = L.begin(); it != L.end(); it++) + if (it->second == Id) { L.erase(it); break; } } } - void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) { - std::lock_guard G(Mutex_); + void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, + const std::string &Payload) { + std::lock_guard G(Mutex_); auto It = Notifiers_.find(Topic); - if(It!=Notifiers_.end()) { + if (It != Notifiers_.end()) { Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload)); } } void KafkaDispatcher::run() { - Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel()); - poco_information(Logger_,"Starting..."); - Poco::AutoPtr Note(Queue_.waitDequeueNotification()); + Poco::Logger &Logger_ = + Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel()); + poco_information(Logger_, "Starting..."); + Poco::AutoPtr Note(Queue_.waitDequeueNotification()); Utils::SetThreadName("kafka:dispatch"); - while(Note && Running_) { - auto Msg = dynamic_cast(Note.get()); - if(Msg!= nullptr) { + while (Note && Running_) { + auto Msg = dynamic_cast(Note.get()); + if (Msg != nullptr) { auto It = Notifiers_.find(Msg->Topic()); if (It != Notifiers_.end()) { - const auto & FL = It->second; - for(const auto &[CallbackFunc,_]:FL) { + const auto &FL = It->second; + for (const auto &[CallbackFunc, _] : FL) { CallbackFunc(Msg->Key(), Msg->Payload()); } } } Note = Queue_.waitDequeueNotification(); } - poco_information(Logger_,"Stopped..."); + poco_information(Logger_, "Stopped..."); } void KafkaDispatcher::Topics(std::vector &T) { T.clear(); - for(const auto &[TopicName,_]:Notifiers_) + for (const auto &[TopicName, _] : Notifiers_) T.push_back(TopicName); } - int KafkaManager::Start() { - if(!KafkaEnabled_) + if (!KafkaEnabled_) return 0; - ConsumerThr_.Start(); + ConsumerThr_.Start(); ProducerThr_.Start(); Dispatcher_.Start(); return 0; } - void KafkaManager::Stop() { - if(KafkaEnabled_) { - poco_information(Logger(),"Stopping..."); + void KafkaManager::Stop() { + if (KafkaEnabled_) { + poco_information(Logger(), "Stopping..."); Dispatcher_.Stop(); ProducerThr_.Stop(); ConsumerThr_.Stop(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); return; } } - void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) { - if(KafkaEnabled_) { - ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad); + void KafkaManager::PostMessage(const std::string &topic, const std::string &key, + const std::string &PayLoad, bool WrapMessage) { + if (KafkaEnabled_) { + ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad); } } - void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) { + void KafkaManager::Dispatch(const std::string &Topic, const std::string &Key, + const std::string &Payload) { Dispatcher_.Dispatch(Topic, Key, Payload); } - [[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) { + [[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string &PayLoad) { return SystemInfoWrapper_ + PayLoad + "}"; } - uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) { - if(KafkaEnabled_) { - return Dispatcher_.RegisterTopicWatcher(Topic,F); + uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, + Types::TopicNotifyFunction &F) { + if (KafkaEnabled_) { + return Dispatcher_.RegisterTopicWatcher(Topic, F); } else { return 0; } } void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) { - if(KafkaEnabled_) { + if (KafkaEnabled_) { Dispatcher_.UnregisterTopicWatcher(Topic, Id); } } - void KafkaManager::Topics(std::vector &T) { - Dispatcher_.Topics(T); + void KafkaManager::Topics(std::vector &T) { Dispatcher_.Topics(T); } + + void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) { + poco_information( + Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition())); } - void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) { - poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition())); - } - - void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) { - poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition())); + void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList &partitions) { + poco_information(Logger(), fmt::format("Partition revocation: {}...", + partitions.front().get_partition())); } } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/KafkaManager.h b/src/framework/KafkaManager.h index e96f25c..b9630df 100644 --- a/src/framework/KafkaManager.h +++ b/src/framework/KafkaManager.h @@ -7,44 +7,43 @@ #include "Poco/Notification.h" #include "Poco/NotificationQueue.h" -#include "framework/SubSystemServer.h" -#include "framework/OpenWifiTypes.h" -#include "framework/utils.h" #include "framework/KafkaTopics.h" +#include "framework/OpenWifiTypes.h" +#include "framework/SubSystemServer.h" +#include "framework/utils.h" #include "cppkafka/cppkafka.h" namespace OpenWifi { - class KafkaMessage: public Poco::Notification { + class KafkaMessage : public Poco::Notification { public: - KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) : - Topic_(Topic), Key_(Key), Payload_(Payload) { - } + KafkaMessage(const std::string &Topic, const std::string &Key, const std::string &Payload) + : Topic_(Topic), Key_(Key), Payload_(Payload) {} - inline const std::string & Topic() { return Topic_; } - inline const std::string & Key() { return Key_; } - inline const std::string & Payload() { return Payload_; } + inline const std::string &Topic() { return Topic_; } + inline const std::string &Key() { return Key_; } + inline const std::string &Payload() { return Payload_; } private: - std::string Topic_; - std::string Key_; - std::string Payload_; + std::string Topic_; + std::string Key_; + std::string Payload_; }; class KafkaProducer : public Poco::Runnable { - public: - void run () override; - void Start(); - void Stop(); - void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload); + public: + void run() override; + void Start(); + void Stop(); + void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload); private: - std::recursive_mutex Mutex_; - Poco::Thread Worker_; - mutable std::atomic_bool Running_=false; - Poco::NotificationQueue Queue_; - }; + std::recursive_mutex Mutex_; + Poco::Thread Worker_; + mutable std::atomic_bool Running_ = false; + Poco::NotificationQueue Queue_; + }; class KafkaConsumer : public Poco::Runnable { public: @@ -53,9 +52,9 @@ namespace OpenWifi { void Stop(); private: - std::recursive_mutex Mutex_; - Poco::Thread Worker_; - mutable std::atomic_bool Running_=false; + std::recursive_mutex Mutex_; + Poco::Thread Worker_; + mutable std::atomic_bool Running_ = false; }; class KafkaDispatcher : public Poco::Runnable { @@ -69,21 +68,20 @@ namespace OpenWifi { void Topics(std::vector &T); private: - std::recursive_mutex Mutex_; - Types::NotifyTable Notifiers_; - Poco::Thread Worker_; - mutable std::atomic_bool Running_=false; - uint64_t FunctionId_=1; - Poco::NotificationQueue Queue_; + std::recursive_mutex Mutex_; + Types::NotifyTable Notifiers_; + Poco::Thread Worker_; + mutable std::atomic_bool Running_ = false; + uint64_t FunctionId_ = 1; + Poco::NotificationQueue Queue_; }; class KafkaManager : public SubSystemServer { public: - friend class KafkaConsumer; friend class KafkaProducer; - inline void initialize(Poco::Util::Application & self) override; + inline void initialize(Poco::Util::Application &self) override; static auto instance() { static auto instance_ = new KafkaManager; @@ -93,30 +91,28 @@ namespace OpenWifi { int Start() override; void Stop() override; - void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true ); - void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload); - [[nodiscard]] std::string WrapSystemId(const std::string & PayLoad); + void PostMessage(const std::string &topic, const std::string &key, + const std::string &PayLoad, bool WrapMessage = true); + void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload); + [[nodiscard]] std::string WrapSystemId(const std::string &PayLoad); [[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; } uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F); void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id); void Topics(std::vector &T); private: - bool KafkaEnabled_ = false; - std::string SystemInfoWrapper_; - KafkaProducer ProducerThr_; - KafkaConsumer ConsumerThr_; - KafkaDispatcher Dispatcher_; + bool KafkaEnabled_ = false; + std::string SystemInfoWrapper_; + KafkaProducer ProducerThr_; + KafkaConsumer ConsumerThr_; + KafkaDispatcher Dispatcher_; - void PartitionAssignment(const cppkafka::TopicPartitionList& partitions); - void PartitionRevocation(const cppkafka::TopicPartitionList& partitions); + void PartitionAssignment(const cppkafka::TopicPartitionList &partitions); + void PartitionRevocation(const cppkafka::TopicPartitionList &partitions); - KafkaManager() noexcept: - SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") { - } + KafkaManager() noexcept : SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {} }; inline auto KafkaManager() { return KafkaManager::instance(); } } // namespace OpenWifi - diff --git a/src/framework/KafkaTopics.h b/src/framework/KafkaTopics.h index c2b7392..4c93b59 100644 --- a/src/framework/KafkaTopics.h +++ b/src/framework/KafkaTopics.h @@ -19,7 +19,7 @@ namespace OpenWifi::KafkaTopics { static const std::string SERVICE_EVENTS{"service_events"}; static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"}; static const std::string DEVICE_TELEMETRY{"device_telemetry"}; - static const std::string PROVISIONING_CHANGE{"provisioning_change"}; + static const std::string PROVISIONING_CHANGE{"provisioning_change"}; namespace ServiceEvents { static const std::string EVENT_JOIN{"join"}; @@ -36,7 +36,6 @@ namespace OpenWifi::KafkaTopics { static const std::string KEY{"key"}; static const std::string VRSN{"version"}; static const std::string TOKEN{"token"}; - } - } -} - + } // namespace Fields + } // namespace ServiceEvents +} // namespace OpenWifi::KafkaTopics diff --git a/src/framework/MicroService.cpp b/src/framework/MicroService.cpp index 5112e58..31d6837 100644 --- a/src/framework/MicroService.cpp +++ b/src/framework/MicroService.cpp @@ -2,40 +2,39 @@ // Created by stephane bourque on 2022-10-26. // -#include "Poco/FileChannel.h" -#include "Poco/ConsoleChannel.h" -#include "Poco/PatternFormatter.h" -#include "Poco/FormattingChannel.h" #include "Poco/AsyncChannel.h" -#include "Poco/NullChannel.h" -#include "Poco/SplitterChannel.h" -#include "Poco/Net/HTTPStreamFactory.h" -#include "Poco/Net/HTTPSStreamFactory.h" +#include "Poco/ConsoleChannel.h" +#include "Poco/FileChannel.h" +#include "Poco/FormattingChannel.h" +#include "Poco/JSON/JSONException.h" #include "Poco/Net/FTPSStreamFactory.h" #include "Poco/Net/FTPStreamFactory.h" +#include "Poco/Net/HTTPSStreamFactory.h" +#include "Poco/Net/HTTPStreamFactory.h" #include "Poco/Net/SSLManager.h" -#include "Poco/JSON/JSONException.h" +#include "Poco/NullChannel.h" +#include "Poco/PatternFormatter.h" +#include "Poco/SplitterChannel.h" +#include "framework/ALBserver.h" +#include "framework/AuthClient.h" +#include "framework/KafkaManager.h" #include "framework/MicroService.h" #include "framework/MicroServiceErrorHandler.h" -#include "framework/UI_WebSocketClientServer.h" #include "framework/MicroServiceNames.h" -#include "framework/AuthClient.h" -#include "framework/ALBserver.h" -#include "framework/KafkaManager.h" -#include "framework/RESTAPI_GenericServerAccounting.h" #include "framework/RESTAPI_ExtServer.h" +#include "framework/RESTAPI_GenericServerAccounting.h" #include "framework/RESTAPI_IntServer.h" -#include "framework/utils.h" +#include "framework/UI_WebSocketClientServer.h" #include "framework/WebSocketLogger.h" +#include "framework/utils.h" namespace OpenWifi { - void MicroService::Exit(int Reason) { - std::exit(Reason); - } + void MicroService::Exit(int Reason) { std::exit(Reason); } - void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) { + void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, + const std::string &Payload) { std::lock_guard G(InfraMutex_); try { Poco::JSON::Parser P; @@ -43,66 +42,99 @@ namespace OpenWifi { if (Object->has(KafkaTopics::ServiceEvents::Fields::ID) && Object->has(KafkaTopics::ServiceEvents::Fields::EVENT)) { - uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID); - auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString(); + uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID); + auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString(); if (ID != ID_) { - if( Event==KafkaTopics::ServiceEvents::EVENT_JOIN || - Event==KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE || - Event==KafkaTopics::ServiceEvents::EVENT_LEAVE ) { - if( Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) && + if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || + Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE || + Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) { + if (Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) && Object->has(KafkaTopics::ServiceEvents::Fields::PUBLIC) && Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) && Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) && Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) { - auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(); - if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) { + auto PrivateEndPoint = + Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(); + if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && + Services_.find(PrivateEndPoint) != Services_.end()) { Services_[PrivateEndPoint].LastUpdate = Utils::Now(); } else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) { Services_.erase(PrivateEndPoint); - poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID)); - } else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) { - poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID)); + poco_debug( + logger(), + fmt::format( + "Service {} ID={} leaving system.", + Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE) + .toString(), + ID)); + } else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || + Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) { + poco_debug( + logger(), + fmt::format( + "Service {} ID={} joining system.", + Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE) + .toString(), + ID)); Services_[PrivateEndPoint] = Types::MicroServiceMeta{ .Id = ID, - .Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()), - .PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(), - .PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(), - .AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(), - .Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(), - .LastUpdate = Utils::Now() }; + .Type = Poco::toLower( + Object->get(KafkaTopics::ServiceEvents::Fields::TYPE) + .toString()), + .PrivateEndPoint = + Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE) + .toString(), + .PublicEndPoint = + Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC) + .toString(), + .AccessKey = + Object->get(KafkaTopics::ServiceEvents::Fields::KEY) + .toString(), + .Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN) + .toString(), + .LastUpdate = Utils::Now()}; std::string SvcList; - for (const auto &Svc: Services_) { - if(SvcList.empty()) + for (const auto &Svc : Services_) { + if (SvcList.empty()) SvcList = Svc.second.Type; else SvcList += ", " + Svc.second.Type; } - poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList)); + poco_information( + logger(), + fmt::format("Current list of microservices: {}", SvcList)); } } else { - poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event)); + poco_error( + logger(), + fmt::format("KAFKA-MSG: invalid event '{}', missing a field.", + Event)); } - } else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) { - if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) { - #ifndef TIP_SECURITY_SERVICE - AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString()); - #endif + } else if (Event == KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) { + if (Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) { +#ifndef TIP_SECURITY_SERVICE + AuthClient()->RemovedCachedToken( + Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString()); +#endif } else { - poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event)); + poco_error( + logger(), + fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event)); } } else { - poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID)); + poco_error(logger(), + fmt::format("Unknown Event: {} Source: {}", Event, ID)); } } } else { - poco_error(logger(),"Bad bus message."); + poco_error(logger(), "Bad bus message."); } - auto i=Services_.begin(); + auto i = Services_.begin(); auto now = Utils::Now(); - for(;i!=Services_.end();) { - if((now - i->second.LastUpdate)>60) { + for (; i != Services_.end();) { + if ((now - i->second.LastUpdate) > 60) { i = Services_.erase(i); } else ++i; @@ -113,13 +145,13 @@ namespace OpenWifi { } } - Types::MicroServiceMetaVec MicroService::GetServices(const std::string & Type) { + Types::MicroServiceMetaVec MicroService::GetServices(const std::string &Type) { std::lock_guard G(InfraMutex_); auto T = Poco::toLower(Type); - Types::MicroServiceMetaVec Res; - for(const auto &[_,ServiceRec]:Services_) { - if(ServiceRec.Type==T) + Types::MicroServiceMetaVec Res; + for (const auto &[_, ServiceRec] : Services_) { + if (ServiceRec.Type == T) Res.push_back(ServiceRec); } return Res; @@ -128,23 +160,25 @@ namespace OpenWifi { Types::MicroServiceMetaVec MicroService::GetServices() { std::lock_guard G(InfraMutex_); - Types::MicroServiceMetaVec Res; - for(const auto &[_,ServiceRec]:Services_) { + Types::MicroServiceMetaVec Res; + for (const auto &[_, ServiceRec] : Services_) { Res.push_back(ServiceRec); } return Res; } void MicroService::LoadConfigurationFile() { - std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,"."); - ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_; + std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, "."); + ConfigFileName_ = + ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_; Poco::Path ConfigFile(ConfigFileName_); - if(!ConfigFile.isFile()) - { - std::cerr << DAEMON_APP_NAME << ": Configuration " - << ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR - + " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl; + if (!ConfigFile.isFile()) { + std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString() + << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR + + " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + + " file." + << std::endl; std::exit(Poco::Util::Application::EXIT_CONFIG); } @@ -159,11 +193,12 @@ namespace OpenWifi { } void MicroService::LoadMyConfig() { - NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable",false); - std::string KeyFile = ConfigPath("openwifi.service.key",""); - if(!KeyFile.empty()) { + NoAPISecurity_ = ConfigGetBool("openwifi.security.restapi.disable", false); + std::string KeyFile = ConfigPath("openwifi.service.key", ""); + if (!KeyFile.empty()) { std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", ""); - AppKey_ = Poco::SharedPtr(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword)); + AppKey_ = Poco::SharedPtr( + new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword)); Cipher_ = CipherFactory_.createCipher(*AppKey_); Signer_.setRSAKey(AppKey_); Signer_.addAllAlgorithms(); @@ -173,8 +208,8 @@ namespace OpenWifi { } ID_ = Utils::GetSystemId(); - if(!DebugMode_) - DebugMode_ = ConfigGetBool("openwifi.system.debug",false); + if (!DebugMode_) + DebugMode_ = ConfigGetBool("openwifi.system.debug", false); MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private"); MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public"); UIURI_ = ConfigGetString("openwifi.system.uri.ui"); @@ -184,151 +219,170 @@ namespace OpenWifi { void MicroService::InitializeLoggingSystem() { static auto initialized = false; - if(!initialized) { + if (!initialized) { initialized = true; LoadConfigurationFile(); - auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file"); - auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", - "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); + auto LoggingDestination = + MicroService::instance().ConfigGetString("logging.type", "file"); + auto LoggingFormat = MicroService::instance().ConfigGetString( + "logging.format", "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true); - auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false); + auto DisableWebSocketLogging = + MicroService::instance().ConfigGetBool("logging.websocket", false); if (LoggingDestination == "null") { Poco::AutoPtr DevNull(new Poco::NullChannel); Poco::Logger::root().setChannel(DevNull); } else if (LoggingDestination == "console") { - SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); + SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); } else if (LoggingDestination == "colorconsole") { - SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); + SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); } else if (LoggingDestination == "sql") { - SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); + SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); } else if (LoggingDestination == "syslog") { - SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); + SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat); } else { - SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR); - } + SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, + DAEMON_ROOT_ENV_VAR); + } - auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); + auto Level = Poco::Logger::parseLevel( + MicroService::instance().ConfigGetString("logging.level", "debug")); Poco::Logger::root().setLevel(Level); - if(!DisableWebSocketLogging) { + if (!DisableWebSocketLogging) { static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = { {1, "log"}}; UI_WebSocketClientServer()->RegisterNotifications(Notifications); } } - } + } - void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) { + void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, + const std::string &FormatterPattern) { - Poco::AutoPtr Console(new Poco::ConsoleChannel); - Poco::AutoPtr Formatter(new Poco::PatternFormatter); - Formatter->setProperty("pattern", FormatterPattern); - Poco::AutoPtr FormattingChannel(new Poco::FormattingChannel(Formatter, Console)); + Poco::AutoPtr Console(new Poco::ConsoleChannel); + Poco::AutoPtr Formatter(new Poco::PatternFormatter); + Formatter->setProperty("pattern", FormatterPattern); + Poco::AutoPtr FormattingChannel( + new Poco::FormattingChannel(Formatter, Console)); - if(DisableWebSocketLogging) { - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(FormattingChannel); - } - } else { - Poco::AutoPtr WSLogger(new WebSocketLogger); - Poco::AutoPtr Splitter(new Poco::SplitterChannel); - Splitter->addChannel(WSLogger); - Splitter->addChannel(FormattingChannel); - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(Splitter); - } - } - Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); - } + if (DisableWebSocketLogging) { + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(FormattingChannel); + } + } else { + Poco::AutoPtr WSLogger(new WebSocketLogger); + Poco::AutoPtr Splitter(new Poco::SplitterChannel); + Splitter->addChannel(WSLogger); + Splitter->addChannel(FormattingChannel); + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(Splitter); + } + } + Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}", + UseAsync, DisableWebSocketLogging)); + } - void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) { + void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, + const std::string &FormatterPattern) { - Poco::AutoPtr Console(new Poco::ColorConsoleChannel); - Poco::AutoPtr Formatter(new Poco::PatternFormatter); - Formatter->setProperty("pattern", FormatterPattern); - Poco::AutoPtr FormattingChannel(new Poco::FormattingChannel(Formatter, Console)); + Poco::AutoPtr Console(new Poco::ColorConsoleChannel); + Poco::AutoPtr Formatter(new Poco::PatternFormatter); + Formatter->setProperty("pattern", FormatterPattern); + Poco::AutoPtr FormattingChannel( + new Poco::FormattingChannel(Formatter, Console)); - if(DisableWebSocketLogging) { - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(FormattingChannel); - } - } else { - Poco::AutoPtr WSLogger(new WebSocketLogger); - Poco::AutoPtr Splitter(new Poco::SplitterChannel); - Splitter->addChannel(WSLogger); - Splitter->addChannel(FormattingChannel); - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(Splitter); - } - } - Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); - } + if (DisableWebSocketLogging) { + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(FormattingChannel); + } + } else { + Poco::AutoPtr WSLogger(new WebSocketLogger); + Poco::AutoPtr Splitter(new Poco::SplitterChannel); + Splitter->addChannel(WSLogger); + Splitter->addChannel(FormattingChannel); + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(Splitter); + } + } + Poco::Logger::root().information( + fmt::format("Enabled color console logs: asynch={} websocket={}", UseAsync, + DisableWebSocketLogging)); + } - void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) { - //"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)" - } + void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync, + [[maybe_unused]] bool DisableWebSocketLogging, + [[maybe_unused]] const std::string &FormatterPattern) { + //"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, + //ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)" + } - void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) { + void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync, + [[maybe_unused]] bool DisableWebSocketLogging, + [[maybe_unused]] const std::string &FormatterPattern) {} - } + void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, + const std::string &FormatterPattern, + const std::string &root_env_var) { + std::string DefaultLogPath = fmt::format("${}/logs", root_env_var); + auto LoggingLocationDir = + MicroService::instance().ConfigPath("logging.path", DefaultLogPath); + Poco::File LD(LoggingLocationDir); + try { + if (!LD.exists()) { + LD.createDirectory(); + } + } catch (const Poco::Exception &E) { + std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl; + } + auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log"; - void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) { - std::string DefaultLogPath = fmt::format("${}/logs",root_env_var); - auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath); - Poco::File LD(LoggingLocationDir); - try { - if(!LD.exists()) { - LD.createDirectory(); - } - } catch(const Poco::Exception &E) { - std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl; - } - auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log"; + Poco::AutoPtr FileChannel(new Poco::FileChannel); + FileChannel->setProperty("rotation", "10 M"); + FileChannel->setProperty("archive", "timestamp"); + FileChannel->setProperty("purgeCount", "10"); + FileChannel->setProperty("path", LoggingLocationDirFilePattern); - Poco::AutoPtr FileChannel(new Poco::FileChannel); - FileChannel->setProperty("rotation", "10 M"); - FileChannel->setProperty("archive", "timestamp"); - FileChannel->setProperty("purgeCount", "10"); - FileChannel->setProperty("path", LoggingLocationDirFilePattern); + Poco::AutoPtr Formatter(new Poco::PatternFormatter); + Formatter->setProperty("pattern", FormatterPattern); + Poco::AutoPtr FormattingChannel( + new Poco::FormattingChannel(Formatter, FileChannel)); - Poco::AutoPtr Formatter(new Poco::PatternFormatter); - Formatter->setProperty("pattern", FormatterPattern); - Poco::AutoPtr FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel)); - - if(DisableWebSocketLogging) { - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(FormattingChannel); - } - } else { - Poco::AutoPtr WSLogger(new WebSocketLogger); - Poco::AutoPtr Splitter(new Poco::SplitterChannel); - Splitter->addChannel(WSLogger); - Splitter->addChannel(FormattingChannel); - if(UseAsync) { - Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); - Poco::Logger::root().setChannel(Async); - } else { - Poco::Logger::root().setChannel(Splitter); - } - } - Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging)); - } + if (DisableWebSocketLogging) { + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(FormattingChannel)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(FormattingChannel); + } + } else { + Poco::AutoPtr WSLogger(new WebSocketLogger); + Poco::AutoPtr Splitter(new Poco::SplitterChannel); + Splitter->addChannel(WSLogger); + Splitter->addChannel(FormattingChannel); + if (UseAsync) { + Poco::AutoPtr Async(new Poco::AsyncChannel(Splitter)); + Poco::Logger::root().setChannel(Async); + } else { + Poco::Logger::root().setChannel(Splitter); + } + } + Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}", + UseAsync, DisableWebSocketLogging)); + } void DaemonPostInitialization(Poco::Util::Application &self); @@ -341,37 +395,39 @@ namespace OpenWifi { SubSystems_.push_back(ALBHealthCheckServer()); SubSystems_.push_back(RESTAPI_ExtServer()); SubSystems_.push_back(RESTAPI_IntServer()); - #ifndef TIP_SECURITY_SERVICE +#ifndef TIP_SECURITY_SERVICE SubSystems_.push_back(AuthClient()); - #endif +#endif Poco::Net::initializeSSL(); Poco::Net::HTTPStreamFactory::registerFactory(); Poco::Net::HTTPSStreamFactory::registerFactory(); Poco::Net::FTPStreamFactory::registerFactory(); Poco::Net::FTPSStreamFactory::registerFactory(); - Poco::File DataDir(ConfigPath("openwifi.system.data")); + Poco::File DataDir(ConfigPath("openwifi.system.data")); DataDir_ = DataDir.path(); - if(!DataDir.exists()) { + if (!DataDir.exists()) { try { DataDir.createDirectory(); } catch (const Poco::Exception &E) { logger().log(E); } } - WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets",""); - if(WWWAssetsDir_.empty()) + WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", ""); + if (WWWAssetsDir_.empty()) WWWAssetsDir_ = DataDir_; LoadMyConfig(); - AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices",true); + AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true); InitializeSubSystemServers(); ServerApplication::initialize(self); DaemonPostInitialization(self); - Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); }; + Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) { + this->BusMessageReceived(Key, Payload); + }; KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F); } @@ -392,58 +448,64 @@ namespace OpenWifi { Poco::Util::Option("help", "", "display help information on command line arguments") .required(false) .repeatable(false) - .callback(Poco::Util::OptionCallback(this, &MicroService::handleHelp))); + .callback( + Poco::Util::OptionCallback(this, &MicroService::handleHelp))); - options.addOption( - Poco::Util::Option("file", "", "specify the configuration file") - .required(false) - .repeatable(false) - .argument("file") - .callback(Poco::Util::OptionCallback(this, &MicroService::handleConfig))); + options.addOption(Poco::Util::Option("file", "", "specify the configuration file") + .required(false) + .repeatable(false) + .argument("file") + .callback(Poco::Util::OptionCallback( + this, &MicroService::handleConfig))); - options.addOption( - Poco::Util::Option("debug", "", "to run in debug, set to true") - .required(false) - .repeatable(false) - .callback(Poco::Util::OptionCallback(this, &MicroService::handleDebug))); + options.addOption(Poco::Util::Option("debug", "", "to run in debug, set to true") + .required(false) + .repeatable(false) + .callback(Poco::Util::OptionCallback( + this, &MicroService::handleDebug))); options.addOption( Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)") .required(false) .repeatable(false) .argument("dir") - .callback(Poco::Util::OptionCallback(this, &MicroService::handleLogs))); - - options.addOption( - Poco::Util::Option("version", "", "get the version and quit.") - .required(false) - .repeatable(false) - .callback(Poco::Util::OptionCallback(this, &MicroService::handleVersion))); + .callback( + Poco::Util::OptionCallback(this, &MicroService::handleLogs))); + options.addOption(Poco::Util::Option("version", "", "get the version and quit.") + .required(false) + .repeatable(false) + .callback(Poco::Util::OptionCallback( + this, &MicroService::handleVersion))); } - void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { + void MicroService::handleHelp([[maybe_unused]] const std::string &name, + [[maybe_unused]] const std::string &value) { HelpRequested_ = true; displayHelp(); stopOptionsProcessing(); } - void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { + void MicroService::handleVersion([[maybe_unused]] const std::string &name, + [[maybe_unused]] const std::string &value) { HelpRequested_ = true; std::cout << Version() << std::endl; stopOptionsProcessing(); } - void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) { - if(value == "true") - DebugMode_ = true ; + void MicroService::handleDebug([[maybe_unused]] const std::string &name, + const std::string &value) { + if (value == "true") + DebugMode_ = true; } - void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) { + void MicroService::handleLogs([[maybe_unused]] const std::string &name, + const std::string &value) { LogDir_ = value; } - void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) { + void MicroService::handleConfig([[maybe_unused]] const std::string &name, + const std::string &value) { ConfigFileName_ = value; } @@ -456,31 +518,32 @@ namespace OpenWifi { } void MicroService::InitializeSubSystemServers() { - for(auto i:SubSystems_) { + for (auto i : SubSystems_) { addSubsystem(i); } } void MicroService::StartSubSystemServers() { AddActivity("Starting"); - for(auto i:SubSystems_) { + for (auto i : SubSystems_) { i->Start(); } - EventBusManager_ = std::make_unique(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel())); + EventBusManager_ = std::make_unique(Poco::Logger::create( + "EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())); EventBusManager_->Start(); } void MicroService::StopSubSystemServers() { AddActivity("Stopping"); EventBusManager_->Stop(); - for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) { + for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) { (*i)->Stop(); } } [[nodiscard]] std::string MicroService::CreateUUID() { - static std::random_device rd; - static std::mt19937_64 gen(rd()); + static std::random_device rd; + static std::mt19937_64 gen(rd()); static std::uniform_int_distribution<> dis(0, 15); static std::uniform_int_distribution<> dis2(8, 11); @@ -510,7 +573,8 @@ namespace OpenWifi { return ss.str(); } - bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) { + bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, + const std::string &Level) { try { auto P = Poco::Logger::parseLevel(Level); auto Sub = Poco::toLower(SubSystem); @@ -528,7 +592,7 @@ namespace OpenWifi { } } } - } catch (const Poco::Exception & E) { + } catch (const Poco::Exception &E) { std::cerr << "Exception" << std::endl; } return false; @@ -545,7 +609,7 @@ namespace OpenWifi { Types::StringVec MicroService::GetSubSystems() const { Types::StringVec Result; - for(auto i:SubSystems_) + for (auto i : SubSystems_) Result.push_back(Poco::toLower(i->Name())); return Result; } @@ -553,35 +617,32 @@ namespace OpenWifi { Types::StringPairVec MicroService::GetLogLevels() { Types::StringPairVec Result; - for(auto &i:SubSystems_) { - auto P = std::make_pair( i->Name(), Utils::LogLevelToString(i->GetLoggingLevel())); + for (auto &i : SubSystems_) { + auto P = std::make_pair(i->Name(), Utils::LogLevelToString(i->GetLoggingLevel())); Result.push_back(P); } return Result; } - const Types::StringVec & MicroService::GetLogLevelNames() { - static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" }; + const Types::StringVec &MicroService::GetLogLevelNames() { + static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", + "notice", "information", "debug", "trace"}; return LevelNames; } - uint64_t MicroService::ConfigGetInt(const std::string &Key,uint64_t Default) { - return (uint64_t) config().getInt64(Key,Default); + uint64_t MicroService::ConfigGetInt(const std::string &Key, uint64_t Default) { + return (uint64_t)config().getInt64(Key, Default); } - uint64_t MicroService::ConfigGetInt(const std::string &Key) { - return config().getInt(Key); + uint64_t MicroService::ConfigGetInt(const std::string &Key) { return config().getInt(Key); } + + uint64_t MicroService::ConfigGetBool(const std::string &Key, bool Default) { + return config().getBool(Key, Default); } - uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) { - return config().getBool(Key,Default); - } + uint64_t MicroService::ConfigGetBool(const std::string &Key) { return config().getBool(Key); } - uint64_t MicroService::ConfigGetBool(const std::string &Key) { - return config().getBool(Key); - } - - std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) { + std::string MicroService::ConfigGetString(const std::string &Key, const std::string &Default) { return config().getString(Key, Default); } @@ -589,7 +650,7 @@ namespace OpenWifi { return config().getString(Key); } - std::string MicroService::ConfigPath(const std::string &Key,const std::string & Default) { + std::string MicroService::ConfigPath(const std::string &Key, const std::string &Default) { std::string R = config().getString(Key, Default); return Poco::Path::expand(R); } @@ -600,28 +661,30 @@ namespace OpenWifi { } std::string MicroService::Encrypt(const std::string &S) { - if(NoBuiltInCrypto_) { + if (NoBuiltInCrypto_) { return S; } - return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; + return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64); + ; } std::string MicroService::Decrypt(const std::string &S) { - if(NoBuiltInCrypto_) { + if (NoBuiltInCrypto_) { return S; } - return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);; + return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64); + ; } - std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const { - Poco::JSON::Object Obj; - Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type); - Obj.set(KafkaTopics::ServiceEvents::Fields::ID,ID_); - Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE,Poco::toLower(DAEMON_APP_NAME)); - Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC,MyPublicEndPoint_); - Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE,MyPrivateEndPoint_); - Obj.set(KafkaTopics::ServiceEvents::Fields::KEY,MyHash_); - Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN,Version_); + std::string MicroService::MakeSystemEventMessage(const std::string &Type) const { + Poco::JSON::Object Obj; + Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT, Type); + Obj.set(KafkaTopics::ServiceEvents::Fields::ID, ID_); + Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE, Poco::toLower(DAEMON_APP_NAME)); + Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC, MyPublicEndPoint_); + Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE, MyPrivateEndPoint_); + Obj.set(KafkaTopics::ServiceEvents::Fields::KEY, MyHash_); + Obj.set(KafkaTopics::ServiceEvents::Fields::VRSN, Version_); std::stringstream ResultText; Poco::JSON::Stringifier::stringify(Obj, ResultText); return ResultText.str(); @@ -640,75 +703,73 @@ namespace OpenWifi { void MicroService::SavePID() { try { std::ofstream O; - O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc); + O.open(MicroService::instance().DataDir() + "/pidfile", + std::ios::binary | std::ios::trunc); O << Poco::Process::id(); O.close(); - } catch (...) - { + } catch (...) { std::cout << "Could not save system ID" << std::endl; } } int MicroService::main([[maybe_unused]] const ArgVec &args) { - MicroServiceErrorHandler ErrorHandler(*this); + MicroServiceErrorHandler ErrorHandler(*this); Poco::ErrorHandler::set(&ErrorHandler); if (!HelpRequested_) { SavePID(); Poco::Logger &logger = Poco::Logger::get(DAEMON_APP_NAME); - logger.notice(fmt::format("Starting {} version {}.",DAEMON_APP_NAME, Version())); + logger.notice(fmt::format("Starting {} version {}.", DAEMON_APP_NAME, Version())); - if(Poco::Net::Socket::supportsIPv6()) - poco_information(logger,"System supports IPv6."); + if (Poco::Net::Socket::supportsIPv6()) + poco_information(logger, "System supports IPv6."); else - poco_information(logger,"System does NOT support IPv6."); + poco_information(logger, "System does NOT support IPv6."); if (config().getBool("application.runAsDaemon", false)) { - poco_information(logger,"Starting as a daemon."); + poco_information(logger, "Starting as a daemon."); } - poco_information(logger,fmt::format("System ID set to {}",ID_)); + poco_information(logger, fmt::format("System ID set to {}", ID_)); StartSubSystemServers(); waitForTerminationRequest(); StopSubSystemServers(); - logger.notice(fmt::format("Stopped {}...",DAEMON_APP_NAME)); + logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME)); } return Application::EXIT_OK; } void MicroService::AddActivity(const std::string &Activity) { - if(!DataDir_.empty()) { - std::string ActivityFile{ DataDir_ + "/activity.log"}; + if (!DataDir_.empty()) { + std::string ActivityFile{DataDir_ + "/activity.log"}; try { - std::ofstream of(ActivityFile,std::ios_base::app | std::ios_base::out ); + std::ofstream of(ActivityFile, std::ios_base::app | std::ios_base::out); auto t = std::chrono::system_clock::now(); std::time_t now = std::chrono::system_clock::to_time_t(t); - of << Activity << " at " << std::ctime(&now) ; + of << Activity << " at " << std::ctime(&now); } catch (...) { - } } } [[nodiscard]] std::string MicroService::Sign(Poco::JWT::Token &T, const std::string &Algo) { - if(NoBuiltInCrypto_) { + if (NoBuiltInCrypto_) { return T.toString(); } else { - return Signer_.sign(T,Algo); + return Signer_.sign(T, Algo); } } void MicroService::DeleteOverrideConfiguration() { - Poco::File F(DataDir_ + ExtraConfigurationFilename); + Poco::File F(DataDir_ + ExtraConfigurationFilename); try { - if(F.exists()) + if (F.exists()) F.remove(); } catch (...) { - } } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index cda0aa3..00532b4 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -9,12 +9,11 @@ #pragma once #include -#include -#include -#include -#include #include - +#include +#include +#include +#include // This must be defined for poco_debug and poco_trace macros to function. @@ -23,97 +22,94 @@ #endif namespace OpenWifi { - inline uint64_t Now() { return std::time(nullptr); }; -} + inline uint64_t Now() { return std::time(nullptr); }; +} // namespace OpenWifi -#include "Poco/Util/Application.h" -#include "Poco/Util/ServerApplication.h" -#include "Poco/Util/Option.h" -#include "Poco/Util/OptionSet.h" -#include "Poco/Crypto/RSAKey.h" -#include "Poco/Crypto/CipherFactory.h" +#include "Poco/AutoPtr.h" #include "Poco/Crypto/Cipher.h" +#include "Poco/Crypto/CipherFactory.h" +#include "Poco/Crypto/RSAKey.h" +#include "Poco/Environment.h" +#include "Poco/JSON/Object.h" +#include "Poco/JWT/Signer.h" #include "Poco/Net/HTTPServerRequest.h" #include "Poco/Process.h" +#include "Poco/Util/Application.h" #include "Poco/Util/HelpFormatter.h" -#include "Poco/JSON/Object.h" -#include "Poco/AutoPtr.h" +#include "Poco/Util/Option.h" +#include "Poco/Util/OptionSet.h" #include "Poco/Util/PropertyFileConfiguration.h" -#include "Poco/JWT/Signer.h" -#include "Poco/Environment.h" +#include "Poco/Util/ServerApplication.h" #include "framework/OpenWifiTypes.h" +#include "framework/EventBusManager.h" +#include "framework/SubSystemServer.h" #include "framework/ow_constants.h" #include "framework/utils.h" -#include "framework/SubSystemServer.h" -#include "framework/EventBusManager.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" #include "cppkafka/cppkafka.h" +#include "fmt/core.h" #include "nlohmann/json.hpp" #include "ow_version.h" -#include "fmt/core.h" -#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl; +#define _OWDEBUG_ std::cout << __FILE__ << ":" << __LINE__ << std::endl; // #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__)); namespace OpenWifi { class MicroService : public Poco::Util::ServerApplication { public: - explicit MicroService( std::string PropFile, - std::string RootEnv, - std::string ConfigVar, - std::string AppName, - uint64_t BusTimer, - SubSystemVec Subsystems) : - DAEMON_PROPERTIES_FILENAME(std::move(PropFile)), - DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), - DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)), - DAEMON_APP_NAME(std::move(AppName)), - DAEMON_BUS_TIMER(BusTimer), - SubSystems_(std::move(Subsystems)), - Logger_(Poco::Logger::get("FRAMEWORK")) { - instance_ = this; - RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count()); + explicit MicroService(std::string PropFile, std::string RootEnv, std::string ConfigVar, + std::string AppName, uint64_t BusTimer, SubSystemVec Subsystems) + : DAEMON_PROPERTIES_FILENAME(std::move(PropFile)), + DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)), + DAEMON_APP_NAME(std::move(AppName)), DAEMON_BUS_TIMER(BusTimer), + SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) { + instance_ = this; + RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count()); // Logger_ = Poco::Logger::root().get("BASE-SVC"); } - inline static const char * ExtraConfigurationFilename = "/configuration_override.json"; + inline static const char *ExtraConfigurationFilename = "/configuration_override.json"; inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); } inline auto UpdateConfig() { return PropConfigurationFile_; } inline bool NoAPISecurity() const { return NoAPISecurity_; } - inline Poco::ThreadPool & TimerPool() { return TimerPool_; } + inline Poco::ThreadPool &TimerPool() { return TimerPool_; } [[nodiscard]] std::string Version() { return Version_; } - [[nodiscard]] inline const std::string & DataDir() { return DataDir_; } - [[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; } + [[nodiscard]] inline const std::string &DataDir() { return DataDir_; } + [[nodiscard]] inline const std::string &WWWAssetsDir() { return WWWAssetsDir_; } [[nodiscard]] bool Debug() const { return DebugMode_; } [[nodiscard]] uint64_t ID() const { return ID_; } [[nodiscard]] std::string Hash() const { return MyHash_; }; [[nodiscard]] std::string ServiceType() const { return DAEMON_APP_NAME; }; [[nodiscard]] std::string PrivateEndPoint() const { return MyPrivateEndPoint_; }; [[nodiscard]] std::string PublicEndPoint() const { return MyPublicEndPoint_; }; - [[nodiscard]] const SubSystemVec & GetFullSubSystems() { return SubSystems_; } + [[nodiscard]] const SubSystemVec &GetFullSubSystems() { return SubSystems_; } inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; }; - [[nodiscard]] const std::string & AppName() { return DAEMON_APP_NAME; } + [[nodiscard]] const std::string &AppName() { return DAEMON_APP_NAME; } static inline uint64_t GetPID() { return Poco::Process::id(); }; - [[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; }; - [[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;}; - [[nodiscard]] inline uint64_t Random(uint64_t ceiling) { return (RandomEngine_() % ceiling); } - [[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) { - return ((RandomEngine_() % (max-min)) + min); + [[nodiscard]] inline const std::string GetPublicAPIEndPoint() { + return MyPublicEndPoint_ + "/api/v1"; + }; + [[nodiscard]] inline const std::string &GetUIURI() const { return UIURI_; }; + [[nodiscard]] inline uint64_t Random(uint64_t ceiling) { + return (RandomEngine_() % ceiling); } - virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) { - Cfg.set("additionalConfiguration",false); - } - static MicroService & instance() { return *instance_; } + [[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) { + return ((RandomEngine_() % (max - min)) + min); + } + virtual void GetExtraConfiguration(Poco::JSON::Object &Cfg) { + Cfg.set("additionalConfiguration", false); + } + static MicroService &instance() { return *instance_; } - inline void Exit(int Reason); - void BusMessageReceived(const std::string &Key, const std::string & Payload); - Types::MicroServiceMetaVec GetServices(const std::string & Type); + inline void Exit(int Reason); + void BusMessageReceived(const std::string &Key, const std::string &Payload); + Types::MicroServiceMetaVec GetServices(const std::string &Type); Types::MicroServiceMetaVec GetServices(); void LoadConfigurationFile(); void Reload(); @@ -136,71 +132,78 @@ namespace OpenWifi { void Reload(const std::string &Sub); Types::StringVec GetSubSystems() const; Types::StringPairVec GetLogLevels(); - const Types::StringVec & GetLogLevelNames(); - uint64_t ConfigGetInt(const std::string &Key,uint64_t Default); + const Types::StringVec &GetLogLevelNames(); + uint64_t ConfigGetInt(const std::string &Key, uint64_t Default); uint64_t ConfigGetInt(const std::string &Key); - uint64_t ConfigGetBool(const std::string &Key,bool Default); + uint64_t ConfigGetBool(const std::string &Key, bool Default); uint64_t ConfigGetBool(const std::string &Key); - std::string ConfigGetString(const std::string &Key,const std::string & Default); + std::string ConfigGetString(const std::string &Key, const std::string &Default); std::string ConfigGetString(const std::string &Key); - std::string ConfigPath(const std::string &Key,const std::string & Default); + std::string ConfigPath(const std::string &Key, const std::string &Default); std::string ConfigPath(const std::string &Key); std::string Encrypt(const std::string &S); std::string Decrypt(const std::string &S); - std::string MakeSystemEventMessage( const std::string & Type ) const; + std::string MakeSystemEventMessage(const std::string &Type) const; [[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); static void SavePID(); int main(const ArgVec &args) override; - void InitializeLoggingSystem(); + void InitializeLoggingSystem(); void DeleteOverrideConfiguration(); [[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo); void AddActivity(const std::string &Activity); - static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern); - static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern); - static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern); - static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern); - static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var); - inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; } + static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, + const std::string &FormatterPattern); + static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, + const std::string &FormatterPattern); + static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, + const std::string &FormatterPattern); + static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, + const std::string &FormatterPattern); + static void SetFileLogs(bool UseAsync, bool AllowWebSocket, + const std::string &FormatterPattern, + const std::string &root_env_var); + inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; } private: - static MicroService * instance_; - bool HelpRequested_ = false; - std::string LogDir_; - std::string ConfigFileName_; - uint64_t ID_ = 1; - Poco::SharedPtr AppKey_; - bool DebugMode_ = false; - std::string DataDir_; - std::string WWWAssetsDir_; - Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory(); - Poco::Crypto::Cipher * Cipher_ = nullptr; - Types::MicroServiceMetaMap Services_; - std::string MyHash_; - std::string MyPrivateEndPoint_; - std::string MyPublicEndPoint_; - std::string UIURI_; - std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH }; - std::recursive_mutex InfraMutex_; - std::default_random_engine RandomEngine_; - Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr; - std::string DAEMON_PROPERTIES_FILENAME; - std::string DAEMON_ROOT_ENV_VAR; - std::string DAEMON_CONFIG_ENV_VAR; - std::string DAEMON_APP_NAME; - uint64_t DAEMON_BUS_TIMER; - SubSystemVec SubSystems_; - bool NoAPISecurity_=false; - bool NoBuiltInCrypto_=false; - bool AllowExternalMicroServices_=false; - Poco::JWT::Signer Signer_; - Poco::Logger &Logger_; - Poco::ThreadPool TimerPool_{"timer:pool",2,32}; - std::unique_ptr EventBusManager_; - }; + static MicroService *instance_; + bool HelpRequested_ = false; + std::string LogDir_; + std::string ConfigFileName_; + uint64_t ID_ = 1; + Poco::SharedPtr AppKey_; + bool DebugMode_ = false; + std::string DataDir_; + std::string WWWAssetsDir_; + Poco::Crypto::CipherFactory &CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory(); + Poco::Crypto::Cipher *Cipher_ = nullptr; + Types::MicroServiceMetaMap Services_; + std::string MyHash_; + std::string MyPrivateEndPoint_; + std::string MyPublicEndPoint_; + std::string UIURI_; + std::string Version_{OW_VERSION::VERSION + "(" + OW_VERSION::BUILD + ")" + " - " + + OW_VERSION::HASH}; + std::recursive_mutex InfraMutex_; + std::default_random_engine RandomEngine_; + Poco::Util::PropertyFileConfiguration *PropConfigurationFile_ = nullptr; + std::string DAEMON_PROPERTIES_FILENAME; + std::string DAEMON_ROOT_ENV_VAR; + std::string DAEMON_CONFIG_ENV_VAR; + std::string DAEMON_APP_NAME; + uint64_t DAEMON_BUS_TIMER; + SubSystemVec SubSystems_; + bool NoAPISecurity_ = false; + bool NoBuiltInCrypto_ = false; + bool AllowExternalMicroServices_ = false; + Poco::JWT::Signer Signer_; + Poco::Logger &Logger_; + Poco::ThreadPool TimerPool_{"timer:pool", 2, 32}; + std::unique_ptr EventBusManager_; + }; - inline MicroService * MicroService::instance_ = nullptr; + inline MicroService *MicroService::instance_ = nullptr; -} +} // namespace OpenWifi diff --git a/src/framework/MicroServiceErrorHandler.h b/src/framework/MicroServiceErrorHandler.h index 03de471..51e4925 100644 --- a/src/framework/MicroServiceErrorHandler.h +++ b/src/framework/MicroServiceErrorHandler.h @@ -4,25 +4,24 @@ #pragma once -#include "fmt/format.h" -#include "Poco/Util/Application.h" #include "Poco/ErrorHandler.h" +#include "Poco/JSON/JSONException.h" +#include "Poco/JSON/Template.h" #include "Poco/Net/NetException.h" #include "Poco/Net/SSLException.h" -#include "Poco/JSON/Template.h" -#include "Poco/JSON/JSONException.h" #include "Poco/Thread.h" +#include "Poco/Util/Application.h" +#include "fmt/format.h" namespace OpenWifi { class MicroServiceErrorHandler : public Poco::ErrorHandler { public: - explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) { - } + explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {} - inline void exception(const Poco::Exception & Base) override { + inline void exception(const Poco::Exception &Base) override { try { - if(Poco::Thread::current()!= nullptr) { + if (Poco::Thread::current() != nullptr) { t_name = Poco::Thread::current()->getName(); t_id = Poco::Thread::current()->id(); } else { @@ -34,179 +33,167 @@ namespace OpenWifi { Base.rethrow(); } catch (const Poco::Net::InvalidCertificateException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::InvalidCertificateException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::InvalidSocketException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::WebSocketException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::Net::ConnectionResetException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::CertificateValidationException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::CertificateValidationException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException " + "thr_name={} thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::SSLContextException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::Net::SSLException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::Net::InvalidAddressException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::Net::NetException &E) { - poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::IOException &E) { - poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error( + App_.logger(), + fmt::format( + "Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), E.what())); } catch (const Poco::TimeoutException &E) { - poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::NoThreadAvailableException &E) { - poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::OutOfMemoryException &E) { - poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::BadCastException &E) { - poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::DataException &E) { - poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error( + App_.logger(), + fmt::format( + "Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), E.what())); } catch (const Poco::PoolOverflowException &E) { - poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::SystemException &E) { - poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::RuntimeException &E) { - poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::JSON::JSONTemplateException &E) { - poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), + fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} " + "code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), + E.what())); } catch (const Poco::JSON::JSONException &E) { - poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::ApplicationException &E) { - poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} " + "thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), + E.message(), E.what())); } catch (const Poco::Exception &E) { - poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}", - t_name, t_id, E.code(), - E.displayText(), - E.message(), - E.what())); + poco_error( + App_.logger(), + fmt::format( + "Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}", + t_name, t_id, E.code(), E.displayText(), E.message(), E.what())); } catch (...) { - poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id)); + poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}", t_name, t_id)); } } - inline void exception(const std::exception & E) override { - if(Poco::Thread::current()!= nullptr) { + inline void exception(const std::exception &E) override { + if (Poco::Thread::current() != nullptr) { t_name = Poco::Thread::current()->getName(); t_id = Poco::Thread::current()->id(); } else { t_name = "startup_code"; t_id = 0; } - poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}", - t_name,E.what(), - t_id)); + poco_warning(App_.logger(), + fmt::format("std::exception in {}: {} thr_id={}", t_name, E.what(), t_id)); } inline void exception() override { - if(Poco::Thread::current()!= nullptr) { + if (Poco::Thread::current() != nullptr) { t_name = Poco::Thread::current()->getName(); t_id = Poco::Thread::current()->id(); } else { t_name = "startup_code"; t_id = 0; } - poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}", - t_name, t_id)); + poco_warning(App_.logger(), + fmt::format("generic exception in {} thr_id={}", t_name, t_id)); } + private: - Poco::Util::Application &App_; - std::string t_name; - int t_id=0; + Poco::Util::Application &App_; + std::string t_name; + int t_id = 0; }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/MicroServiceExtra.h b/src/framework/MicroServiceExtra.h index 1e06e2a..75ca53d 100644 --- a/src/framework/MicroServiceExtra.h +++ b/src/framework/MicroServiceExtra.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include "Poco/BasicEvent.h" #include "Poco/ExpireLRUCache.h" @@ -13,46 +13,40 @@ namespace OpenWifi { class ConfigurationEntry { public: - template explicit ConfigurationEntry(T def) : - Default_(def), - Current_(def){ + template explicit ConfigurationEntry(T def) : Default_(def), Current_(def) {} + + template + explicit ConfigurationEntry(T def, T cur, const std::string &Hint = "") + : Default_(def), Current_(cur), Hint_(Hint) {} + + inline ConfigurationEntry() = default; + inline ~ConfigurationEntry() = default; + + template explicit operator T() const { return std::get(Current_); } + inline ConfigurationEntry &operator=(const char *v) { + Current_ = std::string(v); + return *this; + } + template ConfigurationEntry &operator=(T v) { + Current_ = (T)v; + return *this; } - template explicit ConfigurationEntry(T def, T cur, const std::string &Hint="") : - Default_(def), - Current_(cur), - Hint_(Hint){ - } - - inline ConfigurationEntry()=default; - inline ~ConfigurationEntry()=default; - - template explicit operator T () const { return std::get(Current_); } - inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;} - template ConfigurationEntry & operator=(T v) { Current_ = (T) v; return *this;} - - void reset() { - Current_ = Default_; - } + void reset() { Current_ = Default_; } private: - std::variant Default_, Current_; + std::variant Default_, Current_; std::string Hint_; }; - inline std::string to_string(const ConfigurationEntry &v) { return (std::string) v; } + inline std::string to_string(const ConfigurationEntry &v) { return (std::string)v; } - typedef std::map ConfigurationMap_t; + typedef std::map ConfigurationMap_t; template class FIFO { public: - explicit FIFO(uint32_t Size) : - Size_(Size) { - Buffer_ = new T [Size_]; - } + explicit FIFO(uint32_t Size) : Size_(Size) { Buffer_ = new T[Size_]; } - ~FIFO() { - delete [] Buffer_; - } + ~FIFO() { delete[] Buffer_; } mutable Poco::BasicEvent Writable_; mutable Poco::BasicEvent Readable_; @@ -84,7 +78,7 @@ namespace OpenWifi { Write_ = 0; } Used_++; - MaxEverUsed_ = std::max(Used_,MaxEverUsed_); + MaxEverUsed_ = std::max(Used_, MaxEverUsed_); } bool flag = true; Readable_.notify(this, flag); @@ -93,40 +87,32 @@ namespace OpenWifi { inline bool isFull() { std::lock_guard M(Mutex_); - return Used_==Buffer_->capacity(); + return Used_ == Buffer_->capacity(); } inline auto MaxEverUser() const { return MaxEverUsed_; } private: - std::recursive_mutex Mutex_; - uint32_t Size_=0; - uint32_t Read_=0; - uint32_t Write_=0; - uint32_t Used_=0; - uint32_t MaxEverUsed_=0; - T * Buffer_ = nullptr; + std::recursive_mutex Mutex_; + uint32_t Size_ = 0; + uint32_t Read_ = 0; + uint32_t Write_ = 0; + uint32_t Used_ = 0; + uint32_t MaxEverUsed_ = 0; + T *Buffer_ = nullptr; }; - template class RecordCache { + template + class RecordCache { public: - explicit RecordCache( KeyType Record::* Q) : - MemberOffset(Q){ - }; - inline auto update(const Record &R) { - return Cache_.update(R.*MemberOffset, R); - } - inline auto get(const KeyType &K) { - return Cache_.get(K); - } - inline auto remove(const KeyType &K) { - return Cache_.remove(K); - } - inline auto remove(const Record &R) { - return Cache_.remove(R.*MemberOffset); - } + explicit RecordCache(KeyType Record::*Q) : MemberOffset(Q){}; + inline auto update(const Record &R) { return Cache_.update(R.*MemberOffset, R); } + inline auto get(const KeyType &K) { return Cache_.get(K); } + inline auto remove(const KeyType &K) { return Cache_.remove(K); } + inline auto remove(const Record &R) { return Cache_.remove(R.*MemberOffset); } + private: - KeyType Record::* MemberOffset; - Poco::ExpireLRUCache Cache_{Size,Expiry}; + KeyType Record::*MemberOffset; + Poco::ExpireLRUCache Cache_{Size, Expiry}; }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/MicroServiceFuncs.cpp b/src/framework/MicroServiceFuncs.cpp index 193d119..22eccbd 100644 --- a/src/framework/MicroServiceFuncs.cpp +++ b/src/framework/MicroServiceFuncs.cpp @@ -2,125 +2,125 @@ // Created by stephane bourque on 2022-10-25. // -#include "framework/MicroService.h" #include "framework/MicroServiceFuncs.h" +#include "framework/MicroService.h" namespace OpenWifi { - const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); } + const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); } - Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type) { - return MicroService::instance().GetServices(Type); - } + Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type) { + return MicroService::instance().GetServices(Type); + } - Types::MicroServiceMetaVec MicroServiceGetServices() { - return MicroService::instance().GetServices(); - } + Types::MicroServiceMetaVec MicroServiceGetServices() { + return MicroService::instance().GetServices(); + } - std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); } + std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); } - std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) { - return MicroService::instance().ConfigGetString(Key, DefaultValue); - } + std::string MicroServiceConfigGetString(const std::string &Key, + const std::string &DefaultValue) { + return MicroService::instance().ConfigGetString(Key, DefaultValue); + } - bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue) { - return MicroService::instance().ConfigGetBool(Key, DefaultValue); - } + bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue) { + return MicroService::instance().ConfigGetBool(Key, DefaultValue); + } - std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue) { - return MicroService::instance().ConfigGetInt(Key, DefaultValue); - } + std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue) { + return MicroService::instance().ConfigGetInt(Key, DefaultValue); + } - std::string MicroServicePrivateEndPoint() { return MicroService::instance().PrivateEndPoint(); } + std::string MicroServicePrivateEndPoint() { return MicroService::instance().PrivateEndPoint(); } - std::uint64_t MicroServiceID() { return MicroService::instance().ID(); } + std::uint64_t MicroServiceID() { return MicroService::instance().ID(); } - bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) { - return MicroService::instance().IsValidAPIKEY(Request); - } + bool MicroServiceIsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request) { + return MicroService::instance().IsValidAPIKEY(Request); + } - bool MicroServiceNoAPISecurity() { return MicroService::instance().NoAPISecurity(); } + bool MicroServiceNoAPISecurity() { return MicroService::instance().NoAPISecurity(); } - void MicroServiceLoadConfigurationFile() { MicroService::instance().LoadConfigurationFile(); } + void MicroServiceLoadConfigurationFile() { MicroService::instance().LoadConfigurationFile(); } - void MicroServiceReload() { MicroService::instance().Reload(); } + void MicroServiceReload() { MicroService::instance().Reload(); } - void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); } + void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); } - const Types::StringVec MicroServiceGetLogLevelNames() { - return MicroService::instance().GetLogLevelNames(); - } + const Types::StringVec MicroServiceGetLogLevelNames() { + return MicroService::instance().GetLogLevelNames(); + } - const Types::StringVec MicroServiceGetSubSystems() { - return MicroService::instance().GetSubSystems(); - } + const Types::StringVec MicroServiceGetSubSystems() { + return MicroService::instance().GetSubSystems(); + } - Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); } + Types::StringPairVec MicroServiceGetLogLevels() { + return MicroService::instance().GetLogLevels(); + } - bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) { - return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level); - } + bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) { + return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level); + } - void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer) { - MicroService::instance().GetExtraConfiguration(Answer); - } + void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer) { + MicroService::instance().GetExtraConfiguration(Answer); + } - std::string MicroServiceVersion() { return MicroService::instance().Version(); } + std::string MicroServiceVersion() { return MicroService::instance().Version(); } - std::uint64_t MicroServiceUptimeTotalSeconds() { - return MicroService::instance().uptime().totalSeconds(); - } + std::uint64_t MicroServiceUptimeTotalSeconds() { + return MicroService::instance().uptime().totalSeconds(); + } - std::uint64_t MicroServiceStartTimeEpochTime() { - return MicroService::instance().startTime().epochTime(); - } + std::uint64_t MicroServiceStartTimeEpochTime() { + return MicroService::instance().startTime().epochTime(); + } - std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); } + std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); } - const SubSystemVec MicroServiceGetFullSubSystems() { - return MicroService::instance().GetFullSubSystems(); - } + const SubSystemVec MicroServiceGetFullSubSystems() { + return MicroService::instance().GetFullSubSystems(); + } - std::string MicroServiceCreateUUID() { return MicroService::CreateUUID(); } + std::string MicroServiceCreateUUID() { return MicroService::CreateUUID(); } - std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); } + std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); } - std::string MicroServiceMakeSystemEventMessage(const std::string &Type) { - return MicroService::instance().MakeSystemEventMessage(Type); - } + std::string MicroServiceMakeSystemEventMessage(const std::string &Type) { + return MicroService::instance().MakeSystemEventMessage(Type); + } - Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); } + Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); } - std::string MicroServiceConfigPath(const std::string &Key, - const std::string &DefaultValue) { - return MicroService::instance().ConfigPath(Key, DefaultValue); - } + std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue) { + return MicroService::instance().ConfigPath(Key, DefaultValue); + } - std::string MicroServiceWWWAssetsDir() { - return MicroService::instance().WWWAssetsDir(); - } + std::string MicroServiceWWWAssetsDir() { return MicroService::instance().WWWAssetsDir(); } - std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) { - return MicroService::instance().Random(Start, End); - } + std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End) { + return MicroService::instance().Random(Start, End); + } - std::uint64_t MicroServiceRandom(std::uint64_t Range) { - return MicroService::instance().Random(Range); - } + std::uint64_t MicroServiceRandom(std::uint64_t Range) { + return MicroService::instance().Random(Range); + } - std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo) { - return MicroService::instance().Sign(T, Algo); - } + std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo) { + return MicroService::instance().Sign(T, Algo); + } - std::string MicroServiceGetPublicAPIEndPoint() { - return MicroService::instance().GetPublicAPIEndPoint(); - } + std::string MicroServiceGetPublicAPIEndPoint() { + return MicroService::instance().GetPublicAPIEndPoint(); + } void MicroServiceDeleteOverrideConfiguration() { return MicroService::instance().DeleteOverrideConfiguration(); } - bool AllowExternalMicroServices() { - return MicroService::instance().AllowExternalMicroServices(); - } + bool AllowExternalMicroServices() { + return MicroService::instance().AllowExternalMicroServices(); + } -} +} // namespace OpenWifi diff --git a/src/framework/MicroServiceFuncs.h b/src/framework/MicroServiceFuncs.h index aef4d50..ec06c7a 100644 --- a/src/framework/MicroServiceFuncs.h +++ b/src/framework/MicroServiceFuncs.h @@ -8,20 +8,20 @@ #include "framework/OpenWifiTypes.h" -#include "Poco/Net/HTTPServerRequest.h" #include "Poco/JSON/Object.h" -#include "Poco/ThreadPool.h" #include "Poco/JWT/Token.h" - +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/ThreadPool.h" namespace OpenWifi { class SubSystemServer; - using SubSystemVec=std::vector; - const std::string & MicroServiceDataDirectory(); - Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type); - Types::MicroServiceMetaVec MicroServiceGetServices(); + using SubSystemVec = std::vector; + const std::string &MicroServiceDataDirectory(); + Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type); + Types::MicroServiceMetaVec MicroServiceGetServices(); std::string MicroServicePublicEndPoint(); - std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue); + std::string MicroServiceConfigGetString(const std::string &Key, + const std::string &DefaultValue); bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue); std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue); std::string MicroServicePrivateEndPoint(); @@ -43,15 +43,14 @@ namespace OpenWifi { const SubSystemVec MicroServiceGetFullSubSystems(); std::string MicroServiceCreateUUID(); std::uint64_t MicroServiceDaemonBusTimer(); - std::string MicroServiceMakeSystemEventMessage( const std::string & Type ); - Poco::ThreadPool & MicroServiceTimerPool(); - std::string MicroServiceConfigPath(const std::string &Key, - const std::string &DefaultValue); - std::string MicroServiceWWWAssetsDir(); - std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End); - std::uint64_t MicroServiceRandom(std::uint64_t Range); - std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo); - std::string MicroServiceGetPublicAPIEndPoint(); + std::string MicroServiceMakeSystemEventMessage(const std::string &Type); + Poco::ThreadPool &MicroServiceTimerPool(); + std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue); + std::string MicroServiceWWWAssetsDir(); + std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End); + std::uint64_t MicroServiceRandom(std::uint64_t Range); + std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo); + std::string MicroServiceGetPublicAPIEndPoint(); void MicroServiceDeleteOverrideConfiguration(); - bool AllowExternalMicroServices(); -} + bool AllowExternalMicroServices(); +} // namespace OpenWifi diff --git a/src/framework/MicroServiceNames.h b/src/framework/MicroServiceNames.h index 7563e19..430d9d3 100644 --- a/src/framework/MicroServiceNames.h +++ b/src/framework/MicroServiceNames.h @@ -10,13 +10,13 @@ namespace OpenWifi { static const std::string uSERVICE_SECURITY{"owsec"}; static const std::string uSERVICE_GATEWAY{"owgw"}; - static const std::string uSERVICE_FIRMWARE{ "owfms"}; - static const std::string uSERVICE_TOPOLOGY{ "owtopo"}; - static const std::string uSERVICE_PROVISIONING{ "owprov"}; - static const std::string uSERVICE_OWLS{ "owls"}; - static const std::string uSERVICE_SUBCRIBER{ "owsub"}; - static const std::string uSERVICE_INSTALLER{ "owinst"}; - static const std::string uSERVICE_ANALYTICS{ "owanalytics"}; - static const std::string uSERVICE_OWRRM{ "owrrm"}; + static const std::string uSERVICE_FIRMWARE{"owfms"}; + static const std::string uSERVICE_TOPOLOGY{"owtopo"}; + static const std::string uSERVICE_PROVISIONING{"owprov"}; + static const std::string uSERVICE_OWLS{"owls"}; + static const std::string uSERVICE_SUBCRIBER{"owsub"}; + static const std::string uSERVICE_INSTALLER{"owinst"}; + static const std::string uSERVICE_ANALYTICS{"owanalytics"}; + static const std::string uSERVICE_OWRRM{"owrrm"}; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/OpenAPIRequests.cpp b/src/framework/OpenAPIRequests.cpp index fe157f3..c5e4aad 100644 --- a/src/framework/OpenAPIRequests.cpp +++ b/src/framework/OpenAPIRequests.cpp @@ -4,286 +4,281 @@ #include "OpenAPIRequests.h" +#include "Poco/JSON/Parser.h" #include "Poco/Logger.h" -#include "Poco/URI.h" #include "Poco/Net/HTTPRequest.h" #include "Poco/Net/HTTPSClientSession.h" -#include "Poco/JSON/Parser.h" +#include "Poco/URI.h" #include "fmt/format.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) { - try { + Poco::Net::HTTPServerResponse::HTTPStatus + OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) { + try { - auto Services = MicroServiceGetServices(Type_); - for(auto const &Svc:Services) { - Poco::URI URI(Svc.PrivateEndPoint); + auto Services = MicroServiceGetServices(Type_); + for (auto const &Svc : Services) { + Poco::URI URI(Svc.PrivateEndPoint); - auto Secure = (URI.getScheme() == "https"); + auto Secure = (URI.getScheme() == "https"); - URI.setPath(EndPoint_); - for (const auto &qp : QueryData_) - URI.addQueryParameter(qp.first, qp.second); + URI.setPath(EndPoint_); + for (const auto &qp : QueryData_) + URI.addQueryParameter(qp.first, qp.second); - std::string Path(URI.getPathAndQuery()); - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, - Path, - Poco::Net::HTTPMessage::HTTP_1_1); + std::string Path(URI.getPathAndQuery()); + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path, + Poco::Net::HTTPMessage::HTTP_1_1); - poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) ); + poco_debug(Poco::Logger::get("REST-CALLER-GET"), + fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_)); - if(BearerToken.empty()) { - Request.add("X-API-KEY", Svc.AccessKey); - Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); - } else { - // Authorization: Bearer ${token} - Request.add("Authorization", "Bearer " + BearerToken); - } - - if(Secure) { - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - - Session.sendRequest(Request); - - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); - } - return Response.getStatus(); - } else { - Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - - Session.sendRequest(Request); - - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); - } - return Response.getStatus(); - } - } - } - catch (const Poco::Exception &E) - { - Poco::Logger::get("REST-CALLER-GET").log(E); - } - return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; -} - - Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) { - try { - auto Services = MicroServiceGetServices(Type_); - for(auto const &Svc:Services) { - Poco::URI URI(Svc.PrivateEndPoint); - - auto Secure = (URI.getScheme() == "https"); - - URI.setPath(EndPoint_); - for (const auto &qp : QueryData_) - URI.addQueryParameter(qp.first, qp.second); - - poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) ); - - std::string Path(URI.getPathAndQuery()); - - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, - Path, - Poco::Net::HTTPMessage::HTTP_1_1); - std::ostringstream obody; - Poco::JSON::Stringifier::stringify(Body_,obody); - - Request.setContentType("application/json"); - Request.setContentLength(obody.str().size()); - - if(BearerToken.empty()) { - Request.add("X-API-KEY", Svc.AccessKey); - Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); - } else { - // Authorization: Bearer ${token} - Request.add("Authorization", "Bearer " + BearerToken); - } - - if(Secure) { - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - - std::ostream &os = Session.sendRequest(Request); - os << obody.str(); - - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + if (BearerToken.empty()) { + Request.add("X-API-KEY", Svc.AccessKey); + Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); } else { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + // Authorization: Bearer ${token} + Request.add("Authorization", "Bearer " + BearerToken); } - return Response.getStatus(); - } else { - Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - std::ostream &os = Session.sendRequest(Request); - os << obody.str(); + if (Secure) { + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + Session.sendRequest(Request); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); } else { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + + Session.sendRequest(Request); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); } - return Response.getStatus(); } + } catch (const Poco::Exception &E) { + Poco::Logger::get("REST-CALLER-GET").log(E); } + return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; } - catch (const Poco::Exception &E) - { - Poco::Logger::get("REST-CALLER-PUT").log(E); - } - return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; -} - Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) { - try { - auto Services = MicroServiceGetServices(Type_); + Poco::Net::HTTPServerResponse::HTTPStatus + OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) { + try { + auto Services = MicroServiceGetServices(Type_); + for (auto const &Svc : Services) { + Poco::URI URI(Svc.PrivateEndPoint); - for(auto const &Svc:Services) { - Poco::URI URI(Svc.PrivateEndPoint); + auto Secure = (URI.getScheme() == "https"); + URI.setPath(EndPoint_); + for (const auto &qp : QueryData_) + URI.addQueryParameter(qp.first, qp.second); - auto Secure = (URI.getScheme() == "https"); + poco_debug(Poco::Logger::get("REST-CALLER-PUT"), + fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_)); - URI.setPath(EndPoint_); - for (const auto &qp : QueryData_) - URI.addQueryParameter(qp.first, qp.second); + std::string Path(URI.getPathAndQuery()); - poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) ); + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + std::ostringstream obody; + Poco::JSON::Stringifier::stringify(Body_, obody); - std::string Path(URI.getPathAndQuery()); + Request.setContentType("application/json"); + Request.setContentLength(obody.str().size()); - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, - Path, - Poco::Net::HTTPMessage::HTTP_1_1); - std::ostringstream obody; - Poco::JSON::Stringifier::stringify(Body_,obody); - - Request.setContentType("application/json"); - Request.setContentLength(obody.str().size()); - - if(BearerToken.empty()) { - Request.add("X-API-KEY", Svc.AccessKey); - Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); - } else { - // Authorization: Bearer ${token} - Request.add("Authorization", "Bearer " + BearerToken); - } - - if(Secure) { - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - std::ostream &os = Session.sendRequest(Request); - os << obody.str(); - - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + if (BearerToken.empty()) { + Request.add("X-API-KEY", Svc.AccessKey); + Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); } else { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + // Authorization: Bearer ${token} + Request.add("Authorization", "Bearer " + BearerToken); } - return Response.getStatus(); - } else { - Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - std::ostream &os = Session.sendRequest(Request); - os << obody.str(); - Poco::Net::HTTPResponse Response; - std::istream &is = Session.receiveResponse(Response); - if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + if (Secure) { + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + + std::ostream &os = Session.sendRequest(Request); + os << obody.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } else { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); } else { - Poco::JSON::Parser P; - ResponseObject = P.parse(is).extract(); + Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + + std::ostream &os = Session.sendRequest(Request); + os << obody.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } else { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); } - return Response.getStatus(); } + } catch (const Poco::Exception &E) { + Poco::Logger::get("REST-CALLER-PUT").log(E); } + return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; } - catch (const Poco::Exception &E) - { - Poco::Logger::get("REST-CALLER-POST").log(E); - } - return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; -} - Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) { - try { - auto Services = MicroServiceGetServices(Type_); + Poco::Net::HTTPServerResponse::HTTPStatus + OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, + const std::string &BearerToken) { + try { + auto Services = MicroServiceGetServices(Type_); - for(auto const &Svc:Services) { - Poco::URI URI(Svc.PrivateEndPoint); + for (auto const &Svc : Services) { + Poco::URI URI(Svc.PrivateEndPoint); - auto Secure = (URI.getScheme() == "https"); + auto Secure = (URI.getScheme() == "https"); - URI.setPath(EndPoint_); - for (const auto &qp : QueryData_) - URI.addQueryParameter(qp.first, qp.second); + URI.setPath(EndPoint_); + for (const auto &qp : QueryData_) + URI.addQueryParameter(qp.first, qp.second); - poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) ); + poco_debug(Poco::Logger::get("REST-CALLER-POST"), + fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_)); - std::string Path(URI.getPathAndQuery()); + std::string Path(URI.getPathAndQuery()); - Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, - Path, - Poco::Net::HTTPMessage::HTTP_1_1); - if(BearerToken.empty()) { - Request.add("X-API-KEY", Svc.AccessKey); - Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); - } else { - // Authorization: Bearer ${token} - Request.add("Authorization", "Bearer " + BearerToken); - } - - if(Secure) { - Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - Session.sendRequest(Request); - Poco::Net::HTTPResponse Response; - Session.receiveResponse(Response); - return Response.getStatus(); - } else { - Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); - Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); - Session.sendRequest(Request); - Poco::Net::HTTPResponse Response; - Session.receiveResponse(Response); - return Response.getStatus(); + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + std::ostringstream obody; + Poco::JSON::Stringifier::stringify(Body_, obody); + + Request.setContentType("application/json"); + Request.setContentLength(obody.str().size()); + + if (BearerToken.empty()) { + Request.add("X-API-KEY", Svc.AccessKey); + Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); + } else { + // Authorization: Bearer ${token} + Request.add("Authorization", "Bearer " + BearerToken); + } + + if (Secure) { + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + std::ostream &os = Session.sendRequest(Request); + os << obody.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } else { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); + } else { + Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + std::ostream &os = Session.sendRequest(Request); + os << obody.str(); + + Poco::Net::HTTPResponse Response; + std::istream &is = Session.receiveResponse(Response); + if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } else { + Poco::JSON::Parser P; + ResponseObject = P.parse(is).extract(); + } + return Response.getStatus(); + } } + } catch (const Poco::Exception &E) { + Poco::Logger::get("REST-CALLER-POST").log(E); } + return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; } - catch (const Poco::Exception &E) - { - Poco::Logger::get("REST-CALLER-DELETE").log(E); - } - return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; -} + Poco::Net::HTTPServerResponse::HTTPStatus + OpenAPIRequestDelete::Do(const std::string &BearerToken) { + try { + auto Services = MicroServiceGetServices(Type_); + + for (auto const &Svc : Services) { + Poco::URI URI(Svc.PrivateEndPoint); + + auto Secure = (URI.getScheme() == "https"); + + URI.setPath(EndPoint_); + for (const auto &qp : QueryData_) + URI.addQueryParameter(qp.first, qp.second); + + poco_debug(Poco::Logger::get("REST-CALLER-DELETE"), + fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_)); + + std::string Path(URI.getPathAndQuery()); + + Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, Path, + Poco::Net::HTTPMessage::HTTP_1_1); + if (BearerToken.empty()) { + Request.add("X-API-KEY", Svc.AccessKey); + Request.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); + } else { + // Authorization: Bearer ${token} + Request.add("Authorization", "Bearer " + BearerToken); + } + + if (Secure) { + Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + Session.sendRequest(Request); + Poco::Net::HTTPResponse Response; + Session.receiveResponse(Response); + return Response.getStatus(); + } else { + Poco::Net::HTTPClientSession Session(URI.getHost(), URI.getPort()); + Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000)); + Session.sendRequest(Request); + Poco::Net::HTTPResponse Response; + Session.receiveResponse(Response); + return Response.getStatus(); + } + } + } catch (const Poco::Exception &E) { + Poco::Logger::get("REST-CALLER-DELETE").log(E); + } + return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT; + } } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/OpenAPIRequests.h b/src/framework/OpenAPIRequests.h index ab38c0a..000d3fb 100644 --- a/src/framework/OpenAPIRequests.h +++ b/src/framework/OpenAPIRequests.h @@ -15,96 +15,79 @@ namespace OpenWifi { class OpenAPIRequestGet { public: - explicit OpenAPIRequestGet( const std::string & Type, - const std::string & EndPoint, - const Types::StringPairVec & QueryData, - uint64_t msTimeout, - const std::string &LoggingStr=""): - Type_(Type), - EndPoint_(EndPoint), - QueryData_(QueryData), - msTimeout_(msTimeout), - LoggingStr_(LoggingStr){}; - Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = ""); + explicit OpenAPIRequestGet(const std::string &Type, const std::string &EndPoint, + const Types::StringPairVec &QueryData, uint64_t msTimeout, + const std::string &LoggingStr = "") + : Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout), + LoggingStr_(LoggingStr){}; + Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, + const std::string &BearerToken = ""); + private: - std::string Type_; - std::string EndPoint_; - Types::StringPairVec QueryData_; - uint64_t msTimeout_; - std::string LoggingStr_; + std::string Type_; + std::string EndPoint_; + Types::StringPairVec QueryData_; + uint64_t msTimeout_; + std::string LoggingStr_; }; class OpenAPIRequestPut { public: - explicit OpenAPIRequestPut( const std::string & Type, - const std::string & EndPoint, - const Types::StringPairVec & QueryData, - const Poco::JSON::Object & Body, - uint64_t msTimeout, - const std::string &LoggingStr=""): - Type_(Type), - EndPoint_(EndPoint), - QueryData_(QueryData), - msTimeout_(msTimeout), - Body_(Body), - LoggingStr_(LoggingStr){}; + explicit OpenAPIRequestPut(const std::string &Type, const std::string &EndPoint, + const Types::StringPairVec &QueryData, + const Poco::JSON::Object &Body, uint64_t msTimeout, + const std::string &LoggingStr = "") + : Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout), + Body_(Body), LoggingStr_(LoggingStr){}; - Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = ""); + Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, + const std::string &BearerToken = ""); private: - std::string Type_; - std::string EndPoint_; - Types::StringPairVec QueryData_; - uint64_t msTimeout_; - Poco::JSON::Object Body_; - std::string LoggingStr_; + std::string Type_; + std::string EndPoint_; + Types::StringPairVec QueryData_; + uint64_t msTimeout_; + Poco::JSON::Object Body_; + std::string LoggingStr_; }; class OpenAPIRequestPost { public: - explicit OpenAPIRequestPost( const std::string & Type, - const std::string & EndPoint, - const Types::StringPairVec & QueryData, - const Poco::JSON::Object & Body, - uint64_t msTimeout, - const std::string &LoggingStr=""): - Type_(Type), - EndPoint_(EndPoint), - QueryData_(QueryData), - msTimeout_(msTimeout), - Body_(Body), - LoggingStr_(LoggingStr){}; - Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = ""); + explicit OpenAPIRequestPost(const std::string &Type, const std::string &EndPoint, + const Types::StringPairVec &QueryData, + const Poco::JSON::Object &Body, uint64_t msTimeout, + const std::string &LoggingStr = "") + : Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout), + Body_(Body), LoggingStr_(LoggingStr){}; + Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, + const std::string &BearerToken = ""); + private: - std::string Type_; - std::string EndPoint_; - Types::StringPairVec QueryData_; - uint64_t msTimeout_; - Poco::JSON::Object Body_; - std::string LoggingStr_; + std::string Type_; + std::string EndPoint_; + Types::StringPairVec QueryData_; + uint64_t msTimeout_; + Poco::JSON::Object Body_; + std::string LoggingStr_; }; class OpenAPIRequestDelete { public: - explicit OpenAPIRequestDelete( const std::string & Type, - const std::string & EndPoint, - const Types::StringPairVec & QueryData, - uint64_t msTimeout, - const std::string &LoggingStr=""): - Type_(Type), - EndPoint_(EndPoint), - QueryData_(QueryData), - msTimeout_(msTimeout), - LoggingStr_(LoggingStr){}; - Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = ""); + explicit OpenAPIRequestDelete(const std::string &Type, const std::string &EndPoint, + const Types::StringPairVec &QueryData, uint64_t msTimeout, + const std::string &LoggingStr = "") + : Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout), + LoggingStr_(LoggingStr){}; + Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string &BearerToken = ""); private: - std::string Type_; - std::string EndPoint_; - Types::StringPairVec QueryData_; - uint64_t msTimeout_; - Poco::JSON::Object Body_; - std::string LoggingStr_; + std::string Type_; + std::string EndPoint_; + Types::StringPairVec QueryData_; + uint64_t msTimeout_; + Poco::JSON::Object Body_; + std::string LoggingStr_; }; } // namespace OpenWifi diff --git a/src/framework/OpenWifiTypes.h b/src/framework/OpenWifiTypes.h index 9671d05..7be530d 100644 --- a/src/framework/OpenWifiTypes.h +++ b/src/framework/OpenWifiTypes.h @@ -4,70 +4,71 @@ #pragma once +#include +#include #include +#include +#include +#include #include #include -#include -#include -#include -#include -#include namespace OpenWifi::Types { - typedef std::pair StringPair; - typedef std::vector StringPairVec; - typedef std::queue StringPairQueue; - typedef std::vector StringVec; - typedef std::set StringSet; - typedef std::map> StringMapStringSet; - typedef std::function TopicNotifyFunction; - typedef std::list> TopicNotifyFunctionList; - typedef std::map NotifyTable; - typedef std::map CountedMap; - typedef std::vector TagList; - typedef std::string UUID_t; - typedef std::vector UUIDvec_t; - typedef std::map> Counted3DMapSII; + typedef std::pair StringPair; + typedef std::vector StringPairVec; + typedef std::queue StringPairQueue; + typedef std::vector StringVec; + typedef std::set StringSet; + typedef std::map> StringMapStringSet; + typedef std::function TopicNotifyFunction; + typedef std::list> TopicNotifyFunctionList; + typedef std::map NotifyTable; + typedef std::map CountedMap; + typedef std::vector TagList; + typedef std::string UUID_t; + typedef std::vector UUIDvec_t; + typedef std::map> Counted3DMapSII; struct MicroServiceMeta { - uint64_t Id=0; - std::string Type; - std::string PrivateEndPoint; - std::string PublicEndPoint; - std::string AccessKey; - std::string Version; - uint64_t LastUpdate=0; + uint64_t Id = 0; + std::string Type; + std::string PrivateEndPoint; + std::string PublicEndPoint; + std::string AccessKey; + std::string Version; + uint64_t LastUpdate = 0; }; - typedef std::map MicroServiceMetaMap; - typedef std::vector MicroServiceMetaVec; -} + typedef std::map MicroServiceMetaMap; + typedef std::vector MicroServiceMetaVec; +} // namespace OpenWifi::Types namespace OpenWifi { - inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) { - auto it = M.find(S); - if(it==M.end()) - M[S] = Increment; - else - it->second += Increment; - } + inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, + uint64_t Increment = 1) { + auto it = M.find(S); + if (it == M.end()) + M[S] = Increment; + else + it->second += Increment; + } - inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) { - auto it = M.find(S); - if(it==M.end()) { - std::map E; - E[Index] = Increment; - M[S] = E; - } - else { - std::map & IndexMap = it->second; - auto it_index = IndexMap.find(Index); - if(it_index == IndexMap.end()) { - IndexMap[Index] = Increment; - } else { - it_index->second += Increment; - } - } - } -} + inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, + uint32_t Index, uint64_t Increment = 1) { + auto it = M.find(S); + if (it == M.end()) { + std::map E; + E[Index] = Increment; + M[S] = E; + } else { + std::map &IndexMap = it->second; + auto it_index = IndexMap.find(Index); + if (it_index == IndexMap.end()) { + IndexMap[Index] = Increment; + } else { + it_index->second += Increment; + } + } + } +} // namespace OpenWifi diff --git a/src/framework/RESTAPI_ExtServer.cpp b/src/framework/RESTAPI_ExtServer.cpp index 979a850..921272d 100644 --- a/src/framework/RESTAPI_ExtServer.cpp +++ b/src/framework/RESTAPI_ExtServer.cpp @@ -6,22 +6,23 @@ namespace OpenWifi { - Poco::Net::HTTPRequestHandler *ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) { + Poco::Net::HTTPRequestHandler * + ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) { try { Poco::URI uri(Request.getURI()); auto TID = NextTransactionId_++; - Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str()); + Utils::SetThreadName(fmt::format("x-rest:{}", TID).c_str()); return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID); } catch (...) { - } return nullptr; } - Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, uint64_t Id) { + Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, + uint64_t Id) { RESTAPIHandler::BindingMap Bindings; - Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str()); + Utils::SetThreadName(fmt::format("x-rest:{}", Id).c_str()); return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id); } -} +} // namespace OpenWifi diff --git a/src/framework/RESTAPI_ExtServer.h b/src/framework/RESTAPI_ExtServer.h index ab3961a..0358e42 100644 --- a/src/framework/RESTAPI_ExtServer.h +++ b/src/framework/RESTAPI_ExtServer.h @@ -6,20 +6,23 @@ #include "Poco/Net/HTTPServer.h" -#include "framework/SubSystemServer.h" #include "framework/RESTAPI_Handler.h" +#include "framework/SubSystemServer.h" namespace OpenWifi { - Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id); + Poco::Net::HTTPRequestHandler * + RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id); class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory { public: ExtRequestHandlerFactory() = default; - Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override; + Poco::Net::HTTPRequestHandler * + createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override; + private: - static inline std::atomic_uint64_t NextTransactionId_ = 1; + static inline std::atomic_uint64_t NextTransactionId_ = 1; }; class RESTAPI_ExtServer : public SubSystemServer { @@ -30,16 +33,21 @@ namespace OpenWifi { } inline int Start() override { - poco_information(Logger(),"Starting."); + poco_information(Logger(), "Starting."); Server_.InitLogging(); - for(const auto & Svr: ConfigServersList_) { + for (const auto &Svr : ConfigServersList_) { - if(MicroServiceNoAPISecurity()) { - poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port())); + if (MicroServiceNoAPISecurity()) { + poco_information( + Logger(), + fmt::format("Starting: {}:{}. Security has been disabled for APIs.", + Svr.Address(), Svr.Port())); } else { - poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(), - Svr.KeyFile(),Svr.CertFile())); + poco_information(Logger(), + fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", + Svr.Address(), Svr.Port(), Svr.KeyFile(), + Svr.CertFile())); Svr.LogCert(Logger()); if (!Svr.RootCA().empty()) Svr.LogCas(Logger()); @@ -49,13 +57,15 @@ namespace OpenWifi { Params->setKeepAlive(true); Params->setName("ws:xrest"); - std::unique_ptr NewServer; - if(MicroServiceNoAPISecurity()) { + std::unique_ptr NewServer; + if (MicroServiceNoAPISecurity()) { auto Sock{Svr.CreateSocket(Logger())}; - NewServer = std::make_unique(new ExtRequestHandlerFactory, Pool_, Sock, Params); + NewServer = std::make_unique( + new ExtRequestHandlerFactory, Pool_, Sock, Params); } else { auto Sock{Svr.CreateSecureSocket(Logger())}; - NewServer = std::make_unique(new ExtRequestHandlerFactory, Pool_, Sock, Params); + NewServer = std::make_unique( + new ExtRequestHandlerFactory, Pool_, Sock, Params); }; NewServer->start(); RESTServers_.push_back(std::move(NewServer)); @@ -64,36 +74,34 @@ namespace OpenWifi { } inline void Stop() override { - poco_information(Logger(),"Stopping..."); - for( const auto & svr : RESTServers_ ) + poco_information(Logger(), "Stopping..."); + for (const auto &svr : RESTServers_) svr->stopAll(true); Pool_.stopAll(); Pool_.joinAll(); RESTServers_.clear(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { MicroServiceLoadConfigurationFile(); - poco_information(Logger(),"Reinitializing."); + poco_information(Logger(), "Reinitializing."); Stop(); Start(); } Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id); - const Poco::ThreadPool & Pool() { return Pool_; } + const Poco::ThreadPool &Pool() { return Pool_; } private: - std::vector> RESTServers_; - Poco::ThreadPool Pool_{"x-rest",8,128}; - RESTAPI_GenericServerAccounting Server_; + std::vector> RESTServers_; + Poco::ThreadPool Pool_{"x-rest", 8, 128}; + RESTAPI_GenericServerAccounting Server_; - RESTAPI_ExtServer() noexcept: - SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") - { - } + RESTAPI_ExtServer() noexcept + : SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") {} }; inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_GenericServerAccounting.h b/src/framework/RESTAPI_GenericServerAccounting.h index fa91b27..7482613 100644 --- a/src/framework/RESTAPI_GenericServerAccounting.h +++ b/src/framework/RESTAPI_GenericServerAccounting.h @@ -4,72 +4,70 @@ #pragma once -#include #include +#include -#include "Poco/StringTokenizer.h" -#include "Poco/String.h" #include "Poco/Net/HTTPRequest.h" +#include "Poco/String.h" +#include "Poco/StringTokenizer.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { class RESTAPI_GenericServerAccounting { public: - - enum { - LOG_GET=0, - LOG_DELETE, - LOG_PUT, - LOG_POST - }; + enum { LOG_GET = 0, LOG_DELETE, LOG_PUT, LOG_POST }; void inline SetFlags(bool External, const std::string &Methods) { - Poco::StringTokenizer Tokens(Methods,","); + Poco::StringTokenizer Tokens(Methods, ","); auto Offset = (External ? 0 : 4); - for(const auto &i:Tokens) { - if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_DELETE)==0) - LogFlags_[Offset+LOG_DELETE]=true; - else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_PUT)==0) - LogFlags_[Offset+LOG_PUT]=true; - else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_POST)==0) - LogFlags_[Offset+LOG_POST]=true; - else if(Poco::icompare(i,Poco::Net::HTTPRequest::HTTP_GET)==0) - LogFlags_[Offset+LOG_GET]=true; + for (const auto &i : Tokens) { + if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_DELETE) == 0) + LogFlags_[Offset + LOG_DELETE] = true; + else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_PUT) == 0) + LogFlags_[Offset + LOG_PUT] = true; + else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_POST) == 0) + LogFlags_[Offset + LOG_POST] = true; + else if (Poco::icompare(i, Poco::Net::HTTPRequest::HTTP_GET) == 0) + LogFlags_[Offset + LOG_GET] = true; } } inline void InitLogging() { - std::string Public = MicroServiceConfigGetString("apilogging.public.methods","PUT,POST,DELETE"); + std::string Public = + MicroServiceConfigGetString("apilogging.public.methods", "PUT,POST,DELETE"); SetFlags(true, Public); - std::string Private = MicroServiceConfigGetString("apilogging.private.methods","PUT,POST,DELETE"); + std::string Private = + MicroServiceConfigGetString("apilogging.private.methods", "PUT,POST,DELETE"); SetFlags(false, Private); - std::string PublicBadTokens = MicroServiceConfigGetString("apilogging.public.badtokens.methods",""); - LogBadTokens_[0] = (Poco::icompare(PublicBadTokens,"true")==0); - std::string PrivateBadTokens = MicroServiceConfigGetString("apilogging.private.badtokens.methods",""); - LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens,"true")==0); + std::string PublicBadTokens = + MicroServiceConfigGetString("apilogging.public.badtokens.methods", ""); + LogBadTokens_[0] = (Poco::icompare(PublicBadTokens, "true") == 0); + std::string PrivateBadTokens = + MicroServiceConfigGetString("apilogging.private.badtokens.methods", ""); + LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens, "true") == 0); } [[nodiscard]] inline bool LogIt(const std::string &Method, bool External) const { auto Offset = (External ? 0 : 4); - if(Method == Poco::Net::HTTPRequest::HTTP_GET) - return LogFlags_[Offset+LOG_GET]; - if(Method == Poco::Net::HTTPRequest::HTTP_POST) - return LogFlags_[Offset+LOG_POST]; - if(Method == Poco::Net::HTTPRequest::HTTP_PUT) - return LogFlags_[Offset+LOG_PUT]; - if(Method == Poco::Net::HTTPRequest::HTTP_DELETE) - return LogFlags_[Offset+LOG_DELETE]; + if (Method == Poco::Net::HTTPRequest::HTTP_GET) + return LogFlags_[Offset + LOG_GET]; + if (Method == Poco::Net::HTTPRequest::HTTP_POST) + return LogFlags_[Offset + LOG_POST]; + if (Method == Poco::Net::HTTPRequest::HTTP_PUT) + return LogFlags_[Offset + LOG_PUT]; + if (Method == Poco::Net::HTTPRequest::HTTP_DELETE) + return LogFlags_[Offset + LOG_DELETE]; return false; }; [[nodiscard]] inline bool LogBadTokens(bool External) const { - return LogBadTokens_[ (External ? 0 : 1) ]; + return LogBadTokens_[(External ? 0 : 1)]; }; private: - std::array LogFlags_{false}; - std::array LogBadTokens_{false}; + std::array LogFlags_{false}; + std::array LogBadTokens_{false}; }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_Handler.cpp b/src/framework/RESTAPI_Handler.cpp index acaf371..b8ba754 100644 --- a/src/framework/RESTAPI_Handler.cpp +++ b/src/framework/RESTAPI_Handler.cpp @@ -4,5 +4,4 @@ #include "RESTAPI_Handler.h" -namespace OpenWifi { -} // namespace OpenWifi \ No newline at end of file +namespace OpenWifi {} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_Handler.h b/src/framework/RESTAPI_Handler.h index 4c72497..232958c 100644 --- a/src/framework/RESTAPI_Handler.h +++ b/src/framework/RESTAPI_Handler.h @@ -4,27 +4,27 @@ #pragma once +#include #include #include -#include -#include "Poco/Net/HTTPRequestHandler.h" -#include "Poco/Logger.h" +#include "Poco/DeflatingStream.h" #include "Poco/JSON/Object.h" #include "Poco/JSON/Parser.h" +#include "Poco/Logger.h" +#include "Poco/Net/HTTPRequestHandler.h" #include "Poco/Net/HTTPResponse.h" #include "Poco/Net/HTTPServerResponse.h" -#include "Poco/DeflatingStream.h" -#include "Poco/TemporaryFile.h" #include "Poco/Net/OAuth20Credentials.h" +#include "Poco/TemporaryFile.h" -#include "framework/ow_constants.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/AuthClient.h" #include "framework/RESTAPI_GenericServerAccounting.h" #include "framework/RESTAPI_RateLimiter.h" -#include "framework/utils.h" #include "framework/RESTAPI_utils.h" -#include "framework/AuthClient.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/ow_constants.h" +#include "framework/utils.h" #if defined(TIP_SECURITY_SERVICE) #include "AuthService.h" @@ -37,42 +37,32 @@ namespace OpenWifi { class RESTAPIHandler : public Poco::Net::HTTPRequestHandler { public: struct QueryBlock { - uint64_t StartDate = 0 , EndDate = 0 , Offset = 0 , Limit = 0, LogType = 0 ; + uint64_t StartDate = 0, EndDate = 0, Offset = 0, Limit = 0, LogType = 0; std::string SerialNumber, Filter; - std::vector Select; - bool Lifetime=false, LastOnly=false, Newest=false, CountOnly=false, AdditionalInfo=false; + std::vector Select; + bool Lifetime = false, LastOnly = false, Newest = false, CountOnly = false, + AdditionalInfo = false; }; typedef std::map BindingMap; struct RateLimit { - int64_t Interval=1000; - int64_t MaxCalls=10; + int64_t Interval = 1000; + int64_t MaxCalls = 10; }; - RESTAPIHandler( BindingMap map, - Poco::Logger &l, - std::vector Methods, - RESTAPI_GenericServerAccounting & Server, - uint64_t TransactionId, - bool Internal, - bool AlwaysAuthorize=true, - bool RateLimited=false, - const RateLimit & Profile = RateLimit{.Interval=1000,.MaxCalls=100}, - bool SubscriberOnly=false) - : Bindings_(std::move(map)), - Logger_(l), - Methods_(std::move(Methods)), - Internal_(Internal), - RateLimited_(RateLimited), - SubOnlyService_(SubscriberOnly), - AlwaysAuthorize_(AlwaysAuthorize), - Server_(Server), - MyRates_(Profile), - TransactionId_(TransactionId) - { - } + RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector Methods, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal, bool AlwaysAuthorize = true, bool RateLimited = false, + const RateLimit &Profile = RateLimit{.Interval = 1000, .MaxCalls = 100}, + bool SubscriberOnly = false) + : Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)), + Internal_(Internal), RateLimited_(RateLimited), SubOnlyService_(SubscriberOnly), + AlwaysAuthorize_(AlwaysAuthorize), Server_(Server), MyRates_(Profile), + TransactionId_(TransactionId) {} - inline bool RoleIsAuthorized([[maybe_unused]] const std::string & Path, [[maybe_unused]] const std::string & Method, [[maybe_unused]] std::string & Reason) { + inline bool RoleIsAuthorized([[maybe_unused]] const std::string &Path, + [[maybe_unused]] const std::string &Method, + [[maybe_unused]] std::string &Reason) { return true; } @@ -85,31 +75,33 @@ namespace OpenWifi { // std::string th_name = "restsvr_" + std::to_string(TransactionId_); // Utils::SetThreadName(th_name.c_str()); - if(Request->getContentLength()>0) { - if(Request->getContentType().find("application/json")!=std::string::npos) { - ParsedBody_ = IncomingParser_.parse(Request->stream()).extract(); + if (Request->getContentLength() > 0) { + if (Request->getContentType().find("application/json") != std::string::npos) { + ParsedBody_ = IncomingParser_.parse(Request->stream()) + .extract(); } } - if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) { + if (RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited( + RequestIn, MyRates_.Interval, MyRates_.MaxCalls)) { return UnAuthorized(RESTAPI::Errors::RATE_LIMIT_EXCEEDED); } if (!ContinueProcessing()) return; - bool Expired=false, Contacted=false; + bool Expired = false, Contacted = false; if (AlwaysAuthorize_ && !IsAuthorized(Expired, Contacted, SubOnlyService_)) { - if(Expired) + if (Expired) return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN); - if(Contacted) + if (Contacted) return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); else return UnAuthorized(RESTAPI::Errors::SECURITY_SERVICE_UNREACHABLE); } std::string Reason; - if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) { + if (!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) { return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); } @@ -130,13 +122,17 @@ namespace OpenWifi { } [[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; } - [[nodiscard]] inline const std::vector & SelectedRecords() const { return QB_.Select; } + [[nodiscard]] inline const std::vector &SelectedRecords() const { + return QB_.Select; + } - inline static bool ParseBindings(const std::string & Request, const std::list & EndPoints, BindingMap &bindings) { + inline static bool ParseBindings(const std::string &Request, + const std::list &EndPoints, + BindingMap &bindings) { bindings.clear(); auto PathItems = Poco::StringTokenizer(Request, "/"); - for(const auto &EndPoint:EndPoints) { + for (const auto &EndPoint : EndPoints) { auto ParamItems = Poco::StringTokenizer(EndPoint, "/"); if (PathItems.count() != ParamItems.count()) continue; @@ -153,7 +149,7 @@ namespace OpenWifi { } } } - if(Matched) + if (Matched) return true; } return false; @@ -180,44 +176,57 @@ namespace OpenWifi { return false; } - [[nodiscard]] inline uint64_t GetParameter(const std::string &Name, const uint64_t Default) { - auto Hint = std::find_if(Parameters_.begin(),Parameters_.end(),[&](const std::pair &S){ return S.first==Name; }); - if(Hint==Parameters_.end() || !is_number(Hint->second)) + [[nodiscard]] inline uint64_t GetParameter(const std::string &Name, + const uint64_t Default) { + auto Hint = std::find_if( + Parameters_.begin(), Parameters_.end(), + [&](const std::pair &S) { return S.first == Name; }); + if (Hint == Parameters_.end() || !is_number(Hint->second)) return Default; return std::stoull(Hint->second); } - [[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default=false) { - auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair &S){ return S.first==Name; }); - if(Hint==end(Parameters_) || !is_bool(Hint->second)) + [[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default = false) { + auto Hint = std::find_if( + begin(Parameters_), end(Parameters_), + [&](const std::pair &S) { return S.first == Name; }); + if (Hint == end(Parameters_) || !is_bool(Hint->second)) return Default; - return Hint->second=="true"; + return Hint->second == "true"; } - [[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default="") { - auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair &S){ return S.first==Name; }); - if(Hint==end(Parameters_)) + [[nodiscard]] inline std::string GetParameter(const std::string &Name, + const std::string &Default = "") { + auto Hint = std::find_if( + begin(Parameters_), end(Parameters_), + [&](const std::pair &S) { return S.first == Name; }); + if (Hint == end(Parameters_)) return Default; return Hint->second; } [[nodiscard]] inline bool HasParameter(const std::string &Name, std::string &Value) { - auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair &S){ return S.first==Name; }); - if(Hint==end(Parameters_)) + auto Hint = std::find_if( + begin(Parameters_), end(Parameters_), + [&](const std::pair &S) { return S.first == Name; }); + if (Hint == end(Parameters_)) return false; Value = Hint->second; return true; } - [[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t & Value) { - auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair &S){ return S.first==Name; }); - if(Hint==end(Parameters_)) + [[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t &Value) { + auto Hint = std::find_if( + begin(Parameters_), end(Parameters_), + [&](const std::pair &S) { return S.first == Name; }); + if (Hint == end(Parameters_)) return false; Value = std::stoull(Hint->second); return true; } - [[nodiscard]] inline const std::string & GetBinding(const std::string &Name, const std::string &Default="") { + [[nodiscard]] inline const std::string &GetBinding(const std::string &Name, + const std::string &Default = "") { auto E = Bindings_.find(Poco::toLower(Name)); if (E == Bindings_.end()) return Default; @@ -236,68 +245,75 @@ namespace OpenWifi { return Return; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Types::UUIDvec_t & Value) { - if(O->has(Field) && O->isArray(Field)) { + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, Types::UUIDvec_t &Value) { + if (O->has(Field) && O->isArray(Field)) { auto Arr = O->getArray(Field); - for(const auto &i:*Arr) + for (const auto &i : *Arr) Value.emplace_back(i.toString()); return true; } return false; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value) { - if(O->has(Field)) { + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, std::string &Value) { + if (O->has(Field)) { Value = O->get(Field).toString(); return true; } return false; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value) { - if(O->has(Field)) { + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, uint64_t &Value) { + if (O->has(Field)) { Value = O->get(Field); return true; } return false; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, bool &Value) { - if(O->has(Field)) { - Value = O->get(Field).toString()=="true"; + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, bool &Value) { + if (O->has(Field)) { + Value = O->get(Field).toString() == "true"; return true; } return false; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, double &Value) { - if(O->has(Field)) { - Value = (double) O->get(Field); + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, double &Value) { + if (O->has(Field)) { + Value = (double)O->get(Field); return true; } return false; } - static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) { - if(O->has(Field)) { + static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, + const std::string &Field, Poco::Data::BLOB &Value) { + if (O->has(Field)) { std::string Content = O->get(Field).toString(); auto DecodedBlob = Utils::base64decode(Content); - Value.assignRaw((const unsigned char *)&DecodedBlob[0],DecodedBlob.size()); + Value.assignRaw((const unsigned char *)&DecodedBlob[0], DecodedBlob.size()); return true; } return false; } - - template bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) { - if(O->has(Field)) { + template + bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, + const T &value, T &assignee) { + if (O->has(Field)) { assignee = value; return true; } return false; } - inline void SetCommonHeaders(bool CloseConnection=false) { + inline void SetCommonHeaders(bool CloseConnection = false) { Response->setVersion(Poco::Net::HTTPMessage::HTTP_1_1); Response->setChunkedTransferEncoding(true); Response->setContentType("application/json"); @@ -308,7 +324,7 @@ namespace OpenWifi { Response->set("Access-Control-Allow-Origin", "*"); } Response->set("Vary", "Origin, Accept-Encoding"); - if(CloseConnection) { + if (CloseConnection) { Response->set("Connection", "close"); Response->setKeepAlive(false); } else { @@ -329,7 +345,7 @@ namespace OpenWifi { } Response->set("Access-Control-Allow-Methods", MakeList(Methods_)); auto RequestHeaders = Request->find("Access-Control-Request-Headers"); - if(RequestHeaders!=Request->end()) + if (RequestHeaders != Request->end()) Response->set("Access-Control-Allow-Headers", RequestHeaders->second); Response->set("Vary", "Origin, Accept-Encoding"); Response->set("Access-Control-Allow-Credentials", "true"); @@ -342,21 +358,24 @@ namespace OpenWifi { Response->send(); } - inline void PrepareResponse(Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK, - bool CloseConnection = false) { + inline void PrepareResponse( + Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK, + bool CloseConnection = false) { Response->setStatus(Status); SetCommonHeaders(CloseConnection); } - inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") { + inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, + const std::string &Extra = "") { PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST); - Poco::JSON::Object ErrorObject; - ErrorObject.set("ErrorCode",400); - ErrorObject.set("ErrorDetails",Request->getMethod()); - if(Extra.empty()) - ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + Poco::JSON::Object ErrorObject; + ErrorObject.set("ErrorCode", 400); + ErrorObject.set("ErrorDetails", Request->getMethod()); + if (Extra.empty()) + ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt)); else - ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ; + ErrorObject.set("ErrorDescription", + fmt::format("{}: {} ({})", E.err_num, E.err_txt, Extra)); std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); @@ -364,44 +383,43 @@ namespace OpenWifi { inline void InternalError(const OpenWifi::RESTAPI::Errors::msg &E) { PrepareResponse(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR); - Poco::JSON::Object ErrorObject; - ErrorObject.set("ErrorCode",500); - ErrorObject.set("ErrorDetails",Request->getMethod()); - ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + Poco::JSON::Object ErrorObject; + ErrorObject.set("ErrorCode", 500); + ErrorObject.set("ErrorDetails", Request->getMethod()); + ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt)); std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); } inline void UnAuthorized(const OpenWifi::RESTAPI::Errors::msg &E) { PrepareResponse(Poco::Net::HTTPResponse::HTTP_FORBIDDEN); - Poco::JSON::Object ErrorObject; - ErrorObject.set("ErrorCode",E.err_num); - ErrorObject.set("ErrorDetails",Request->getMethod()); - ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + Poco::JSON::Object ErrorObject; + ErrorObject.set("ErrorCode", E.err_num); + ErrorObject.set("ErrorDetails", Request->getMethod()); + ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt)); std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); } inline void NotFound() { PrepareResponse(Poco::Net::HTTPResponse::HTTP_NOT_FOUND); - Poco::JSON::Object ErrorObject; - ErrorObject.set("ErrorCode",404); - ErrorObject.set("ErrorDetails",Request->getMethod()); - const auto & E = OpenWifi::RESTAPI::Errors::Error404; - ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + Poco::JSON::Object ErrorObject; + ErrorObject.set("ErrorCode", 404); + ErrorObject.set("ErrorDetails", Request->getMethod()); + const auto &E = OpenWifi::RESTAPI::Errors::Error404; + ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt)); std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); - poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", - Requester(), - Utils::FormatIPv6(Request->clientAddress().toString()), - Request->getMethod(), - Request->getURI())); + poco_debug(Logger_, + fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", Requester(), + Utils::FormatIPv6(Request->clientAddress().toString()), + Request->getMethod(), Request->getURI())); } inline void OK() { PrepareResponse(); - if( Request->getMethod()==Poco::Net::HTTPRequest::HTTP_DELETE || - Request->getMethod()==Poco::Net::HTTPRequest::HTTP_OPTIONS) { + if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE || + Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) { Response->send(); } else { Poco::JSON::Object ErrorObject; @@ -413,85 +431,86 @@ namespace OpenWifi { } } - inline void SendCompressedTarFile(const std::string & FileName, const std::string & Content) { + inline void SendCompressedTarFile(const std::string &FileName, const std::string &Content) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); - Response->set("Content-Type","application/gzip"); - Response->set("Content-Disposition", "attachment; filename=" + FileName ); - Response->set("Content-Transfer-Encoding","binary"); + Response->set("Content-Type", "application/gzip"); + Response->set("Content-Disposition", "attachment; filename=" + FileName); + Response->set("Content-Transfer-Encoding", "binary"); Response->set("Accept-Ranges", "bytes"); Response->set("Cache-Control", "no-store"); Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT"); Response->setStatus(Poco::Net::HTTPResponse::HTTP_OK); Response->setContentLength(Content.size()); Response->setChunkedTransferEncoding(true); - std::ostream& OutputStream = Response->send(); + std::ostream &OutputStream = Response->send(); OutputStream << Content; } - inline void SendFile(Poco::File & File, const std::string & UUID) { + inline void SendFile(Poco::File &File, const std::string &UUID) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); - Response->set("Content-Type","application/octet-stream"); - Response->set("Content-Disposition", "attachment; filename=" + UUID ); - Response->set("Content-Transfer-Encoding","binary"); + Response->set("Content-Type", "application/octet-stream"); + Response->set("Content-Disposition", "attachment; filename=" + UUID); + Response->set("Content-Transfer-Encoding", "binary"); Response->set("Accept-Ranges", "bytes"); Response->set("Cache-Control", "no-store"); Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT"); Response->setContentLength(File.getSize()); - Response->sendFile(File.path(),"application/octet-stream"); + Response->sendFile(File.path(), "application/octet-stream"); } - inline void SendFile(Poco::File & File) { + inline void SendFile(Poco::File &File) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); - Poco::Path P(File.path()); + Poco::Path P(File.path()); auto MT = Utils::FindMediaType(File); - if(MT.Encoding==Utils::BINARY) { - Response->set("Content-Transfer-Encoding","binary"); + if (MT.Encoding == Utils::BINARY) { + Response->set("Content-Transfer-Encoding", "binary"); Response->set("Accept-Ranges", "bytes"); } Response->set("Cache-Control", "no-store"); Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT"); - Response->sendFile(File.path(),MT.ContentType); + Response->sendFile(File.path(), MT.ContentType); } - inline void SendFile(Poco::TemporaryFile &TempAvatar, [[maybe_unused]] const std::string &Type, const std::string & Name) { + inline void SendFile(Poco::TemporaryFile &TempAvatar, + [[maybe_unused]] const std::string &Type, const std::string &Name) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); auto MT = Utils::FindMediaType(Name); - if(MT.Encoding==Utils::BINARY) { - Response->set("Content-Transfer-Encoding","binary"); + if (MT.Encoding == Utils::BINARY) { + Response->set("Content-Transfer-Encoding", "binary"); Response->set("Accept-Ranges", "bytes"); } - Response->set("Content-Disposition", "attachment; filename=" + Name ); + Response->set("Content-Disposition", "attachment; filename=" + Name); Response->set("Accept-Ranges", "bytes"); Response->set("Cache-Control", "no-store"); Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT"); Response->setContentLength(TempAvatar.getSize()); - Response->sendFile(TempAvatar.path(),MT.ContentType); + Response->sendFile(TempAvatar.path(), MT.ContentType); } - inline void SendFileContent(const std::string &Content, const std::string &Type, const std::string & Name) { + inline void SendFileContent(const std::string &Content, const std::string &Type, + const std::string &Name) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); auto MT = Utils::FindMediaType(Name); - if(MT.Encoding==Utils::BINARY) { - Response->set("Content-Transfer-Encoding","binary"); + if (MT.Encoding == Utils::BINARY) { + Response->set("Content-Transfer-Encoding", "binary"); Response->set("Accept-Ranges", "bytes"); } - Response->set("Content-Disposition", "attachment; filename=" + Name ); + Response->set("Content-Disposition", "attachment; filename=" + Name); Response->set("Accept-Ranges", "bytes"); Response->set("Cache-Control", "no-store"); Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT"); Response->setContentLength(Content.size()); - Response->setContentType(Type ); - auto & OutputStream = Response->send(); - OutputStream << Content ; + Response->setContentType(Type); + auto &OutputStream = Response->send(); + OutputStream << Content; } - inline void SendHTMLFileBack(Poco::File & File, - const Types::StringPairVec & FormVars) { + inline void SendHTMLFileBack(Poco::File &File, const Types::StringPairVec &FormVars) { Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); SetCommonHeaders(); Response->set("Pragma", "private"); @@ -501,13 +520,14 @@ namespace OpenWifi { Response->setContentLength(FormContent.size()); Response->setChunkedTransferEncoding(true); Response->setContentType("text/html"); - std::ostream& ostr = Response->send(); + std::ostream &ostr = Response->send(); ostr << FormContent; } - inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status, bool CloseConnection=false) { + inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status, + bool CloseConnection = false) { PrepareResponse(Status, CloseConnection); - if(Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) { + if (Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) { Response->setContentLength(0); Response->erase("Content-Type"); Response->setChunkedTransferEncoding(false); @@ -519,7 +539,8 @@ namespace OpenWifi { if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) { ProcessOptions(); return false; - } else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) == Methods_.end()) { + } else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) == + Methods_.end()) { BadRequest(RESTAPI::Errors::UnsupportedHTTPMethod); return false; } @@ -527,19 +548,20 @@ namespace OpenWifi { return true; } - inline bool IsAuthorized(bool & Expired, bool & Contacted, bool SubOnly = false ); + inline bool IsAuthorized(bool &Expired, bool &Contacted, bool SubOnly = false); inline void ReturnObject(Poco::JSON::Object &Object) { PrepareResponse(); - if(Request!= nullptr) { + if (Request != nullptr) { // can we compress ??? auto AcceptedEncoding = Request->find("Accept-Encoding"); - if(AcceptedEncoding!=Request->end()) { - if( AcceptedEncoding->second.find("gzip")!=std::string::npos || - AcceptedEncoding->second.find("compress")!=std::string::npos) { + if (AcceptedEncoding != Request->end()) { + if (AcceptedEncoding->second.find("gzip") != std::string::npos || + AcceptedEncoding->second.find("compress") != std::string::npos) { Response->set("Content-Encoding", "gzip"); std::ostream &Answer = Response->send(); - Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP); + Poco::DeflatingOutputStream deflater(Answer, + Poco::DeflatingStreamBuf::STREAM_GZIP); Poco::JSON::Stringifier::stringify(Object, deflater); deflater.close(); return; @@ -552,74 +574,79 @@ namespace OpenWifi { inline void ReturnRawJSON(const std::string &json_doc) { PrepareResponse(); - if(Request!= nullptr) { + if (Request != nullptr) { // can we compress ??? auto AcceptedEncoding = Request->find("Accept-Encoding"); - if(AcceptedEncoding!=Request->end()) { - if( AcceptedEncoding->second.find("gzip")!=std::string::npos || - AcceptedEncoding->second.find("compress")!=std::string::npos) { + if (AcceptedEncoding != Request->end()) { + if (AcceptedEncoding->second.find("gzip") != std::string::npos || + AcceptedEncoding->second.find("compress") != std::string::npos) { Response->set("Content-Encoding", "gzip"); std::ostream &Answer = Response->send(); - Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP); - deflater << json_doc; + Poco::DeflatingOutputStream deflater(Answer, + Poco::DeflatingStreamBuf::STREAM_GZIP); + deflater << json_doc; deflater.close(); return; } } } std::ostream &Answer = Response->send(); - Answer << json_doc; + Answer << json_doc; } inline void ReturnCountOnly(uint64_t Count) { - Poco::JSON::Object Answer; + Poco::JSON::Object Answer; Answer.set("count", Count); ReturnObject(Answer); } inline bool InitQueryBlock() { - if(QueryBlockInitialized_) + if (QueryBlockInitialized_) return true; - QueryBlockInitialized_=true; + QueryBlockInitialized_ = true; QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, ""); QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0); QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0); QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 0); QB_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100); QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, ""); - QB_.Lifetime = GetBoolParameter(RESTAPI::Protocol::LIFETIME,false); - QB_.LogType = GetParameter(RESTAPI::Protocol::LOGTYPE,0); - QB_.LastOnly = GetBoolParameter(RESTAPI::Protocol::LASTONLY,false); - QB_.Newest = GetBoolParameter(RESTAPI::Protocol::NEWEST,false); - QB_.CountOnly = GetBoolParameter(RESTAPI::Protocol::COUNTONLY,false); - QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false); + QB_.Lifetime = GetBoolParameter(RESTAPI::Protocol::LIFETIME, false); + QB_.LogType = GetParameter(RESTAPI::Protocol::LOGTYPE, 0); + QB_.LastOnly = GetBoolParameter(RESTAPI::Protocol::LASTONLY, false); + QB_.Newest = GetBoolParameter(RESTAPI::Protocol::NEWEST, false); + QB_.CountOnly = GetBoolParameter(RESTAPI::Protocol::COUNTONLY, false); + QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO, false); auto RawSelect = GetParameter(RESTAPI::Protocol::SELECT, ""); - auto Entries = Poco::StringTokenizer(RawSelect,","); - for(const auto &i:Entries) { + auto Entries = Poco::StringTokenizer(RawSelect, ","); + for (const auto &i : Entries) { QB_.Select.emplace_back(i); } - if(QB_.Offset<1) - QB_.Offset=0; + if (QB_.Offset < 1) + QB_.Offset = 0; return true; } - [[nodiscard]] inline uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0){ - if(Obj->has(Parameter)) + [[nodiscard]] inline uint64_t Get(const char *Parameter, const Poco::JSON::Object::Ptr &Obj, + uint64_t Default = 0) { + if (Obj->has(Parameter)) return Obj->get(Parameter); return Default; } - [[nodiscard]] inline std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default=""){ - if(Obj->has(Parameter)) + [[nodiscard]] inline std::string GetS(const char *Parameter, + const Poco::JSON::Object::Ptr &Obj, + const std::string &Default = "") { + if (Obj->has(Parameter)) return Obj->get(Parameter).toString(); return Default; } - [[nodiscard]] inline bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false){ - if(Obj->has(Parameter)) - return Obj->get(Parameter).toString()=="true"; + [[nodiscard]] inline bool GetB(const char *Parameter, const Poco::JSON::Object::Ptr &Obj, + bool Default = false) { + if (Obj->has(Parameter)) + return Obj->get(Parameter).toString() == "true"; return Default; } @@ -627,113 +654,120 @@ namespace OpenWifi { return RESTAPIHandler::Get(RESTAPI::Protocol::WHEN, Obj); } - template void ReturnObject(const char *Name, const std::vector & Objects) { - Poco::JSON::Object Answer; - RESTAPI_utils::field_to_json(Answer,Name,Objects); + template void ReturnObject(const char *Name, const std::vector &Objects) { + Poco::JSON::Object Answer; + RESTAPI_utils::field_to_json(Answer, Name, Objects); ReturnObject(Answer); } - template void Object(const char *Name, const std::vector & Objects) { - Poco::JSON::Object Answer; - RESTAPI_utils::field_to_json(Answer,Name,Objects); + template void Object(const char *Name, const std::vector &Objects) { + Poco::JSON::Object Answer; + RESTAPI_utils::field_to_json(Answer, Name, Objects); ReturnObject(Answer); } template void Object(const T &O) { - Poco::JSON::Object Answer; + Poco::JSON::Object Answer; O.to_json(Answer); ReturnObject(Answer); } - Poco::Logger & Logger() { return Logger_; } + Poco::Logger &Logger() { return Logger_; } - virtual void DoGet() = 0 ; - virtual void DoDelete() = 0 ; - virtual void DoPost() = 0 ; - virtual void DoPut() = 0 ; + virtual void DoGet() = 0; + virtual void DoDelete() = 0; + virtual void DoPost() = 0; + virtual void DoPut() = 0; + + Poco::Net::HTTPServerRequest *Request = nullptr; + Poco::Net::HTTPServerResponse *Response = nullptr; + SecurityObjects::UserInfoAndPolicy UserInfo_; + QueryBlock QB_; + const std::string &Requester() const { return REST_Requester_; } - Poco::Net::HTTPServerRequest *Request= nullptr; - Poco::Net::HTTPServerResponse *Response= nullptr; - SecurityObjects::UserInfoAndPolicy UserInfo_; - QueryBlock QB_; - const std::string & Requester() const { return REST_Requester_; } protected: - BindingMap Bindings_; - Poco::URI::QueryParameters Parameters_; - Poco::Logger &Logger_; - std::string SessionToken_; - std::vector Methods_; - bool Internal_=false; - bool RateLimited_=false; - bool QueryBlockInitialized_=false; - bool SubOnlyService_=false; - bool AlwaysAuthorize_=true; - Poco::JSON::Parser IncomingParser_; - RESTAPI_GenericServerAccounting & Server_; - RateLimit MyRates_; - uint64_t TransactionId_; - Poco::JSON::Object::Ptr ParsedBody_; - std::string REST_Requester_; + BindingMap Bindings_; + Poco::URI::QueryParameters Parameters_; + Poco::Logger &Logger_; + std::string SessionToken_; + std::vector Methods_; + bool Internal_ = false; + bool RateLimited_ = false; + bool QueryBlockInitialized_ = false; + bool SubOnlyService_ = false; + bool AlwaysAuthorize_ = true; + Poco::JSON::Parser IncomingParser_; + RESTAPI_GenericServerAccounting &Server_; + RateLimit MyRates_; + uint64_t TransactionId_; + Poco::JSON::Object::Ptr ParsedBody_; + std::string REST_Requester_; }; -#ifdef TIP_SECURITY_SERVICE - [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, - SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub ); +#ifdef TIP_SECURITY_SERVICE + [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request, + std::string &SessionToken, + SecurityObjects::UserInfoAndPolicy &UInfo, + std::uint64_t TID, bool &Expired, bool Sub); #endif - inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) { - if(Internal_ && Request->has("X-INTERNAL-NAME")) { + inline bool RESTAPIHandler::IsAuthorized(bool &Expired, [[maybe_unused]] bool &Contacted, + bool Sub) { + if (Internal_ && Request->has("X-INTERNAL-NAME")) { auto Allowed = MicroServiceIsValidAPIKEY(*Request); Contacted = true; - if(!Allowed) { - if(Server_.LogBadTokens(false)) { - poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}", - Utils::FormatIPv6(Request->clientAddress().toString()), - TransactionId_, - Request->getMethod(), Request->getURI())); + if (!Allowed) { + if (Server_.LogBadTokens(false)) { + poco_debug(Logger_, + fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}", + Utils::FormatIPv6(Request->clientAddress().toString()), + TransactionId_, Request->getMethod(), + Request->getURI())); } } else { auto Id = Request->get("X-INTERNAL-NAME", "unknown"); REST_Requester_ = Id; - if(Server_.LogIt(Request->getMethod(),true)) { - poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}", - Utils::FormatIPv6(Request->clientAddress().toString()), - TransactionId_, - Id, - Request->getMethod(), Request->getURI())); + if (Server_.LogIt(Request->getMethod(), true)) { + poco_debug(Logger_, + fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}", + Utils::FormatIPv6(Request->clientAddress().toString()), + TransactionId_, Id, Request->getMethod(), + Request->getURI())); } } return Allowed; - } else if(!Internal_ && Request->has("X-API-KEY")) { - SessionToken_ = Request->get("X-API-KEY", ""); - bool suspended=false; -#ifdef TIP_SECURITY_SERVICE - std::uint64_t expiresOn; - if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn, suspended)) { + } else if (!Internal_ && Request->has("X-API-KEY")) { + SessionToken_ = Request->get("X-API-KEY", ""); + bool suspended = false; +#ifdef TIP_SECURITY_SERVICE + std::uint64_t expiresOn; + if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, + Expired, expiresOn, suspended)) { #else - if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, suspended)) { + if (AuthClient()->IsValidApiKey(SessionToken_, UserInfo_, TransactionId_, Expired, + Contacted, suspended)) { #endif - REST_Requester_ = UserInfo_.userinfo.email; - if(Server_.LogIt(Request->getMethod(),true)) { - poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}", - UserInfo_.userinfo.email, - TransactionId_, - Utils::FormatIPv6(Request->clientAddress().toString()), - Request->clientAddress().toString(), - Request->getMethod(), - Request->getURI())); - } - return true; - } else { - if(Server_.LogBadTokens(true)) { - poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}", - Utils::FormatIPv6(Request->clientAddress().toString()), - TransactionId_, - Request->getMethod(), - Request->getURI())); - } - } - return false; - } else { + REST_Requester_ = UserInfo_.userinfo.email; + if (Server_.LogIt(Request->getMethod(), true)) { + poco_debug(Logger_, + fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' " + "Method={} Path={}", + UserInfo_.userinfo.email, TransactionId_, + Utils::FormatIPv6(Request->clientAddress().toString()), + Request->clientAddress().toString(), + Request->getMethod(), Request->getURI())); + } + return true; + } else { + if (Server_.LogBadTokens(true)) { + poco_debug(Logger_, + fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}", + Utils::FormatIPv6(Request->clientAddress().toString()), + TransactionId_, Request->getMethod(), + Request->getURI())); + } + } + return false; + } else { if (SessionToken_.empty()) { try { Poco::Net::OAuth20Credentials Auth(*Request); @@ -744,29 +778,31 @@ namespace OpenWifi { Logger_.log(E); } } -#ifdef TIP_SECURITY_SERVICE - if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) { +#ifdef TIP_SECURITY_SERVICE + if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, + Sub)) { #else - if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) { + if (AuthClient()->IsAuthorized(SessionToken_, UserInfo_, TransactionId_, Expired, + Contacted, Sub)) { #endif REST_Requester_ = UserInfo_.userinfo.email; - if(Server_.LogIt(Request->getMethod(),true)) { - poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}", - UserInfo_.userinfo.email, - TransactionId_, - Utils::FormatIPv6(Request->clientAddress().toString()), - Request->clientAddress().toString(), - Request->getMethod(), - Request->getURI())); + if (Server_.LogIt(Request->getMethod(), true)) { + poco_debug( + Logger_, + fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}", + UserInfo_.userinfo.email, TransactionId_, + Utils::FormatIPv6(Request->clientAddress().toString()), + Request->clientAddress().toString(), Request->getMethod(), + Request->getURI())); } return true; } else { - if(Server_.LogBadTokens(true)) { - poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}", - Utils::FormatIPv6(Request->clientAddress().toString()), - TransactionId_, - Request->getMethod(), - Request->getURI())); + if (Server_.LogBadTokens(true)) { + poco_debug(Logger_, + fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}", + Utils::FormatIPv6(Request->clientAddress().toString()), + TransactionId_, Request->getMethod(), + Request->getURI())); } } return false; @@ -775,53 +811,59 @@ namespace OpenWifi { class RESTAPI_UnknownRequestHandler : public RESTAPIHandler { public: - RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) - : RESTAPIHandler(bindings, L, std::vector{}, Server, TransactionId, Internal) {} - inline void DoGet() override {}; - inline void DoPost() override {}; - inline void DoPut() override {}; - inline void DoDelete() override {}; + RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) + : RESTAPIHandler(bindings, L, std::vector{}, Server, TransactionId, + Internal) {} + inline void DoGet() override{}; + inline void DoPost() override{}; + inline void DoPut() override{}; + inline void DoDelete() override{}; }; - template - constexpr auto test_has_PathName_method(T*) - -> decltype( T::PathName() , std::true_type{} ) - { - return std::true_type{}; - } - constexpr auto test_has_PathName_method(...) -> std::false_type - { - return std::false_type{}; + template + constexpr auto test_has_PathName_method(T *) -> decltype(T::PathName(), std::true_type{}) { + return std::true_type{}; + } + constexpr auto test_has_PathName_method(...) -> std::false_type { return std::false_type{}; } + + template + RESTAPIHandler *RESTAPI_Router(const std::string &RequestedPath, + RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId) { + static_assert(test_has_PathName_method((T *)nullptr), + "Class must have a static PathName() method."); + if (RESTAPIHandler::ParseBindings(RequestedPath, T::PathName(), Bindings)) { + return new T(Bindings, Logger, Server, TransactionId, false); } - template - RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) { - static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method."); - if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) { - return new T(Bindings, Logger, Server, TransactionId, false); - } + if constexpr (sizeof...(Args) == 0) { + return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId, + false); + } else { + return RESTAPI_Router(RequestedPath, Bindings, Logger, Server, TransactionId); + } + } - if constexpr (sizeof...(Args) == 0) { - return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, false); - } else { - return RESTAPI_Router(RequestedPath, Bindings, Logger, Server, TransactionId); - } + template + RESTAPIHandler *RESTAPI_Router_I(const std::string &RequestedPath, + RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId) { + static_assert(test_has_PathName_method((T *)nullptr), + "Class must have a static PathName() method."); + if (RESTAPIHandler::ParseBindings(RequestedPath, T::PathName(), Bindings)) { + return new T(Bindings, Logger, Server, TransactionId, true); } - template - RESTAPIHandler * RESTAPI_Router_I(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) { - static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method."); - if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) { - return new T(Bindings, Logger, Server, TransactionId, true ); - } - - if constexpr (sizeof...(Args) == 0) { - return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, true); - } else { - return RESTAPI_Router_I(RequestedPath, Bindings, Logger, Server, TransactionId); - } + if constexpr (sizeof...(Args) == 0) { + return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId, true); + } else { + return RESTAPI_Router_I(RequestedPath, Bindings, Logger, Server, + TransactionId); } + } } // namespace OpenWifi diff --git a/src/framework/RESTAPI_IntServer.h b/src/framework/RESTAPI_IntServer.h index 4926771..6270b95 100644 --- a/src/framework/RESTAPI_IntServer.h +++ b/src/framework/RESTAPI_IntServer.h @@ -6,20 +6,23 @@ #include "Poco/Net/HTTPServer.h" -#include "framework/SubSystemServer.h" #include "framework/RESTAPI_Handler.h" +#include "framework/SubSystemServer.h" namespace OpenWifi { - Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, - Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id); + Poco::Net::HTTPRequestHandler * + RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, + Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id); class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory { public: inline IntRequestHandlerFactory() = default; - Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override; + Poco::Net::HTTPRequestHandler * + createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override; + private: - static inline std::atomic_uint64_t NextTransactionId_ = 1; + static inline std::atomic_uint64_t NextTransactionId_ = 1; }; class RESTAPI_IntServer : public SubSystemServer { @@ -30,16 +33,21 @@ namespace OpenWifi { } inline int Start() override { - poco_information(Logger(),"Starting."); + poco_information(Logger(), "Starting."); Server_.InitLogging(); - for(const auto & Svr: ConfigServersList_) { + for (const auto &Svr : ConfigServersList_) { - if(MicroServiceNoAPISecurity()) { - poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port())); + if (MicroServiceNoAPISecurity()) { + poco_information( + Logger(), + fmt::format("Starting: {}:{}. Security has been disabled for APIs.", + Svr.Address(), Svr.Port())); } else { - poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(), - Svr.KeyFile(),Svr.CertFile())); + poco_information(Logger(), + fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", + Svr.Address(), Svr.Port(), Svr.KeyFile(), + Svr.CertFile())); Svr.LogCert(Logger()); if (!Svr.RootCA().empty()) Svr.LogCas(Logger()); @@ -49,13 +57,15 @@ namespace OpenWifi { Params->setKeepAlive(true); Params->setName("ws:irest"); - std::unique_ptr NewServer; - if(MicroServiceNoAPISecurity()) { + std::unique_ptr NewServer; + if (MicroServiceNoAPISecurity()) { auto Sock{Svr.CreateSocket(Logger())}; - NewServer = std::make_unique(new IntRequestHandlerFactory, Pool_, Sock, Params); + NewServer = std::make_unique( + new IntRequestHandlerFactory, Pool_, Sock, Params); } else { auto Sock{Svr.CreateSecureSocket(Logger())}; - NewServer = std::make_unique(new IntRequestHandlerFactory, Pool_, Sock, Params); + NewServer = std::make_unique( + new IntRequestHandlerFactory, Pool_, Sock, Params); }; NewServer->start(); RESTServers_.push_back(std::move(NewServer)); @@ -65,40 +75,37 @@ namespace OpenWifi { } inline void Stop() override { - poco_information(Logger(),"Stopping..."); - for( const auto & svr : RESTServers_ ) + poco_information(Logger(), "Stopping..."); + for (const auto &svr : RESTServers_) svr->stopAll(true); Pool_.stopAll(); Pool_.joinAll(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { MicroServiceLoadConfigurationFile(); - poco_information(Logger(),"Reinitializing."); + poco_information(Logger(), "Reinitializing."); Stop(); Start(); } inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) { RESTAPIHandler::BindingMap Bindings; - Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str()); + Utils::SetThreadName(fmt::format("i-rest:{}", Id).c_str()); return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); } - const Poco::ThreadPool & Pool() { return Pool_; } - private: - std::vector> RESTServers_; - Poco::ThreadPool Pool_{"i-rest",4,64}; - RESTAPI_GenericServerAccounting Server_; + const Poco::ThreadPool &Pool() { return Pool_; } - RESTAPI_IntServer() noexcept: - SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") - { - } + private: + std::vector> RESTServers_; + Poco::ThreadPool Pool_{"i-rest", 4, 64}; + RESTAPI_GenericServerAccounting Server_; + + RESTAPI_IntServer() noexcept + : SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") {} }; inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); }; - } // namespace OpenWifi - diff --git a/src/framework/RESTAPI_PartHandler.h b/src/framework/RESTAPI_PartHandler.h index 4e0f2f0..c466102 100644 --- a/src/framework/RESTAPI_PartHandler.h +++ b/src/framework/RESTAPI_PartHandler.h @@ -4,29 +4,26 @@ #pragma once -#include -#include "Poco/Net/PartHandler.h" -#include "Poco/Net/MessageHeader.h" #include "Poco/CountingStream.h" +#include "Poco/Net/MessageHeader.h" +#include "Poco/Net/PartHandler.h" #include "Poco/NullStream.h" #include "Poco/StreamCopier.h" +#include namespace OpenWifi { - class RESTAPI_PartHandler: public Poco::Net::PartHandler { + class RESTAPI_PartHandler : public Poco::Net::PartHandler { public: - RESTAPI_PartHandler(): - _length(0) - { - } + RESTAPI_PartHandler() : _length(0) {} - inline void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream) override - { + inline void handlePart(const Poco::Net::MessageHeader &header, + std::istream &stream) override { _type = header.get("Content-Type", "(unspecified)"); - if (header.has("Content-Disposition")) - { + if (header.has("Content-Disposition")) { std::string disp; Poco::Net::NameValueCollection params; - Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, params); + Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, + params); _name = params.get("name", "(unnamed)"); _fileName = params.get("filename", "(unnamed)"); } @@ -37,25 +34,13 @@ namespace OpenWifi { _length = (int)istr.chars(); } - [[nodiscard]] inline int length() const - { - return _length; - } + [[nodiscard]] inline int length() const { return _length; } - [[nodiscard]] inline const std::string& name() const - { - return _name; - } + [[nodiscard]] inline const std::string &name() const { return _name; } - [[nodiscard]] inline const std::string& fileName() const - { - return _fileName; - } + [[nodiscard]] inline const std::string &fileName() const { return _fileName; } - [[nodiscard]] inline const std::string& contentType() const - { - return _type; - } + [[nodiscard]] inline const std::string &contentType() const { return _type; } private: int _length; @@ -63,4 +48,4 @@ namespace OpenWifi { std::string _name; std::string _fileName; }; -} +} // namespace OpenWifi diff --git a/src/framework/RESTAPI_RateLimiter.h b/src/framework/RESTAPI_RateLimiter.h index 954227e..d55ff07 100644 --- a/src/framework/RESTAPI_RateLimiter.h +++ b/src/framework/RESTAPI_RateLimiter.h @@ -6,9 +6,9 @@ #include "framework/SubSystemServer.h" -#include "Poco/URI.h" -#include "Poco/Net/HTTPServerRequest.h" #include "Poco/ExpireLRUCache.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/URI.h" #include "fmt/format.h" @@ -16,10 +16,9 @@ namespace OpenWifi { class RESTAPI_RateLimiter : public SubSystemServer { public: - struct ClientCacheEntry { - int64_t Start=0; - int Count=0; + int64_t Start = 0; + int Count = 0; }; static auto instance() { @@ -27,49 +26,47 @@ namespace OpenWifi { return instance_; } - inline int Start() final { return 0;}; - inline void Stop() final { }; + inline int Start() final { return 0; }; + inline void Stop() final{}; - inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, int64_t MaxCalls) { - Poco::URI uri(R.getURI()); + inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, + int64_t MaxCalls) { + Poco::URI uri(R.getURI()); auto H = str_hash(uri.getPath() + R.clientAddress().host().toString()); auto E = Cache_.get(H); - auto Now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - if(E.isNull()) { - Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1}); + auto Now = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()) + .count(); + if (E.isNull()) { + Cache_.add(H, ClientCacheEntry{.Start = Now, .Count = 1}); return false; } - if((Now-E->Start)Start) < Period) { E->Count++; - Cache_.update(H,E); - if(E->Count > MaxCalls) { - poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString())); + Cache_.update(H, E); + if (E->Count > MaxCalls) { + poco_warning(Logger(), fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", + R.clientAddress().toString())); return true; } return false; } E->Start = Now; E->Count = 1; - Cache_.update(H,E); + Cache_.update(H, E); return false; } - inline void Clear() { - Cache_.clear(); - } + inline void Clear() { Cache_.clear(); } private: - Poco::ExpireLRUCache Cache_{2048}; - std::hash str_hash; - - RESTAPI_RateLimiter() noexcept: - SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") - { - } + Poco::ExpireLRUCache Cache_{2048}; + std::hash str_hash; + RESTAPI_RateLimiter() noexcept + : SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") {} }; inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); } - -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_SystemCommand.h b/src/framework/RESTAPI_SystemCommand.h index 9ce9691..f86f57d 100644 --- a/src/framework/RESTAPI_SystemCommand.h +++ b/src/framework/RESTAPI_SystemCommand.h @@ -14,19 +14,19 @@ namespace OpenWifi { class RESTAPI_system_command : public RESTAPIHandler { public: - RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) + RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) : RESTAPIHandler(bindings, L, std::vector{Poco::Net::HTTPRequest::HTTP_POST, Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, - TransactionId, - Internal) {} - static auto PathName() { return std::list{"/api/v1/system"};} + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/system"}; } inline void DoGet() { std::string Arg; - if(HasParameter("command",Arg) && Arg=="info") { + if (HasParameter("command", Arg) && Arg == "info") { Poco::JSON::Object Answer; Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion()); Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds()); @@ -36,19 +36,19 @@ namespace OpenWifi { Answer.set(RESTAPI::Protocol::HOSTNAME, Poco::Environment::nodeName()); Answer.set(RESTAPI::Protocol::UI, MicroServiceGetUIURI()); - Poco::JSON::Array Certificates; + Poco::JSON::Array Certificates; auto SubSystems = MicroServiceGetFullSubSystems(); - std::set CertNames; + std::set CertNames; - for(const auto &i:SubSystems) { - auto Hosts=i->HostSize(); - for(uint64_t j=0;jHostSize(); + for (uint64_t j = 0; j < Hosts; ++j) { auto CertFileName = i->Host(j).CertFile(); - if(!CertFileName.empty()) { - Poco::File F1(CertFileName); - if(F1.exists()) { + if (!CertFileName.empty()) { + Poco::File F1(CertFileName); + if (F1.exists()) { auto InsertResult = CertNames.insert(CertFileName); - if(InsertResult.second) { + if (InsertResult.second) { Poco::JSON::Object Inner; Poco::Path F(CertFileName); Inner.set("filename", F.getFileName()); @@ -64,8 +64,8 @@ namespace OpenWifi { Answer.set("certificates", Certificates); return ReturnObject(Answer); } - if(GetBoolParameter("extraConfiguration")) { - Poco::JSON::Object Answer; + if (GetBoolParameter("extraConfiguration")) { + Poco::JSON::Object Answer; MicroServiceGetExtraConfiguration(Answer); return ReturnObject(Answer); } @@ -73,7 +73,7 @@ namespace OpenWifi { } inline void DoPost() final { - const auto & Obj = ParsedBody_; + const auto &Obj = ParsedBody_; if (Obj->has(RESTAPI::Protocol::COMMAND)) { auto Command = Poco::toLower(Obj->get(RESTAPI::Protocol::COMMAND).toString()); if (Command == RESTAPI::Protocol::SETLOGLEVEL) { @@ -88,7 +88,8 @@ namespace OpenWifi { auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj); auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj); MicroServiceSetSubsystemLogLevel(Name, Value); - poco_information(Logger_, + poco_information( + Logger_, fmt::format("Setting log level for {} at {}", Name, Value)); } } @@ -109,7 +110,7 @@ namespace OpenWifi { } else if (Command == RESTAPI::Protocol::GETLOGLEVELNAMES) { Poco::JSON::Object Result; Poco::JSON::Array LevelNamesArray; - const Types::StringVec &LevelNames = MicroServiceGetLogLevelNames(); + const Types::StringVec &LevelNames = MicroServiceGetLogLevelNames(); for (const auto &i : LevelNames) LevelNamesArray.add(i); Result.set(RESTAPI::Protocol::LIST, LevelNamesArray); @@ -117,7 +118,7 @@ namespace OpenWifi { } else if (Command == RESTAPI::Protocol::GETSUBSYSTEMNAMES) { Poco::JSON::Object Result; Poco::JSON::Array LevelNamesArray; - const Types::StringVec &SubSystemNames = MicroServiceGetSubSystems(); + const Types::StringVec &SubSystemNames = MicroServiceGetSubSystems(); for (const auto &i : SubSystemNames) LevelNamesArray.add(i); Result.set(RESTAPI::Protocol::LIST, LevelNamesArray); @@ -131,10 +132,10 @@ namespace OpenWifi { std::vector Names; for (const auto &i : *SubSystems) Names.push_back(i.toString()); - std::thread ReloadThread([Names](){ + std::thread ReloadThread([Names]() { std::this_thread::sleep_for(10000ms); - for(const auto &i:Names) { - if(i=="daemon") + for (const auto &i : Names) { + if (i == "daemon") MicroServiceReload(); else MicroServiceReload(i); @@ -150,8 +151,8 @@ namespace OpenWifi { BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } - void DoPut() final {}; - void DoDelete() final {}; + void DoPut() final{}; + void DoDelete() final{}; }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_SystemConfiguration.h b/src/framework/RESTAPI_SystemConfiguration.h index c75be97..d148784 100644 --- a/src/framework/RESTAPI_SystemConfiguration.h +++ b/src/framework/RESTAPI_SystemConfiguration.h @@ -4,8 +4,8 @@ #pragma once -#include "framework/RESTAPI_Handler.h" #include "framework/MicroServiceFuncs.h" +#include "framework/RESTAPI_Handler.h" using namespace std::chrono_literals; @@ -14,8 +14,8 @@ namespace OpenWifi { class RESTAPI_system_configuration : public RESTAPIHandler { public: RESTAPI_system_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, - RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, - bool Internal) + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) : RESTAPIHandler(bindings, L, std::vector{Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_GET, @@ -27,21 +27,18 @@ namespace OpenWifi { inline void DoPost() final {} - inline void DoGet() final { + inline void DoGet() final { return OK(); } - return OK(); - } - - inline void DoPut() final{ - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { + inline void DoPut() final { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); } return OK(); }; - inline void DoDelete() final{ - if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { + inline void DoDelete() final { + if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) { return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); } MicroServiceDeleteOverrideConfiguration(); @@ -49,4 +46,4 @@ namespace OpenWifi { }; }; -} +} // namespace OpenWifi diff --git a/src/framework/RESTAPI_WebSocketServer.h b/src/framework/RESTAPI_WebSocketServer.h index 294c52f..5a4bc99 100644 --- a/src/framework/RESTAPI_WebSocketServer.h +++ b/src/framework/RESTAPI_WebSocketServer.h @@ -4,42 +4,44 @@ #pragma once -#include "framework/RESTAPI_Handler.h" #include "Poco/Net/WebSocket.h" +#include "framework/RESTAPI_Handler.h" -#include "framework/UI_WebSocketClientServer.h" #include "framework/MicroServiceFuncs.h" +#include "framework/UI_WebSocketClientServer.h" namespace OpenWifi { class RESTAPI_webSocketServer : public RESTAPIHandler { public: - inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) + inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, + uint64_t TransactionId, bool Internal) : RESTAPIHandler(bindings, L, - std::vector{ Poco::Net::HTTPRequest::HTTP_GET, - Poco::Net::HTTPRequest::HTTP_OPTIONS}, - Server, TransactionId, Internal,false) {} - static auto PathName() { return std::list{"/api/v1/ws"};} + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal, false) {} + static auto PathName() { return std::list{"/api/v1/ws"}; } void DoGet() final { - try - { - if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) { - try - { - Poco::Net::WebSocket WS(*Request, *Response); - auto Id = MicroServiceCreateUUID(); - UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_); - } - catch (...) { - std::cout << "Cannot create websocket client..." << std::endl; - } + try { + if (Request->find("Upgrade") != Request->end() && + Poco::icompare((*Request)["Upgrade"], "websocket") == 0) { + try { + Poco::Net::WebSocket WS(*Request, *Response); + auto Id = MicroServiceCreateUUID(); + UI_WebSocketClientServer()->NewClient(WS, Id, UserInfo_.userinfo.email, + TransactionId_); + } catch (...) { + std::cout << "Cannot create websocket client..." << std::endl; } - } catch(...) { - std::cout << "Cannot upgrade connection..." << std::endl; } - }; - void DoDelete() final {}; - void DoPost() final {}; - void DoPut() final {}; + } catch (...) { + std::cout << "Cannot upgrade connection..." << std::endl; + } + }; + void DoDelete() final{}; + void DoPost() final{}; + void DoPut() final{}; + private: }; -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/RESTAPI_utils.h b/src/framework/RESTAPI_utils.h index 566b20f..a3eca9d 100644 --- a/src/framework/RESTAPI_utils.h +++ b/src/framework/RESTAPI_utils.h @@ -6,9 +6,9 @@ #include +#include "Poco/Data/LOB.h" #include "Poco/JSON/Object.h" #include "Poco/JSON/Parser.h" -#include "Poco/Data/LOB.h" #include "Poco/Net/HTTPServerRequest.h" #include "framework/OpenWifiTypes.h" @@ -16,7 +16,8 @@ namespace OpenWifi::RESTAPI_utils { - inline void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) { + inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj, + const std::string &ObjStr) { std::string D = ObjStr.empty() ? "{}" : ObjStr; Poco::JSON::Parser P; Poco::Dynamic::Var result = P.parse(D); @@ -25,23 +26,23 @@ namespace OpenWifi::RESTAPI_utils { } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, bool V) { - Obj.set(Field,V); + Obj.set(Field, V); } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, double V) { - Obj.set(Field,V); + Obj.set(Field, V); } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, float V) { - Obj.set(Field,V); + Obj.set(Field, V); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::string & S) { - Obj.set(Field,S); + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::string &S) { + Obj.set(Field, S); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const char * S) { - Obj.set(Field,S); + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const char *S) { + Obj.set(Field, S); } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, int16_t Value) { @@ -65,87 +66,93 @@ namespace OpenWifi::RESTAPI_utils { } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, uint64_t Value) { - Obj.set(Field,Value); + Obj.set(Field, Value); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) { - auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size()); - Obj.set(Field,Result); + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, + const Poco::Data::BLOB &Value) { + auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(), Value.size()); + Obj.set(Field, Result); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) { - Poco::JSON::Array Array; - for(const auto &i:S) { - Poco::JSON::Object O; - O.set("tag",i.first); + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, + const Types::StringPairVec &S) { + Poco::JSON::Array Array; + for (const auto &i : S) { + Poco::JSON::Object O; + O.set("tag", i.first); O.set("value", i.second); Array.add(O); } - Obj.set(Field,Array); + Obj.set(Field, Array); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringVec &V) { - Poco::JSON::Array A; - for(const auto &i:V) + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, + const Types::StringVec &V) { + Poco::JSON::Array A; + for (const auto &i : V) A.add(i); - Obj.set(Field,A); + Obj.set(Field, A); } inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::TagList &V) { - Poco::JSON::Array A; - for(const auto &i:V) + Poco::JSON::Array A; + for (const auto &i : V) A.add(i); - Obj.set(Field,A); + Obj.set(Field, A); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) { - Poco::JSON::Array A; - for(const auto &[Key,Value]:M) { - Poco::JSON::Object O; - O.set("tag",Key); + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, + const Types::CountedMap &M) { + Poco::JSON::Array A; + for (const auto &[Key, Value] : M) { + Poco::JSON::Object O; + O.set("tag", Key); O.set("value", Value); A.add(O); } - Obj.set(Field,A); + Obj.set(Field, A); } - inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::Counted3DMapSII &M) { - Poco::JSON::Array A; - for(const auto &[OrgName,MonthlyNumberMap]:M) { - Poco::JSON::Object OrgObject; - OrgObject.set("tag",OrgName); - Poco::JSON::Array MonthlyArray; - for(const auto &[Month,Counter]:MonthlyNumberMap) { - Poco::JSON::Object Inner; + inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, + const Types::Counted3DMapSII &M) { + Poco::JSON::Array A; + for (const auto &[OrgName, MonthlyNumberMap] : M) { + Poco::JSON::Object OrgObject; + OrgObject.set("tag", OrgName); + Poco::JSON::Array MonthlyArray; + for (const auto &[Month, Counter] : MonthlyNumberMap) { + Poco::JSON::Object Inner; Inner.set("value", Month); Inner.set("counter", Counter); MonthlyArray.add(Inner); } - OrgObject.set("index",MonthlyArray); + OrgObject.set("index", MonthlyArray); A.add(OrgObject); } Obj.set(Field, A); } - template void field_to_json(Poco::JSON::Object &Obj, - const char *Field, - const T &V, + template + void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &V, std::function F) { Obj.set(Field, F(V)); } - template void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector &Value) { + template + void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector &Value) { Poco::JSON::Array Arr; - for(const auto &i:Value) { - Poco::JSON::Object AO; + for (const auto &i : Value) { + Poco::JSON::Object AO; i.to_json(AO); Arr.add(AO); } Obj.set(Field, Arr); } - template void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) { - Poco::JSON::Object Answer; + template + void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) { + Poco::JSON::Object Answer; Value.to_json(Answer); Obj.set(Field, Answer); } @@ -155,188 +162,207 @@ namespace OpenWifi::RESTAPI_utils { /////////////////////////// /////////////////////////// - template bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T & V, + template + bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &V, std::function F) { - if(Obj->has(Field) && !Obj->isNull(Field)) + if (Obj->has(Field) && !Obj->isNull(Field)) V = F(Obj->get(Field).toString()); return true; } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::string &S) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + std::string &S) { + if (Obj->has(Field) && !Obj->isNull(Field)) S = Obj->get(Field).toString(); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + double &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (double)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + float &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (float)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + bool &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (Obj->get(Field).toString() == "true"); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int16_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + int16_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (int16_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int32_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) - Value = (int32_t) Obj->get(Field); + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + int32_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) + Value = (int32_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + int64_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (int64_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint16_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + uint16_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (uint16_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint32_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + uint32_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (uint32_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + uint64_t &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) Value = (uint64_t)Obj->get(Field); } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) { - if(Obj->has(Field) && !Obj->isNull(Field)) { + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + Poco::Data::BLOB &Value) { + if (Obj->has(Field) && !Obj->isNull(Field)) { auto Result = Utils::base64decode(Obj->get(Field).toString()); - Value.assignRaw((const unsigned char *)&Result[0],Result.size()); + Value.assignRaw((const unsigned char *)&Result[0], Result.size()); } } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) { - if(Obj->isArray(Field) && !Obj->isNull(Field)) { + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + Types::StringPairVec &Vec) { + if (Obj->isArray(Field) && !Obj->isNull(Field)) { auto O = Obj->getArray(Field); - for(const auto &i:*O) { - std::string S1,S2; + for (const auto &i : *O) { + std::string S1, S2; auto Inner = i.extract(); - if(Inner->has("tag")) + if (Inner->has("tag")) S1 = Inner->get("tag").toString(); - if(Inner->has("value")) + if (Inner->has("value")) S2 = Inner->get("value").toString(); - auto P = std::make_pair(S1,S2); + auto P = std::make_pair(S1, S2); Vec.push_back(P); } } } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringVec &Value) { - if(Obj->isArray(Field) && !Obj->isNull(Field)) { + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + Types::StringVec &Value) { + if (Obj->isArray(Field) && !Obj->isNull(Field)) { Value.clear(); Poco::JSON::Array::Ptr A = Obj->getArray(Field); - for(const auto &i:*A) { + for (const auto &i : *A) { Value.push_back(i.toString()); } } } - inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::TagList &Value) { - if(Obj->isArray(Field) && !Obj->isNull(Field)) { + inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + Types::TagList &Value) { + if (Obj->isArray(Field) && !Obj->isNull(Field)) { Value.clear(); Poco::JSON::Array::Ptr A = Obj->getArray(Field); - for(const auto &i:*A) { + for (const auto &i : *A) { Value.push_back(i); } } } - template void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::vector &Value) { - if(Obj->isArray(Field) && !Obj->isNull(Field)) { - Poco::JSON::Array::Ptr Arr = Obj->getArray(Field); - for(auto &i:*Arr) { + template + void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, + std::vector &Value) { + if (Obj->isArray(Field) && !Obj->isNull(Field)) { + Poco::JSON::Array::Ptr Arr = Obj->getArray(Field); + for (auto &i : *Arr) { auto InnerObj = i.extract(); - T NewItem; + T NewItem; NewItem.from_json(InnerObj); Value.push_back(NewItem); } } } - template void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) { - if(Obj->isObject(Field) && !Obj->isNull(Field)) { - Poco::JSON::Object::Ptr A = Obj->getObject(Field); + template + void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) { + if (Obj->isObject(Field) && !Obj->isNull(Field)) { + Poco::JSON::Object::Ptr A = Obj->getObject(Field); Value.from_json(A); } } - inline std::string to_string(const Types::TagList & ObjectArray) { + inline std::string to_string(const Types::TagList &ObjectArray) { Poco::JSON::Array OutputArr; - if(ObjectArray.empty()) + if (ObjectArray.empty()) return "[]"; - for(auto const &i:ObjectArray) { + for (auto const &i : ObjectArray) { OutputArr.add(i); } std::ostringstream OS; - Poco::JSON::Stringifier::stringify(OutputArr,OS, 0,0, Poco::JSON_PRESERVE_KEY_ORDER ); + Poco::JSON::Stringifier::stringify(OutputArr, OS, 0, 0, Poco::JSON_PRESERVE_KEY_ORDER); return OS.str(); } - inline std::string to_string(const Types::StringVec & ObjectArray) { + inline std::string to_string(const Types::StringVec &ObjectArray) { Poco::JSON::Array OutputArr; - if(ObjectArray.empty()) + if (ObjectArray.empty()) return "[]"; - for(auto const &i:ObjectArray) { + for (auto const &i : ObjectArray) { OutputArr.add(i); } std::ostringstream OS; - Poco::JSON::Stringifier::condense(OutputArr,OS); + Poco::JSON::Stringifier::condense(OutputArr, OS); return OS.str(); } - inline std::string to_string(const Types::StringPairVec & ObjectArray) { + inline std::string to_string(const Types::StringPairVec &ObjectArray) { Poco::JSON::Array OutputArr; - if(ObjectArray.empty()) + if (ObjectArray.empty()) return "[]"; - for(auto const &i:ObjectArray) { + for (auto const &i : ObjectArray) { Poco::JSON::Array InnerArray; InnerArray.add(i.first); InnerArray.add(i.second); OutputArr.add(InnerArray); } std::ostringstream OS; - Poco::JSON::Stringifier::condense(OutputArr,OS); + Poco::JSON::Stringifier::condense(OutputArr, OS); return OS.str(); } - template std::string to_string(const std::vector & ObjectArray) { + template std::string to_string(const std::vector &ObjectArray) { Poco::JSON::Array OutputArr; - if(ObjectArray.empty()) + if (ObjectArray.empty()) return "[]"; - for(auto const &i:ObjectArray) { + for (auto const &i : ObjectArray) { Poco::JSON::Object O; i.to_json(O); OutputArr.add(O); } std::ostringstream OS; - Poco::JSON::Stringifier::condense(OutputArr,OS); + Poco::JSON::Stringifier::condense(OutputArr, OS); return OS.str(); } - template std::string to_string(const std::vector> & ObjectArray) { + template std::string to_string(const std::vector> &ObjectArray) { Poco::JSON::Array OutputArr; - if(ObjectArray.empty()) + if (ObjectArray.empty()) return "[]"; - for(auto const &i:ObjectArray) { + for (auto const &i : ObjectArray) { Poco::JSON::Array InnerArr; - for(auto const &j:i) { - if constexpr(std::is_integral::value) { + for (auto const &j : i) { + if constexpr (std::is_integral::value) { InnerArr.add(j); - } if constexpr(std::is_same_v) { + } + if constexpr (std::is_same_v) { InnerArr.add(j); } else { InnerArr.add(j); @@ -348,22 +374,22 @@ namespace OpenWifi::RESTAPI_utils { OutputArr.add(InnerArr); } std::ostringstream OS; - Poco::JSON::Stringifier::condense(OutputArr,OS); + Poco::JSON::Stringifier::condense(OutputArr, OS); return OS.str(); } - template std::string to_string(const T & Object) { + template std::string to_string(const T &Object) { Poco::JSON::Object OutputObj; Object.to_json(OutputObj); std::ostringstream OS; - Poco::JSON::Stringifier::condense(OutputObj,OS); + Poco::JSON::Stringifier::condense(OutputObj, OS); return OS.str(); } - inline Types::StringVec to_object_array(const std::string & ObjectString) { + inline Types::StringVec to_object_array(const std::string &ObjectString) { - Types::StringVec Result; - if(ObjectString.empty()) + Types::StringVec Result; + if (ObjectString.empty()) return Result; try { @@ -373,14 +399,13 @@ namespace OpenWifi::RESTAPI_utils { Result.push_back(i.toString()); } } catch (...) { - } return Result; } - inline OpenWifi::Types::TagList to_taglist(const std::string & ObjectString) { - Types::TagList Result; - if(ObjectString.empty()) + inline OpenWifi::Types::TagList to_taglist(const std::string &ObjectString) { + Types::TagList Result; + if (ObjectString.empty()) return Result; try { @@ -390,36 +415,34 @@ namespace OpenWifi::RESTAPI_utils { Result.push_back(i); } } catch (...) { - } return Result; } inline Types::StringPairVec to_stringpair_array(const std::string &S) { - Types::StringPairVec R; - if(S.empty()) + Types::StringPairVec R; + if (S.empty()) return R; try { Poco::JSON::Parser P; auto Object = P.parse(S).template extract(); for (const auto &i : *Object) { auto InnerObject = i.template extract(); - if(InnerObject->size()==2) { + if (InnerObject->size() == 2) { auto S1 = InnerObject->getElement(0); auto S2 = InnerObject->getElement(1); - R.push_back(std::make_pair(S1,S2)); + R.push_back(std::make_pair(S1, S2)); } } } catch (...) { - } return R; } - template std::vector to_object_array(const std::string & ObjectString) { - std::vector Result; - if(ObjectString.empty()) + template std::vector to_object_array(const std::string &ObjectString) { + std::vector Result; + if (ObjectString.empty()) return Result; try { @@ -432,14 +455,14 @@ namespace OpenWifi::RESTAPI_utils { Result.push_back(Obj); } } catch (...) { - } return Result; } - template std::vector> to_array_of_array_of_object(const std::string & ObjectString) { - std::vector> Result; - if(ObjectString.empty()) + template + std::vector> to_array_of_array_of_object(const std::string &ObjectString) { + std::vector> Result; + if (ObjectString.empty()) return Result; try { Poco::JSON::Parser P1; @@ -447,8 +470,8 @@ namespace OpenWifi::RESTAPI_utils { for (auto const &i : *OutterArray) { Poco::JSON::Parser P2; auto InnerArray = P2.parse(i).template extract(); - std::vector InnerVector; - for(auto const &j: *InnerArray) { + std::vector InnerVector; + for (auto const &j : *InnerArray) { auto Object = j.template extract(); T Obj; Obj.from_json(Object); @@ -457,28 +480,27 @@ namespace OpenWifi::RESTAPI_utils { Result.push_back(InnerVector); } } catch (...) { - } return Result; } - template T to_object(const std::string & ObjectString) { - T Result; + template T to_object(const std::string &ObjectString) { + T Result; - if(ObjectString.empty()) + if (ObjectString.empty()) return Result; - Poco::JSON::Parser P; + Poco::JSON::Parser P; auto Object = P.parse(ObjectString).template extract(); Result.from_json(Object); return Result; } - template bool from_request(T & Obj, Poco::Net::HTTPServerRequest &Request) { + template bool from_request(T &Obj, Poco::Net::HTTPServerRequest &Request) { Poco::JSON::Parser IncomingParser; auto RawObject = IncomingParser.parse(Request.stream()).extract(); Obj.from_json(RawObject); return true; } -} +} // namespace OpenWifi::RESTAPI_utils diff --git a/src/framework/StorageClass.h b/src/framework/StorageClass.h index e9f3feb..2255de5 100644 --- a/src/framework/StorageClass.h +++ b/src/framework/StorageClass.h @@ -4,137 +4,133 @@ #pragma once +#include "Poco/Data/SQLite/Connector.h" #include "Poco/Data/Session.h" #include "Poco/Data/SessionPool.h" -#include "Poco/Data/SQLite/Connector.h" #include "Poco/JSON/Object.h" #ifndef SMALL_BUILD -#include "Poco/Data/PostgreSQL/Connector.h" #include "Poco/Data/MySQL/Connector.h" +#include "Poco/Data/PostgreSQL/Connector.h" #endif -#include "framework/SubSystemServer.h" #include "framework/MicroServiceFuncs.h" +#include "framework/SubSystemServer.h" namespace OpenWifi { - enum DBType { - sqlite, - pgsql, - mysql - }; + enum DBType { sqlite, pgsql, mysql }; - class StorageClass : public SubSystemServer { - public: - StorageClass() noexcept: - SubSystemServer("StorageClass", "STORAGE-SVR", "storage") - { - } + class StorageClass : public SubSystemServer { + public: + StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {} - int Start() override { - std::lock_guard Guard(Mutex_); + int Start() override { + std::lock_guard Guard(Mutex_); - Logger().notice("Starting."); - std::string DBType = MicroServiceConfigGetString("storage.type",""); + Logger().notice("Starting."); + std::string DBType = MicroServiceConfigGetString("storage.type", ""); - if (DBType == "sqlite") { - Setup_SQLite(); - } else if (DBType == "postgresql") { - Setup_PostgreSQL(); - } else if (DBType == "mysql") { - Setup_MySQL(); - } - return 0; - } + if (DBType == "sqlite") { + Setup_SQLite(); + } else if (DBType == "postgresql") { + Setup_PostgreSQL(); + } else if (DBType == "mysql") { + Setup_MySQL(); + } + return 0; + } - void Stop() override { - Pool_->shutdown(); - } + void Stop() override { Pool_->shutdown(); } - DBType Type() const { return dbType_; }; - private: - inline int Setup_SQLite(); - inline int Setup_MySQL(); - inline int Setup_PostgreSQL(); + DBType Type() const { return dbType_; }; - protected: - std::unique_ptr Pool_; - Poco::Data::SQLite::Connector SQLiteConn_; - Poco::Data::PostgreSQL::Connector PostgresConn_; - Poco::Data::MySQL::Connector MySQLConn_; - DBType dbType_ = sqlite; - }; + private: + inline int Setup_SQLite(); + inline int Setup_MySQL(); + inline int Setup_PostgreSQL(); -#ifdef SMALL_BUILD - int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; } - int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; } + protected: + std::unique_ptr Pool_; + Poco::Data::SQLite::Connector SQLiteConn_; + Poco::Data::PostgreSQL::Connector PostgresConn_; + Poco::Data::MySQL::Connector MySQLConn_; + DBType dbType_ = sqlite; + }; + +#ifdef SMALL_BUILD + int Service::Setup_MySQL() { + Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); + return 0; + } + int Service::Setup_PostgreSQL() { + Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); + return 0; + } #else - inline int StorageClass::Setup_SQLite() { - Logger().notice("SQLite StorageClass enabled."); - dbType_ = sqlite; - auto DBName = MicroServiceDataDirectory() + "/" + MicroServiceConfigGetString("storage.type.sqlite.db",""); - int NumSessions = (int) MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64); - int IdleTime = (int) MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60); + inline int StorageClass::Setup_SQLite() { + Logger().notice("SQLite StorageClass enabled."); + dbType_ = sqlite; + auto DBName = MicroServiceDataDirectory() + "/" + + MicroServiceConfigGetString("storage.type.sqlite.db", ""); + int NumSessions = (int)MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64); + int IdleTime = (int)MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60); - Poco::Data::SQLite::Connector::registerConnector(); -// Pool_ = std::make_unique(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8, -// (int)NumSessions, (int)IdleTime)); - Pool_ = std::make_unique(SQLiteConn_.name(), DBName, 8, - (int)NumSessions, (int)IdleTime); - return 0; - } + Poco::Data::SQLite::Connector::registerConnector(); + // Pool_ = std::make_unique(new + // Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8, + // (int)NumSessions, + // (int)IdleTime)); + Pool_ = std::make_unique(SQLiteConn_.name(), DBName, 8, + (int)NumSessions, (int)IdleTime); + return 0; + } - inline int StorageClass::Setup_MySQL() { - Logger().notice("MySQL StorageClass enabled."); - dbType_ = mysql; - int NumSessions = (int) MicroServiceConfigGetInt("storage.type.mysql.maxsessions", 64); - int IdleTime = (int) MicroServiceConfigGetInt("storage.type.mysql.idletime", 60); - auto Host = MicroServiceConfigGetString("storage.type.mysql.host",""); - auto Username = MicroServiceConfigGetString("storage.type.mysql.username",""); - auto Password = MicroServiceConfigGetString("storage.type.mysql.password",""); - auto Database = MicroServiceConfigGetString("storage.type.mysql.database",""); - auto Port = MicroServiceConfigGetString("storage.type.mysql.port",""); + inline int StorageClass::Setup_MySQL() { + Logger().notice("MySQL StorageClass enabled."); + dbType_ = mysql; + int NumSessions = (int)MicroServiceConfigGetInt("storage.type.mysql.maxsessions", 64); + int IdleTime = (int)MicroServiceConfigGetInt("storage.type.mysql.idletime", 60); + auto Host = MicroServiceConfigGetString("storage.type.mysql.host", ""); + auto Username = MicroServiceConfigGetString("storage.type.mysql.username", ""); + auto Password = MicroServiceConfigGetString("storage.type.mysql.password", ""); + auto Database = MicroServiceConfigGetString("storage.type.mysql.database", ""); + auto Port = MicroServiceConfigGetString("storage.type.mysql.port", ""); - std::string ConnectionStr = - "host=" + Host + - ";user=" + Username + - ";password=" + Password + - ";db=" + Database + - ";port=" + Port + - ";compress=true;auto-reconnect=true"; + std::string ConnectionStr = "host=" + Host + ";user=" + Username + ";password=" + Password + + ";db=" + Database + ";port=" + Port + + ";compress=true;auto-reconnect=true"; - Poco::Data::MySQL::Connector::registerConnector(); - Pool_ = std::make_unique(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime); + Poco::Data::MySQL::Connector::registerConnector(); + Pool_ = std::make_unique(MySQLConn_.name(), ConnectionStr, 8, + NumSessions, IdleTime); - return 0; - } + return 0; + } - inline int StorageClass::Setup_PostgreSQL() { - Logger().notice("PostgreSQL StorageClass enabled."); - dbType_ = pgsql; - int NumSessions = (int) MicroServiceConfigGetInt("storage.type.postgresql.maxsessions", 64); - int IdleTime = (int) MicroServiceConfigGetInt("storage.type.postgresql.idletime", 60); - auto Host = MicroServiceConfigGetString("storage.type.postgresql.host", ""); - auto Username = MicroServiceConfigGetString("storage.type.postgresql.username", ""); - auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", ""); - auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", ""); - auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", ""); - auto ConnectionTimeout = MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", ""); + inline int StorageClass::Setup_PostgreSQL() { + Logger().notice("PostgreSQL StorageClass enabled."); + dbType_ = pgsql; + int NumSessions = (int)MicroServiceConfigGetInt("storage.type.postgresql.maxsessions", 64); + int IdleTime = (int)MicroServiceConfigGetInt("storage.type.postgresql.idletime", 60); + auto Host = MicroServiceConfigGetString("storage.type.postgresql.host", ""); + auto Username = MicroServiceConfigGetString("storage.type.postgresql.username", ""); + auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", ""); + auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", ""); + auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", ""); + auto ConnectionTimeout = + MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", ""); - std::string ConnectionStr = - "host=" + Host + - " user=" + Username + - " password=" + Password + - " dbname=" + Database + - " port=" + Port + - " connect_timeout=" + ConnectionTimeout; + std::string ConnectionStr = "host=" + Host + " user=" + Username + " password=" + Password + + " dbname=" + Database + " port=" + Port + + " connect_timeout=" + ConnectionTimeout; - Poco::Data::PostgreSQL::Connector::registerConnector(); - Pool_ = std::make_unique(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime); + Poco::Data::PostgreSQL::Connector::registerConnector(); + Pool_ = std::make_unique(PostgresConn_.name(), ConnectionStr, 8, + NumSessions, IdleTime); - return 0; - } + return 0; + } #endif -} +} // namespace OpenWifi diff --git a/src/framework/SubSystemServer.cpp b/src/framework/SubSystemServer.cpp index 0222a83..f6df356 100644 --- a/src/framework/SubSystemServer.cpp +++ b/src/framework/SubSystemServer.cpp @@ -6,36 +6,29 @@ #include "framework/SubSystemServer.h" -#include "Poco/Net/SSLManager.h" -#include "Poco/DateTimeFormatter.h" #include "Poco/DateTimeFormat.h" +#include "Poco/DateTimeFormatter.h" +#include "Poco/Net/SSLManager.h" #include "framework/MicroServiceFuncs.h" namespace OpenWifi { - PropertiesFileServerEntry::PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file, - std::string Cert_file, std::string RootCa, std::string Issuer, - std::string ClientCas, std::string Cas, - std::string Key_file_password, std::string Name, - Poco::Net::Context::VerificationMode M, - int backlog) - : address_(std::move(Address)), - port_(port), - cert_file_(std::move(Cert_file)), - key_file_(std::move(Key_file)), - root_ca_(std::move(RootCa)), - key_file_password_(std::move(Key_file_password)), - issuer_cert_file_(std::move(Issuer)), - client_cas_(std::move(ClientCas)), - cas_(std::move(Cas)), - name_(std::move(Name)), - backlog_(backlog), - level_(M) { + PropertiesFileServerEntry::PropertiesFileServerEntry( + std::string Address, uint32_t port, std::string Key_file, std::string Cert_file, + std::string RootCa, std::string Issuer, std::string ClientCas, std::string Cas, + std::string Key_file_password, std::string Name, Poco::Net::Context::VerificationMode M, + int backlog) + : address_(std::move(Address)), port_(port), cert_file_(std::move(Cert_file)), + key_file_(std::move(Key_file)), root_ca_(std::move(RootCa)), + key_file_password_(std::move(Key_file_password)), issuer_cert_file_(std::move(Issuer)), + client_cas_(std::move(ClientCas)), cas_(std::move(Cas)), name_(std::move(Name)), + backlog_(backlog), level_(M){ - }; + }; - [[nodiscard]] Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const { + [[nodiscard]] Poco::Net::SecureServerSocket + PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const { Poco::Net::Context::Params P; P.verificationMode = level_; @@ -45,11 +38,13 @@ namespace OpenWifi { P.dhUse2048Bits = true; P.caLocation = cas_; - auto Context = Poco::AutoPtr(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P)); + auto Context = Poco::AutoPtr( + new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P)); - if(!key_file_password_.empty()) { - auto PassphraseHandler = Poco::SharedPtr( new MyPrivateKeyPassphraseHandler(key_file_password_,L)); - Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context); + if (!key_file_password_.empty()) { + auto PassphraseHandler = Poco::SharedPtr( + new MyPrivateKeyPassphraseHandler(key_file_password_, L)); + Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr, Context); } if (!cert_file_.empty() && !key_file_.empty()) { @@ -111,7 +106,8 @@ namespace OpenWifi { } } - [[nodiscard]] Poco::Net::ServerSocket PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const { + [[nodiscard]] Poco::Net::ServerSocket + PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const { Poco::Net::Context::Params P; if (address_ == "*") { @@ -127,20 +123,25 @@ namespace OpenWifi { } } - void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const { - L.information("============================================================================================="); + void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, + const Poco::Crypto::X509Certificate &C) const { + L.information("============================================================================" + "================="); L.information(fmt::format("> Issuer: {}", C.issuerName())); - L.information("---------------------------------------------------------------------------------------------"); + L.information("----------------------------------------------------------------------------" + "-----------------"); L.information(fmt::format("> Common Name: {}", C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME))); L.information(fmt::format("> Country: {}", C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY))); L.information(fmt::format("> Locality: {}", C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME))); - L.information(fmt::format("> State/Prov: {}", - C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE))); - L.information(fmt::format("> Org name: {}", - C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME))); + L.information( + fmt::format("> State/Prov: {}", + C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE))); + L.information( + fmt::format("> Org name: {}", + C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME))); L.information( fmt::format("> Org unit: {}", C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_UNIT_NAME))); @@ -149,9 +150,11 @@ namespace OpenWifi { C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS))); L.information(fmt::format("> Serial#: {}", C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER))); - L.information("---------------------------------------------------------------------------------------------"); + L.information("----------------------------------------------------------------------------" + "-----------------"); L.information(fmt::format("> Subject: {}", C.subjectName())); - L.information("---------------------------------------------------------------------------------------------"); + L.information("----------------------------------------------------------------------------" + "-----------------"); L.information(fmt::format("> Common Name: {}", C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME))); L.information(fmt::format("> Country: {}", @@ -172,52 +175,66 @@ namespace OpenWifi { C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS))); L.information(fmt::format("> Serial#: {}", C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER))); - L.information("---------------------------------------------------------------------------------------------"); + L.information("----------------------------------------------------------------------------" + "-----------------"); L.information(fmt::format("> Signature Algo: {}", C.signatureAlgorithm())); - auto From = Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT); + auto From = + Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT); L.information(fmt::format("> Valid from: {}", From)); auto Expires = Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT); L.information(fmt::format("> Expires on: {}", Expires)); L.information(fmt::format("> Version: {}", (int)C.version())); L.information(fmt::format("> Serial #: {}", C.serialNumber())); - L.information("============================================================================================="); + L.information("============================================================================" + "================="); } void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const { try { Poco::Crypto::X509Certificate C(cert_file_); - L.information("============================================================================================="); - L.information("============================================================================================="); + L.information("========================================================================" + "====================="); + L.information("========================================================================" + "====================="); L.information(fmt::format("Certificate Filename: {}", cert_file_)); LogCertInfo(L, C); - L.information("============================================================================================="); + L.information("========================================================================" + "====================="); if (!issuer_cert_file_.empty()) { Poco::Crypto::X509Certificate C1(issuer_cert_file_); - L.information("============================================================================================="); - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); + L.information("====================================================================" + "========================="); L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_)); LogCertInfo(L, C1); - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); } if (!client_cas_.empty()) { std::vector Certs = Poco::Net::X509Certificate::readPEM(client_cas_); - L.information("============================================================================================="); - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); + L.information("====================================================================" + "========================="); L.information(fmt::format("Client CAs Filename: {}", client_cas_)); - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); auto i = 1; for (const auto &C3 : Certs) { L.information(fmt::format(" Index: {}", i)); - L.information("============================================================================================="); + L.information("================================================================" + "============================="); LogCertInfo(L, C3); i++; } - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); } } catch (const Poco::Exception &E) { @@ -230,28 +247,31 @@ namespace OpenWifi { std::vector Certs = Poco::Net::X509Certificate::readPEM(root_ca_); - L.information("============================================================================================="); - L.information("============================================================================================="); + L.information("========================================================================" + "====================="); + L.information("========================================================================" + "====================="); L.information(fmt::format("CA Filename: {}", root_ca_)); - L.information("============================================================================================="); + L.information("========================================================================" + "====================="); auto i = 1; for (const auto &C : Certs) { L.information(fmt::format(" Index: {}", i)); - L.information("============================================================================================="); + L.information("====================================================================" + "========================="); LogCertInfo(L, C); i++; } - L.information("============================================================================================="); + L.information("========================================================================" + "====================="); } catch (const Poco::Exception &E) { L.log(E); } } SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix, - const std::string &SubSystemConfigPrefix): - Name_(Name), - LoggerPrefix_(LoggingPrefix), - SubSystemConfigPrefix_(SubSystemConfigPrefix) { + const std::string &SubSystemConfigPrefix) + : Name_(Name), LoggerPrefix_(LoggingPrefix), SubSystemConfigPrefix_(SubSystemConfigPrefix) { } void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) { @@ -259,10 +279,13 @@ namespace OpenWifi { bool good = true; auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, ""); - if(NewLevel.empty()) - Logger_ = std::make_unique(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())); + if (NewLevel.empty()) + Logger_ = std::make_unique(Poco::Logger::create( + LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())); else - Logger_ = std::make_unique(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel))); + Logger_ = std::make_unique( + Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), + Poco::Logger::parseLevel(NewLevel))); ConfigServersList_.clear(); while (good) { @@ -297,24 +320,18 @@ namespace OpenWifi { } else if (L == "once") M = Poco::Net::Context::VERIFY_ONCE; - PropertiesFileServerEntry entry(MicroServiceConfigGetString(address, ""), - MicroServiceConfigGetInt(port, 0), - MicroServiceConfigPath(key, ""), - MicroServiceConfigPath(cert, ""), - MicroServiceConfigPath(rootca, ""), - MicroServiceConfigPath(issuer, ""), - MicroServiceConfigPath(clientcas, ""), - MicroServiceConfigPath(cas, ""), - MicroServiceConfigGetString(key_password, ""), - MicroServiceConfigGetString(name, ""), M, - (int)MicroServiceConfigGetInt(backlog, 64)); + PropertiesFileServerEntry entry( + MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0), + MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""), + MicroServiceConfigPath(rootca, ""), MicroServiceConfigPath(issuer, ""), + MicroServiceConfigPath(clientcas, ""), MicroServiceConfigPath(cas, ""), + MicroServiceConfigGetString(key_password, ""), + MicroServiceConfigGetString(name, ""), M, + (int)MicroServiceConfigGetInt(backlog, 64)); ConfigServersList_.push_back(entry); i++; } } } - - - } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/SubSystemServer.h b/src/framework/SubSystemServer.h index 268f899..303fbf4 100644 --- a/src/framework/SubSystemServer.h +++ b/src/framework/SubSystemServer.h @@ -4,32 +4,30 @@ #pragma once -#include #include +#include -#include "Poco/Util/Application.h" #include "Poco/Net/Context.h" -#include "Poco/Net/SecureServerSocket.h" #include "Poco/Net/PrivateKeyPassphraseHandler.h" +#include "Poco/Net/SecureServerSocket.h" +#include "Poco/Util/Application.h" namespace OpenWifi { class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler { public: - explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger & Logger): - PrivateKeyPassphraseHandler(true), - Password_(Password), - Logger_(Logger) { - } + explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger &Logger) + : PrivateKeyPassphraseHandler(true), Password_(Password), Logger_(Logger) {} - void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) { - poco_information(Logger_,"Returning key passphrase."); + void onPrivateKeyRequested([[maybe_unused]] const void *pSender, std::string &privateKey) { + poco_information(Logger_, "Returning key passphrase."); privateKey = Password_; }; - inline Poco::Logger & Logger() { return Logger_; } + inline Poco::Logger &Logger() { return Logger_; } + private: std::string Password_; - Poco::Logger & Logger_; + Poco::Logger &Logger_; }; class PropertiesFileServerEntry { @@ -76,24 +74,24 @@ namespace OpenWifi { class SubSystemServer : public Poco::Util::Application::Subsystem { public: - SubSystemServer(const std::string & Name, const std::string &LoggingPrefix, - const std::string & SubSystemConfigPrefix); + SubSystemServer(const std::string &Name, const std::string &LoggingPrefix, + const std::string &SubSystemConfigPrefix); void initialize(Poco::Util::Application &self) override; - inline void uninitialize() override { - } + inline void uninitialize() override {} inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { - poco_information(Logger_->L_,"Reloading of this subsystem is not supported."); + poco_information(Logger_->L_, "Reloading of this subsystem is not supported."); } - inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override { - } - inline const std::string & Name() const { return Name_; }; - inline const char * name() const override { return Name_.c_str(); } + inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {} + inline const std::string &Name() const { return Name_; }; + inline const char *name() const override { return Name_.c_str(); } - inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; }; + inline const PropertiesFileServerEntry &Host(uint64_t index) { + return ConfigServersList_[index]; + }; inline uint64_t HostSize() const { return ConfigServersList_.size(); } - inline Poco::Logger & Logger() const { return Logger_->L_; } - inline void SetLoggingLevel(const std::string & levelName) { + inline Poco::Logger &Logger() const { return Logger_->L_; } + inline void SetLoggingLevel(const std::string &levelName) { Logger_->L_.setLevel(Poco::Logger::parseLevel(levelName)); } inline int GetLoggingLevel() { return Logger_->L_.getLevel(); } @@ -102,23 +100,21 @@ namespace OpenWifi { virtual void Stop() = 0; struct LoggerWrapper { - Poco::Logger & L_; - LoggerWrapper(Poco::Logger &L) : - L_(L) { - } + Poco::Logger &L_; + LoggerWrapper(Poco::Logger &L) : L_(L) {} }; protected: - std::recursive_mutex Mutex_; + std::recursive_mutex Mutex_; std::vector ConfigServersList_; private: - std::unique_ptr Logger_; - std::string Name_; - std::string LoggerPrefix_; - std::string SubSystemConfigPrefix_; + std::unique_ptr Logger_; + std::string Name_; + std::string LoggerPrefix_; + std::string SubSystemConfigPrefix_; }; - typedef std::vector SubSystemVec; + typedef std::vector SubSystemVec; } // namespace OpenWifi diff --git a/src/framework/UI_WebSocketClientNotifications.cpp b/src/framework/UI_WebSocketClientNotifications.cpp index c8fcfda..7ad187b 100644 --- a/src/framework/UI_WebSocketClientNotifications.cpp +++ b/src/framework/UI_WebSocketClientNotifications.cpp @@ -5,7 +5,4 @@ #include "framework/UI_WebSocketClientNotifications.h" #include "framework/UI_WebSocketClientServer.h" -namespace OpenWifi { - -} - +namespace OpenWifi {} diff --git a/src/framework/UI_WebSocketClientNotifications.h b/src/framework/UI_WebSocketClientNotifications.h index d534a5c..fc10863 100644 --- a/src/framework/UI_WebSocketClientNotifications.h +++ b/src/framework/UI_WebSocketClientNotifications.h @@ -9,37 +9,35 @@ namespace OpenWifi { - template + template - struct WebSocketNotification { - inline static uint64_t xid = 1; - uint64_t notification_id = ++xid; - std::uint64_t type_id=0; - ContentStruct content; + struct WebSocketNotification { + inline static uint64_t xid = 1; + uint64_t notification_id = ++xid; + std::uint64_t type_id = 0; + ContentStruct content; - void to_json(Poco::JSON::Object &Obj) const; + void to_json(Poco::JSON::Object &Obj) const; - bool from_json(const Poco::JSON::Object::Ptr &Obj); - }; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; - template - void WebSocketNotification::to_json(Poco::JSON::Object &Obj) const { - RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id); + template + void WebSocketNotification::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id); RESTAPI_utils::field_to_json(Obj, "type_id", type_id); - RESTAPI_utils::field_to_json(Obj, "content", content); - } + RESTAPI_utils::field_to_json(Obj, "content", content); + } - template - bool WebSocketNotification::from_json(const Poco::JSON::Object::Ptr &Obj) { - try { - RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id); + template + bool WebSocketNotification::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id); RESTAPI_utils::field_from_json(Obj, "type_id", type_id); RESTAPI_utils::field_from_json(Obj, "content", content); - return true; - } catch (...) { - - } - return false; - } -} - + return true; + } catch (...) { + } + return false; + } +} // namespace OpenWifi diff --git a/src/framework/UI_WebSocketClientServer.cpp b/src/framework/UI_WebSocketClientServer.cpp index ee4a53d..37c426f 100644 --- a/src/framework/UI_WebSocketClientServer.cpp +++ b/src/framework/UI_WebSocketClientServer.cpp @@ -4,14 +4,14 @@ #include -#include "Poco/NObserver.h" #include "Poco/JSON/JSONException.h" #include "Poco/JSON/Parser.h" #include "Poco/Logger.h" +#include "Poco/NObserver.h" -#include "framework/UI_WebSocketClientServer.h" #include "framework/AuthClient.h" #include "framework/MicroServiceFuncs.h" +#include "framework/UI_WebSocketClientServer.h" #include "fmt/format.h" @@ -19,80 +19,82 @@ #include "AuthService.h" #endif -#define DBG { std::cout << __LINE__ << std::endl; } +#define DBG \ + { std::cout << __LINE__ << std::endl; } namespace OpenWifi { - void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) { + void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket &WS, const std::string &Id, + const std::string &UserName, std::uint64_t TID) { - std::lock_guard G(LocalMutex_); - auto Client = std::make_unique(WS,Id, UserName); - auto ClientSocket = Client->WS_->impl()->sockfd(); - TID_ = TID; - Client->WS_->setNoDelay(true); - Client->WS_->setKeepAlive(true); - Client->WS_->setBlocking(false); - Reactor_.addEventHandler(*Client->WS_, - Poco::NObserver( - *this, &UI_WebSocketClientServer::OnSocketReadable)); - Reactor_.addEventHandler(*Client->WS_, - Poco::NObserver( - *this, &UI_WebSocketClientServer::OnSocketShutdown)); - Reactor_.addEventHandler(*Client->WS_, - Poco::NObserver( - *this, &UI_WebSocketClientServer::OnSocketError)); - Client->SocketRegistered_ = true; - Clients_[ClientSocket] = std::move(Client); + std::lock_guard G(LocalMutex_); + auto Client = std::make_unique(WS, Id, UserName); + auto ClientSocket = Client->WS_->impl()->sockfd(); + TID_ = TID; + Client->WS_->setNoDelay(true); + Client->WS_->setKeepAlive(true); + Client->WS_->setBlocking(false); + Reactor_.addEventHandler( + *Client->WS_, + Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketReadable)); + Reactor_.addEventHandler( + *Client->WS_, + Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketShutdown)); + Reactor_.addEventHandler( + *Client->WS_, Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketError)); + Client->SocketRegistered_ = true; + Clients_[ClientSocket] = std::move(Client); UsersConnected_ = Clients_.size(); - } - - void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) { - Processor_ = F; } - UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept: - SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") - { - } + void UI_WebSocketClientServer::SetProcessor(UI_WebSocketClientProcessor *F) { Processor_ = F; } + + UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept + : SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") {} void UI_WebSocketClientServer::run() { Running_ = true; - while(Running_) { + while (Running_) { Poco::Thread::trySleep(2000); - if(!Running_) + if (!Running_) break; - std::lock_guard G(LocalMutex_); - for(const auto i:ToBeRemoved_) { + std::lock_guard G(LocalMutex_); + for (const auto i : ToBeRemoved_) { // std::cout << "Erasing old WS UI connection..." << std::endl; Clients_.erase(i); } - ToBeRemoved_.clear(); + ToBeRemoved_.clear(); UsersConnected_ = Clients_.size(); } - } - void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) { - if(Client->second->SocketRegistered_) { - Client->second->SocketRegistered_ = false; - Reactor_.removeEventHandler(*Client->second->WS_, - Poco::NObserver(*this,&UI_WebSocketClientServer::OnSocketReadable)); - Reactor_.removeEventHandler(*Client->second->WS_, - Poco::NObserver(*this,&UI_WebSocketClientServer::OnSocketShutdown)); - Reactor_.removeEventHandler(*Client->second->WS_, - Poco::NObserver(*this,&UI_WebSocketClientServer::OnSocketError)); - } + void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) { + if (Client->second->SocketRegistered_) { + Client->second->SocketRegistered_ = false; + Reactor_.removeEventHandler( + *Client->second->WS_, + Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketReadable)); + Reactor_.removeEventHandler( + *Client->second->WS_, + Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketShutdown)); + Reactor_.removeEventHandler( + *Client->second->WS_, + Poco::NObserver( + *this, &UI_WebSocketClientServer::OnSocketError)); + } ToBeRemoved_.push_back(Client); - } + } int UI_WebSocketClientServer::Start() { - poco_information(Logger(),"Starting..."); - GoogleApiKey_ = MicroServiceConfigGetString("google.apikey",""); + poco_information(Logger(), "Starting..."); + GoogleApiKey_ = MicroServiceConfigGetString("google.apikey", ""); GeoCodeEnabled_ = !GoogleApiKey_.empty(); ReactorThread_.start(Reactor_); ReactorThread_.setName("ws:ui-reactor"); @@ -102,29 +104,31 @@ namespace OpenWifi { }; void UI_WebSocketClientServer::Stop() { - if(Running_) { - poco_information(Logger(),"Stopping..."); - Clients_.clear(); + if (Running_) { + poco_information(Logger(), "Stopping..."); + Clients_.clear(); Reactor_.stop(); ReactorThread_.join(); Running_ = false; CleanerThread_.wakeUp(); CleanerThread_.join(); - poco_information(Logger(),"Stopped..."); + poco_information(Logger(), "Stopped..."); } }; - bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) { - return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_); + bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, + const OpenWifi::UI_WebSocketClientInfo &Client) { + return std::find(Client.Filter_.begin(), Client.Filter_.end(), id) != end(Client.Filter_); } - bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) { + bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, + const std::string &Payload) { std::lock_guard G(LocalMutex_); - for(const auto &Client:Clients_) { - if(Client.second->UserName_ == UserName) { + for (const auto &Client : Clients_) { + if (Client.second->UserName_ == UserName) { try { - if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) { + if (!IsFiltered(id, *Client.second) && Client.second->Authenticated_) { return Client.second->WS_->sendFrame( Payload.c_str(), (int)Payload.size()) == (int)Payload.size(); } else { @@ -141,31 +145,32 @@ namespace OpenWifi { void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) { std::lock_guard G(LocalMutex_); - for(const auto &Client:Clients_) { + for (const auto &Client : Clients_) { try { - if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) - Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()); + if (!IsFiltered(id, *Client.second) && Client.second->Authenticated_) + Client.second->WS_->sendFrame(Payload.c_str(), (int)Payload.size()); } catch (...) { - } } } - UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient( [[maybe_unused]] std::lock_guard &G, int ClientSocket) { - return Clients_.find(ClientSocket); - } + UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient( + [[maybe_unused]] std::lock_guard &G, int ClientSocket) { + return Clients_.find(ClientSocket); + } void UI_WebSocketClientServer::SortNotifications() { struct { - bool operator()(const NotificationEntry &A, const NotificationEntry & B) const { - return A.id < B.id; }; + bool operator()(const NotificationEntry &A, const NotificationEntry &B) const { + return A.id < B.id; + }; } CompareNotifications; std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications); NotificationTypesJSON_.clear(); - Poco::JSON::Array AllNotifications; - for(const auto ¬ification:NotificationTypes_) { - Poco::JSON::Object Notification; + Poco::JSON::Array AllNotifications; + for (const auto ¬ification : NotificationTypes_) { + Poco::JSON::Object Notification; Notification.set("id", notification.id); Notification.set("helper", notification.helper); AllNotifications.add(Notification); @@ -173,52 +178,60 @@ namespace OpenWifi { NotificationTypesJSON_.set("notificationTypes", AllNotifications); } - void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) { - std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_)); + void UI_WebSocketClientServer::RegisterNotifications( + const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) { + std::copy(Notifications.begin(), Notifications.end(), + std::back_inserter(NotificationTypes_)); SortNotifications(); } - void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr &pNf) { - std::lock_guard G(LocalMutex_); - auto Client = Clients_.find(pNf->socket().impl()->sockfd()); - if(Client==end(Clients_)) - return; - EndConnection(Client); + void UI_WebSocketClientServer::OnSocketError( + [[maybe_unused]] const Poco::AutoPtr &pNf) { + std::lock_guard G(LocalMutex_); + auto Client = Clients_.find(pNf->socket().impl()->sockfd()); + if (Client == end(Clients_)) + return; + EndConnection(Client); } - void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr &pNf) { + void UI_WebSocketClientServer::OnSocketReadable( + [[maybe_unused]] const Poco::AutoPtr &pNf) { - UI_WebSocketClientServer::ClientList::iterator Client; - std::lock_guard G(LocalMutex_); + UI_WebSocketClientServer::ClientList::iterator Client; + std::lock_guard G(LocalMutex_); try { - Client = Clients_.find(pNf->socket().impl()->sockfd()); - if( Client == end(Clients_)) - return; + Client = Clients_.find(pNf->socket().impl()->sockfd()); + if (Client == end(Clients_)) + return; Poco::Buffer IncomingFrame(0); - int flags; - int n; + int flags; + int n; n = Client->second->WS_->receiveFrame(IncomingFrame, flags); auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; if (n == 0) { - poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_)); + poco_debug(Logger(), + fmt::format("CLOSE({}): {} UI Client is closing WS connection.", + Client->second->Id_, Client->second->UserName_)); return EndConnection(Client); } switch (Op) { case Poco::Net::WebSocket::FRAME_OP_PING: { - Client->second->WS_->sendFrame("", 0, - (int)Poco::Net::WebSocket::FRAME_OP_PONG | - (int)Poco::Net::WebSocket::FRAME_FLAG_FIN); + Client->second->WS_->sendFrame("", 0, + (int)Poco::Net::WebSocket::FRAME_OP_PONG | + (int)Poco::Net::WebSocket::FRAME_FLAG_FIN); } break; case Poco::Net::WebSocket::FRAME_OP_PONG: { } break; case Poco::Net::WebSocket::FRAME_OP_CLOSE: { - poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_)); - return EndConnection(Client); + poco_debug(Logger(), + fmt::format("CLOSE({}): {} UI Client is closing WS connection.", + Client->second->Id_, Client->second->UserName_)); + return EndConnection(Client); } break; case Poco::Net::WebSocket::FRAME_OP_TEXT: { constexpr const char *DropMessagesCommand = "drop-notifications"; @@ -228,80 +241,84 @@ namespace OpenWifi { auto Tokens = Utils::Split(Frame, ':'); bool Expired = false; #if not defined(TIP_SECURITY_SERVICE) - bool Contacted = false; + bool Contacted = false; #endif if (Tokens.size() == 2 && #if defined(TIP_SECURITY_SERVICE) - AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) { + AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, + Expired)) { #else - AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) { + AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, + Expired, Contacted)) { #endif - Client->second->Authenticated_ = true; - Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; - poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_)); + Client->second->Authenticated_ = true; + Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; + poco_debug(Logger(), + fmt::format("START({}): {} UI Client is starting WS connection.", + Client->second->Id_, Client->second->UserName_)); auto WelcomeMessage = NotificationTypesJSON_; WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!"); std::ostringstream OS; WelcomeMessage.stringify(OS); - Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size()); - Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; + Client->second->WS_->sendFrame(OS.str().c_str(), (int)OS.str().size()); + Client->second->UserName_ = Client->second->UserInfo_.userinfo.email; } else { - Poco::JSON::Object WelcomeMessage; + Poco::JSON::Object WelcomeMessage; WelcomeMessage.set("error", "Invalid token. Closing connection."); std::ostringstream OS; WelcomeMessage.stringify(OS); - Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size()); - return EndConnection(Client); + Client->second->WS_->sendFrame(OS.str().c_str(), (int)OS.str().size()); + return EndConnection(Client); } } else { - Poco::JSON::Parser P; - auto Obj = - P.parse(IncomingFrame.begin()).extract(); + Poco::JSON::Parser P; + auto Obj = P.parse(IncomingFrame.begin()).extract(); - if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) { + if (Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) { auto Filters = Obj->getArray(DropMessagesCommand); Client->second->Filter_.clear(); - for(const auto &Filter:*Filters) { - Client->second->Filter_.emplace_back( (std::uint64_t) Filter); + for (const auto &Filter : *Filters) { + Client->second->Filter_.emplace_back((std::uint64_t)Filter); } - std::sort(begin(Client->second->Filter_),end(Client->second->Filter_)); + std::sort(begin(Client->second->Filter_), end(Client->second->Filter_)); return; } - std::string Answer; - bool CloseConnection=false; - if (Processor_ != nullptr) { - Processor_->Processor(Obj, Answer, CloseConnection,Client->second->UserInfo_.userinfo); - } - if (!Answer.empty()) - Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size()); - else { - Client->second->WS_->sendFrame("{}", 2); - } + std::string Answer; + bool CloseConnection = false; + if (Processor_ != nullptr) { + Processor_->Processor(Obj, Answer, CloseConnection, + Client->second->UserInfo_.userinfo); + } + if (!Answer.empty()) + Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size()); + else { + Client->second->WS_->sendFrame("{}", 2); + } - if(CloseConnection) { - return EndConnection(Client); - } + if (CloseConnection) { + return EndConnection(Client); + } } } break; default: { } } } catch (...) { - return EndConnection(Client); + return EndConnection(Client); } } - void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr &pNf) { - try { - std::lock_guard G(LocalMutex_); + void UI_WebSocketClientServer::OnSocketShutdown( + [[maybe_unused]] const Poco::AutoPtr &pNf) { + try { + std::lock_guard G(LocalMutex_); auto Client = Clients_.find(pNf->socket().impl()->sockfd()); - if (Client == end(Clients_)) - return; - EndConnection(Client); - } catch (...) { - - } + if (Client == end(Clients_)) + return; + EndConnection(Client); + } catch (...) { + } } } // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/UI_WebSocketClientServer.h b/src/framework/UI_WebSocketClientServer.h index e008faf..a727b4c 100644 --- a/src/framework/UI_WebSocketClientServer.h +++ b/src/framework/UI_WebSocketClientServer.h @@ -7,11 +7,11 @@ #include #include -#include "Poco/Runnable.h" -#include "Poco/Net/SocketReactor.h" -#include "Poco/Net/WebSocket.h" #include "Poco/JSON/Object.h" #include "Poco/Net/SocketNotification.h" +#include "Poco/Net/SocketReactor.h" +#include "Poco/Net/WebSocket.h" +#include "Poco/Runnable.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" #include "framework/SubSystemServer.h" @@ -21,25 +21,28 @@ namespace OpenWifi { class UI_WebSocketClientProcessor { public: - virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done , const SecurityObjects::UserInfo & UserInfo) = 0; + virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, + const SecurityObjects::UserInfo &UserInfo) = 0; + private: }; - struct UI_WebSocketClientInfo { - std::unique_ptr WS_ = nullptr; - std::string Id_; - std::string UserName_; - bool Authenticated_ = false; - bool SocketRegistered_=false; - std::vector Filter_; - SecurityObjects::UserInfoAndPolicy UserInfo_; + struct UI_WebSocketClientInfo { + std::unique_ptr WS_ = nullptr; + std::string Id_; + std::string UserName_; + bool Authenticated_ = false; + bool SocketRegistered_ = false; + std::vector Filter_; + SecurityObjects::UserInfoAndPolicy UserInfo_; - UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) { - WS_ = std::make_unique(WS); - Id_ = Id; - UserName_ = username; - } - }; + UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, + const std::string &username) { + WS_ = std::make_unique(WS); + Id_ = Id; + UserName_ = username; + } + }; class UI_WebSocketClientServer : public SubSystemServer, Poco::Runnable { @@ -49,26 +52,26 @@ namespace OpenWifi { return instance_; } - bool IsAnyoneConnected() { - return UsersConnected_; - } + bool IsAnyoneConnected() { return UsersConnected_; } int Start() override; void Stop() override; void run() override; - Poco::Net::SocketReactor & Reactor() { return Reactor_; } - void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID); + Poco::Net::SocketReactor &Reactor() { return Reactor_; } + void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, + std::uint64_t TID); void SetProcessor(UI_WebSocketClientProcessor *F); [[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; } [[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; } - template bool - SendUserNotification(const std::string &userName, const WebSocketNotification &Notification) { + template + bool SendUserNotification(const std::string &userName, + const WebSocketNotification &Notification) { - Poco::JSON::Object Payload; + Poco::JSON::Object Payload; Notification.to_json(Payload); - Poco::JSON::Object Msg; - Msg.set("notification",Payload); + Poco::JSON::Object Msg; + Msg.set("notification", Payload); std::ostringstream OO; Msg.stringify(OO); @@ -76,58 +79,59 @@ namespace OpenWifi { } template void SendNotification(const WebSocketNotification &Notification) { - Poco::JSON::Object Payload; + Poco::JSON::Object Payload; Notification.to_json(Payload); - Poco::JSON::Object Msg; - Msg.set("notification",Payload); + Poco::JSON::Object Msg; + Msg.set("notification", Payload); std::ostringstream OO; Msg.stringify(OO); SendToAll(Notification.type_id, OO.str()); } - [[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload); + [[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, + const std::string &Payload); void SendToAll(std::uint64_t id, const std::string &Payload); struct NotificationEntry { - std::uint64_t id=0; - std::string helper; + std::uint64_t id = 0; + std::string helper; }; - using ClientList = std::map>; + using ClientList = std::map>; using NotificationTypeIdVec = std::vector; - void RegisterNotifications(const NotificationTypeIdVec & Notifications); + void RegisterNotifications(const NotificationTypeIdVec &Notifications); bool IsFiltered(std::uint64_t id, const UI_WebSocketClientInfo &Client); - private: - volatile bool Running_ = false; - std::atomic_uint64_t UsersConnected_=0; - Poco::Net::SocketReactor Reactor_; - Poco::Thread ReactorThread_; - Poco::Thread CleanerThread_; - std::recursive_mutex LocalMutex_; - bool GeoCodeEnabled_ = false; - std::string GoogleApiKey_; - ClientList Clients_; - UI_WebSocketClientProcessor *Processor_ = nullptr; - NotificationTypeIdVec NotificationTypes_; - Poco::JSON::Object NotificationTypesJSON_; - std::vector ToBeRemoved_; - std::uint64_t TID_=0; + private: + volatile bool Running_ = false; + std::atomic_uint64_t UsersConnected_ = 0; + Poco::Net::SocketReactor Reactor_; + Poco::Thread ReactorThread_; + Poco::Thread CleanerThread_; + std::recursive_mutex LocalMutex_; + bool GeoCodeEnabled_ = false; + std::string GoogleApiKey_; + ClientList Clients_; + UI_WebSocketClientProcessor *Processor_ = nullptr; + NotificationTypeIdVec NotificationTypes_; + Poco::JSON::Object NotificationTypesJSON_; + std::vector ToBeRemoved_; + std::uint64_t TID_ = 0; UI_WebSocketClientServer() noexcept; - void EndConnection(ClientList::iterator Client); + void EndConnection(ClientList::iterator Client); - void OnSocketReadable(const Poco::AutoPtr &pNf); - void OnSocketShutdown(const Poco::AutoPtr &pNf); - void OnSocketError(const Poco::AutoPtr &pNf); + void OnSocketReadable(const Poco::AutoPtr &pNf); + void OnSocketShutdown(const Poco::AutoPtr &pNf); + void OnSocketError(const Poco::AutoPtr &pNf); - ClientList::iterator FindWSClient( std::lock_guard &G, int ClientSocket); + ClientList::iterator FindWSClient(std::lock_guard &G, + int ClientSocket); void SortNotifications(); }; inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); } -}; - +}; // namespace OpenWifi diff --git a/src/framework/WebSocketLogger.h b/src/framework/WebSocketLogger.h index 7c0553e..7b4174a 100644 --- a/src/framework/WebSocketLogger.h +++ b/src/framework/WebSocketLogger.h @@ -5,61 +5,64 @@ #pragma once #include "framework/SubSystemServer.h" -#include "framework/UI_WebSocketClientServer.h" #include "framework/UI_WebSocketClientNotifications.h" - +#include "framework/UI_WebSocketClientServer.h" namespace OpenWifi { class WebSocketLogger : public Poco::Channel { public: + WebSocketLogger() {} - WebSocketLogger() { - } + ~WebSocketLogger() {} - ~WebSocketLogger() { - } - - std::string getProperty( [[maybe_unused]] const std::string &p ) const { + std::string getProperty([[maybe_unused]] const std::string &p) const { std::cout << "WS getProperty" << std::endl; return ""; } - void close() final { - } + void close() final {} - void open() final { - } + void open() final {} static std::string to_string(Poco::Message::Priority p) { - switch(p) { - case Poco::Message::PRIO_INFORMATION: return "information"; - case Poco::Message::PRIO_CRITICAL: return "critical"; - case Poco::Message::PRIO_DEBUG: return "debug"; - case Poco::Message::PRIO_ERROR: return "error"; - case Poco::Message::PRIO_FATAL: return "fatal"; - case Poco::Message::PRIO_NOTICE: return "notice"; - case Poco::Message::PRIO_TRACE: return "trace"; - case Poco::Message::PRIO_WARNING: return "warning"; - default: return "none"; + switch (p) { + case Poco::Message::PRIO_INFORMATION: + return "information"; + case Poco::Message::PRIO_CRITICAL: + return "critical"; + case Poco::Message::PRIO_DEBUG: + return "debug"; + case Poco::Message::PRIO_ERROR: + return "error"; + case Poco::Message::PRIO_FATAL: + return "fatal"; + case Poco::Message::PRIO_NOTICE: + return "notice"; + case Poco::Message::PRIO_TRACE: + return "trace"; + case Poco::Message::PRIO_WARNING: + return "warning"; + default: + return "none"; } } struct NotificationLogMessage { - std::string msg; - std::string level; - std::uint64_t timestamp; - std::string source; - std::string thread_name; - std::uint64_t thread_id=0; + std::string msg; + std::string level; + std::uint64_t timestamp; + std::string source; + std::string thread_name; + std::uint64_t thread_id = 0; inline void to_json(Poco::JSON::Object &Obj) const { - RESTAPI_utils::field_to_json(Obj,"msg", msg); - RESTAPI_utils::field_to_json(Obj,"level", level); - RESTAPI_utils::field_to_json(Obj,"timestamp", timestamp); - RESTAPI_utils::field_to_json(Obj,"source", source); - RESTAPI_utils::field_to_json(Obj,"thread_name", thread_name); - RESTAPI_utils::field_to_json(Obj,"thread_id", thread_id); + RESTAPI_utils::field_to_json(Obj, "msg", msg); + RESTAPI_utils::field_to_json(Obj, "level", level); + RESTAPI_utils::field_to_json(Obj, "timestamp", timestamp); + RESTAPI_utils::field_to_json(Obj, "source", source); + RESTAPI_utils::field_to_json(Obj, "thread_name", thread_name); + RESTAPI_utils::field_to_json(Obj, "thread_id", thread_id); } inline bool from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -71,18 +74,18 @@ namespace OpenWifi { RESTAPI_utils::field_from_json(Obj, "thread_name", thread_name); RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id); return true; - } catch(...) { - + } catch (...) { } return false; } }; - typedef WebSocketNotification WebSocketClientNotificationLogMessage_t; + typedef WebSocketNotification + WebSocketClientNotificationLogMessage_t; void log(const Poco::Message &m) final { - if(UI_WebSocketClientServer()->IsAnyoneConnected()) { - WebSocketClientNotificationLogMessage_t Msg; + if (UI_WebSocketClientServer()->IsAnyoneConnected()) { + WebSocketClientNotificationLogMessage_t Msg; Msg.content.msg = m.getText(); Msg.content.level = WebSocketLogger::to_string(m.getPriority()); Msg.content.timestamp = m.getTime().epochTime(); @@ -94,14 +97,15 @@ namespace OpenWifi { } } - void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) { + void setProperty([[maybe_unused]] const std::string &name, + [[maybe_unused]] const std::string &value) { std::cout << "WS setProperty" << std::endl; } private: - std::recursive_mutex Mutex_; + std::recursive_mutex Mutex_; }; -// inline auto WebSocketLogger() { return WebSocketLogger::instance(); } + // inline auto WebSocketLogger() { return WebSocketLogger::instance(); } -} \ No newline at end of file +} // namespace OpenWifi \ No newline at end of file diff --git a/src/framework/orm.h b/src/framework/orm.h index 23eb591..9e83540 100644 --- a/src/framework/orm.h +++ b/src/framework/orm.h @@ -8,1015 +8,1030 @@ #pragma once -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include -#include "Poco/Tuple.h" -#include "Poco/Data/SessionPool.h" -#include "Poco/Data/Statement.h" #include "Poco/Data/RecordSet.h" #include "Poco/Data/SQLite/Connector.h" +#include "Poco/Data/SessionPool.h" +#include "Poco/Data/Statement.h" #include "Poco/Logger.h" #include "Poco/StringTokenizer.h" +#include "Poco/Tuple.h" #include "StorageClass.h" #include "fmt/format.h" namespace ORM { - enum FieldType { - FT_INT, - FT_BIGINT, - FT_TEXT, - FT_VARCHAR, - FT_BLOB, - FT_BOOLEAN, - FT_REAL - }; - - enum Indextype { - ASC, - DESC - }; - - struct Field { - std::string Name; - FieldType Type; - int Size=0; - bool Index=false; - - - Field(std::string N, FieldType T, int S=0, bool Index=false) : - Name(std::move(N)), - Type(T), - Size(S), - Index(Index) {} - - explicit Field(std::string N) : - Name(std::move(N)) - { - Type = FT_TEXT; - } - - Field(std::string N, int S) : - Name(std::move(N)), Size(S) - { - if(Size>0 && Size<255) - Type = FT_VARCHAR; - else - Type = FT_TEXT; - } - - Field(std::string N, int S, bool I): - Name(std::move(N)), Size(S), Index(I) - { - if(Size>0 && Size<255) - Type = FT_VARCHAR; - else - Type = FT_TEXT; - } - }; - typedef std::vector FieldVec; - - struct IndexEntry { - std::string FieldName; - Indextype Type; - }; - typedef std::vector IndexEntryVec; - - struct Index { - std::string Name; - IndexEntryVec Entries; - }; - typedef std::vector IndexVec; - - inline std::string FieldTypeToChar(OpenWifi::DBType Type, FieldType T, int Size=0) { - switch(T) { - case FT_INT: return "INT"; - case FT_BIGINT: return "BIGINT"; - case FT_TEXT: return "TEXT"; - case FT_BOOLEAN: return "BOOLEAN"; - case FT_VARCHAR: - if(Size) - return std::string("VARCHAR(") + std::to_string(Size) + std::string(")"); - else - return "TEXT"; - case FT_BLOB: - if(Type==OpenWifi::DBType::mysql) - return "LONGBLOB"; - else if(Type==OpenWifi::DBType::pgsql) - return "BYTEA"; - else - return "BLOB"; - case FT_REAL: - return "REAL"; - default: - assert(false); - - } - assert(false); - return ""; - } - - inline std::string Escape(const std::string &S) { - std::string R; - - for(const auto &i:S) { - if (i == '\'') - R += "''"; - else - R += i; - } - return R; - } - - inline std::string WHERE_AND_(std::string Result) { - return Result; - } - - template std::string WHERE_AND_(std::string Result, const char *fieldName, const T & Value, Args... args) { - if constexpr(std::is_same_v) - { - if(!Value.empty()) { - if(!Result.empty()) - Result += " and "; - Result += fieldName; - Result += '='; - Result += "'"; - Result += Escape(Value); - Result += "'"; - } - return WHERE_AND_(Result,args...); - } else if constexpr(std::is_same_v) { - if(*Value!=0) { - if(!Result.empty()) - Result += " and "; - Result += fieldName; - Result += '='; - Result += "'"; - Result += Escape(Value); - Result += "'"; - } - return WHERE_AND_(Result,args...); - } else if constexpr (std::is_same_v) { - if(!Result.empty()) - Result += " and "; - Result += fieldName; - Result += '='; - Result += Value ? "true" : "false"; - return WHERE_AND_(Result,args...); - } else if constexpr (std::is_arithmetic_v) { - if(!Result.empty()) - Result += " and "; - Result += fieldName ; - Result += '='; - Result += std::to_string(Value); - return WHERE_AND_(Result,args...); - } else { - assert(false); - } - return WHERE_AND_(Result,args...); - } - - template std::string WHERE_AND(Args... args) { - std::string Result; - return WHERE_AND_(Result, args...); - } - - enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE }; - enum SqlBinaryOp { AND = 0 , OR }; - - static const std::vector BOPS{" and ", " or "}; - static const std::vector SQLCOMPS{"=","!=","<","<=",">",">="}; - - inline std::string to_string(uint64_t V) { - return std::to_string(V); - } - - inline std::string to_string(int V) { - return std::to_string(V); - } - - inline std::string to_string(bool V) { - return std::to_string(V); - } - - inline std::string to_string(const std::string &S) { - return S; - } - - inline std::string to_string(const Poco::Data::BLOB &blob) { - std::string result; - result.assign(blob.begin(),blob.end()); - return result; - } - - inline std::string to_string(const char * S) { - return S; - } - - template class DBCache { - public: - DBCache(unsigned Size, unsigned Timeout) : - Size_(Size), - Timeout_(Timeout) - { - - } - virtual void Create(const RecordType &R)=0; - virtual bool GetFromCache(const std::string &FieldName, const std::string &Value, RecordType &R)=0; - virtual void UpdateCache(const RecordType &R)=0; - virtual void Delete(const std::string &FieldName, const std::string &Value)=0; - private: - size_t Size_=0; - uint64_t Timeout_=0; - }; - - template class DB { - public: - - typedef const char * field_name_t; - - DB( OpenWifi::DBType dbtype, - const char *TableName, - const FieldVec & Fields, - const IndexVec & Indexes, - Poco::Data::SessionPool & Pool, - Poco::Logger &L, - const char *Prefix, - DBCache * Cache=nullptr): - TableName_(TableName), - Type_(dbtype), - Pool_(Pool), - Logger_(L), - Prefix_(Prefix), - Cache_(Cache) - { - assert(RecordTuple::length == Fields.size()); - - bool first = true; - int Place=0; - - for(const auto &i:Fields) { - std::string FieldName = Poco::toLower(i.Name); - FieldNames_[FieldName] = Place; - if(!first) { - CreateFields_ += ", "; - SelectFields_ += ", "; - UpdateFields_ += ", "; - SelectList_ += ", "; - } else { - SelectList_ += "("; - } - - CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : ""); - SelectFields_ += FieldName ; - UpdateFields_ += FieldName + "=?"; - SelectList_ += "?"; - first = false; - Place++; - } - SelectList_ += ")"; - - if(!Indexes.empty()) { - if(Type_==OpenWifi::DBType::sqlite || Type_==OpenWifi::DBType::pgsql) { - for(const auto &j:Indexes) { - std::string IndexLine; - - IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " ("; - bool first_entry=true; - for(const auto &k:j.Entries) { - auto IndexFieldName = Poco::toLower(k.FieldName); - assert(ValidFieldName(IndexFieldName)); - if(!first_entry) { - IndexLine += " , "; - } - first_entry = false; - IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ; - } - IndexLine += " )"; - IndexCreation_.template emplace_back(IndexLine); - } - } else if(Type_==OpenWifi::DBType::mysql) { - bool firstIndex = true; - std::string IndexLine; - for(const auto &j:Indexes) { - if(!firstIndex) - IndexLine += ", "; - firstIndex = false; - IndexLine += " INDEX " + j.Name + " ( " ; - bool first_entry=true; - for(const auto &k:j.Entries) { - auto IndexFieldName = Poco::toLower(k.FieldName); - assert(FieldNames_.find(IndexFieldName) != FieldNames_.end()); - if(!first_entry) { - IndexLine += " ,"; - } - first_entry = false; - IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC"); - } - IndexLine += " ) "; - } - IndexCreation_.template emplace_back(IndexLine); - } - } - } - - [[nodiscard]] const std::string & CreateFields() const { return CreateFields_; }; - [[nodiscard]] const std::string & SelectFields() const { return SelectFields_; }; - [[nodiscard]] const std::string & SelectList() const { return SelectList_; }; - [[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; }; - - inline std::string OP(field_name_t F, SqlComparison O , bool V) { - assert(ValidFieldName(F)); - return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ; - } - - inline std::string OP(field_name_t F, SqlComparison O , int V) { - assert(ValidFieldName(F)); - return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; - } - - inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) { - assert(ValidFieldName(F)); - return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; - } - - std::string OP(field_name_t F, SqlComparison O , const std::string & V) { - assert(ValidFieldName(F)); - return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; - } - - std::string OP(field_name_t F, SqlComparison O , const char * V) { - assert(ValidFieldName(F)); - return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; - } - - static std::string OP( const std::string &P1, SqlBinaryOp BOP , const std::string &P2) { - return std::string("(")+P1 + BOPS[BOP] + P2 +")"; - } - - std::string OP( [[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) { - return P1 + BOPS[BOP] + P2 +")"; - } - - template std::string OP( bool ParanOpen, const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) { - return P1 + BOPS[BOP] + OP(ParanOpen, P2, More...) + ")"; - } - - template std::string OP( const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) { - return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...); - } - - bool Upgrade() { - uint32_t To; - return Upgrade(0, To); - } - - inline bool Create() { - switch(Type_) { - case OpenWifi::DBType::mysql: { - try { - Poco::Data::Session Session = Pool_.get(); - std::string Statement = IndexCreation_.empty() ? "create table if not exists " + TableName_ +" ( " + CreateFields_ + " )" : - "create table if not exists " + TableName_ +" ( " + CreateFields_ + " ), " + IndexCreation_[0] + " )"; - Session << Statement , Poco::Data::Keywords::now; - } catch (const Poco::Exception &E) { - Logger_.error("Failure to create MySQL DB resources."); - Logger_.log(E); - } - } - break; - - case OpenWifi::DBType::sqlite: { - try { - Poco::Data::Session Session = Pool_.get(); - std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )"; - Session << Statement , Poco::Data::Keywords::now; - for(const auto &i:IndexCreation_) { - Session << i , Poco::Data::Keywords::now; - } - } catch (const Poco::Exception &E) { - Logger_.error("Failure to create SQLITE DB resources."); - Logger_.log(E); - } - } - break; - - case OpenWifi::DBType::pgsql: { - try { - Poco::Data::Session Session = Pool_.get(); - std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )"; - Session << Statement , Poco::Data::Keywords::now; - for(const auto &i:IndexCreation_) { - Session << i , Poco::Data::Keywords::now; - } - } catch (const Poco::Exception &E) { - Logger_.error("Failure to create POSTGRESQL DB resources."); - Logger_.log(E); - } - } - break; - } - return Upgrade(); - } - - [[nodiscard]] std::string ConvertParams(const std::string & S) const { - if(Type_!=OpenWifi::DBType::pgsql) - return S; - - std::string R; - R.reserve(S.size()*2+1); - auto Idx=1; - for(auto const & i:S) - { - if(i=='?') { - R += '$'; - R.append(std::to_string(Idx++)); - } else { - R += i; - } - } - - return R; - } - - void Convert( const RecordTuple &in , RecordType &out); - void Convert( const RecordType &in , RecordTuple &out); - - inline const std::string & Prefix() { return Prefix_; }; - - bool CreateRecord( const RecordType & R) { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Insert(Session); - - RecordTuple RT; - Convert(R, RT); - std::string St = "insert into " + TableName_ + " ( " + SelectFields_ + " ) values " + SelectList_; - Insert << ConvertParams(St) , - Poco::Data::Keywords::use(RT); - Insert.execute(); - - if(Cache_) - Cache_->Create(R); - return true; - - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - template bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) { - try { - assert(ValidFieldName(FieldName)); - - if(Cache_) { - if(Cache_->GetFromCache(FieldName, Value, R)) - return true; - } - - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - RecordTuple RT; - - std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" + " limit 1"; - - auto tValue{Value}; - - Select << ConvertParams(St) , - Poco::Data::Keywords::into(RT), - Poco::Data::Keywords::use(tValue); - Select.execute(); - - if(Select.execute()==1) { - Convert(RT,R); - if(Cache_) - Cache_->UpdateCache(R); - return true; - } - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool GetRecord(RecordType & T , const std::string &WhereClause) { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - RecordTuple RT; - - std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + WhereClause + " limit 1"; - - Select << ConvertParams(St) , - Poco::Data::Keywords::into(RT); - Select.execute(); - - if(Select.execute()==1) { - Convert(RT,T); - if(Cache_) - Cache_->UpdateCache(T); - return true; - } - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - typedef std::vector StringVec; - - template < typename T, - typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) { - try { - - assert( ValidFieldName(FieldName) ); - - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - RecordTuple RT; - - std::string St = "select " + SelectFields_ + " from " + TableName_ - + " where " + FieldName[0] + "=? and " + FieldName[1] + "=?" ; - Select << ConvertParams(St) , - Poco::Data::Keywords::into(RT), - Poco::Data::Keywords::use(V0), - Poco::Data::Keywords::use(V1); - - if(Select.execute()==1) { - Convert(RT,R); - return true; - } - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - template bool Join(const std::string &statement, std::vector &records) { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - - Select << statement , - Poco::Data::Keywords::into(records); - Select.execute(); - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - typedef std::vector RecordList; - typedef std::vector RecordVec; - typedef RecordType RecordName; - - bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - RecordList RL; - std::string St = "select " + SelectFields_ + " from " + TableName_ + - (Where.empty() ? "" : " where " + Where) + OrderBy + - ComputeRange(Offset, HowMany) ; - - Select << St , - Poco::Data::Keywords::into(RL); - Select.execute(); - - if(Select.rowsExtracted()>0) { - for(auto &i:RL) { - RecordType R; - Convert(i, R); - Records.template emplace_back(R); - } - return true; - } - return false; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - template bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) { - try { - assert( ValidFieldName(FieldName) ); - - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Update(Session); - - RecordTuple RT; - - Convert(R, RT); - - auto tValue(Value); - - std::string St = "update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?" ; - Update << ConvertParams(St) , - Poco::Data::Keywords::use(RT), - Poco::Data::Keywords::use(tValue); - Update.execute(); - if(Cache_) - Cache_->UpdateCache(R); - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool RunStatement(const std::string &St) { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Command(Session); - - Command << St ; - Command.execute(); - - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - template bool ReplaceRecord(field_name_t FieldName, const 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 bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) { - try { - assert( ValidFieldName(FieldName) ); - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Select(Session); - RecordTuple RT; - - std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ; - RecordType R; - auto tValue{Value}; - Select << ConvertParams(St) , - Poco::Data::Keywords::into(RT), - Poco::Data::Keywords::use(tValue); - - if(Select.execute()==1) { - Convert(RT,R); - Name = R.info.name; - Description = R.info.description; - return true; - } - return false; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - template bool DeleteRecord(field_name_t FieldName, const T & Value) { - try { - assert( ValidFieldName(FieldName) ); - - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Delete(Session); - - std::string St = "delete from " + TableName_ + " where " + FieldName + "=?" ; - auto tValue{Value}; - - Delete << ConvertParams(St) , - Poco::Data::Keywords::use(tValue); - Delete.execute(); - if(Cache_) - Cache_->Delete(FieldName, Value); - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool DeleteRecords( const std::string & WhereClause ) { - try { - assert( !WhereClause.empty()); - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Delete(Session); - - std::string St = "delete from " + TableName_ + " where " + WhereClause; - Delete << St; - Delete.execute(); - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool Exists(field_name_t FieldName, const std::string & Value) { - try { - assert( ValidFieldName(FieldName) ); - - RecordType R; - if(GetRecord(FieldName,Value,R)) - return true; - return false; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool Iterate( std::function F, const std::string & WhereClause = "" ) { - try { - - uint64_t Offset=0; - uint64_t Batch=50; - bool Done=false; - while(!Done) { - std::vector Records; - if(GetRecords(Offset,Batch,Records, WhereClause)) { - for(const auto &i:Records) { - if(!F(i)) - return true; - } - if(Records.size() bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) { - try { - assert( ValidFieldName(FieldName) ); - - RecordType R; - if(GetRecord(FieldName, ParentUUID, R)) { - auto it = std::find((R.*T).begin(),(R.*T).end(),ChildUUID); - if(Add) { - if(it!=(R.*T).end() && *it == ChildUUID) - return false; - (R.*T).push_back(ChildUUID); - std::sort((R.*T).begin(),(R.*T).end()); - } else { - if(it!=(R.*T).end() && *it == ChildUUID) - (R.*T).erase(it); - else - return false; - } - UpdateRecord(FieldName, ParentUUID, R); - return true; - } - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - bool RunScript(const std::vector & Statements, bool IgnoreExceptions=true) { - try { - Poco::Data::Session Session = Pool_.get(); - Poco::Data::Statement Command(Session); - - for(const auto &i:Statements) { - try { - Command << i, Poco::Data::Keywords::now; - } catch (const Poco::Exception &E) { - // Logger_.log(E); - // Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This may or may not be a problem.", i)); - if(!IgnoreExceptions) { - return false; - } - } - Command.reset(Session); - } - return true; - } catch (const Poco::Exception &E) { - Logger_.log(E); - } - return false; - } - - virtual uint32_t Version() { - return 0; - } - - virtual bool Upgrade(uint32_t from, uint32_t &to) { - to = from; - return true; - } - - inline bool AddChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DelConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, true); - } - - inline bool DelVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { - return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, false); - } - - inline bool AddInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { - std::string FakeUUID{ Prefix + ":" + ChildUUID}; - return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true); - } - - inline bool DeleteInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { - std::string FakeUUID{ Prefix + ":" + ChildUUID}; - return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false); - } - - inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector & UUIDs ) { - RecordType R; - if(GetRecord(FieldName,UUID,R)) { - UUIDs = R.inUse; - return true; - } - return false; - } - - inline bool ValidFieldName(const std::string &FieldName) { - return FieldNames_.find(Poco::toLower(FieldName)) != FieldNames_.end(); - } - - inline bool ValidFieldName(const char *FieldName) { - std::string Field{FieldName}; - return ValidFieldName(Field); - } - - [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { - if(From<1) From=0; - switch(Type_) { - case OpenWifi::DBType::sqlite: - return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " "; - case OpenWifi::DBType::pgsql: - return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; - case OpenWifi::DBType::mysql: - return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; - default: - return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; - } - } - - Poco::Logger & Logger() { return Logger_; } - - inline bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) { - if(Cache_) - Cache_->Delete(FieldName, Value); - return true; - } - - inline void GetFieldNames( OpenWifi::Types::StringVec & F) { - for(const auto &[field,_]:FieldNames_) - F.push_back(field); - } - - protected: - std::string TableName_; - OpenWifi::DBType Type_; - Poco::Data::SessionPool &Pool_; - Poco::Logger &Logger_; - std::string Prefix_; - DBCache *Cache_= nullptr; - private: - std::string CreateFields_; - std::string SelectFields_; - std::string SelectList_; - std::string UpdateFields_; - std::vector IndexCreation_; - std::map FieldNames_; - }; -} - + enum FieldType { FT_INT, FT_BIGINT, FT_TEXT, FT_VARCHAR, FT_BLOB, FT_BOOLEAN, FT_REAL }; + + enum Indextype { ASC, DESC }; + + struct Field { + std::string Name; + FieldType Type; + int Size = 0; + bool Index = false; + + Field(std::string N, FieldType T, int S = 0, bool Index = false) + : Name(std::move(N)), Type(T), Size(S), Index(Index) {} + + explicit Field(std::string N) : Name(std::move(N)) { Type = FT_TEXT; } + + Field(std::string N, int S) : Name(std::move(N)), Size(S) { + if (Size > 0 && Size < 255) + Type = FT_VARCHAR; + else + Type = FT_TEXT; + } + + Field(std::string N, int S, bool I) : Name(std::move(N)), Size(S), Index(I) { + if (Size > 0 && Size < 255) + Type = FT_VARCHAR; + else + Type = FT_TEXT; + } + }; + typedef std::vector FieldVec; + + struct IndexEntry { + std::string FieldName; + Indextype Type; + }; + typedef std::vector IndexEntryVec; + + struct Index { + std::string Name; + IndexEntryVec Entries; + }; + typedef std::vector IndexVec; + + inline std::string FieldTypeToChar(OpenWifi::DBType Type, FieldType T, int Size = 0) { + switch (T) { + case FT_INT: + return "INT"; + case FT_BIGINT: + return "BIGINT"; + case FT_TEXT: + return "TEXT"; + case FT_BOOLEAN: + return "BOOLEAN"; + case FT_VARCHAR: + if (Size) + return std::string("VARCHAR(") + std::to_string(Size) + std::string(")"); + else + return "TEXT"; + case FT_BLOB: + if (Type == OpenWifi::DBType::mysql) + return "LONGBLOB"; + else if (Type == OpenWifi::DBType::pgsql) + return "BYTEA"; + else + return "BLOB"; + case FT_REAL: + return "REAL"; + default: + assert(false); + } + assert(false); + return ""; + } + + inline std::string Escape(const std::string &S) { + std::string R; + + for (const auto &i : S) { + if (i == '\'') + R += "''"; + else + R += i; + } + return R; + } + + inline std::string WHERE_AND_(std::string Result) { return Result; } + + template + std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value, + Args... args) { + if constexpr (std::is_same_v) { + if (!Value.empty()) { + if (!Result.empty()) + Result += " and "; + Result += fieldName; + Result += '='; + Result += "'"; + Result += Escape(Value); + Result += "'"; + } + return WHERE_AND_(Result, args...); + } else if constexpr (std::is_same_v) { + if (*Value != 0) { + if (!Result.empty()) + Result += " and "; + Result += fieldName; + Result += '='; + Result += "'"; + Result += Escape(Value); + Result += "'"; + } + return WHERE_AND_(Result, args...); + } else if constexpr (std::is_same_v) { + if (!Result.empty()) + Result += " and "; + Result += fieldName; + Result += '='; + Result += Value ? "true" : "false"; + return WHERE_AND_(Result, args...); + } else if constexpr (std::is_arithmetic_v) { + if (!Result.empty()) + Result += " and "; + Result += fieldName; + Result += '='; + Result += std::to_string(Value); + return WHERE_AND_(Result, args...); + } else { + assert(false); + } + return WHERE_AND_(Result, args...); + } + + template std::string WHERE_AND(Args... args) { + std::string Result; + return WHERE_AND_(Result, args...); + } + + enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE }; + enum SqlBinaryOp { AND = 0, OR }; + + static const std::vector BOPS{" and ", " or "}; + static const std::vector SQLCOMPS{"=", "!=", "<", "<=", ">", ">="}; + + inline std::string to_string(uint64_t V) { return std::to_string(V); } + + inline std::string to_string(int V) { return std::to_string(V); } + + inline std::string to_string(bool V) { return std::to_string(V); } + + inline std::string to_string(const std::string &S) { return S; } + + inline std::string to_string(const Poco::Data::BLOB &blob) { + std::string result; + result.assign(blob.begin(), blob.end()); + return result; + } + + inline std::string to_string(const char *S) { return S; } + + template class DBCache { + public: + DBCache(unsigned Size, unsigned Timeout) : Size_(Size), Timeout_(Timeout) {} + virtual void Create(const RecordType &R) = 0; + virtual bool GetFromCache(const std::string &FieldName, const std::string &Value, + RecordType &R) = 0; + virtual void UpdateCache(const RecordType &R) = 0; + virtual void Delete(const std::string &FieldName, const std::string &Value) = 0; + + private: + size_t Size_ = 0; + uint64_t Timeout_ = 0; + }; + + template class DB { + public: + typedef const char *field_name_t; + + DB(OpenWifi::DBType dbtype, const char *TableName, const FieldVec &Fields, + const IndexVec &Indexes, Poco::Data::SessionPool &Pool, Poco::Logger &L, + const char *Prefix, DBCache *Cache = nullptr) + : TableName_(TableName), Type_(dbtype), Pool_(Pool), Logger_(L), Prefix_(Prefix), + Cache_(Cache) { + assert(RecordTuple::length == Fields.size()); + + bool first = true; + int Place = 0; + + for (const auto &i : Fields) { + std::string FieldName = Poco::toLower(i.Name); + FieldNames_[FieldName] = Place; + if (!first) { + CreateFields_ += ", "; + SelectFields_ += ", "; + UpdateFields_ += ", "; + SelectList_ += ", "; + } else { + SelectList_ += "("; + } + + CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type, i.Size) + + (i.Index ? " unique primary key" : ""); + SelectFields_ += FieldName; + UpdateFields_ += FieldName + "=?"; + SelectList_ += "?"; + first = false; + Place++; + } + SelectList_ += ")"; + + if (!Indexes.empty()) { + if (Type_ == OpenWifi::DBType::sqlite || Type_ == OpenWifi::DBType::pgsql) { + for (const auto &j : Indexes) { + std::string IndexLine; + + IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + + std::string(" ON ") + TableName_ + " ("; + bool first_entry = true; + for (const auto &k : j.Entries) { + auto IndexFieldName = Poco::toLower(k.FieldName); + assert(ValidFieldName(IndexFieldName)); + if (!first_entry) { + IndexLine += " , "; + } + first_entry = false; + IndexLine += IndexFieldName + std::string(" ") + + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC"); + } + IndexLine += " )"; + IndexCreation_.template emplace_back(IndexLine); + } + } else if (Type_ == OpenWifi::DBType::mysql) { + bool firstIndex = true; + std::string IndexLine; + for (const auto &j : Indexes) { + if (!firstIndex) + IndexLine += ", "; + firstIndex = false; + IndexLine += " INDEX " + j.Name + " ( "; + bool first_entry = true; + for (const auto &k : j.Entries) { + auto IndexFieldName = Poco::toLower(k.FieldName); + assert(FieldNames_.find(IndexFieldName) != FieldNames_.end()); + if (!first_entry) { + IndexLine += " ,"; + } + first_entry = false; + IndexLine += IndexFieldName + + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC"); + } + IndexLine += " ) "; + } + IndexCreation_.template emplace_back(IndexLine); + } + } + } + + [[nodiscard]] const std::string &CreateFields() const { return CreateFields_; }; + [[nodiscard]] const std::string &SelectFields() const { return SelectFields_; }; + [[nodiscard]] const std::string &SelectList() const { return SelectList_; }; + [[nodiscard]] const std::string &UpdateFields() const { return UpdateFields_; }; + + inline std::string OP(field_name_t F, SqlComparison O, bool V) { + assert(ValidFieldName(F)); + return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")"; + } + + inline std::string OP(field_name_t F, SqlComparison O, int V) { + assert(ValidFieldName(F)); + return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")"; + } + + inline std::string OP(field_name_t F, SqlComparison O, uint64_t V) { + assert(ValidFieldName(F)); + return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")"; + } + + std::string OP(field_name_t F, SqlComparison O, const std::string &V) { + assert(ValidFieldName(F)); + return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')"; + } + + std::string OP(field_name_t F, SqlComparison O, const char *V) { + assert(ValidFieldName(F)); + return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')"; + } + + static std::string OP(const std::string &P1, SqlBinaryOp BOP, const std::string &P2) { + return std::string("(") + P1 + BOPS[BOP] + P2 + ")"; + } + + std::string OP([[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP, + const std::string &P2) { + return P1 + BOPS[BOP] + P2 + ")"; + } + + template + std::string OP(bool ParanOpen, const std::string &P1, SqlBinaryOp BOP, + const std::string &P2, Others... More) { + return P1 + BOPS[BOP] + OP(ParanOpen, P2, More...) + ")"; + } + + template + std::string OP(const std::string &P1, SqlBinaryOp BOP, const std::string &P2, + Others... More) { + return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...); + } + + bool Upgrade() { + uint32_t To; + return Upgrade(0, To); + } + + inline bool Create() { + switch (Type_) { + case OpenWifi::DBType::mysql: { + try { + Poco::Data::Session Session = Pool_.get(); + std::string Statement = IndexCreation_.empty() + ? "create table if not exists " + TableName_ + + " ( " + CreateFields_ + " )" + : "create table if not exists " + TableName_ + + " ( " + CreateFields_ + " ), " + + IndexCreation_[0] + " )"; + Session << Statement, Poco::Data::Keywords::now; + } catch (const Poco::Exception &E) { + Logger_.error("Failure to create MySQL DB resources."); + Logger_.log(E); + } + } break; + + case OpenWifi::DBType::sqlite: { + try { + Poco::Data::Session Session = Pool_.get(); + std::string Statement = + "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )"; + Session << Statement, Poco::Data::Keywords::now; + for (const auto &i : IndexCreation_) { + Session << i, Poco::Data::Keywords::now; + } + } catch (const Poco::Exception &E) { + Logger_.error("Failure to create SQLITE DB resources."); + Logger_.log(E); + } + } break; + + case OpenWifi::DBType::pgsql: { + try { + Poco::Data::Session Session = Pool_.get(); + std::string Statement = + "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )"; + Session << Statement, Poco::Data::Keywords::now; + for (const auto &i : IndexCreation_) { + Session << i, Poco::Data::Keywords::now; + } + } catch (const Poco::Exception &E) { + Logger_.error("Failure to create POSTGRESQL DB resources."); + Logger_.log(E); + } + } break; + } + return Upgrade(); + } + + [[nodiscard]] std::string ConvertParams(const std::string &S) const { + if (Type_ != OpenWifi::DBType::pgsql) + return S; + + std::string R; + R.reserve(S.size() * 2 + 1); + auto Idx = 1; + for (auto const &i : S) { + if (i == '?') { + R += '$'; + R.append(std::to_string(Idx++)); + } else { + R += i; + } + } + + return R; + } + + void Convert(const RecordTuple &in, RecordType &out); + void Convert(const RecordType &in, RecordTuple &out); + + inline const std::string &Prefix() { return Prefix_; }; + + bool CreateRecord(const RecordType &R) { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Insert(Session); + + RecordTuple RT; + Convert(R, RT); + std::string St = "insert into " + TableName_ + " ( " + SelectFields_ + + " ) values " + SelectList_; + Insert << ConvertParams(St), Poco::Data::Keywords::use(RT); + Insert.execute(); + + if (Cache_) + Cache_->Create(R); + return true; + + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + template + bool GetRecord(field_name_t FieldName, const T &Value, RecordType &R) { + try { + assert(ValidFieldName(FieldName)); + + if (Cache_) { + if (Cache_->GetFromCache(FieldName, Value, R)) + return true; + } + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + RecordTuple RT; + + std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + + FieldName + "=?" + " limit 1"; + + auto tValue{Value}; + + Select << ConvertParams(St), Poco::Data::Keywords::into(RT), + Poco::Data::Keywords::use(tValue); + Select.execute(); + + if (Select.execute() == 1) { + Convert(RT, R); + if (Cache_) + Cache_->UpdateCache(R); + return true; + } + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool GetRecord(RecordType &T, const std::string &WhereClause) { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + RecordTuple RT; + + std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + + WhereClause + " limit 1"; + + Select << ConvertParams(St), Poco::Data::Keywords::into(RT); + Select.execute(); + + if (Select.execute() == 1) { + Convert(RT, T); + if (Cache_) + Cache_->UpdateCache(T); + return true; + } + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + typedef std::vector StringVec; + + template + bool GR(field_name_t FieldName, T &R, T0 &V0, T1 &V1) { + try { + + assert(ValidFieldName(FieldName)); + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + RecordTuple RT; + + std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + + FieldName[0] + "=? and " + FieldName[1] + "=?"; + Select << ConvertParams(St), Poco::Data::Keywords::into(RT), + Poco::Data::Keywords::use(V0), Poco::Data::Keywords::use(V1); + + if (Select.execute() == 1) { + Convert(RT, R); + return true; + } + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + template bool Join(const std::string &statement, std::vector &records) { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + + Select << statement, Poco::Data::Keywords::into(records); + Select.execute(); + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + typedef std::vector RecordList; + typedef std::vector RecordVec; + typedef RecordType RecordName; + + bool GetRecords(uint64_t Offset, uint64_t HowMany, RecordVec &Records, + const std::string &Where = "", const std::string &OrderBy = "") { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + RecordList RL; + std::string St = "select " + SelectFields_ + " from " + TableName_ + + (Where.empty() ? "" : " where " + Where) + OrderBy + + ComputeRange(Offset, HowMany); + + Select << St, Poco::Data::Keywords::into(RL); + Select.execute(); + + if (Select.rowsExtracted() > 0) { + for (auto &i : RL) { + RecordType R; + Convert(i, R); + Records.template emplace_back(R); + } + return true; + } + return false; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + template + bool UpdateRecord(field_name_t FieldName, const T &Value, const RecordType &R) { + try { + assert(ValidFieldName(FieldName)); + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Update(Session); + + RecordTuple RT; + + Convert(R, RT); + + auto tValue(Value); + + std::string St = + "update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?"; + Update << ConvertParams(St), Poco::Data::Keywords::use(RT), + Poco::Data::Keywords::use(tValue); + Update.execute(); + if (Cache_) + Cache_->UpdateCache(R); + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool RunStatement(const std::string &St) { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Command(Session); + + Command << St; + Command.execute(); + + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + template + bool ReplaceRecord(field_name_t FieldName, const 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 + bool GetNameAndDescription(field_name_t FieldName, const T &Value, std::string &Name, + std::string &Description) { + try { + assert(ValidFieldName(FieldName)); + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + RecordTuple RT; + + std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + + FieldName + "=?"; + RecordType R; + auto tValue{Value}; + Select << ConvertParams(St), Poco::Data::Keywords::into(RT), + Poco::Data::Keywords::use(tValue); + + if (Select.execute() == 1) { + Convert(RT, R); + Name = R.info.name; + Description = R.info.description; + return true; + } + return false; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + template bool DeleteRecord(field_name_t FieldName, const T &Value) { + try { + assert(ValidFieldName(FieldName)); + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Delete(Session); + + std::string St = "delete from " + TableName_ + " where " + FieldName + "=?"; + auto tValue{Value}; + + Delete << ConvertParams(St), Poco::Data::Keywords::use(tValue); + Delete.execute(); + if (Cache_) + Cache_->Delete(FieldName, Value); + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool DeleteRecords(const std::string &WhereClause) { + try { + assert(!WhereClause.empty()); + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Delete(Session); + + std::string St = "delete from " + TableName_ + " where " + WhereClause; + Delete << St; + Delete.execute(); + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool Exists(field_name_t FieldName, const std::string &Value) { + try { + assert(ValidFieldName(FieldName)); + + RecordType R; + if (GetRecord(FieldName, Value, R)) + return true; + return false; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool Iterate(std::function F, + const std::string &WhereClause = "") { + try { + + uint64_t Offset = 0; + uint64_t Batch = 50; + bool Done = false; + while (!Done) { + std::vector Records; + if (GetRecords(Offset, Batch, Records, WhereClause)) { + for (const auto &i : Records) { + if (!F(i)) + return true; + } + if (Records.size() < Batch) + return true; + Offset += Batch; + } else { + Done = true; + } + } + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool PrepareOrderBy(const std::string &OrderByList, std::string &OrderByString) { + auto items = Poco::StringTokenizer(OrderByList, ","); + std::string ItemList; + + for (const auto &i : items) { + auto T = Poco::StringTokenizer(i, ":"); + if (T.count() != 2) { + return false; + } + if (T[1] != "a" && T[1] != "d") { + return false; + } + if (!ItemList.empty()) + ItemList += " , "; + auto hint = FieldNames_.find(Poco::toLower(T[0])); + if (hint == FieldNames_.end()) { + return false; + } + ItemList += T[0] + (T[1] == "a" ? " ASC" : " DESC"); + } + + if (!ItemList.empty()) { + OrderByString = " ORDER BY " + ItemList; + } + return true; + } + + uint64_t Count(const std::string &Where = "") { + try { + uint64_t Cnt = 0; + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + + std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " + + (Where.empty() ? "" : (" where " + Where))}; + + Select << st, Poco::Data::Keywords::into(Cnt); + Select.execute(); + + return Cnt; + + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return 0; + } + + template + bool ManipulateVectorMember(X T, field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID, bool Add) { + try { + assert(ValidFieldName(FieldName)); + + RecordType R; + if (GetRecord(FieldName, ParentUUID, R)) { + auto it = std::find((R.*T).begin(), (R.*T).end(), ChildUUID); + if (Add) { + if (it != (R.*T).end() && *it == ChildUUID) + return false; + (R.*T).push_back(ChildUUID); + std::sort((R.*T).begin(), (R.*T).end()); + } else { + if (it != (R.*T).end() && *it == ChildUUID) + (R.*T).erase(it); + else + return false; + } + UpdateRecord(FieldName, ParentUUID, R); + return true; + } + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + bool RunScript(const std::vector &Statements, bool IgnoreExceptions = true) { + try { + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Command(Session); + + for (const auto &i : Statements) { + try { + Command << i, Poco::Data::Keywords::now; + } catch (const Poco::Exception &E) { + // Logger_.log(E); + // Logger_.error(Poco::format("The following statement '%s' generated an + // exception during a table upgrade. This may or may not be a problem.", + // i)); + if (!IgnoreExceptions) { + return false; + } + } + Command.reset(Session); + } + return true; + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return false; + } + + virtual uint32_t Version() { return 0; } + + virtual bool Upgrade(uint32_t from, uint32_t &to) { + to = from; + return true; + } + + inline bool AddChild(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteChild(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddLocation(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteLocation(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddContact(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteContact(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddVenue(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteVenue(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddDevice(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteDevice(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddEntity(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DeleteEntity(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddUser(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DelUser(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddConfiguration(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, + ChildUUID, true); + } + + inline bool DelConfiguration(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, + ChildUUID, false); + } + + inline bool AddVariable(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, + true); + } + + inline bool DelVariable(field_name_t FieldName, const std::string &ParentUUID, + const std::string &ChildUUID) { + return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, + false); + } + + inline bool AddInUse(field_name_t FieldName, const std::string &ParentUUID, + const std::string &Prefix, const std::string &ChildUUID) { + std::string FakeUUID{Prefix + ":" + ChildUUID}; + return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID, + true); + } + + inline bool DeleteInUse(field_name_t FieldName, const std::string &ParentUUID, + const std::string &Prefix, const std::string &ChildUUID) { + std::string FakeUUID{Prefix + ":" + ChildUUID}; + return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID, + false); + } + + inline bool GetInUse(field_name_t FieldName, const std::string &UUID, + std::vector &UUIDs) { + RecordType R; + if (GetRecord(FieldName, UUID, R)) { + UUIDs = R.inUse; + return true; + } + return false; + } + + inline bool ValidFieldName(const std::string &FieldName) { + return FieldNames_.find(Poco::toLower(FieldName)) != FieldNames_.end(); + } + + inline bool ValidFieldName(const char *FieldName) { + std::string Field{FieldName}; + return ValidFieldName(Field); + } + + [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { + if (From < 1) + From = 0; + switch (Type_) { + case OpenWifi::DBType::sqlite: + return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " "; + case OpenWifi::DBType::pgsql: + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + + " "; + case OpenWifi::DBType::mysql: + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + + " "; + default: + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + + " "; + } + } + + Poco::Logger &Logger() { return Logger_; } + + inline bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value) { + if (Cache_) + Cache_->Delete(FieldName, Value); + return true; + } + + inline void GetFieldNames(OpenWifi::Types::StringVec &F) { + for (const auto &[field, _] : FieldNames_) + F.push_back(field); + } + + protected: + std::string TableName_; + OpenWifi::DBType Type_; + Poco::Data::SessionPool &Pool_; + Poco::Logger &Logger_; + std::string Prefix_; + DBCache *Cache_ = nullptr; + + private: + std::string CreateFields_; + std::string SelectFields_; + std::string SelectList_; + std::string UpdateFields_; + std::vector IndexCreation_; + std::map FieldNames_; + }; +} // namespace ORM diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 060873d..207d5d8 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -4,8 +4,8 @@ #pragma once -#include #include +#include #include "Poco/String.h" @@ -21,7 +21,7 @@ namespace OpenWifi { enum UNAUTHORIZED_REASON { - SUCCESS=0, + SUCCESS = 0, PASSWORD_CHANGE_REQUIRED, INVALID_CREDENTIALS, PASSWORD_ALREADY_USED, @@ -36,449 +36,592 @@ namespace OpenWifi { MFA_FAILURE, SECURITY_SERVICE_UNREACHABLE, CANNOT_REFRESH_TOKEN, - ACCOUNT_SUSPENDED + ACCOUNT_SUSPENDED }; } namespace OpenWifi::RESTAPI::Errors { - struct msg { uint64_t err_num; std::string err_txt; }; - static const struct msg Error404{404,"Resource does not exist."}; + struct msg { + uint64_t err_num; + std::string err_txt; + }; + static const struct msg Error404 { 404, "Resource does not exist." }; - static const struct msg SUCCESS{0,"No error."}; - static const struct msg PASSWORD_CHANGE_REQUIRED{1,"Password change required"}; - static const struct msg INVALID_CREDENTIALS{2,"Invalid credentials."}; - static const struct msg PASSWORD_ALREADY_USED{3,"Password already used."}; - static const struct msg USERNAME_PENDING_VERIFICATION{4,"Username pending verification."}; - static const struct msg PASSWORD_INVALID{5,"Password is invalid"}; - static const struct msg INTERNAL_ERROR{6,"Internal error."}; - static const struct msg ACCESS_DENIED{7,"Access denied."}; - static const struct msg INVALID_TOKEN{8,"Invalid token."}; - static const struct msg EXPIRED_TOKEN{9,"Expired token."}; - static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."}; - static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."}; - static const struct msg MFA_FAILURE{12,"MFA failure."}; - static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."}; - static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."}; - static const struct msg ACCOUNT_SUSPENDED{15,"Account has been suspended."}; + static const struct msg SUCCESS { 0, "No error." }; + static const struct msg PASSWORD_CHANGE_REQUIRED { 1, "Password change required" }; + static const struct msg INVALID_CREDENTIALS { 2, "Invalid credentials." }; + static const struct msg PASSWORD_ALREADY_USED { 3, "Password already used." }; + static const struct msg USERNAME_PENDING_VERIFICATION { 4, "Username pending verification." }; + static const struct msg PASSWORD_INVALID { 5, "Password is invalid" }; + static const struct msg INTERNAL_ERROR { 6, "Internal error." }; + static const struct msg ACCESS_DENIED { 7, "Access denied." }; + static const struct msg INVALID_TOKEN { 8, "Invalid token." }; + static const struct msg EXPIRED_TOKEN { 9, "Expired token." }; + static const struct msg RATE_LIMIT_EXCEEDED { 10, "Rate limit exceeded." }; + static const struct msg BAD_MFA_TRANSACTION { 11, "Bad MFA transaction." }; + static const struct msg MFA_FAILURE { 12, "MFA failure." }; + static const struct msg SECURITY_SERVICE_UNREACHABLE { + 13, "Security service is unreachable, try again later." + }; + static const struct msg CANNOT_REFRESH_TOKEN { 14, "Cannot refresh token." }; + static const struct msg ACCOUNT_SUSPENDED { 15, "Account has been suspended." }; - static const struct msg MissingUUID{1000,"Missing UUID."}; - static const struct msg MissingSerialNumber{1001,"Missing Serial Number."}; - static const struct msg InternalError{1002,"Internal error. Please try later."}; - static const struct msg InvalidJSONDocument{1003,"Invalid JSON document."}; - static const struct msg UnsupportedHTTPMethod{1004,"Unsupported HTTP Method"}; - static const struct msg StillInUse{1005,"Element still in use."}; - static const struct msg CouldNotBeDeleted{1006,"Element could not be deleted."}; - static const struct msg NameMustBeSet{1007,"The name property must be set."}; - static const struct msg ConfigBlockInvalid{1008,"Configuration block type invalid."}; - static const struct msg UnknownId{1009,"Unknown UUID."}; - static const struct msg InvalidDeviceTypes{1010,"Unknown or invalid device type(s)."}; - static const struct msg RecordNotCreated{1011,"Record could not be created."}; - static const struct msg RecordNotUpdated{1012,"Record could not be updated."}; - static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."}; - static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."}; - static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."}; - static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."}; - static const struct msg ConfigurationMustExist{1017,"Configuration must exist."}; - static const struct msg MissingOrInvalidParameters{1018,"Invalid or missing parameters."}; - static const struct msg UnknownSerialNumber{1019,"Unknown Serial Number."}; - static const struct msg InvalidSerialNumber{1020,"Invalid Serial Number."}; - static const struct msg SerialNumberExists{1021,"Serial Number already exists."}; - static const struct msg ValidNonRootUUID{1022,"Must be a non-root, and valid UUID."}; - static const struct msg VenueMustExist{1023,"Venue does not exist."}; - static const struct msg NotBoth{1024,"You cannot specify both Entity and Venue"}; - static const struct msg EntityMustExist{1025,"Entity must exist."}; - static const struct msg ParentOrEntityMustBeSet{1026,"Parent or Entity must be set."}; - static const struct msg ContactMustExist{1027,"Contact must exist."}; - static const struct msg LocationMustExist{1028,"Location must exist."}; - static const struct msg OnlyWSSupported{1029,"This endpoint only supports WebSocket."}; - static const struct msg SerialNumberMismatch{1030,"Serial Number mismatch."}; - static const struct msg InvalidCommand{1031,"Invalid command."}; - static const struct msg NoRecordsDeleted{1032,"No records deleted."}; - static const struct msg DeviceNotConnected{1033,"Device is not currently connected."}; - static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."}; - static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."}; - static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."}; - static const struct msg MissingUserID{1037,"Missing user ID."}; - static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"}; - static const struct msg InvalidUserRole{1039,"Invalid userRole."}; - static const struct msg InvalidEmailAddress{1040,"Invalid email address."}; - static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."}; - static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."}; - static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."}; - static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."}; - static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."}; - static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."}; - static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."}; - static const struct msg UserPendingVerification{1048,"User access denied pending email verification."}; - static const struct msg PasswordMustBeChanged{1049,"Password must be changed."}; - static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."}; - static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."}; - static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."}; - static const struct msg ExpiredToken{1053,"Token has expired, user must login."}; - static const struct msg SubscriberMustExist{1054,"Subscriber must exist."}; - static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."}; - static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."}; - static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"}; - static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"}; - static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."}; - static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."}; - static const struct msg UserAlreadyExists{1061,"Username already exists."}; - static const struct msg NotImplemented{1062,"Function not implemented."}; - static const struct msg VariableMustExist{1063,"Specified variable does not exist."}; - static const struct msg InvalidEntityType{1064,"Invalid entity type."}; - static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."}; - static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"}; - static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."}; - static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."}; - static const struct msg InvalidRRM{1069,"Invalid RRM value."}; - static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."}; - static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."}; - static const struct msg InvalidBillingPeriod{1072,"Invalid billing period."}; - static const struct msg InvalidSubscriberId{1073,"Invalid subscriber ID."}; - static const struct msg InvalidContactId{1074,"Invalid contact ID."}; - static const struct msg InvalidLocationId{1075,"Invalid location ID."}; - static const struct msg InvalidContactType{1076,"Invalid contact type."}; - static const struct msg InvalidLocationType{1077,"Invalid location type."}; - static const struct msg InvalidOperatorId{1078,"Invalid operator ID."}; - static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."}; - static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."}; - static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."}; - static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."}; - static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."}; - static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."}; - static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."}; + static const struct msg MissingUUID { 1000, "Missing UUID." }; + static const struct msg MissingSerialNumber { 1001, "Missing Serial Number." }; + static const struct msg InternalError { 1002, "Internal error. Please try later." }; + static const struct msg InvalidJSONDocument { 1003, "Invalid JSON document." }; + static const struct msg UnsupportedHTTPMethod { 1004, "Unsupported HTTP Method" }; + static const struct msg StillInUse { 1005, "Element still in use." }; + static const struct msg CouldNotBeDeleted { 1006, "Element could not be deleted." }; + static const struct msg NameMustBeSet { 1007, "The name property must be set." }; + static const struct msg ConfigBlockInvalid { 1008, "Configuration block type invalid." }; + static const struct msg UnknownId { 1009, "Unknown UUID." }; + static const struct msg InvalidDeviceTypes { 1010, "Unknown or invalid device type(s)." }; + static const struct msg RecordNotCreated { 1011, "Record could not be created." }; + static const struct msg RecordNotUpdated { 1012, "Record could not be updated." }; + static const struct msg UnknownManagementPolicyUUID { 1013, "Unknown management policy UUID." }; + static const struct msg CannotDeleteRoot { + 1014, "Root Entity cannot be removed, only modified." + }; + static const struct msg MustCreateRootFirst { 1015, "Root entity must be created first." }; + static const struct msg ParentUUIDMustExist { 1016, "Parent UUID must exist." }; + static const struct msg ConfigurationMustExist { 1017, "Configuration must exist." }; + static const struct msg MissingOrInvalidParameters { 1018, "Invalid or missing parameters." }; + static const struct msg UnknownSerialNumber { 1019, "Unknown Serial Number." }; + static const struct msg InvalidSerialNumber { 1020, "Invalid Serial Number." }; + static const struct msg SerialNumberExists { 1021, "Serial Number already exists." }; + static const struct msg ValidNonRootUUID { 1022, "Must be a non-root, and valid UUID." }; + static const struct msg VenueMustExist { 1023, "Venue does not exist." }; + static const struct msg NotBoth { 1024, "You cannot specify both Entity and Venue" }; + static const struct msg EntityMustExist { 1025, "Entity must exist." }; + static const struct msg ParentOrEntityMustBeSet { 1026, "Parent or Entity must be set." }; + static const struct msg ContactMustExist { 1027, "Contact must exist." }; + static const struct msg LocationMustExist { 1028, "Location must exist." }; + static const struct msg OnlyWSSupported { 1029, "This endpoint only supports WebSocket." }; + static const struct msg SerialNumberMismatch { 1030, "Serial Number mismatch." }; + static const struct msg InvalidCommand { 1031, "Invalid command." }; + static const struct msg NoRecordsDeleted { 1032, "No records deleted." }; + static const struct msg DeviceNotConnected { 1033, "Device is not currently connected." }; + static const struct msg CannotCreateWS { + 1034, "Telemetry system could not create WS endpoint. Please try again." + }; + static const struct msg BothDeviceTypeRevision { + 1035, "Both deviceType and revision must be set." + }; + static const struct msg IdOrSerialEmpty { 1036, "SerialNumber and Id must not be empty." }; + static const struct msg MissingUserID { 1037, "Missing user ID." }; + static const struct msg IdMustBe0 { 1038, "To create a user, you must set the ID to 0" }; + static const struct msg InvalidUserRole { 1039, "Invalid userRole." }; + static const struct msg InvalidEmailAddress { 1040, "Invalid email address." }; + static const struct msg PasswordRejected { + 1041, "Password was rejected. This maybe an old password." + }; + static const struct msg InvalidIPRanges { 1042, "Invalid IP range specifications." }; + static const struct msg InvalidLOrderBy { 1043, "Invalid orderBy specification." }; + static const struct msg NeedMobileNumber { + 1044, "You must provide at least one validated phone number." + }; + static const struct msg BadMFAMethod { 1045, "MFA only supports sms or email." }; + static const struct msg InvalidCredentials { 1046, "Invalid credentials (username/password)." }; + static const struct msg InvalidPassword { + 1047, "Password does not conform to basic password rules." + }; + static const struct msg UserPendingVerification { + 1048, "User access denied pending email verification." + }; + static const struct msg PasswordMustBeChanged { 1049, "Password must be changed." }; + static const struct msg UnrecognizedRequest { + 1050, "Ill-formed request. Please consult documentation." + }; + static const struct msg MissingAuthenticationInformation { + 1051, "Missing authentication information." + }; + static const struct msg InsufficientAccessRights { + 1052, "Insufficient access rights to complete the operation." + }; + static const struct msg ExpiredToken { 1053, "Token has expired, user must login." }; + static const struct msg SubscriberMustExist { 1054, "Subscriber must exist." }; + static const struct msg AuthenticatorVerificationIncomplete { + 1055, "Authenticator validation is not complete." + }; + static const struct msg SMSCouldNotBeSentRetry { + 1056, "SMS could not be sent to validate device, try later or change the phone number." + }; + static const struct msg SMSCouldNotValidate { 1057, "Code and number could not be validated" }; + static const struct msg InvalidDeviceClass { + 1058, "Invalid device class. Must be: any, venue, entity, or subscriber" + }; + static const struct msg SerialNumberAlreadyProvisioned { + 1059, "This device has already been provisioned to a subscriber." + }; + static const struct msg SerialNumberNotTheProperClass { + 1060, "Device is not available to subscribers. It ahs been assigned to another class of " + "devices." + }; + static const struct msg UserAlreadyExists { 1061, "Username already exists." }; + static const struct msg NotImplemented { 1062, "Function not implemented." }; + static const struct msg VariableMustExist { 1063, "Specified variable does not exist." }; + static const struct msg InvalidEntityType { 1064, "Invalid entity type." }; + static const struct msg CannotDeleteSubEntity { + 1065, "Cannot delete the default subscriber entity." + }; + static const struct msg OperatorIdMustExist { 1066, "Missing or bad Operator ID" }; + static const struct msg CannotDeleteDefaultOperator { + 1067, "Cannot delete the default operator." + }; + static const struct msg CannotCreateDefaultOperator { + 1068, "Cannot create the default operator." + }; + static const struct msg InvalidRRM { 1069, "Invalid RRM value." }; + static const struct msg InvalidIPAddresses { 1070, "Invalid IP addresses." }; + static const struct msg InvalidBillingCode { 1071, "Empty of invalid billing code." }; + static const struct msg InvalidBillingPeriod { 1072, "Invalid billing period." }; + static const struct msg InvalidSubscriberId { 1073, "Invalid subscriber ID." }; + static const struct msg InvalidContactId { 1074, "Invalid contact ID." }; + static const struct msg InvalidLocationId { 1075, "Invalid location ID." }; + static const struct msg InvalidContactType { 1076, "Invalid contact type." }; + static const struct msg InvalidLocationType { 1077, "Invalid location type." }; + static const struct msg InvalidOperatorId { 1078, "Invalid operator ID." }; + static const struct msg InvalidServiceClassId { 1079, "Invalid service class ID." }; + static const struct msg InvalidSubscriberDeviceId { 1080, "Invalid subscriber device ID." }; + static const struct msg InvalidRegistrationOperatorId { + 1081, "Invalid registration operator ID." + }; + static const struct msg InvalidRegistrationOperatorName { + 1082, "Invalid registration operator name." + }; + static const struct msg RegistrationNameDuplicate { 1083, "Registration name must be unique." }; + static const struct msg SMSMFANotEnabled { + 1084, "SMS is not enabled in the security service." + }; + static const struct msg EMailMFANotEnabled { + 1085, "email is not enabled in the security service." + }; - static const struct msg TOTInvalidCode{1086,"Invalid code."}; - static const struct msg TOTInvalidIndex{1087,"Invalid index."}; - static const struct msg TOTRepeatedCode{1088,"Code is repeated. Must be new code."}; - static const struct msg TOTInvalidProtocol{1089,"Invalid protocol sequence."}; - static const struct msg TOTNoSession{1090,"No validation session present."}; + static const struct msg TOTInvalidCode { 1086, "Invalid code." }; + static const struct msg TOTInvalidIndex { 1087, "Invalid index." }; + static const struct msg TOTRepeatedCode { 1088, "Code is repeated. Must be new code." }; + static const struct msg TOTInvalidProtocol { 1089, "Invalid protocol sequence." }; + static const struct msg TOTNoSession { 1090, "No validation session present." }; - static const struct msg SignupAlreadySigned{1091,"Code is repeated. Must be new code."}; - static const struct msg SignupEmailCheck{1092,"Waiting for email check completion."}; - static const struct msg SignupWaitingForDevice{1093,"Waiting for device."}; + static const struct msg SignupAlreadySigned { 1091, "Code is repeated. Must be new code." }; + static const struct msg SignupEmailCheck { 1092, "Waiting for email check completion." }; + static const struct msg SignupWaitingForDevice { 1093, "Waiting for device." }; - static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"}; - static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."}; - static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"}; - static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."}; + static const struct msg SMSMissingPhoneNumber { 1094, "Missing phone number" }; + static const struct msg SMSTryLater { + 1095, "SMS could not be sent. Verify the number or try again later." + }; + static const struct msg SMSMissingChallenge { 1096, "Missing 'challengeCode'" }; + static const struct msg MustHaveConfigElement { 1097, "Must have 'configuration' element." }; - static const struct msg ModelIDListCannotBeEmpty{1098,"Model ID list cannot be empty."}; - static const struct msg DefConfigNameExists{1099,"Configuration name already exists."}; + static const struct msg ModelIDListCannotBeEmpty { 1098, "Model ID list cannot be empty." }; + static const struct msg DefConfigNameExists { 1099, "Configuration name already exists." }; - static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."}; - static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."}; + static const struct msg SubNoDeviceActivated { 1100, "No devices activated yet." }; + static const struct msg SubConfigNotRefreshed { 1101, "Configuration could not be refreshed." }; - static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."}; - static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."}; - static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."}; - static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."}; - static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."}; + static const struct msg ProvServiceNotAvailable { + 1102, "Provisioning service not available yet." + }; + static const struct msg SSIDInvalidPassword { + 1103, "Invalid password length. Must be 8 characters or greater, and a maximum of 32 " + "characters." + }; + static const struct msg InvalidStartingIPAddress { + 1104, "Invalid starting/ending IP address." + }; + static const struct msg SubnetFormatError { + 1105, "Subnet must be in format like 192.168.1.1/24." + }; + static const struct msg DeviceModeError { + 1106, "Device mode subnet must be of the form 192.168.1.1/24." + }; - static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."}; - static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."}; - static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."}; + static const struct msg BadDeviceMode { 1107, "Mode must be bridge, nat, or manual." }; + static const struct msg DefaultGatewayFormat { + 1108, "Default gateway must be in format like 192.168.1.1." + }; + static const struct msg PrimaryDNSFormat { + 1109, "Primary DNS must be an IP address i.e. 192.168.1.1." + }; - static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."}; - static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."}; - static const struct msg InvalidDeviceID{1112,"Invalid deviceID."}; - static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."}; - static const struct msg UnknownConfigurationSection{1114,"Unknown section."}; + static const struct msg SecondaryDNSFormat { + 1110, "Secondary DNS must be an IP address i.e. 192.168.1.1." + }; + static const struct msg BadConnectionType { + 1111, "Internet Connection must be automatic, bridge, pppoe, or manual." + }; + static const struct msg InvalidDeviceID { 1112, "Invalid deviceID." }; + static const struct msg InvalidVisibilityAttribute { 1113, "Invalid visibility attribute." }; + static const struct msg UnknownConfigurationSection { 1114, "Unknown section." }; - static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."}; - static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."}; - static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."}; - static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."}; + static const struct msg CannotValidatePhoneNumber { + 1115, "Phone number could not be validated." + }; + static const struct msg RootUsersNoOwners { 1116, "ROOT users may not have owners." }; + static const struct msg PartnerMustHaveEntity { + 1118, "Partner user must belong to an entity." + }; + static const struct msg RootCannotModifyUsers { 1119, "ROOT may not modify user roles." }; - static const struct msg CertificateNotIssued{1120,"Certificate was not issued."}; - static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."}; - static const struct msg InvalidCertificateType{1122,"Invalid certificate type."}; - static const struct msg InvalidDeviceName{1123,"Invalid device name."}; + static const struct msg CertificateNotIssued { 1120, "Certificate was not issued." }; + static const struct msg IncompleteCertificate { + 1121, "Incomplete certificate information. Cannot be downloaded. You must delete and " + "recreate." + }; + static const struct msg InvalidCertificateType { 1122, "Invalid certificate type." }; + static const struct msg InvalidDeviceName { 1123, "Invalid device name." }; - static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"}; - static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"}; - static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."}; - static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."}; - static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."}; + static const struct msg InvalidRedirectorName { 1124, "Invalid redirector name" }; + static const struct msg CommonNameAlreadyExists { + 1125, "A device/server of this name already exists" + }; + static const struct msg CertificateAlreadyExists { + 1126, "A certificate for this device already exists." + }; + static const struct msg CannotCreateCertTryAgain { + 1127, "Device certificate could not be created. Please try later." + }; + static const struct msg CouldNotRevoke { 1128, "Certificate could not be revoked." }; - static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."}; - static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."}; - static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."}; + static const struct msg CouldNotModifyCert { + 1129, "Certificate could not me modified. Please verify the information you supplied." + }; + static const struct msg BatchCertNoCreated { + 1130, "Certificates have not been created for this batch." + }; + static const struct msg BatchTooBig { + 1131, "Illegal number of MAC Addresses: must be between 1 and 1000." + }; - static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."}; - static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."}; - static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."}; - static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."}; - static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."}; - static const struct msg CouldNotPerformCommand{1137,"Could not perform command."}; + static const struct msg OutstandingJobs { + 1132, "Batch has running outstanding jobs. Please wait until job is finished." + }; + static const struct msg InvalidSMSNotificationList { 1133, "Invalid SMS Notification list." }; + static const struct msg InvalidEMailNotificationList { + 1134, "Invalid email Notification list." + }; + static const struct msg CannotChangeCommanNames { + 1135, "You cannot provide new/modified common names after jobs have been run for a batch." + }; + static const struct msg FailedToVerifyDigicert { + 1136, "Failed to verify the DigiCert information provided." + }; + static const struct msg CouldNotPerformCommand { 1137, "Could not perform command." }; - static const struct msg PoolNameInvalid{1138,"Pool name is invalid."}; - static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."}; - static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."}; - static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."}; - static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."}; - static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."}; + static const struct msg PoolNameInvalid { 1138, "Pool name is invalid." }; + static const struct msg InvalidRadiusProxyStrategy { + 1139, "Strategy name must be: random, round_robin, weighted." + }; + static const struct msg InvalidRadiusProxyMonitorMethod { + 1140, "monitorMethod must be: none, https, radius." + }; + static const struct msg MustHaveAtLeastOneRadiusServer { + 1141, "Must have at least one RADIUS server." + }; + static const struct msg InvalidRadiusServerEntry { + 1142, "RADIUS Server IP address invalid or port missing." + }; + static const struct msg InvalidRadiusServerWeigth { + 1143, "RADIUS Server IP weight cannot be 0." + }; - static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"}; - static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."}; + static const struct msg MaximumRTTYSessionsReached { + 1144, "Too many RTTY sessions currently active" + }; + static const struct msg DeviceIsAlreadyBusy { + 1145, "Device is already executing a command. Please try later." + }; - static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."}; + static const struct msg DeviceRequiresSignature { + 1146, "Device requires device signature to be provided." + }; - static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."}; - static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."}; - static const struct msg UserMustExist{1149,"User must exist."}; - static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."}; - static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."}; + static const struct msg ApiKeyNameAlreadyExists { 1147, "API Key name must be unique." }; + static const struct msg TooManyApiKeys { 1148, "Too many API Keys have already been created." }; + static const struct msg UserMustExist { 1149, "User must exist." }; + static const struct msg ApiKeyNameDoesNotExist { 1150, "API Key name does not exist." }; + static const struct msg ApiKeyDoesNotExist { 1150, "API Key does not exist." }; - static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."}; - static const struct msg InvalidURI{1152,"Invalid URI."}; - static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."}; + static const struct msg DeviceIsRestricted { + 1151, "Device is protected by regulation. This function is not allowed." + }; + static const struct msg InvalidURI { 1152, "Invalid URI." }; + static const struct msg InvalidScriptSelection { + 1153, "Only script or scriptId must be specified. Not both." + }; - static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."}; - static const struct msg AccountSuspended{1155,"You account was suspended. You can only use this site in read-only mode for now."}; - static const struct msg BatchNameAlreadyExists{1156,"Batch name must be unique."}; - static const struct msg RedirectorNameIsInvalid{1157,"Redirector name is invalid."}; - static const struct msg CertificateAlreadyBelongsToYou{1158,"The serial number already belongs to you. Please use the certificate modification API to change the redirector."}; - static const struct msg RelocationDisabledForThisDevice{1159,"Relocation disabled for this device."}; - static const struct msg CannotModifyServerCertificates{1160,"Server certificates cannot be modified."}; - - static const struct msg TransferNotInDispute{1161,"The specified transfer is not being disputed."}; - static const struct msg MissingComment{1162,"Missing comment."}; - static const struct msg EntityNotAllowedToTransfer{1163,"Entity is not allowed to transfer devices."}; - static const struct msg DailyTransferQuotaExceeded{1164,"Entity has exceeded its daily quota."}; - static const struct msg CertificateWasNotRevoked{1165,"Certificate was not revoked, so it may not be re-created."}; - static const struct msg CertificateTransferNoLongerExists{1166,"The device certificate associated with this transfer no longer seem to exist."}; - static const struct msg CertificateTransferEntityNoLongerExists{1167,"The entity tied to this transfer no longer seems to exist."}; - static const struct msg CannotRollBackDueToDigiCert{1168,"The change could not be rolled back at this time. Please try later."}; - static const struct msg CertificateTransferAlreadyRolledBack{1169,"The certificate has already been rolled back."}; - static const struct msg FirmwareBDInProgress{1170,"Firmware DB update already in progress."}; - - } + static const struct msg NoDeviceStatisticsYet { 1154, "Device statistics not available yet." }; + static const struct msg AccountSuspended { + 1155, "You account was suspended. You can only use this site in read-only mode for now." + }; + static const struct msg BatchNameAlreadyExists { 1156, "Batch name must be unique." }; + static const struct msg RedirectorNameIsInvalid { 1157, "Redirector name is invalid." }; + static const struct msg CertificateAlreadyBelongsToYou { + 1158, "The serial number already belongs to you. Please use the certificate modification " + "API to change the redirector." + }; + static const struct msg RelocationDisabledForThisDevice { + 1159, "Relocation disabled for this device." + }; + static const struct msg CannotModifyServerCertificates { + 1160, "Server certificates cannot be modified." + }; + static const struct msg TransferNotInDispute { + 1161, "The specified transfer is not being disputed." + }; + static const struct msg MissingComment { 1162, "Missing comment." }; + static const struct msg EntityNotAllowedToTransfer { + 1163, "Entity is not allowed to transfer devices." + }; + static const struct msg DailyTransferQuotaExceeded { + 1164, "Entity has exceeded its daily quota." + }; + static const struct msg CertificateWasNotRevoked { + 1165, "Certificate was not revoked, so it may not be re-created." + }; + static const struct msg CertificateTransferNoLongerExists { + 1166, "The device certificate associated with this transfer no longer seem to exist." + }; + static const struct msg CertificateTransferEntityNoLongerExists { + 1167, "The entity tied to this transfer no longer seems to exist." + }; + static const struct msg CannotRollBackDueToDigiCert { + 1168, "The change could not be rolled back at this time. Please try later." + }; + static const struct msg CertificateTransferAlreadyRolledBack { + 1169, "The certificate has already been rolled back." + }; + static const struct msg FirmwareBDInProgress { + 1170, "Firmware DB update already in progress." + }; +} // namespace OpenWifi::RESTAPI::Errors namespace OpenWifi::RESTAPI::Protocol { - static const char * CAPABILITIES = "capabilities"; - static const char * LOGS = "logs"; - static const char * HEALTHCHECKS = "healthchecks"; - static const char * STATISTICS = "statistics"; - static const char * STATUS = "status"; - static const char * SERIALNUMBER = "serialNumber"; - static const char * PERFORM = "perform"; - static const char * CONFIGURE = "configure"; - static const char * UPGRADE = "upgrade"; - static const char * REBOOT = "reboot"; - static const char * FACTORY = "factory"; - static const char * LEDS = "leds"; - static const char * TRACE = "trace"; - static const char * REQUEST = "request"; - static const char * WIFISCAN = "wifiscan"; - static const char * EVENTQUEUE = "eventqueue"; - static const char * RTTY = "rtty"; - static const char * COMMAND = "command"; - static const char * STARTDATE = "startDate"; - static const char * ENDDATE = "endDate"; - static const char * OFFSET = "offset"; - static const char * LIMIT = "limit"; - static const char * LIFETIME = "lifetime"; - static const char * UUID = "UUID"; - static const char * DATA = "data"; - static const char * CONFIGURATION = "configuration"; - static const char * WHEN = "when"; - static const char * URI = "uri"; - static const char * LOGTYPE = "logType"; - static const char * VALUES = "values"; - static const char * TYPES = "types"; - static const char * PAYLOAD = "payload"; - static const char * KEEPREDIRECTOR = "keepRedirector"; - static const char * NETWORK = "network"; - static const char * INTERFACE = "interface"; - static const char * BANDS = "bands"; - static const char * CHANNELS = "channels"; - static const char * VERBOSE = "verbose"; - static const char * MESSAGE = "message"; - static const char * STATE = "state"; - static const char * HEALTHCHECK = "healthcheck"; - static const char * PCAP_FILE_TYPE = "pcap"; - static const char * DURATION = "duration"; - static const char * NUMBEROFPACKETS = "numberOfPackets"; - static const char * FILTER = "filter"; - static const char * SELECT = "select"; - static const char * SERIALONLY = "serialOnly"; - static const char * COUNTONLY = "countOnly"; - static const char * DEVICEWITHSTATUS = "deviceWithStatus"; - static const char * DEVICESWITHSTATUS = "devicesWithStatus"; - static const char * DEVICES = "devices"; - static const char * COUNT = "count"; - static const char * SERIALNUMBERS = "serialNumbers"; - static const char * CONFIGURATIONS = "configurations"; - static const char * NAME = "name"; - static const char * COMMANDS = "commands"; - static const char * COMMANDUUID = "commandUUID"; - static const char * FIRMWARES = "firmwares"; - static const char * TOPIC = "topic"; - static const char * HOST = "host"; - static const char * OS = "os"; - static const char * HOSTNAME = "hostname"; - static const char * PROCESSORS = "processors"; - static const char * REASON = "reason"; - static const char * RELOAD = "reload"; - static const char * SUBSYSTEMS = "subsystems"; - static const char * FILEUUID = "uuid"; - static const char * USERID = "userId"; - static const char * PASSWORD = "password"; - static const char * TOKEN = "token"; - static const char * SETLOGLEVEL = "setloglevel"; - static const char * GETLOGLEVELS = "getloglevels"; - static const char * GETSUBSYSTEMNAMES = "getsubsystemnames"; - static const char * GETLOGLEVELNAMES = "getloglevelnames"; - static const char * STATS = "stats"; - static const char * PING = "ping"; - static const char * PARAMETERS = "parameters"; - static const char * VALUE = "value"; - static const char * LASTONLY = "lastOnly"; - static const char * NEWEST = "newest"; - static const char * ACTIVESCAN = "activeScan"; - static const char * OVERRIDEDFS = "override_dfs"; - static const char * LIST = "list"; - static const char * TAG = "tag"; - static const char * TAGLIST = "tagList"; - static const char * DESCRIPTION = "description"; - static const char * NOTES = "notes"; - static const char * DEVICETYPE = "deviceType"; - static const char * REVISION = "revision"; - static const char * AGES = "ages"; - static const char * REVISIONS = "revisions"; - static const char * DEVICETYPES = "deviceTypes"; - static const char * LATESTONLY = "latestOnly"; - static const char * IDONLY = "idOnly"; - static const char * REVISIONSET = "revisionSet"; - static const char * DEVICESET = "deviceSet"; - static const char * HISTORY = "history"; - static const char * ID = "id"; - static const char * VERSION = "version"; - static const char * TIMES = "times"; - static const char * UPTIME = "uptime"; - static const char * START = "start"; - static const char * DEBUG = "debug"; - static const char * SCRIPT = "script"; - static const char * TIMEOUT = "timeout"; + static const char *CAPABILITIES = "capabilities"; + static const char *LOGS = "logs"; + static const char *HEALTHCHECKS = "healthchecks"; + static const char *STATISTICS = "statistics"; + static const char *STATUS = "status"; + static const char *SERIALNUMBER = "serialNumber"; + static const char *PERFORM = "perform"; + static const char *CONFIGURE = "configure"; + static const char *UPGRADE = "upgrade"; + static const char *REBOOT = "reboot"; + static const char *FACTORY = "factory"; + static const char *LEDS = "leds"; + static const char *TRACE = "trace"; + static const char *REQUEST = "request"; + static const char *WIFISCAN = "wifiscan"; + static const char *EVENTQUEUE = "eventqueue"; + static const char *RTTY = "rtty"; + static const char *COMMAND = "command"; + static const char *STARTDATE = "startDate"; + static const char *ENDDATE = "endDate"; + static const char *OFFSET = "offset"; + static const char *LIMIT = "limit"; + static const char *LIFETIME = "lifetime"; + static const char *UUID = "UUID"; + static const char *DATA = "data"; + static const char *CONFIGURATION = "configuration"; + static const char *WHEN = "when"; + static const char *URI = "uri"; + static const char *LOGTYPE = "logType"; + static const char *VALUES = "values"; + static const char *TYPES = "types"; + static const char *PAYLOAD = "payload"; + static const char *KEEPREDIRECTOR = "keepRedirector"; + static const char *NETWORK = "network"; + static const char *INTERFACE = "interface"; + static const char *BANDS = "bands"; + static const char *CHANNELS = "channels"; + static const char *VERBOSE = "verbose"; + static const char *MESSAGE = "message"; + static const char *STATE = "state"; + static const char *HEALTHCHECK = "healthcheck"; + static const char *PCAP_FILE_TYPE = "pcap"; + static const char *DURATION = "duration"; + static const char *NUMBEROFPACKETS = "numberOfPackets"; + static const char *FILTER = "filter"; + static const char *SELECT = "select"; + static const char *SERIALONLY = "serialOnly"; + static const char *COUNTONLY = "countOnly"; + static const char *DEVICEWITHSTATUS = "deviceWithStatus"; + static const char *DEVICESWITHSTATUS = "devicesWithStatus"; + static const char *DEVICES = "devices"; + static const char *COUNT = "count"; + static const char *SERIALNUMBERS = "serialNumbers"; + static const char *CONFIGURATIONS = "configurations"; + static const char *NAME = "name"; + static const char *COMMANDS = "commands"; + static const char *COMMANDUUID = "commandUUID"; + static const char *FIRMWARES = "firmwares"; + static const char *TOPIC = "topic"; + static const char *HOST = "host"; + static const char *OS = "os"; + static const char *HOSTNAME = "hostname"; + static const char *PROCESSORS = "processors"; + static const char *REASON = "reason"; + static const char *RELOAD = "reload"; + static const char *SUBSYSTEMS = "subsystems"; + static const char *FILEUUID = "uuid"; + static const char *USERID = "userId"; + static const char *PASSWORD = "password"; + static const char *TOKEN = "token"; + static const char *SETLOGLEVEL = "setloglevel"; + static const char *GETLOGLEVELS = "getloglevels"; + static const char *GETSUBSYSTEMNAMES = "getsubsystemnames"; + static const char *GETLOGLEVELNAMES = "getloglevelnames"; + static const char *STATS = "stats"; + static const char *PING = "ping"; + static const char *PARAMETERS = "parameters"; + static const char *VALUE = "value"; + static const char *LASTONLY = "lastOnly"; + static const char *NEWEST = "newest"; + static const char *ACTIVESCAN = "activeScan"; + static const char *OVERRIDEDFS = "override_dfs"; + static const char *LIST = "list"; + static const char *TAG = "tag"; + static const char *TAGLIST = "tagList"; + static const char *DESCRIPTION = "description"; + static const char *NOTES = "notes"; + static const char *DEVICETYPE = "deviceType"; + static const char *REVISION = "revision"; + static const char *AGES = "ages"; + static const char *REVISIONS = "revisions"; + static const char *DEVICETYPES = "deviceTypes"; + static const char *LATESTONLY = "latestOnly"; + static const char *IDONLY = "idOnly"; + static const char *REVISIONSET = "revisionSet"; + static const char *DEVICESET = "deviceSet"; + static const char *HISTORY = "history"; + static const char *ID = "id"; + static const char *VERSION = "version"; + static const char *TIMES = "times"; + static const char *UPTIME = "uptime"; + static const char *START = "start"; + static const char *DEBUG = "debug"; + static const char *SCRIPT = "script"; + static const char *TIMEOUT = "timeout"; - static const char * NEWPASSWORD = "newPassword"; - static const char * USERS = "users"; - static const char * WITHEXTENDEDINFO = "withExtendedInfo"; + static const char *NEWPASSWORD = "newPassword"; + static const char *USERS = "users"; + static const char *WITHEXTENDEDINFO = "withExtendedInfo"; - static const char * ERRORTEXT = "errorText"; - static const char * ERRORCODE = "errorCode"; - static const char * AVATARID = "avatarId"; - static const char * UNNAMED = "(unnamed)"; - static const char * UNSPECIFIED = "(unspecified)"; - static const char * CONTENTDISPOSITION = "Content-Disposition"; - static const char * CONTENTTYPE = "Content-Type"; + static const char *ERRORTEXT = "errorText"; + static const char *ERRORCODE = "errorCode"; + static const char *AVATARID = "avatarId"; + static const char *UNNAMED = "(unnamed)"; + static const char *UNSPECIFIED = "(unspecified)"; + static const char *CONTENTDISPOSITION = "Content-Disposition"; + static const char *CONTENTTYPE = "Content-Type"; - static const char * REQUIREMENTS = "requirements"; - static const char * PASSWORDPATTERN = "passwordPattern"; - static const char * ACCESSPOLICY = "accessPolicy"; - static const char * PASSWORDPOLICY = "passwordPolicy"; - static const char * FORGOTPASSWORD = "forgotPassword"; - static const char * RESENDMFACODE = "resendMFACode"; - static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge"; - static const char * ME = "me"; - static const char * TELEMETRY = "telemetry"; - static const char * INTERVAL = "interval"; - static const char * UI = "UI"; - static const char * BANDWIDTH = "bandwidth"; -} + static const char *REQUIREMENTS = "requirements"; + static const char *PASSWORDPATTERN = "passwordPattern"; + static const char *ACCESSPOLICY = "accessPolicy"; + static const char *PASSWORDPOLICY = "passwordPolicy"; + static const char *FORGOTPASSWORD = "forgotPassword"; + static const char *RESENDMFACODE = "resendMFACode"; + static const char *COMPLETEMFACHALLENGE = "completeMFAChallenge"; + static const char *ME = "me"; + static const char *TELEMETRY = "telemetry"; + static const char *INTERVAL = "interval"; + static const char *UI = "UI"; + static const char *BANDWIDTH = "bandwidth"; +} // namespace OpenWifi::RESTAPI::Protocol namespace OpenWifi::uCentralProtocol { - const int SERIAL_NUMBER_LENGTH = 30; + const int SERIAL_NUMBER_LENGTH = 30; - // vocabulary used in the PROTOCOL.md file - static const char *JSONRPC = "jsonrpc"; - static const char *ID = "id"; - static const char *UUID = "uuid"; - static const char *JSONRPC_VERSION = "2.0"; - static const char *METHOD = "method"; - static const char *PARAMS = "params"; - static const char *SERIAL = "serial"; - static const char *FIRMWARE = "firmware"; - static const char *CONNECT = "connect"; - static const char *STATE = "state"; - static const char *STATUS = "status"; - static const char *ERROR = "error"; - static const char *TEXT = "text"; - static const char *HEALTHCHECK = "healthcheck"; - static const char *LOG = "log"; - static const char *CRASHLOG = "crashlog"; - static const char *PING = "ping"; - static const char *CFGPENDING = "cfgpending"; - static const char *RECOVERY = "recovery"; - static const char *COMPRESS_64 = "compress_64"; - static const char *CAPABILITIES = "capabilities"; - static const char *REQUEST_UUID = "request_uuid"; - static const char *SANITY = "sanity"; - static const char *DATA = "data"; - static const char *LOGLINES = "loglines"; - static const char *SEVERITY = "severity"; - static const char *ACTIVE = "active"; - static const char *OVERRIDEDFS = "override_dfs"; - static const char *REBOOT = "reboot"; - static const char *WHEN = "when"; - static const char *CONFIG = "config"; - static const char *EMPTY_JSON_DOC = "{}"; - static const char *RESULT = "result"; + // vocabulary used in the PROTOCOL.md file + static const char *JSONRPC = "jsonrpc"; + static const char *ID = "id"; + static const char *UUID = "uuid"; + static const char *JSONRPC_VERSION = "2.0"; + static const char *METHOD = "method"; + static const char *PARAMS = "params"; + static const char *SERIAL = "serial"; + static const char *FIRMWARE = "firmware"; + static const char *CONNECT = "connect"; + static const char *STATE = "state"; + static const char *STATUS = "status"; + static const char *ERROR = "error"; + static const char *TEXT = "text"; + static const char *HEALTHCHECK = "healthcheck"; + static const char *LOG = "log"; + static const char *CRASHLOG = "crashlog"; + static const char *PING = "ping"; + static const char *CFGPENDING = "cfgpending"; + static const char *RECOVERY = "recovery"; + static const char *COMPRESS_64 = "compress_64"; + static const char *CAPABILITIES = "capabilities"; + static const char *REQUEST_UUID = "request_uuid"; + static const char *SANITY = "sanity"; + static const char *DATA = "data"; + static const char *LOGLINES = "loglines"; + static const char *SEVERITY = "severity"; + static const char *ACTIVE = "active"; + static const char *OVERRIDEDFS = "override_dfs"; + static const char *REBOOT = "reboot"; + static const char *WHEN = "when"; + static const char *CONFIG = "config"; + static const char *EMPTY_JSON_DOC = "{}"; + static const char *RESULT = "result"; static const char *RESULT_64 = "result_64"; static const char *RESULT_SZ = "result_sz"; - static const char *REQUEST = "request"; - static const char *PERFORM = "perform"; - static const char *CONFIGURE = "configure"; - static const char *PENDING = "pending"; - static const char *SUBMITTED_BY_SYSTEM = "*system"; - static const char *URI = "uri"; - static const char *COMMAND = "command"; - static const char *PAYLOAD = "payload"; - static const char *KEEP_REDIRECTOR = "keep_redirector"; - static const char *DURATION = "duration"; - static const char *PATTERN = "pattern"; - static const char *LEDS = "leds"; + static const char *REQUEST = "request"; + static const char *PERFORM = "perform"; + static const char *CONFIGURE = "configure"; + static const char *PENDING = "pending"; + static const char *SUBMITTED_BY_SYSTEM = "*system"; + static const char *URI = "uri"; + static const char *COMMAND = "command"; + static const char *PAYLOAD = "payload"; + static const char *KEEP_REDIRECTOR = "keep_redirector"; + static const char *DURATION = "duration"; + static const char *PATTERN = "pattern"; + static const char *LEDS = "leds"; static const char *DEBUG = "debug"; - static const char *ON = "on"; - static const char *OFF = "off"; - static const char *BLINK = "blink"; - static const char *PACKETS = "packets"; - static const char *NETWORK = "network"; - static const char *INTERFACE = "interface"; - static const char *TRACE = "trace"; - static const char *WIFISCAN = "wifiscan"; - static const char *TYPES = "types"; - static const char *EVENT = "event"; - static const char *MESSAGE = "message"; - static const char *RTTY = "rtty"; - static const char *TOKEN = "token"; - static const char *SERVER = "server"; - static const char *PORT = "port"; - static const char *USER = "user"; - static const char *TIMEOUT = "timeout"; - static const char *UPGRADE = "upgrade"; - static const char *FACTORY = "factory"; - static const char *VERBOSE = "verbose"; - static const char *BANDS = "bands"; - static const char *CHANNELS = "channels"; - static const char *PASSWORD = "password"; - static const char *DEVICEUPDATE = "deviceupdate"; + static const char *ON = "on"; + static const char *OFF = "off"; + static const char *BLINK = "blink"; + static const char *PACKETS = "packets"; + static const char *NETWORK = "network"; + static const char *INTERFACE = "interface"; + static const char *TRACE = "trace"; + static const char *WIFISCAN = "wifiscan"; + static const char *TYPES = "types"; + static const char *EVENT = "event"; + static const char *MESSAGE = "message"; + static const char *RTTY = "rtty"; + static const char *TOKEN = "token"; + static const char *SERVER = "server"; + static const char *PORT = "port"; + static const char *USER = "user"; + static const char *TIMEOUT = "timeout"; + static const char *UPGRADE = "upgrade"; + static const char *FACTORY = "factory"; + static const char *VERBOSE = "verbose"; + static const char *BANDS = "bands"; + static const char *CHANNELS = "channels"; + static const char *PASSWORD = "password"; + static const char *DEVICEUPDATE = "deviceupdate"; static const char *FWSIGNATURE = "FWsignature"; static const char *SIGNATURE = "signature"; - static const char *SERIALNUMBER = "serialNumber"; - static const char *COMPATIBLE = "compatible"; - static const char *DISCONNECTION = "disconnection"; - static const char *TIMESTAMP = "timestamp"; - static const char *SYSTEM = "system"; - static const char *HOST = "host"; - static const char *CONNECTIONIP = "connectionIp"; - static const char *TELEMETRY = "telemetry"; - static const char *BANDWIDTH = "bandwidth"; + static const char *SERIALNUMBER = "serialNumber"; + static const char *COMPATIBLE = "compatible"; + static const char *DISCONNECTION = "disconnection"; + static const char *TIMESTAMP = "timestamp"; + static const char *SYSTEM = "system"; + static const char *HOST = "host"; + static const char *CONNECTIONIP = "connectionIp"; + static const char *TELEMETRY = "telemetry"; + static const char *BANDWIDTH = "bandwidth"; static const char *SCRIPT = "script"; static const char *TYPE = "type"; @@ -490,24 +633,24 @@ namespace OpenWifi::uCentralProtocol { static const char *RADIUSCOA = "coa"; static const char *RADIUSDST = "dst"; static const char *IES = "ies"; - } +} // namespace OpenWifi::uCentralProtocol namespace OpenWifi::uCentralProtocol::Events { - static const char *CONNECT = "connect"; - static const char *STATE = "state"; - static const char *HEALTHCHECK = "healthcheck"; - static const char *LOG = "log"; - static const char *CRASHLOG = "crashlog"; - static const char *PING = "ping"; - static const char *CFGPENDING = "cfgpending"; - static const char *RECOVERY = "recovery"; - static const char *TELEMETRY = "telemetry"; - static const char *DEVICEUPDATE = "deviceupdate"; + static const char *CONNECT = "connect"; + static const char *STATE = "state"; + static const char *HEALTHCHECK = "healthcheck"; + static const char *LOG = "log"; + static const char *CRASHLOG = "crashlog"; + static const char *PING = "ping"; + static const char *CFGPENDING = "cfgpending"; + static const char *RECOVERY = "recovery"; + static const char *TELEMETRY = "telemetry"; + static const char *DEVICEUPDATE = "deviceupdate"; static const char *VENUE_BROADCAST = "venue_broadcast"; static const char *ALARM = "alarm"; - enum EVENT_MSG { + enum EVENT_MSG { ET_UNKNOWN, ET_CONNECT, ET_STATE, @@ -525,41 +668,41 @@ namespace OpenWifi::uCentralProtocol::Events { ET_ALARM }; - inline EVENT_MSG EventFromString(const std::string & Method) { - if(strcmp(STATE,Method.c_str())==0) + inline EVENT_MSG EventFromString(const std::string &Method) { + if (strcmp(STATE, Method.c_str()) == 0) return ET_STATE; - else if(strcmp(HEALTHCHECK,Method.c_str())==0) + else if (strcmp(HEALTHCHECK, Method.c_str()) == 0) return ET_HEALTHCHECK; - else if(strcmp(CONNECT,Method.c_str())==0) + else if (strcmp(CONNECT, Method.c_str()) == 0) return ET_CONNECT; - else if(strcmp(CFGPENDING,Method.c_str())==0) + else if (strcmp(CFGPENDING, Method.c_str()) == 0) return ET_CFGPENDING; - else if(strcmp(CRASHLOG,Method.c_str())==0) + else if (strcmp(CRASHLOG, Method.c_str()) == 0) return ET_CRASHLOG; - else if(strcmp(DEVICEUPDATE,Method.c_str())==0) + else if (strcmp(DEVICEUPDATE, Method.c_str()) == 0) return ET_DEVICEUPDATE; - else if(strcmp(LOG,Method.c_str())==0) + else if (strcmp(LOG, Method.c_str()) == 0) return ET_LOG; - else if(strcmp(PING,Method.c_str())==0) + else if (strcmp(PING, Method.c_str()) == 0) return ET_PING; - else if(strcmp(RECOVERY,Method.c_str())==0) + else if (strcmp(RECOVERY, Method.c_str()) == 0) return ET_RECOVERY; - else if(strcmp(TELEMETRY,Method.c_str())==0) + else if (strcmp(TELEMETRY, Method.c_str()) == 0) return ET_TELEMETRY; - else if(strcmp(VENUE_BROADCAST,Method.c_str())==0) + else if (strcmp(VENUE_BROADCAST, Method.c_str()) == 0) return ET_VENUEBROADCAST; - else if(strcmp(EVENT,Method.c_str())==0) + else if (strcmp(EVENT, Method.c_str()) == 0) return ET_EVENT; - else if(strcmp(WIFISCAN,Method.c_str())==0) + else if (strcmp(WIFISCAN, Method.c_str()) == 0) return ET_WIFISCAN; - else if(strcmp(ALARM,Method.c_str())==0) + else if (strcmp(ALARM, Method.c_str()) == 0) return ET_WIFISCAN; return ET_ALARM; }; -} +} // namespace OpenWifi::uCentralProtocol::Events namespace OpenWifi::APCommands { - enum class Commands:uint8_t { + enum class Commands : uint8_t { capabilities, logs, healthchecks, @@ -581,60 +724,47 @@ namespace OpenWifi::APCommands { unknown }; - inline static const std::vector uCentralAPCommands { - RESTAPI::Protocol::CAPABILITIES, - RESTAPI::Protocol::LOGS, - RESTAPI::Protocol::HEALTHCHECKS, - RESTAPI::Protocol::STATISTICS, - RESTAPI::Protocol::STATUS, - RESTAPI::Protocol::RTTY, - RESTAPI::Protocol::CONFIGURE, - RESTAPI::Protocol::UPGRADE, - RESTAPI::Protocol::REBOOT, - RESTAPI::Protocol::FACTORY, - RESTAPI::Protocol::LEDS, - RESTAPI::Protocol::TRACE, - RESTAPI::Protocol::REQUEST, - RESTAPI::Protocol::WIFISCAN, - RESTAPI::Protocol::EVENTQUEUE, - RESTAPI::Protocol::TELEMETRY, - RESTAPI::Protocol::PING, - RESTAPI::Protocol::SCRIPT}; + inline static const std::vector uCentralAPCommands{ + RESTAPI::Protocol::CAPABILITIES, RESTAPI::Protocol::LOGS, + RESTAPI::Protocol::HEALTHCHECKS, RESTAPI::Protocol::STATISTICS, + RESTAPI::Protocol::STATUS, RESTAPI::Protocol::RTTY, + RESTAPI::Protocol::CONFIGURE, RESTAPI::Protocol::UPGRADE, + RESTAPI::Protocol::REBOOT, RESTAPI::Protocol::FACTORY, + RESTAPI::Protocol::LEDS, RESTAPI::Protocol::TRACE, + RESTAPI::Protocol::REQUEST, RESTAPI::Protocol::WIFISCAN, + RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY, + RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT}; - inline const char * to_string(Commands Cmd) { - return uCentralAPCommands[(uint8_t)Cmd]; - } + inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } inline Commands to_apcommand(const char *cmd) { - for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) { - if(strcmp(uCentralAPCommands[i],cmd)==0) + for (auto i = (uint8_t)Commands::capabilities; i != (uint8_t)Commands::unknown; ++i) { + if (strcmp(uCentralAPCommands[i], cmd) == 0) return (Commands)i; } return Commands::unknown; } -} +} // namespace OpenWifi::APCommands namespace OpenWifi::Provisioning::DeviceClass { - static const char * ANY = "any"; - static const char * SUBSCRIBER = "subscriber"; - static const char * VENUE = "venue"; - static const char * ENTITY = "entity"; + static const char *ANY = "any"; + static const char *SUBSCRIBER = "subscriber"; + static const char *VENUE = "venue"; + static const char *ENTITY = "entity"; - inline bool Validate(const char *s) { - static std::vector Values{ ANY, ENTITY, SUBSCRIBER, VENUE }; - return std::find(cbegin(Values), cend(Values), s) != cend(Values); - } + inline bool Validate(const char *s) { + static std::vector Values{ANY, ENTITY, SUBSCRIBER, VENUE}; + return std::find(cbegin(Values), cend(Values), s) != cend(Values); + } -} +} // namespace OpenWifi::Provisioning::DeviceClass -#if defined(__GNUC__ ) +#if defined(__GNUC__) #pragma GCC diagnostic pop #endif #if defined(__clang__) #pragma clang diagnostic pop #endif - - diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index a03f0a5..976bcc6 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -4,572 +4,586 @@ #include "Poco/Path.h" -#include "framework/utils.h" #include "framework/AppServiceRegistry.h" +#include "framework/utils.h" namespace OpenWifi::Utils { -bool NormalizeMac(std::string & Mac) { - Poco::replaceInPlace(Mac,":",""); - Poco::replaceInPlace(Mac,"-",""); - if(Mac.size()!=12) - return false; - for(const auto &i:Mac) { - if(!std::isxdigit(i)) + bool NormalizeMac(std::string &Mac) { + Poco::replaceInPlace(Mac, ":", ""); + Poco::replaceInPlace(Mac, "-", ""); + if (Mac.size() != 12) return false; + for (const auto &i : Mac) { + if (!std::isxdigit(i)) + return false; + } + Poco::toLowerInPlace(Mac); + return true; } - Poco::toLowerInPlace(Mac); - return true; -} -[[nodiscard]] bool ValidSerialNumber(const std::string &Serial) { - return ((Serial.size() < uCentralProtocol::SERIAL_NUMBER_LENGTH) && - std::all_of(Serial.begin(),Serial.end(),[](auto i){return std::isxdigit(i);})); -} + [[nodiscard]] bool ValidSerialNumber(const std::string &Serial) { + return ((Serial.size() < uCentralProtocol::SERIAL_NUMBER_LENGTH) && + std::all_of(Serial.begin(), Serial.end(), [](auto i) { return std::isxdigit(i); })); + } -[[nodiscard]] bool ValidUUID(const std::string &UUID) { - if(UUID.size()>36) - return false; - uint dashes=0; - return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0); -} + [[nodiscard]] bool ValidUUID(const std::string &UUID) { + if (UUID.size() > 36) + return false; + uint dashes = 0; + return (std::all_of(UUID.begin(), UUID.end(), + [&](auto i) { + if (i == '-') + dashes++; + return i == '-' || std::isxdigit(i); + })) && + (dashes > 0); + } -[[nodiscard]] std::vector Split(const std::string &List, char Delimiter ) { - std::vector ReturnList; + [[nodiscard]] std::vector Split(const std::string &List, char Delimiter) { + std::vector ReturnList; - unsigned long P=0; + unsigned long P = 0; - while(P 12) + R = R.substr(0, 12); + + char buf[18]; + + buf[0] = R[0]; + buf[1] = R[1]; + buf[2] = ':'; + buf[3] = R[2]; + buf[4] = R[3]; + buf[5] = ':'; + buf[6] = R[4]; + buf[7] = R[5]; + buf[8] = ':'; + buf[9] = R[6]; + buf[10] = R[7]; + buf[11] = ':'; + buf[12] = R[8]; + buf[13] = R[9]; + buf[14] = ':'; + buf[15] = R[10]; + buf[16] = R[11]; + buf[17] = 0; + + return buf; + } + + uint64_t MACToInt(const std::string &MAC) { + uint64_t Result = 0; + for (const auto &c : MAC) { + if (c == ':') + continue; + Result <<= 4; + if (c >= '0' && c <= '9') { + Result += (c - '0'); + } else if (c >= 'a' && c <= 'f') { + Result += (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + Result += (c - 'A' + 10); + } + } + return Result; + } + + [[nodiscard]] bool ValidHostname(const std::string &Hostname) { + static std::regex HostNameRegex( + "^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$"); + return std::regex_match(Hostname, HostNameRegex); + } + + [[nodiscard]] std::string ToHex(const std::vector &B) { + std::string R; + R.reserve(B.size() * 2); + + static const char hex[] = "0123456789abcdef"; + + for (const auto &i : B) { + R += (hex[(i & 0xf0) >> 4]); + R += (hex[(i & 0x0f)]); + } + + return R; + } + + inline static const char kEncodeLookup[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + inline static const char kPadCharacter = '='; + + using byte = std::uint8_t; + + [[nodiscard]] std::string base64encode(const byte *input, uint32_t size) { + std::string encoded; + encoded.reserve(((size / 3) + (size % 3 > 0)) * 4); + + std::uint32_t temp, i, ee; + ee = (size / 3); + + for (i = 0; i < 3 * ee; ++i) { + temp = input[i++] << 16; + temp += input[i++] << 8; + temp += input[i]; + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); + encoded.append(1, kEncodeLookup[(temp & 0x0000003F)]); + } + + switch (size % 3) { + case 1: + temp = input[i] << 16; + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(2, kPadCharacter); + break; + case 2: + temp = input[i++] << 16; + temp += input[i] << 8; + encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); + encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); + encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); + encoded.append(1, kPadCharacter); break; } - else - ReturnList.push_back(List.substr(P,P2-P)); - P=P2+1; - } - return ReturnList; -} - -[[nodiscard]] std::string FormatIPv6(const std::string & I ) -{ - if(I.substr(0,8) == "[::ffff:") - { - unsigned long PClosingBracket = I.find_first_of(']'); - - std::string ip = I.substr(8, PClosingBracket-8); - std::string port = I.substr(PClosingBracket+1); - return ip + port; + return encoded; } - return I; -} + [[nodiscard]] std::vector base64decode(const std::string &input) { + if (input.length() % 4) + throw std::runtime_error("Invalid base64 length!"); -void padTo(std::string& str, size_t num, char paddingChar) { - str.append(num - str.length() % num, paddingChar); -} + std::size_t padding = 0; -[[nodiscard]] std::string SerialToMAC(const std::string &Serial) { - std::string R = Serial; + if (input.length()) { + if (input[input.length() - 1] == kPadCharacter) + padding++; + if (input[input.length() - 2] == kPadCharacter) + padding++; + } - if(R.size()<12) - padTo(R,12,'0'); - else if (R.size()>12) - R = R.substr(0,12); + std::vector decoded; + decoded.reserve(((input.length() / 4) * 3) - padding); - char buf[18]; + std::uint32_t temp = 0; + auto it = input.begin(); - buf[0] = R[0]; buf[1] = R[1] ; buf[2] = ':' ; - buf[3] = R[2] ; buf[4] = R[3]; buf[5] = ':' ; - buf[6] = R[4]; buf[7] = R[5] ; buf[8] = ':' ; - buf[9] = R[6] ; buf[10]= R[7]; buf[11] = ':'; - buf[12] = R[8] ; buf[13]= R[9]; buf[14] = ':'; - buf[15] = R[10] ; buf[16]= R[11];buf[17] = 0; + while (it < input.end()) { + for (std::size_t i = 0; i < 4; ++i) { + temp <<= 6; + if (*it >= 0x41 && *it <= 0x5A) + temp |= *it - 0x41; + else if (*it >= 0x61 && *it <= 0x7A) + temp |= *it - 0x47; + else if (*it >= 0x30 && *it <= 0x39) + temp |= *it + 0x04; + else if (*it == 0x2B) + temp |= 0x3E; + else if (*it == 0x2F) + temp |= 0x3F; + else if (*it == kPadCharacter) { + switch (input.end() - it) { + case 1: + decoded.push_back((temp >> 16) & 0x000000FF); + decoded.push_back((temp >> 8) & 0x000000FF); + return decoded; + case 2: + decoded.push_back((temp >> 10) & 0x000000FF); + return decoded; + default: + throw std::runtime_error("Invalid padding in base64!"); + } + } else + throw std::runtime_error("Invalid character in base64!"); - return buf; -} + ++it; + } -uint64_t MACToInt(const std::string &MAC) { - uint64_t Result = 0 ; - for(const auto &c:MAC) { - if(c==':') - continue; - Result <<= 4; - if(c>='0' && c<='9') { - Result += (c - '0'); - } else if (c>='a' && c<='f') { - Result += (c-'a'+10); - } else if (c>='A' && c<='F') { - Result += (c-'A'+10); + decoded.push_back((temp >> 16) & 0x000000FF); + decoded.push_back((temp >> 8) & 0x000000FF); + decoded.push_back((temp)&0x000000FF); + } + + return decoded; + } + + bool ParseTime(const std::string &Time, int &Hours, int &Minutes, int &Seconds) { + Poco::StringTokenizer TimeTokens(Time, ":", Poco::StringTokenizer::TOK_TRIM); + + Hours = Minutes = Seconds = 0; + if (TimeTokens.count() == 1) { + Hours = std::atoi(TimeTokens[0].c_str()); + } else if (TimeTokens.count() == 2) { + Hours = std::atoi(TimeTokens[0].c_str()); + Minutes = std::atoi(TimeTokens[1].c_str()); + } else if (TimeTokens.count() == 3) { + Hours = std::atoi(TimeTokens[0].c_str()); + Minutes = std::atoi(TimeTokens[1].c_str()); + Seconds = std::atoi(TimeTokens[2].c_str()); + } else + return false; + return true; + } + + bool ParseDate(const std::string &Time, int &Year, int &Month, int &Day) { + Poco::StringTokenizer DateTokens(Time, "-", Poco::StringTokenizer::TOK_TRIM); + + Year = Month = Day = 0; + if (DateTokens.count() == 3) { + Year = std::atoi(DateTokens[0].c_str()); + Month = std::atoi(DateTokens[1].c_str()); + Day = std::atoi(DateTokens[2].c_str()); + } else + return false; + return true; + } + + bool CompareTime(int H1, int H2, int M1, int M2, int S1, int S2) { + if (H1 < H2) + return true; + if (H1 > H2) + return false; + if (M1 < M2) + return true; + if (M2 > M1) + return false; + if (S1 <= S2) + return true; + return false; + } + + [[nodiscard]] std::string LogLevelToString(int Level) { + switch (Level) { + case Poco::Message::PRIO_DEBUG: + return "debug"; + case Poco::Message::PRIO_INFORMATION: + return "information"; + case Poco::Message::PRIO_FATAL: + return "fatal"; + case Poco::Message::PRIO_WARNING: + return "warning"; + case Poco::Message::PRIO_NOTICE: + return "notice"; + case Poco::Message::PRIO_CRITICAL: + return "critical"; + case Poco::Message::PRIO_ERROR: + return "error"; + case Poco::Message::PRIO_TRACE: + return "trace"; + default: + return "none"; } } - return Result; -} -[[nodiscard]] bool ValidHostname(const std::string &Hostname) { - static std::regex HostNameRegex("^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$"); - return std::regex_match(Hostname,HostNameRegex); -} - -[[nodiscard]] std::string ToHex(const std::vector & B) { - std::string R; - R.reserve(B.size()*2); - - static const char hex[] = "0123456789abcdef"; - - for(const auto &i:B) - { - R += (hex[ (i & 0xf0) >> 4]); - R += (hex[ (i & 0x0f) ]); + [[nodiscard]] uint64_t SerialNumberToInt(const std::string &S) { + return std::stoull(S, nullptr, 16); } - return R; -} - -inline static const char kEncodeLookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -inline static const char kPadCharacter = '='; - -using byte = std::uint8_t; - -[[nodiscard]] std::string base64encode(const byte *input, uint32_t size) { - std::string encoded; - encoded.reserve(((size / 3) + (size % 3 > 0)) * 4); - - std::uint32_t temp,i,ee; - ee = (size/3); - - for (i = 0; i < 3*ee; ++i) { - temp = input[i++] << 16; - temp += input[i++] << 8; - temp += input[i]; - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); - encoded.append(1, kEncodeLookup[(temp & 0x0000003F)]); + [[nodiscard]] std::string IntToSerialNumber(uint64_t S) { + char b[16]; + for (int i = 0; i < 12; ++i) { + int B = (S & 0x0f); + if (B < 10) + b[11 - i] = B + '0'; + else + b[11 - i] = B - 10 + 'a'; + S >>= 4; + } + b[12] = 0; + return b; } - switch (size % 3) { - case 1: - temp = input[i] << 16; - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(2, kPadCharacter); - break; - case 2: - temp = input[i++] << 16; - temp += input[i] << 8; - encoded.append(1, kEncodeLookup[(temp & 0x00FC0000) >> 18]); - encoded.append(1, kEncodeLookup[(temp & 0x0003F000) >> 12]); - encoded.append(1, kEncodeLookup[(temp & 0x00000FC0) >> 6]); - encoded.append(1, kPadCharacter); - break; + [[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits) { + auto S1_i = SerialNumberToInt(S1); + auto S2_i = SerialNumberToInt(S2); + return ((S1_i >> Bits) == (S2_i >> Bits)); } - return encoded; -} + [[nodiscard]] uint64_t SerialNumberToOUI(const std::string &S) { + uint64_t Result = 0; + int Digits = 0; -[[nodiscard]] std::vector base64decode(const std::string& input) -{ - if(input.length() % 4) - throw std::runtime_error("Invalid base64 length!"); - - std::size_t padding=0; - - if(input.length()) - { - if(input[input.length() - 1] == kPadCharacter) padding++; - if(input[input.length() - 2] == kPadCharacter) padding++; + for (const auto &i : S) { + if (std::isxdigit(i)) { + if (i >= '0' && i <= '9') { + Result <<= 4; + Result += i - '0'; + } else if (i >= 'A' && i <= 'F') { + Result <<= 4; + Result += i - 'A' + 10; + } else if (i >= 'a' && i <= 'f') { + Result <<= 4; + Result += i - 'a' + 10; + } + Digits++; + if (Digits == 6) + break; + } + } + return Result; } - std::vector decoded; - decoded.reserve(((input.length() / 4) * 3) - padding); + [[nodiscard]] uint64_t GetDefaultMacAsInt64() { + uint64_t Result = 0; + auto IFaceList = Poco::Net::NetworkInterface::list(); - std::uint32_t temp=0; - auto it = input.begin(); + for (const auto &iface : IFaceList) { + if (iface.isRunning() && !iface.isLoopback()) { + auto MAC = iface.macAddress(); + for (auto const &i : MAC) { + Result <<= 8; + Result += (uint8_t)i; + } + if (Result != 0) + break; + } + } + return Result; + } - while(it < input.end()) - { - for(std::size_t i = 0; i < 4; ++i) - { - temp <<= 6; - if (*it >= 0x41 && *it <= 0x5A) temp |= *it - 0x41; - else if(*it >= 0x61 && *it <= 0x7A) temp |= *it - 0x47; - else if(*it >= 0x30 && *it <= 0x39) temp |= *it + 0x04; - else if(*it == 0x2B) temp |= 0x3E; - else if(*it == 0x2F) temp |= 0x3F; - else if(*it == kPadCharacter) - { - switch(input.end() - it) - { - case 1: - decoded.push_back((temp >> 16) & 0x000000FF); - decoded.push_back((temp >> 8 ) & 0x000000FF); - return decoded; - case 2: - decoded.push_back((temp >> 10) & 0x000000FF); - return decoded; - default: - throw std::runtime_error("Invalid padding in base64!"); + [[nodiscard]] uint64_t InitializeSystemId() { + std::random_device RDev; + std::srand(RDev()); + std::chrono::high_resolution_clock Clock; + auto Now = Clock.now().time_since_epoch().count(); + auto S = (GetDefaultMacAsInt64() + std::rand() + Now); + OpenWifi::AppServiceRegistry().Set("systemid", S); + return S; + } + + [[nodiscard]] uint64_t GetSystemId() { + uint64_t ID = 0; + if (!AppServiceRegistry().Get("systemid", ID)) { + return InitializeSystemId(); + } + return ID; + } + + [[nodiscard]] bool ValidEMailAddress(const std::string &email) { + // define a regular expression + static const std::regex pattern( + "[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*"); + // try to match the string with the regular expression + return std::regex_match(email, pattern); + } + + [[nodiscard]] std::string LoadFile(const Poco::File &F) { + std::string Result; + try { + std::ostringstream OS; + std::ifstream IF(F.path()); + Poco::StreamCopier::copyStream(IF, OS); + Result = OS.str(); + } catch (...) { + } + return Result; + } + + void ReplaceVariables(std::string &Content, const Types::StringPairVec &P) { + for (const auto &[Variable, Value] : P) { + Poco::replaceInPlace(Content, "${" + Variable + "}", Value); + } + } + + [[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F) { + const auto E = Poco::Path(F.path()).getExtension(); + if (E == "png") + return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/png"}; + if (E == "gif") + return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/gif"}; + if (E == "jpeg" || E == "jpg") + return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/jpeg"}; + if (E == "svg" || E == "svgz") + return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "image/svg+xml"}; + if (E == "html") + return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/html"}; + if (E == "css") + return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/css"}; + if (E == "js") + return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "application/javascript"}; + return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/octet-stream"}; + } + + [[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F) { + static const char hex[] = "0123456789abcdef"; + std::string Result; + try { + std::ifstream IF(F.path()); + + int Count = 0; + while (IF.good()) { + if (Count) + Result += ", "; + if ((Count % 32) == 0) + Result += "\r\n"; + Count++; + unsigned char C = IF.get(); + Result += "0x"; + Result += (char)(hex[(C & 0xf0) >> 4]); + Result += (char)(hex[(C & 0x0f)]); + } + } catch (...) { + } + return Result; + } + + [[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds) { + std::string Result; + int Days = Seconds / (24 * 60 * 60); + Seconds -= Days * (24 * 60 * 60); + int Hours = Seconds / (60 * 60); + Seconds -= Hours * (60 * 60); + int Minutes = Seconds / 60; + Seconds -= Minutes * 60; + Result = std::to_string(Days) + " days, " + std::to_string(Hours) + ":" + + std::to_string(Minutes) + ":" + std::to_string(Seconds); + return Result; + } + + [[nodiscard]] bool wgets(const std::string &URL, std::string &Response) { + try { + Poco::URI uri(URL); + Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); + + // prepare path + std::string path(uri.getPathAndQuery()); + if (path.empty()) { + path = "/"; + } + + // send request + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, + Poco::Net::HTTPMessage::HTTP_1_1); + session.sendRequest(req); + + Poco::Net::HTTPResponse res; + std::istream &is = session.receiveResponse(res); + std::ostringstream os; + + Poco::StreamCopier::copyStream(is, os); + Response = os.str(); + + return true; + } catch (...) { + } + return false; + } + + [[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName) { + try { + Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); + + // send request + Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), + Poco::Net::HTTPMessage::HTTP_1_1); + session.sendRequest(req); + + Poco::Net::HTTPResponse res; + std::istream &is = session.receiveResponse(res); + std::fstream os(FileName, + std::ios_base::trunc | std::ios_base::binary | std::ios_base::out); + Poco::StreamCopier::copyStream(is, os); + return true; + } catch (...) { + } + return false; + } + + bool ExtractBase64CompressedData(const std::string &CompressedData, + std::string &UnCompressedData, uint64_t compress_sz) { + std::istringstream ifs(CompressedData); + Poco::Base64Decoder b64in(ifs); + std::ostringstream ofs; + Poco::StreamCopier::copyStream(b64in, ofs); + + int factor = 20; + unsigned long MaxSize = compress_sz ? (unsigned long)(compress_sz + 5000) + : (unsigned long)(ofs.str().size() * factor); + while (true) { + std::vector UncompressedBuffer(MaxSize); + unsigned long FinalSize = MaxSize; + auto status = uncompress((uint8_t *)&UncompressedBuffer[0], &FinalSize, + (uint8_t *)ofs.str().c_str(), ofs.str().size()); + if (status == Z_OK) { + UncompressedBuffer[FinalSize] = 0; + UnCompressedData = (char *)&UncompressedBuffer[0]; + return true; + } + if (status == Z_BUF_ERROR) { + if (factor < 300) { + factor += 10; + MaxSize = ofs.str().size() * factor; + continue; + } else { + return false; } } - else throw std::runtime_error("Invalid character in base64!"); - - ++it; - } - - decoded.push_back((temp >> 16) & 0x000000FF); - decoded.push_back((temp >> 8 ) & 0x000000FF); - decoded.push_back((temp ) & 0x000000FF); - } - - return decoded; -} - -bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds) { - Poco::StringTokenizer TimeTokens(Time,":",Poco::StringTokenizer::TOK_TRIM); - - Hours = Minutes = Seconds = 0 ; - if(TimeTokens.count()==1) { - Hours = std::atoi(TimeTokens[0].c_str()); - } else if(TimeTokens.count()==2) { - Hours = std::atoi(TimeTokens[0].c_str()); - Minutes = std::atoi(TimeTokens[1].c_str()); - } else if(TimeTokens.count()==3) { - Hours = std::atoi(TimeTokens[0].c_str()); - Minutes = std::atoi(TimeTokens[1].c_str()); - Seconds = std::atoi(TimeTokens[2].c_str()); - } else - return false; - return true; -} - - -bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day) { - Poco::StringTokenizer DateTokens(Time,"-",Poco::StringTokenizer::TOK_TRIM); - - Year = Month = Day = 0 ; - if(DateTokens.count()==3) { - Year = std::atoi(DateTokens[0].c_str()); - Month = std::atoi(DateTokens[1].c_str()); - Day = std::atoi(DateTokens[2].c_str()); - } else - return false; - return true; -} - -bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2) { - if(H1H2) - return false; - if(M1M1) - return false; - if(S1<=S2) - return true; - return false; -} - -[[nodiscard]] std::string LogLevelToString(int Level) { - switch(Level) { - case Poco::Message::PRIO_DEBUG: return "debug"; - case Poco::Message::PRIO_INFORMATION: return "information"; - case Poco::Message::PRIO_FATAL: return "fatal"; - case Poco::Message::PRIO_WARNING: return "warning"; - case Poco::Message::PRIO_NOTICE: return "notice"; - case Poco::Message::PRIO_CRITICAL: return "critical"; - case Poco::Message::PRIO_ERROR: return "error"; - case Poco::Message::PRIO_TRACE: return "trace"; - default: return "none"; - } -} - -[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S) { - return std::stoull(S,nullptr,16); -} - -[[nodiscard]] std::string IntToSerialNumber(uint64_t S) { - char b[16]; - for(int i=0;i<12;++i) { - int B = (S & 0x0f); - if(B<10) - b[11-i] = B+'0'; - else - b[11-i] = B - 10 + 'a'; - S >>= 4 ; - } - b[12]=0; - return b; -} - - -[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits) { - auto S1_i = SerialNumberToInt(S1); - auto S2_i = SerialNumberToInt(S2); - return ((S1_i>>Bits)==(S2_i>>Bits)); -} - -[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S) { - uint64_t Result = 0 ; - int Digits=0; - - for(const auto &i:S) { - if(std::isxdigit(i)) { - if(i>='0' && i<='9') { - Result <<=4; - Result += i-'0'; - } else if(i>='A' && i<='F') { - Result <<=4; - Result += i-'A'+10; - } else if(i>='a' && i<='f') { - Result <<=4; - Result += i-'a'+10; - } - Digits++; - if(Digits==6) - break; - } - } - return Result; -} - -[[nodiscard]] uint64_t GetDefaultMacAsInt64() { - uint64_t Result=0; - auto IFaceList = Poco::Net::NetworkInterface::list(); - - for(const auto &iface:IFaceList) { - if(iface.isRunning() && !iface.isLoopback()) { - auto MAC = iface.macAddress(); - for (auto const &i : MAC) { - Result <<= 8; - Result += (uint8_t)i; - } - if (Result != 0) - break; - } - } - return Result; -} - -[[nodiscard]] uint64_t InitializeSystemId() { - std::random_device RDev; - std::srand(RDev()); - std::chrono::high_resolution_clock Clock; - auto Now = Clock.now().time_since_epoch().count(); - auto S = (GetDefaultMacAsInt64() + std::rand() + Now) ; - OpenWifi::AppServiceRegistry().Set("systemid",S); - return S; -} - -[[nodiscard]] uint64_t GetSystemId() { - uint64_t ID=0; - if(!AppServiceRegistry().Get("systemid",ID)) { - return InitializeSystemId(); - } - return ID; -} - -[[nodiscard]] bool ValidEMailAddress(const std::string &email) { - // define a regular expression - static const std::regex pattern - ("[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*"); - // try to match the string with the regular expression - return std::regex_match(email, pattern); -} - -[[nodiscard]] std::string LoadFile( const Poco::File & F) { - std::string Result; - try { - std::ostringstream OS; - std::ifstream IF(F.path()); - Poco::StreamCopier::copyStream(IF, OS); - Result = OS.str(); - } catch (...) { - - } - return Result; -} - -void ReplaceVariables( std::string & Content , const Types::StringPairVec & P) { - for(const auto &[Variable,Value]:P) { - Poco::replaceInPlace(Content,"${" + Variable + "}", Value); - } -} - -[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F) { - const auto E = Poco::Path(F.path()).getExtension(); - if(E=="png") - return MediaTypeEncoding{ .Encoding = BINARY, - .ContentType = "image/png" }; - if(E=="gif") - return MediaTypeEncoding{ .Encoding = BINARY, - .ContentType = "image/gif" }; - if(E=="jpeg" || E=="jpg") - return MediaTypeEncoding{ .Encoding = BINARY, - .ContentType = "image/jpeg" }; - if(E=="svg" || E=="svgz") - return MediaTypeEncoding{ .Encoding = PLAIN, - .ContentType = "image/svg+xml" }; - if(E=="html") - return MediaTypeEncoding{ .Encoding = PLAIN, - .ContentType = "text/html" }; - if(E=="css") - return MediaTypeEncoding{ .Encoding = PLAIN, - .ContentType = "text/css" }; - if(E=="js") - return MediaTypeEncoding{ .Encoding = PLAIN, - .ContentType = "application/javascript" }; - return MediaTypeEncoding{ .Encoding = BINARY, - .ContentType = "application/octet-stream" }; -} - -[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F) { - static const char hex[] = "0123456789abcdef"; - std::string Result; - try { - std::ifstream IF(F.path()); - - int Count = 0; - while (IF.good()) { - if (Count) - Result += ", "; - if ((Count % 32) == 0) - Result += "\r\n"; - Count++; - unsigned char C = IF.get(); - Result += "0x"; - Result += (char) (hex[(C & 0xf0) >> 4]); - Result += (char) (hex[(C & 0x0f)]); - } - } catch(...) { - - } - return Result; -} - -[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds) { - std::string Result; - int Days = Seconds / (24*60*60); - Seconds -= Days * (24*60*60); - int Hours= Seconds / (60*60); - Seconds -= Hours * (60*60); - int Minutes = Seconds / 60; - Seconds -= Minutes * 60; - Result = std::to_string(Days) +" days, " + std::to_string(Hours) + ":" + std::to_string(Minutes) + ":" + std::to_string(Seconds); - return Result; -} - -[[nodiscard]] bool wgets(const std::string &URL, std::string &Response) { - try { - Poco::URI uri(URL); - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); - - // prepare path - std::string path(uri.getPathAndQuery()); - if (path.empty()) { - path = "/"; - } - - // send request - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1); - session.sendRequest(req); - - Poco::Net::HTTPResponse res; - std::istream &is = session.receiveResponse(res); - std::ostringstream os; - - Poco::StreamCopier::copyStream(is,os); - Response = os.str(); - - return true; - } catch (...) { - - } - return false; -} - -[[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName) { - try { - Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort()); - - // send request - Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1); - session.sendRequest(req); - - Poco::Net::HTTPResponse res; - std::istream &is = session.receiveResponse(res); - std::fstream os(FileName,std::ios_base::trunc | std::ios_base::binary | std::ios_base::out); - Poco::StreamCopier::copyStream(is,os); - return true; - } catch (...) { - - } - return false; -} - -bool ExtractBase64CompressedData(const std::string &CompressedData, - std::string &UnCompressedData, uint64_t compress_sz ) { - std::istringstream ifs(CompressedData); - Poco::Base64Decoder b64in(ifs); - std::ostringstream ofs; - Poco::StreamCopier::copyStream(b64in, ofs); - - int factor = 20; - unsigned long MaxSize = compress_sz ? (unsigned long) (compress_sz + 5000) : (unsigned long) (ofs.str().size() * factor); - while(true) { - std::vector UncompressedBuffer(MaxSize); - unsigned long FinalSize = MaxSize; - auto status = uncompress((uint8_t *)&UncompressedBuffer[0], &FinalSize, - (uint8_t *)ofs.str().c_str(), ofs.str().size()); - if(status==Z_OK) { - UncompressedBuffer[FinalSize] = 0; - UnCompressedData = (char *)&UncompressedBuffer[0]; - return true; - } - if(status==Z_BUF_ERROR) { - if(factor<300) { - factor+=10; - MaxSize = ofs.str().size() * factor; - continue; - } else { - return false; - } + return false; } return false; } - return false; -} - bool IsAlphaNumeric(const std::string &s) { - return std::all_of(s.begin(),s.end(),[](char c) -> bool { return isalnum(c); }); - } + bool IsAlphaNumeric(const std::string &s) { + return std::all_of(s.begin(), s.end(), [](char c) -> bool { return isalnum(c); }); + } - std::string SanitizeToken(const std::string &Token) { - if(Token.size()>8) { - return Token.substr(0,4) + "****" + Token.substr(Token.size()-4,4); - } - return "*******"; - } + std::string SanitizeToken(const std::string &Token) { + if (Token.size() > 8) { + return Token.substr(0, 4) + "****" + Token.substr(Token.size() - 4, 4); + } + return "*******"; + } [[nodiscard]] bool ValidateURI(const std::string &uri) { try { - Poco::URI u(uri); + Poco::URI u(uri); return true; } catch (...) { - } return false; } - [[nodiscard]] std::uint64_t ConvertDate(const std::string &Date) { - Poco::DateTime DT; - int TZ; - Poco::DateTimeParser::parse(Poco::DateTimeFormat::ISO8601_FORMAT,Date,DT,TZ); - return DT.timestamp().epochTime(); - } + [[nodiscard]] std::uint64_t ConvertDate(const std::string &Date) { + Poco::DateTime DT; + int TZ; + Poco::DateTimeParser::parse(Poco::DateTimeFormat::ISO8601_FORMAT, Date, DT, TZ); + return DT.timestamp().epochTime(); + } -} +} // namespace OpenWifi::Utils diff --git a/src/framework/utils.h b/src/framework/utils.h index 7a8255a..698912f 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -4,145 +4,140 @@ #pragma once -#include #include -#include #include +#include #include #include -#include #include +#include +#include -#include "Poco/Thread.h" -#include "Poco/StringTokenizer.h" -#include "Poco/String.h" -#include "Poco/SHA2Engine.h" -#include "Poco/Message.h" -#include "Poco/StreamCopier.h" -#include "Poco/File.h" -#include "Poco/Net/NetworkInterface.h" -#include "Poco/URI.h" -#include "Poco/Net/HTTPRequest.h" -#include "Poco/Net/HTTPClientSession.h" -#include "Poco/Net/HTTPSClientSession.h" -#include "Poco/Net/HTTPResponse.h" #include "Poco/Base64Decoder.h" #include "Poco/Base64Encoder.h" +#include "Poco/File.h" +#include "Poco/Message.h" +#include "Poco/Net/HTTPClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/NetworkInterface.h" +#include "Poco/SHA2Engine.h" +#include "Poco/StreamCopier.h" +#include "Poco/String.h" +#include "Poco/StringTokenizer.h" +#include "Poco/Thread.h" +#include "Poco/URI.h" #include "Poco/zlib.h" -#include "framework/ow_constants.h" #include "framework/OpenWifiTypes.h" +#include "framework/ow_constants.h" namespace OpenWifi::Utils { inline uint64_t Now() { return std::time(nullptr); }; - bool NormalizeMac(std::string & Mac); + bool NormalizeMac(std::string &Mac); inline void SetThreadName(const char *name) { - #ifdef __linux__ +#ifdef __linux__ Poco::Thread::current()->setName(name); pthread_setname_np(pthread_self(), name); - #endif - #ifdef __APPLE__ +#endif +#ifdef __APPLE__ Poco::Thread::current()->setName(name); pthread_setname_np(name); - #endif +#endif } inline void SetThreadName(Poco::Thread &thr, const char *name) { - #ifdef __linux__ +#ifdef __linux__ thr.setName(name); pthread_setname_np(thr.tid(), name); - #endif - #ifdef __APPLE__ +#endif +#ifdef __APPLE__ thr.setName(name); - #endif +#endif } - enum MediaTypeEncodings { - PLAIN, - BINARY, - BASE64 - }; + enum MediaTypeEncodings { PLAIN, BINARY, BASE64 }; struct MediaTypeEncoding { - MediaTypeEncodings Encoding=PLAIN; - std::string ContentType; + MediaTypeEncodings Encoding = PLAIN; + std::string ContentType; }; [[nodiscard]] bool ValidSerialNumber(const std::string &Serial); [[nodiscard]] bool ValidUUID(const std::string &UUID); - [[nodiscard]] bool ValidHostname(const std::string &hostname); + [[nodiscard]] bool ValidHostname(const std::string &hostname); - template std::string ComputeHash(Args&&... args) { - Poco::SHA2Engine E; + template std::string ComputeHash(Args &&...args) { + Poco::SHA2Engine E; auto as_string = [](auto p) { - if constexpr(std::is_arithmetic_v) { + if constexpr (std::is_arithmetic_v) { return std::to_string(p); } else { return p; } }; - (E.update(as_string(args)),...); + (E.update(as_string(args)), ...); return Poco::SHA2Engine::digestToHex(E.digest()); } - [[nodiscard]] std::vector Split(const std::string &List, char Delimiter=',' ); - [[nodiscard]] std::string FormatIPv6(const std::string & I ); - void padTo(std::string& str, size_t num, char paddingChar = '\0'); + [[nodiscard]] std::vector Split(const std::string &List, char Delimiter = ','); + [[nodiscard]] std::string FormatIPv6(const std::string &I); + void padTo(std::string &str, size_t num, char paddingChar = '\0'); [[nodiscard]] std::string SerialToMAC(const std::string &Serial); uint64_t MACToInt(const std::string &MAC); - [[nodiscard]] std::string ToHex(const std::vector & B); + [[nodiscard]] std::string ToHex(const std::vector &B); using byte = std::uint8_t; [[nodiscard]] std::string base64encode(const byte *input, uint32_t size); - [[nodiscard]] std::vector base64decode(const std::string& input);; - bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds); - bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day); - bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2); + [[nodiscard]] std::vector base64decode(const std::string &input); + ; + bool ParseTime(const std::string &Time, int &Hours, int &Minutes, int &Seconds); + bool ParseDate(const std::string &Time, int &Year, int &Month, int &Day); + bool CompareTime(int H1, int H2, int M1, int M2, int S1, int S2); [[nodiscard]] std::string LogLevelToString(int Level); - [[nodiscard]] uint64_t SerialNumberToInt(const std::string & S); + [[nodiscard]] uint64_t SerialNumberToInt(const std::string &S); [[nodiscard]] std::string IntToSerialNumber(uint64_t S); - [[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits=2); - [[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S); + [[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, + int Bits = 2); + [[nodiscard]] uint64_t SerialNumberToOUI(const std::string &S); [[nodiscard]] uint64_t GetDefaultMacAsInt64(); [[nodiscard]] uint64_t InitializeSystemId(); [[nodiscard]] uint64_t GetSystemId(); [[nodiscard]] bool ValidEMailAddress(const std::string &email); - [[nodiscard]] std::string LoadFile( const Poco::File & F); - void ReplaceVariables( std::string & Content , const Types::StringPairVec & P); + [[nodiscard]] std::string LoadFile(const Poco::File &F); + void ReplaceVariables(std::string &Content, const Types::StringPairVec &P); [[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F); [[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F); [[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds); [[nodiscard]] bool wgets(const std::string &URL, std::string &Response); [[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName); [[nodiscard]] bool IsAlphaNumeric(const std::string &s); - [[nodiscard]] std::string SanitizeToken(const std::string &Token); + [[nodiscard]] std::string SanitizeToken(const std::string &Token); [[nodiscard]] bool ValidateURI(const std::string &uri); - [[nodiscard]] std::uint64_t ConvertDate(const std::string &d); + [[nodiscard]] std::uint64_t ConvertDate(const std::string &d); - template< typename T > - std::string int_to_hex( T i ) - { + template std::string int_to_hex(T i) { std::stringstream stream; - stream << std::setfill ('0') << std::setw(12) - << std::hex << i; + stream << std::setfill('0') << std::setw(12) << std::hex << i; return stream.str(); } - inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) { - while(!M.try_lock_shared() && Flag) { + inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) { + while (!M.try_lock_shared() && Flag) { Poco::Thread::yield(); Poco::Thread::trySleep((long)wait_ms); } return Flag; } - inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) { - while(!M.try_lock() && Flag) { + inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms = 100) { + while (!M.try_lock() && Flag) { Poco::Thread::yield(); Poco::Thread::trySleep(wait_ms); } @@ -150,5 +145,5 @@ namespace OpenWifi::Utils { } bool ExtractBase64CompressedData(const std::string &CompressedData, - std::string &UnCompressedData, uint64_t compress_sz ); -} + std::string &UnCompressedData, uint64_t compress_sz); +} // namespace OpenWifi::Utils diff --git a/src/seclibs/cpptotp/bytes.cpp b/src/seclibs/cpptotp/bytes.cpp index 8a60b7e..660f64f 100644 --- a/src/seclibs/cpptotp/bytes.cpp +++ b/src/seclibs/cpptotp/bytes.cpp @@ -15,327 +15,261 @@ #include #include -namespace CppTotp -{ -namespace Bytes -{ +namespace CppTotp { + namespace Bytes { -void clearByteString(ByteString * bstr) -{ - volatile Byte * bs = const_cast(bstr->data()); + void clearByteString(ByteString *bstr) { + volatile Byte *bs = const_cast(bstr->data()); - for (size_t i = 0; i < bstr->size(); ++i) - { - bs[i] = Byte(0); - } -} - -void swizzleByteStrings(ByteString * target, ByteString * source) -{ - clearByteString(target); - target->assign(*source); - clearByteString(source); -} - -static char nibbleToLCHex(uint8_t nib) -{ - if (nib < 0xa) - { - return static_cast(nib + '0'); - } - else if (nib < 0x10) - { - return static_cast((nib - 10) + 'a'); - } - else - { - assert(0 && "not actually a nibble"); - return '\0'; - } -} - -static uint8_t hexToNibble(char c) -{ - if (c >= '0' && c <= '9') - { - return static_cast(c - '0'); - } - else if (c >= 'A' && c <= 'F') - { - return static_cast(c - 'A' + 10); - } - else if (c >= 'a' && c <= 'f') - { - return static_cast(c - 'a' + 10); - } - else - { - assert(0 && "not actually a hex digit"); - return 0xff; - } -} - -std::string toHexString(const ByteString & bstr) -{ - std::string ret; - - for (Byte b : bstr) - { - ret.push_back(nibbleToLCHex((b >> 4) & 0x0F)); - ret.push_back(nibbleToLCHex((b >> 0) & 0x0F)); - } - - return ret; -} - -ByteString fromHexStringSkipUnknown(const std::string & str) -{ - std::string hstr; - for (char c : str) - { - if ( - (c >= '0' && c <= '9') || - (c >= 'A' && c <= 'F') || - (c >= 'a' && c <= 'f') - ) - { - hstr.push_back(c); - } - // ignore otherwise - } - - if (hstr.size() % 2 != 0) - { - throw std::invalid_argument("hex string (unknown characters ignored) length not divisible by 2"); - } - - ByteString ret; - for (size_t i = 0; i < hstr.size(); i += 2) - { - uint8_t top = hexToNibble(hstr[i+0]); - uint8_t btm = hexToNibble(hstr[i+1]); - - ret.push_back((top << 4) | btm); - } - return ret; -} - -Bytes::ByteString u32beToByteString(uint32_t num) -{ - Bytes::ByteString ret; - ret.push_back((num >> 24) & 0xFF); - ret.push_back((num >> 16) & 0xFF); - ret.push_back((num >> 8) & 0xFF); - ret.push_back((num >> 0) & 0xFF); - return ret; -} - -Bytes::ByteString u64beToByteString(uint64_t num) -{ - Bytes::ByteString left = u32beToByteString((num >> 32) & 0xFFFFFFFF); - Bytes::ByteString right = u32beToByteString((num >> 0) & 0xFFFFFFFF); - return left + right; -} - -static ByteString b32ChunkToBytes(const std::string & str) -{ - ByteString ret; - uint64_t whole = 0x00; - size_t padcount = 0; - size_t finalcount; - - if (str.length() != 8) - { - throw std::invalid_argument("incorrect length of base32 chunk"); - } - - size_t i; - - for (i = 0; i < 8; ++i) - { - char c = str[i]; - uint64_t bits; - - if (c == '=') - { - bits = 0; - ++padcount; - } - else if (padcount > 0) - { - throw std::invalid_argument("padding character followed by non-padding character"); - } - else if (c >= 'A' && c <= 'Z') - { - bits = static_cast(c - 'A'); - } - else if (c >= '2' && c <= '7') - { - bits = static_cast(c - '2' + 26); - } - else - { - throw std::invalid_argument("not a base32 character: " + std::string(1, c)); + for (size_t i = 0; i < bstr->size(); ++i) { + bs[i] = Byte(0); + } } - // shift into the chunk - whole |= (bits << ((7-i)*5)); - } - - switch (padcount) - { - case 0: - finalcount = 5; - break; - case 1: - finalcount = 4; - break; - case 3: - finalcount = 3; - break; - case 4: - finalcount = 2; - break; - case 6: - finalcount = 1; - break; - default: - throw std::invalid_argument("invalid number of padding characters"); - } - - for (i = 0; i < finalcount; ++i) - { - // shift out of the chunk - ret.push_back(static_cast((whole >> ((4-i)*8)) & 0xFF)); - } - - return ret; -} - -static inline uint64_t u64(uint8_t n) -{ - return static_cast(n); -} - -static std::string bytesToB32Chunk(const ByteString & bs) -{ - if (bs.size() < 1 || bs.size() > 5) - { - throw std::invalid_argument("need a chunk of at least 1 and at most 5 bytes"); - } - - uint64_t whole = 0x00; - size_t putchars = 2; - std::string ret; - - // shift into the chunk - whole |= (u64(bs[0]) << 32); - if (bs.size() > 1) - { - whole |= (u64(bs[1]) << 24); - putchars += 2; // at least 4 - } - if (bs.size() > 2) - { - whole |= (u64(bs[2]) << 16); - ++putchars; // at least 5 - } - if (bs.size() > 3) - { - whole |= (u64(bs[3]) << 8); - putchars += 2; // at least 7 - } - if (bs.size() > 4) - { - whole |= u64(bs[4]); - ++putchars; // at least 8 - } - - size_t i; - for (i = 0; i < putchars; ++i) - { - // shift out of the chunk - - Byte val = (whole >> ((7-i)*5)) & 0x1F; - - // map bits to base32 - - if (val < 26) - { - ret.push_back(static_cast(val + 'A')); + void swizzleByteStrings(ByteString *target, ByteString *source) { + clearByteString(target); + target->assign(*source); + clearByteString(source); } - else - { - ret.push_back(static_cast(val - 26 + '2')); + + static char nibbleToLCHex(uint8_t nib) { + if (nib < 0xa) { + return static_cast(nib + '0'); + } else if (nib < 0x10) { + return static_cast((nib - 10) + 'a'); + } else { + assert(0 && "not actually a nibble"); + return '\0'; + } } - } - // pad + static uint8_t hexToNibble(char c) { + if (c >= '0' && c <= '9') { + return static_cast(c - '0'); + } else if (c >= 'A' && c <= 'F') { + return static_cast(c - 'A' + 10); + } else if (c >= 'a' && c <= 'f') { + return static_cast(c - 'a' + 10); + } else { + assert(0 && "not actually a hex digit"); + return 0xff; + } + } - for (i = putchars; i < 8; ++i) - { - ret.push_back('='); - } + std::string toHexString(const ByteString &bstr) { + std::string ret; - return ret; -} + for (Byte b : bstr) { + ret.push_back(nibbleToLCHex((b >> 4) & 0x0F)); + ret.push_back(nibbleToLCHex((b >> 0) & 0x0F)); + } -ByteString fromBase32(const std::string & b32str) -{ - if (b32str.size() % 8 != 0) - { - throw std::invalid_argument("base32 string length not divisible by 8"); - } + return ret; + } - ByteString ret; + ByteString fromHexStringSkipUnknown(const std::string &str) { + std::string hstr; + for (char c : str) { + if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { + hstr.push_back(c); + } + // ignore otherwise + } - for (size_t i = 0; i < b32str.size(); i += 8) - { - std::string sub(b32str, i, 8); - ByteString chk = b32ChunkToBytes(sub); - ret.append(chk); - } + if (hstr.size() % 2 != 0) { + throw std::invalid_argument( + "hex string (unknown characters ignored) length not divisible by 2"); + } - return ret; -} + ByteString ret; + for (size_t i = 0; i < hstr.size(); i += 2) { + uint8_t top = hexToNibble(hstr[i + 0]); + uint8_t btm = hexToNibble(hstr[i + 1]); -ByteString fromUnpaddedBase32(const std::string & b32str) -{ - std::string newstr = b32str; + ret.push_back((top << 4) | btm); + } + return ret; + } - while (newstr.size() % 8 != 0) - { - newstr.push_back('='); - } + Bytes::ByteString u32beToByteString(uint32_t num) { + Bytes::ByteString ret; + ret.push_back((num >> 24) & 0xFF); + ret.push_back((num >> 16) & 0xFF); + ret.push_back((num >> 8) & 0xFF); + ret.push_back((num >> 0) & 0xFF); + return ret; + } - return fromBase32(newstr); -} + Bytes::ByteString u64beToByteString(uint64_t num) { + Bytes::ByteString left = u32beToByteString((num >> 32) & 0xFFFFFFFF); + Bytes::ByteString right = u32beToByteString((num >> 0) & 0xFFFFFFFF); + return left + right; + } -std::string toBase32(const ByteString & bs) -{ - std::string ret; + static ByteString b32ChunkToBytes(const std::string &str) { + ByteString ret; + uint64_t whole = 0x00; + size_t padcount = 0; + size_t finalcount; - size_t i, j, len; - for (j = 0; j < bs.size() / 5; ++j) - { - i = j * 5; - ByteString sub(bs, i, 5); - std::string chk = bytesToB32Chunk(sub); - ret.append(chk); - } + if (str.length() != 8) { + throw std::invalid_argument("incorrect length of base32 chunk"); + } - i = j * 5; - len = bs.size() - i; - if (len > 0) - { - // block of size < 5 remains - ByteString sub(bs, i, std::string::npos); - std::string chk = bytesToB32Chunk(sub); - ret.append(chk); - } + size_t i; - return ret; -} + for (i = 0; i < 8; ++i) { + char c = str[i]; + uint64_t bits; -} -} + if (c == '=') { + bits = 0; + ++padcount; + } else if (padcount > 0) { + throw std::invalid_argument( + "padding character followed by non-padding character"); + } else if (c >= 'A' && c <= 'Z') { + bits = static_cast(c - 'A'); + } else if (c >= '2' && c <= '7') { + bits = static_cast(c - '2' + 26); + } else { + throw std::invalid_argument("not a base32 character: " + std::string(1, c)); + } + + // shift into the chunk + whole |= (bits << ((7 - i) * 5)); + } + + switch (padcount) { + case 0: + finalcount = 5; + break; + case 1: + finalcount = 4; + break; + case 3: + finalcount = 3; + break; + case 4: + finalcount = 2; + break; + case 6: + finalcount = 1; + break; + default: + throw std::invalid_argument("invalid number of padding characters"); + } + + for (i = 0; i < finalcount; ++i) { + // shift out of the chunk + ret.push_back(static_cast((whole >> ((4 - i) * 8)) & 0xFF)); + } + + return ret; + } + + static inline uint64_t u64(uint8_t n) { return static_cast(n); } + + static std::string bytesToB32Chunk(const ByteString &bs) { + if (bs.size() < 1 || bs.size() > 5) { + throw std::invalid_argument("need a chunk of at least 1 and at most 5 bytes"); + } + + uint64_t whole = 0x00; + size_t putchars = 2; + std::string ret; + + // shift into the chunk + whole |= (u64(bs[0]) << 32); + if (bs.size() > 1) { + whole |= (u64(bs[1]) << 24); + putchars += 2; // at least 4 + } + if (bs.size() > 2) { + whole |= (u64(bs[2]) << 16); + ++putchars; // at least 5 + } + if (bs.size() > 3) { + whole |= (u64(bs[3]) << 8); + putchars += 2; // at least 7 + } + if (bs.size() > 4) { + whole |= u64(bs[4]); + ++putchars; // at least 8 + } + + size_t i; + for (i = 0; i < putchars; ++i) { + // shift out of the chunk + + Byte val = (whole >> ((7 - i) * 5)) & 0x1F; + + // map bits to base32 + + if (val < 26) { + ret.push_back(static_cast(val + 'A')); + } else { + ret.push_back(static_cast(val - 26 + '2')); + } + } + + // pad + + for (i = putchars; i < 8; ++i) { + ret.push_back('='); + } + + return ret; + } + + ByteString fromBase32(const std::string &b32str) { + if (b32str.size() % 8 != 0) { + throw std::invalid_argument("base32 string length not divisible by 8"); + } + + ByteString ret; + + for (size_t i = 0; i < b32str.size(); i += 8) { + std::string sub(b32str, i, 8); + ByteString chk = b32ChunkToBytes(sub); + ret.append(chk); + } + + return ret; + } + + ByteString fromUnpaddedBase32(const std::string &b32str) { + std::string newstr = b32str; + + while (newstr.size() % 8 != 0) { + newstr.push_back('='); + } + + return fromBase32(newstr); + } + + std::string toBase32(const ByteString &bs) { + std::string ret; + + size_t i, j, len; + for (j = 0; j < bs.size() / 5; ++j) { + i = j * 5; + ByteString sub(bs, i, 5); + std::string chk = bytesToB32Chunk(sub); + ret.append(chk); + } + + i = j * 5; + len = bs.size() - i; + if (len > 0) { + // block of size < 5 remains + ByteString sub(bs, i, std::string::npos); + std::string chk = bytesToB32Chunk(sub); + ret.append(chk); + } + + return ret; + } + + } // namespace Bytes +} // namespace CppTotp diff --git a/src/seclibs/cpptotp/bytes.h b/src/seclibs/cpptotp/bytes.h index 73d30dc..59fabcf 100644 --- a/src/seclibs/cpptotp/bytes.h +++ b/src/seclibs/cpptotp/bytes.h @@ -14,57 +14,54 @@ #include -namespace CppTotp -{ -namespace Bytes -{ +namespace CppTotp { + namespace Bytes { -/** The type of a single byte. */ -typedef uint8_t Byte; + /** The type of a single byte. */ + typedef uint8_t Byte; -/** The type of a byte string. */ -typedef std::basic_string ByteString; + /** The type of a byte string. */ + typedef std::basic_string ByteString; -/** Deletes the contents of a byte string. */ -void clearByteString(ByteString * bstr); + /** Deletes the contents of a byte string. */ + void clearByteString(ByteString *bstr); -/** Replaces target with source, clearing as much as possible. */ -void swizzleByteStrings(ByteString * target, ByteString * source); + /** Replaces target with source, clearing as much as possible. */ + void swizzleByteStrings(ByteString *target, ByteString *source); -/** Converts a byte string into a hex string. */ -std::string toHexString(const ByteString & bstr); + /** Converts a byte string into a hex string. */ + std::string toHexString(const ByteString &bstr); -/** Converts an unsigned 32-bit integer into a corresponding byte string. */ -ByteString u32beToByteString(uint32_t num); + /** Converts an unsigned 32-bit integer into a corresponding byte string. */ + ByteString u32beToByteString(uint32_t num); -/** Converts an unsigned 64-bit integer into a corresponding byte string. */ -ByteString u64beToByteString(uint64_t num); + /** Converts an unsigned 64-bit integer into a corresponding byte string. */ + ByteString u64beToByteString(uint64_t num); -/** Converts a Base32 string into the correspoding byte string. */ -ByteString fromBase32(const std::string & b32str); + /** Converts a Base32 string into the correspoding byte string. */ + ByteString fromBase32(const std::string &b32str); -/** - * Converts a potentially unpadded Base32 string into the corresponding byte - * string. - */ -ByteString fromUnpaddedBase32(const std::string & b32str); + /** + * Converts a potentially unpadded Base32 string into the corresponding byte + * string. + */ + ByteString fromUnpaddedBase32(const std::string &b32str); -/** Converts byte string into the corresponding Base32 string. */ -std::string toBase32(const ByteString & b32str); + /** Converts byte string into the corresponding Base32 string. */ + std::string toBase32(const ByteString &b32str); -/** Deletes the contets of a byte string on destruction. */ -class ByteStringDestructor -{ -private: - /** The byte string to clear. */ - ByteString * m_bs; + /** Deletes the contets of a byte string on destruction. */ + class ByteStringDestructor { + private: + /** The byte string to clear. */ + ByteString *m_bs; -public: - ByteStringDestructor(ByteString * bs) : m_bs(bs) {} - ~ByteStringDestructor() { clearByteString(m_bs); } -}; + public: + ByteStringDestructor(ByteString *bs) : m_bs(bs) {} + ~ByteStringDestructor() { clearByteString(m_bs); } + }; -} -} + } // namespace Bytes +} // namespace CppTotp #endif diff --git a/src/seclibs/cpptotp/otp.cpp b/src/seclibs/cpptotp/otp.cpp index 823d96d..93bc224 100644 --- a/src/seclibs/cpptotp/otp.cpp +++ b/src/seclibs/cpptotp/otp.cpp @@ -15,86 +15,72 @@ #include #include -namespace CppTotp -{ +namespace CppTotp { -Bytes::ByteString hmacSha1_64(const Bytes::ByteString & key, const Bytes::ByteString & msg) -{ - return hmacSha1(key, msg, 64); -} - -//uint32_t hotp(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t digitCount, HmacFunc hmacf) -uint32_t hotp(const Bytes::ByteString & key, uint64_t counter, size_t digitCount, HmacFunc hmacf) -{ - Bytes::ByteString msg = Bytes::u64beToByteString(counter); - Bytes::ByteStringDestructor dmsg(&msg); - - Bytes::ByteString hmac = hmacf(key, msg); - Bytes::ByteStringDestructor dhmac(&hmac); - - uint32_t digits10 = 1; - for (size_t i = 0; i < digitCount; ++i) - { - digits10 *= 10; + Bytes::ByteString hmacSha1_64(const Bytes::ByteString &key, const Bytes::ByteString &msg) { + return hmacSha1(key, msg, 64); } - // fetch the offset (from the last nibble) - uint8_t offset = hmac[hmac.size()-1] & 0x0F; + // uint32_t hotp(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t + // digitCount, HmacFunc hmacf) + uint32_t hotp(const Bytes::ByteString &key, uint64_t counter, size_t digitCount, + HmacFunc hmacf) { + Bytes::ByteString msg = Bytes::u64beToByteString(counter); + Bytes::ByteStringDestructor dmsg(&msg); - // fetch the four bytes from the offset - Bytes::ByteString fourWord = hmac.substr(offset, 4); - Bytes::ByteStringDestructor dfourWord(&fourWord); + Bytes::ByteString hmac = hmacf(key, msg); + Bytes::ByteStringDestructor dhmac(&hmac); - // turn them into a 32-bit integer - uint32_t ret = - (fourWord[0] << 24) | - (fourWord[1] << 16) | - (fourWord[2] << 8) | - (fourWord[3] << 0) - ; + uint32_t digits10 = 1; + for (size_t i = 0; i < digitCount; ++i) { + digits10 *= 10; + } - // snip off the MSB (to alleviate signed/unsigned troubles) - // and calculate modulo digit count - return (ret & 0x7fffffff) % digits10; -} + // fetch the offset (from the last nibble) + uint8_t offset = hmac[hmac.size() - 1] & 0x0F; -uint32_t totp(const Bytes::ByteString & key, uint64_t timeNow, uint64_t timeStart, uint64_t timeStep, size_t digitCount, HmacFunc hmacf) -{ - uint64_t timeValue = (timeNow - timeStart) / timeStep; - return hotp(key, timeValue, digitCount, hmacf); -} + // fetch the four bytes from the offset + Bytes::ByteString fourWord = hmac.substr(offset, 4); + Bytes::ByteStringDestructor dfourWord(&fourWord); -} + // turn them into a 32-bit integer + uint32_t ret = + (fourWord[0] << 24) | (fourWord[1] << 16) | (fourWord[2] << 8) | (fourWord[3] << 0); + + // snip off the MSB (to alleviate signed/unsigned troubles) + // and calculate modulo digit count + return (ret & 0x7fffffff) % digits10; + } + + uint32_t totp(const Bytes::ByteString &key, uint64_t timeNow, uint64_t timeStart, + uint64_t timeStep, size_t digitCount, HmacFunc hmacf) { + uint64_t timeValue = (timeNow - timeStart) / timeStep; + return hotp(key, timeValue, digitCount, hmacf); + } + +} // namespace CppTotp #if TEST_OTP -int main(void) -{ +int main(void) { using namespace CppTotp; - uint64_t start = 0; - uint64_t step = 30; - uint8_t digitsH = 6; - uint8_t digitsT = 8; + uint64_t start = 0; + uint64_t step = 30; + uint8_t digitsH = 6; + uint8_t digitsT = 8; const Bytes::ByteString key = reinterpret_cast("12345678901234567890"); - std::cout - << (hotp(key, 0, digitsH) == 755224) - << (hotp(key, 1, digitsH) == 287082) - << (hotp(key, 2, digitsH) == 359152) - << (hotp(key, 3, digitsH) == 969429) - << (hotp(key, 4, digitsH) == 338314) - << (hotp(key, 5, digitsH) == 254676) - << (hotp(key, 6, digitsH) == 287922) - << (hotp(key, 7, digitsH) == 162583) - << (hotp(key, 8, digitsH) == 399871) - << (hotp(key, 9, digitsH) == 520489) - << (totp(key, 59, start, step, digitsT) == 94287082) - << (totp(key, 1111111109, start, step, digitsT) == 7081804) - << (totp(key, 1111111111, start, step, digitsT) == 14050471) - << (totp(key, 1234567890, start, step, digitsT) == 89005924) - << (totp(key, 2000000000, start, step, digitsT) == 69279037) - << (totp(key, 20000000000, start, step, digitsT) == 65353130) - << std::endl; + std::cout << (hotp(key, 0, digitsH) == 755224) << (hotp(key, 1, digitsH) == 287082) + << (hotp(key, 2, digitsH) == 359152) << (hotp(key, 3, digitsH) == 969429) + << (hotp(key, 4, digitsH) == 338314) << (hotp(key, 5, digitsH) == 254676) + << (hotp(key, 6, digitsH) == 287922) << (hotp(key, 7, digitsH) == 162583) + << (hotp(key, 8, digitsH) == 399871) << (hotp(key, 9, digitsH) == 520489) + << (totp(key, 59, start, step, digitsT) == 94287082) + << (totp(key, 1111111109, start, step, digitsT) == 7081804) + << (totp(key, 1111111111, start, step, digitsT) == 14050471) + << (totp(key, 1234567890, start, step, digitsT) == 89005924) + << (totp(key, 2000000000, start, step, digitsT) == 69279037) + << (totp(key, 20000000000, start, step, digitsT) == 65353130) << std::endl; const Bytes::ByteString tutestkey = reinterpret_cast("HelloWorld"); std::cout << totp(tutestkey, time(NULL), 0, 30, 6) << std::endl; diff --git a/src/seclibs/cpptotp/otp.h b/src/seclibs/cpptotp/otp.h index 4ab2da8..9afa7c0 100644 --- a/src/seclibs/cpptotp/otp.h +++ b/src/seclibs/cpptotp/otp.h @@ -15,23 +15,25 @@ #include -namespace CppTotp -{ +namespace CppTotp { -/** The 64-bit-blocksize variant of HMAC-SHA1. */ -Bytes::ByteString hmacSha1_64(const Bytes::ByteString & key, const Bytes::ByteString & msg); + /** The 64-bit-blocksize variant of HMAC-SHA1. */ + Bytes::ByteString hmacSha1_64(const Bytes::ByteString &key, const Bytes::ByteString &msg); -/** - * Calculate the HOTP value of the given key, message and digit count. - */ -//uint32_t hotp(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t digitCount = 6, HmacFunc hmac = hmacSha1_64); -uint32_t hotp(const Bytes::ByteString & key, uint64_t counter, size_t digitCount = 6, HmacFunc hmac = hmacSha1_64); + /** + * Calculate the HOTP value of the given key, message and digit count. + */ + // uint32_t hotp(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t digitCount + // = 6, HmacFunc hmac = hmacSha1_64); + uint32_t hotp(const Bytes::ByteString &key, uint64_t counter, size_t digitCount = 6, + HmacFunc hmac = hmacSha1_64); -/** - * Calculate the TOTP value from the given parameters. - */ -uint32_t totp(const Bytes::ByteString & key, uint64_t timeNow, uint64_t timeStart, uint64_t timeStep, size_t digitCount = 6, HmacFunc hmac = hmacSha1_64); + /** + * Calculate the TOTP value from the given parameters. + */ + uint32_t totp(const Bytes::ByteString &key, uint64_t timeNow, uint64_t timeStart, + uint64_t timeStep, size_t digitCount = 6, HmacFunc hmac = hmacSha1_64); -} +} // namespace CppTotp #endif diff --git a/src/seclibs/cpptotp/sha1.cpp b/src/seclibs/cpptotp/sha1.cpp index 3c105e5..1a83afc 100644 --- a/src/seclibs/cpptotp/sha1.cpp +++ b/src/seclibs/cpptotp/sha1.cpp @@ -13,211 +13,192 @@ #include -namespace CppTotp -{ +namespace CppTotp { -static inline uint32_t lrot32(uint32_t num, uint8_t rotcount) -{ - return (num << rotcount) | (num >> (32 - rotcount)); -} - -Bytes::ByteString sha1(const Bytes::ByteString & msg) -{ - const size_t size_bytes = msg.size(); - const uint64_t size_bits = size_bytes * 8; - Bytes::ByteString bstr = msg; - Bytes::ByteStringDestructor asplode(&bstr); - - // the size of msg in bits is always even. adding the '1' bit will make - // it odd and therefore incongruent to 448 modulo 512, so we can get - // away with tacking on 0x80 and then the 0x00s. - bstr.push_back(0x80); - while (bstr.size() % (512/8) != (448/8)) - { - bstr.push_back(0x00); + static inline uint32_t lrot32(uint32_t num, uint8_t rotcount) { + return (num << rotcount) | (num >> (32 - rotcount)); } - // append the size in bits (uint64be) - bstr.append(Bytes::u64beToByteString(size_bits)); + Bytes::ByteString sha1(const Bytes::ByteString &msg) { + const size_t size_bytes = msg.size(); + const uint64_t size_bits = size_bytes * 8; + Bytes::ByteString bstr = msg; + Bytes::ByteStringDestructor asplode(&bstr); - assert(bstr.size() % (512/8) == 0); - - // initialize the hash counters - uint32_t h0 = 0x67452301; - uint32_t h1 = 0xEFCDAB89; - uint32_t h2 = 0x98BADCFE; - uint32_t h3 = 0x10325476; - uint32_t h4 = 0xC3D2E1F0; - - // for each 64-byte chunk - for (size_t i = 0; i < bstr.size()/64; ++i) - { - Bytes::ByteString chunk(bstr.begin() + i*64, bstr.begin() + (i+1)*64); - Bytes::ByteStringDestructor xplode(&chunk); - - uint32_t words[80]; - size_t j; - - // 0-15: the chunk as a sequence of 32-bit big-endian integers - for (j = 0; j < 16; ++j) - { - words[j] = - (chunk[4*j + 0] << 24) | - (chunk[4*j + 1] << 16) | - (chunk[4*j + 2] << 8) | - (chunk[4*j + 3] << 0) - ; + // the size of msg in bits is always even. adding the '1' bit will make + // it odd and therefore incongruent to 448 modulo 512, so we can get + // away with tacking on 0x80 and then the 0x00s. + bstr.push_back(0x80); + while (bstr.size() % (512 / 8) != (448 / 8)) { + bstr.push_back(0x00); } - // 16-79: derivatives of 0-15 - for (j = 16; j < 32; ++j) - { - // unoptimized - words[j] = lrot32(words[j-3] ^ words[j-8] ^ words[j-14] ^ words[j-16], 1); - } - for (j = 32; j < 80; ++j) - { - // Max Locktyuchin's optimization (SIMD) - words[j] = lrot32(words[j-6] ^ words[j-16] ^ words[j-28] ^ words[j-32], 2); + // append the size in bits (uint64be) + bstr.append(Bytes::u64beToByteString(size_bits)); + + assert(bstr.size() % (512 / 8) == 0); + + // initialize the hash counters + uint32_t h0 = 0x67452301; + uint32_t h1 = 0xEFCDAB89; + uint32_t h2 = 0x98BADCFE; + uint32_t h3 = 0x10325476; + uint32_t h4 = 0xC3D2E1F0; + + // for each 64-byte chunk + for (size_t i = 0; i < bstr.size() / 64; ++i) { + Bytes::ByteString chunk(bstr.begin() + i * 64, bstr.begin() + (i + 1) * 64); + Bytes::ByteStringDestructor xplode(&chunk); + + uint32_t words[80]; + size_t j; + + // 0-15: the chunk as a sequence of 32-bit big-endian integers + for (j = 0; j < 16; ++j) { + words[j] = (chunk[4 * j + 0] << 24) | (chunk[4 * j + 1] << 16) | + (chunk[4 * j + 2] << 8) | (chunk[4 * j + 3] << 0); + } + + // 16-79: derivatives of 0-15 + for (j = 16; j < 32; ++j) { + // unoptimized + words[j] = lrot32(words[j - 3] ^ words[j - 8] ^ words[j - 14] ^ words[j - 16], 1); + } + for (j = 32; j < 80; ++j) { + // Max Locktyuchin's optimization (SIMD) + words[j] = lrot32(words[j - 6] ^ words[j - 16] ^ words[j - 28] ^ words[j - 32], 2); + } + + // initialize hash values for the round + uint32_t a = h0; + uint32_t b = h1; + uint32_t c = h2; + uint32_t d = h3; + uint32_t e = h4; + + // the loop + for (j = 0; j < 80; ++j) { + uint32_t f = 0, k = 0; + + if (j < 20) { + f = (b & c) | ((~b) & d); + k = 0x5A827999; + } else if (j < 40) { + f = b ^ c ^ d; + k = 0x6ED9EBA1; + } else if (j < 60) { + f = (b & c) | (b & d) | (c & d); + k = 0x8F1BBCDC; + } else if (j < 80) { + f = b ^ c ^ d; + k = 0xCA62C1D6; + } else { + assert(0 && "how did I get here?"); + } + + uint32_t tmp = lrot32(a, 5) + f + e + k + words[j]; + e = d; + d = c; + c = lrot32(b, 30); + b = a; + a = tmp; + } + + // add that to the result so far + h0 += a; + h1 += b; + h2 += c; + h3 += d; + h4 += e; } - // initialize hash values for the round - uint32_t a = h0; - uint32_t b = h1; - uint32_t c = h2; - uint32_t d = h3; - uint32_t e = h4; + // assemble the digest + Bytes::ByteString first = Bytes::u32beToByteString(h0); + Bytes::ByteStringDestructor x1(&first); + Bytes::ByteString second = Bytes::u32beToByteString(h1); + Bytes::ByteStringDestructor x2(&second); + Bytes::ByteString third = Bytes::u32beToByteString(h2); + Bytes::ByteStringDestructor x3(&third); + Bytes::ByteString fourth = Bytes::u32beToByteString(h3); + Bytes::ByteStringDestructor x4(&fourth); + Bytes::ByteString fifth = Bytes::u32beToByteString(h4); + Bytes::ByteStringDestructor x5(&fifth); - // the loop - for (j = 0; j < 80; ++j) - { - uint32_t f = 0, k = 0; + return first + second + third + fourth + fifth; + } - if (j < 20) - { - f = (b & c) | ((~ b) & d); - k = 0x5A827999; - } - else if (j < 40) - { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } - else if (j < 60) - { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } - else if (j < 80) - { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - else - { - assert(0 && "how did I get here?"); - } + Bytes::ByteString hmacSha1(const Bytes::ByteString &key, const Bytes::ByteString &msg, + size_t blockSize = 64); - uint32_t tmp = lrot32(a, 5) + f + e + k + words[j]; - e = d; - d = c; - c = lrot32(b, 30); - b = a; - a = tmp; + Bytes::ByteString hmacSha1(const Bytes::ByteString &key, const Bytes::ByteString &msg, + size_t blockSize) { + Bytes::ByteString realKey = key; + Bytes::ByteStringDestructor asplode(&realKey); + + if (realKey.size() > blockSize) { + // resize by calculating hash + Bytes::ByteString newRealKey = sha1(realKey); + Bytes::swizzleByteStrings(&realKey, &newRealKey); + } + if (realKey.size() < blockSize) { + // pad with zeroes + realKey.resize(blockSize, 0x00); } - // add that to the result so far - h0 += a; - h1 += b; - h2 += c; - h3 += d; - h4 += e; + // prepare the pad keys + Bytes::ByteString innerPadKey = realKey; + Bytes::ByteStringDestructor xplodeI(&innerPadKey); + Bytes::ByteString outerPadKey = realKey; + Bytes::ByteStringDestructor xplodeO(&outerPadKey); + + // transform the pad keys + for (size_t i = 0; i < realKey.size(); ++i) { + innerPadKey[i] = innerPadKey[i] ^ 0x36; + outerPadKey[i] = outerPadKey[i] ^ 0x5c; + } + + // sha1(outerPadKey + sha1(innerPadKey + msg)) + Bytes::ByteString innerMsg = innerPadKey + msg; + Bytes::ByteStringDestructor xplodeIM(&innerMsg); + Bytes::ByteString innerHash = sha1(innerMsg); + Bytes::ByteStringDestructor xplodeIH(&innerHash); + Bytes::ByteString outerMsg = outerPadKey + innerHash; + Bytes::ByteStringDestructor xplodeOM(&outerMsg); + + return sha1(outerMsg); } - // assemble the digest - Bytes::ByteString first = Bytes::u32beToByteString(h0); - Bytes::ByteStringDestructor x1(&first); - Bytes::ByteString second = Bytes::u32beToByteString(h1); - Bytes::ByteStringDestructor x2(&second); - Bytes::ByteString third = Bytes::u32beToByteString(h2); - Bytes::ByteStringDestructor x3(&third); - Bytes::ByteString fourth = Bytes::u32beToByteString(h3); - Bytes::ByteStringDestructor x4(&fourth); - Bytes::ByteString fifth = Bytes::u32beToByteString(h4); - Bytes::ByteStringDestructor x5(&fifth); - - return first + second + third + fourth + fifth; -} - -Bytes::ByteString hmacSha1(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t blockSize = 64); - -Bytes::ByteString hmacSha1(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t blockSize) -{ - Bytes::ByteString realKey = key; - Bytes::ByteStringDestructor asplode(&realKey); - - if (realKey.size() > blockSize) - { - // resize by calculating hash - Bytes::ByteString newRealKey = sha1(realKey); - Bytes::swizzleByteStrings(&realKey, &newRealKey); - } - if (realKey.size() < blockSize) - { - // pad with zeroes - realKey.resize(blockSize, 0x00); - } - - // prepare the pad keys - Bytes::ByteString innerPadKey = realKey; - Bytes::ByteStringDestructor xplodeI(&innerPadKey); - Bytes::ByteString outerPadKey = realKey; - Bytes::ByteStringDestructor xplodeO(&outerPadKey); - - // transform the pad keys - for (size_t i = 0; i < realKey.size(); ++i) - { - innerPadKey[i] = innerPadKey[i] ^ 0x36; - outerPadKey[i] = outerPadKey[i] ^ 0x5c; - } - - // sha1(outerPadKey + sha1(innerPadKey + msg)) - Bytes::ByteString innerMsg = innerPadKey + msg; - Bytes::ByteStringDestructor xplodeIM(&innerMsg); - Bytes::ByteString innerHash = sha1(innerMsg); - Bytes::ByteStringDestructor xplodeIH(&innerHash); - Bytes::ByteString outerMsg = outerPadKey + innerHash; - Bytes::ByteStringDestructor xplodeOM(&outerMsg); - - return sha1(outerMsg); -} - -} +} // namespace CppTotp #if TEST_SHA1 -int main(void) -{ +int main(void) { using namespace CppTotp; - const uint8_t * strEmpty = reinterpret_cast(""); - const uint8_t * strDog = reinterpret_cast("The quick brown fox jumps over the lazy dog"); - const uint8_t * strCog = reinterpret_cast("The quick brown fox jumps over the lazy cog"); - const uint8_t * strKey = reinterpret_cast("key"); + const uint8_t *strEmpty = reinterpret_cast(""); + const uint8_t *strDog = + reinterpret_cast("The quick brown fox jumps over the lazy dog"); + const uint8_t *strCog = + reinterpret_cast("The quick brown fox jumps over the lazy cog"); + const uint8_t *strKey = reinterpret_cast("key"); Bytes::ByteString shaEmpty = sha1(Bytes::ByteString(strEmpty)); - Bytes::ByteString shaDog = sha1(Bytes::ByteString(strDog)); - Bytes::ByteString shaCog = sha1(Bytes::ByteString(strCog)); + Bytes::ByteString shaDog = sha1(Bytes::ByteString(strDog)); + Bytes::ByteString shaCog = sha1(Bytes::ByteString(strCog)); - Bytes::ByteString hmacShaEmpty = hmacSha1(Bytes::ByteString(), Bytes::ByteString()); + Bytes::ByteString hmacShaEmpty = hmacSha1(Bytes::ByteString(), Bytes::ByteString()); Bytes::ByteString hmacShaKeyDog = hmacSha1(strKey, strDog); - std::cout - << (Bytes::toHexString(shaEmpty) == "da39a3ee5e6b4b0d3255bfef95601890afd80709") << std::endl - << (Bytes::toHexString(shaDog) == "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12") << std::endl - << (Bytes::toHexString(shaCog) == "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3") << std::endl - << std::endl - << (Bytes::toHexString(hmacShaEmpty) == "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") << std::endl - << (Bytes::toHexString(hmacShaKeyDog) == "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9") << std::endl - << std::endl; + std::cout << (Bytes::toHexString(shaEmpty) == "da39a3ee5e6b4b0d3255bfef95601890afd80709") + << std::endl + << (Bytes::toHexString(shaDog) == "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12") + << std::endl + << (Bytes::toHexString(shaCog) == "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3") + << std::endl + << std::endl + << (Bytes::toHexString(hmacShaEmpty) == "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d") + << std::endl + << (Bytes::toHexString(hmacShaKeyDog) == "de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9") + << std::endl + << std::endl; return 0; } diff --git a/src/seclibs/cpptotp/sha1.h b/src/seclibs/cpptotp/sha1.h index 0fc39e4..d89d853 100644 --- a/src/seclibs/cpptotp/sha1.h +++ b/src/seclibs/cpptotp/sha1.h @@ -12,23 +12,23 @@ #include "bytes.h" -namespace CppTotp -{ +namespace CppTotp { -typedef Bytes::ByteString (*HmacFunc)(const Bytes::ByteString &, const Bytes::ByteString &); + typedef Bytes::ByteString (*HmacFunc)(const Bytes::ByteString &, const Bytes::ByteString &); -/** - * Calculate the SHA-1 hash of the given message. - */ -Bytes::ByteString sha1(const Bytes::ByteString & msg); + /** + * Calculate the SHA-1 hash of the given message. + */ + Bytes::ByteString sha1(const Bytes::ByteString &msg); -/** - * Calculate the HMAC-SHA-1 hash of the given key/message pair. - * - * @note Most services assume a block size of 64. - */ -Bytes::ByteString hmacSha1(const Bytes::ByteString & key, const Bytes::ByteString & msg, size_t blockSize = 64); + /** + * Calculate the HMAC-SHA-1 hash of the given key/message pair. + * + * @note Most services assume a block size of 64. + */ + Bytes::ByteString hmacSha1(const Bytes::ByteString &key, const Bytes::ByteString &msg, + size_t blockSize = 64); -} +} // namespace CppTotp #endif diff --git a/src/seclibs/qrcode/qrcodegen.cpp b/src/seclibs/qrcode/qrcodegen.cpp index a21dfdd..b66e6c2 100644 --- a/src/seclibs/qrcode/qrcodegen.cpp +++ b/src/seclibs/qrcode/qrcodegen.cpp @@ -1,9 +1,9 @@ -/* +/* * QR Code generator library (C++) - * + * * Copyright (c) Project Nayuki. (MIT License) * https://www.nayuki.io/page/qr-code-generator-library - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to @@ -21,852 +21,846 @@ * Software. */ +#include "qrcodegen.hpp" #include #include #include #include #include #include +#include #include #include -#include -#include "qrcodegen.hpp" using std::int8_t; -using std::uint8_t; using std::size_t; +using std::uint8_t; using std::vector; - namespace qrcodegen { - // Returns a string of SVG code for an image depicting the given QR Code, with the given number - // of border modules. The string always uses Unix newlines (\n), regardless of the platform. - std::string toSvgString(const QrCode &qr, int border) { - if (border < 0) - throw std::domain_error("Border must be non-negative"); - if (border > INT_MAX / 2 || border * 2 > INT_MAX - qr.getSize()) - throw std::overflow_error("Border too large"); - - std::ostringstream sb; - sb << "\n"; - sb << "\n"; - sb << "\n"; - sb << "\t\n"; - sb << "\t\n"; - sb << "\n"; - return sb.str(); - } - - // Prints the given QrCode object to the console. - void printQr(const QrCode &qr) { - int border = 4; - for (int y = -border; y < qr.getSize() + border; y++) { - for (int x = -border; x < qr.getSize() + border; x++) { - std::cout << (qr.getModule(x, y) ? "##" : " "); - } - std::cout << std::endl; - } - std::cout << std::endl; - } - -/*---- Class QrSegment ----*/ - -QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) : - modeBits(mode) { - numBitsCharCount[0] = cc0; - numBitsCharCount[1] = cc1; - numBitsCharCount[2] = cc2; -} - - -int QrSegment::Mode::getModeBits() const { - return modeBits; -} - - -int QrSegment::Mode::numCharCountBits(int ver) const { - return numBitsCharCount[(ver + 7) / 17]; -} - - -const QrSegment::Mode QrSegment::Mode::NUMERIC (0x1, 10, 12, 14); -const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13); -const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16); -const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12); -const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0); - - -QrSegment QrSegment::makeBytes(const vector &data) { - if (data.size() > static_cast(INT_MAX)) - throw std::length_error("Data too long"); - BitBuffer bb; - for (uint8_t b : data) - bb.appendBits(b, 8); - return QrSegment(Mode::BYTE, static_cast(data.size()), std::move(bb)); -} - - -QrSegment QrSegment::makeNumeric(const char *digits) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *digits != '\0'; digits++, charCount++) { - char c = *digits; - if (c < '0' || c > '9') - throw std::domain_error("String contains non-numeric characters"); - accumData = accumData * 10 + (c - '0'); - accumCount++; - if (accumCount == 3) { - bb.appendBits(static_cast(accumData), 10); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 or 2 digits remaining - bb.appendBits(static_cast(accumData), accumCount * 3 + 1); - return QrSegment(Mode::NUMERIC, charCount, std::move(bb)); -} - - -QrSegment QrSegment::makeAlphanumeric(const char *text) { - BitBuffer bb; - int accumData = 0; - int accumCount = 0; - int charCount = 0; - for (; *text != '\0'; text++, charCount++) { - const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text); - if (temp == nullptr) - throw std::domain_error("String contains unencodable characters in alphanumeric mode"); - accumData = accumData * 45 + static_cast(temp - ALPHANUMERIC_CHARSET); - accumCount++; - if (accumCount == 2) { - bb.appendBits(static_cast(accumData), 11); - accumData = 0; - accumCount = 0; - } - } - if (accumCount > 0) // 1 character remaining - bb.appendBits(static_cast(accumData), 6); - return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb)); -} - - -vector QrSegment::makeSegments(const char *text) { - // Select the most efficient segment encoding automatically - vector result; - if (*text == '\0'); // Leave result empty - else if (isNumeric(text)) - result.push_back(makeNumeric(text)); - else if (isAlphanumeric(text)) - result.push_back(makeAlphanumeric(text)); - else { - vector bytes; - for (; *text != '\0'; text++) - bytes.push_back(static_cast(*text)); - result.push_back(makeBytes(bytes)); - } - return result; -} - - -QrSegment QrSegment::makeEci(long assignVal) { - BitBuffer bb; - if (assignVal < 0) - throw std::domain_error("ECI assignment value out of range"); - else if (assignVal < (1 << 7)) - bb.appendBits(static_cast(assignVal), 8); - else if (assignVal < (1 << 14)) { - bb.appendBits(2, 2); - bb.appendBits(static_cast(assignVal), 14); - } else if (assignVal < 1000000L) { - bb.appendBits(6, 3); - bb.appendBits(static_cast(assignVal), 21); - } else - throw std::domain_error("ECI assignment value out of range"); - return QrSegment(Mode::ECI, 0, std::move(bb)); -} - - -QrSegment::QrSegment(const Mode &md, int numCh, const std::vector &dt) : - mode(&md), - numChars(numCh), - data(dt) { - if (numCh < 0) - throw std::domain_error("Invalid value"); -} - - -QrSegment::QrSegment(const Mode &md, int numCh, std::vector &&dt) : - mode(&md), - numChars(numCh), - data(std::move(dt)) { - if (numCh < 0) - throw std::domain_error("Invalid value"); -} - - -int QrSegment::getTotalBits(const vector &segs, int version) { - int result = 0; - for (const QrSegment &seg : segs) { - int ccbits = seg.mode->numCharCountBits(version); - if (seg.numChars >= (1L << ccbits)) - return -1; // The segment's length doesn't fit the field's bit width - if (4 + ccbits > INT_MAX - result) - return -1; // The sum will overflow an int type - result += 4 + ccbits; - if (seg.data.size() > static_cast(INT_MAX - result)) - return -1; // The sum will overflow an int type - result += static_cast(seg.data.size()); - } - return result; -} - - -bool QrSegment::isNumeric(const char *text) { - for (; *text != '\0'; text++) { - char c = *text; - if (c < '0' || c > '9') - return false; - } - return true; -} - - -bool QrSegment::isAlphanumeric(const char *text) { - for (; *text != '\0'; text++) { - if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr) - return false; - } - return true; -} - - -const QrSegment::Mode &QrSegment::getMode() const { - return *mode; -} - - -int QrSegment::getNumChars() const { - return numChars; -} - - -const std::vector &QrSegment::getData() const { - return data; -} - - -const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; - - - -/*---- Class QrCode ----*/ - -int QrCode::getFormatBits(Ecc ecl) { - switch (ecl) { - case Ecc::LOW : return 1; - case Ecc::MEDIUM : return 0; - case Ecc::QUARTILE: return 3; - case Ecc::HIGH : return 2; - default: throw std::logic_error("Unreachable"); - } -} - - -QrCode QrCode::encodeText(const char *text, Ecc ecl) { - vector segs = QrSegment::makeSegments(text); - return encodeSegments(segs, ecl); -} - - -QrCode QrCode::encodeBinary(const vector &data, Ecc ecl) { - vector segs{QrSegment::makeBytes(data)}; - return encodeSegments(segs, ecl); -} - - -QrCode QrCode::encodeSegments(const vector &segs, Ecc ecl, - int minVersion, int maxVersion, int mask, bool boostEcl) { - if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) - throw std::invalid_argument("Invalid value"); - - // Find the minimal version number to use - int version, dataUsedBits; - for (version = minVersion; ; version++) { - int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available - dataUsedBits = QrSegment::getTotalBits(segs, version); - if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) - break; // This version number is found to be suitable - if (version >= maxVersion) { // All versions in the range could not fit the given data - std::ostringstream sb; - if (dataUsedBits == -1) - sb << "Segment too long"; - else { - sb << "Data length = " << dataUsedBits << " bits, "; - sb << "Max capacity = " << dataCapacityBits << " bits"; - } - throw data_too_long(sb.str()); - } - } - assert(dataUsedBits != -1); - - // Increase the error correction level while the data still fits in the current version number - for (Ecc newEcl : {Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high - if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8) - ecl = newEcl; - } - - // Concatenate all segments to create the data bit string - BitBuffer bb; - for (const QrSegment &seg : segs) { - bb.appendBits(static_cast(seg.getMode().getModeBits()), 4); - bb.appendBits(static_cast(seg.getNumChars()), seg.getMode().numCharCountBits(version)); - bb.insert(bb.end(), seg.getData().begin(), seg.getData().end()); - } - assert(bb.size() == static_cast(dataUsedBits)); - - // Add terminator and pad up to a byte if applicable - size_t dataCapacityBits = static_cast(getNumDataCodewords(version, ecl)) * 8; - assert(bb.size() <= dataCapacityBits); - bb.appendBits(0, std::min(4, static_cast(dataCapacityBits - bb.size()))); - bb.appendBits(0, (8 - static_cast(bb.size() % 8)) % 8); - assert(bb.size() % 8 == 0); - - // Pad with alternating bytes until data capacity is reached - for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) - bb.appendBits(padByte, 8); - - // Pack bits into bytes in big endian - vector dataCodewords(bb.size() / 8); - for (size_t i = 0; i < bb.size(); i++) - dataCodewords.at(i >> 3) |= (bb.at(i) ? 1 : 0) << (7 - (i & 7)); - - // Create the QR Code object - return QrCode(version, ecl, dataCodewords, mask); -} - - -QrCode::QrCode(int ver, Ecc ecl, const vector &dataCodewords, int msk) : - // Initialize fields and check arguments - version(ver), - errorCorrectionLevel(ecl) { - if (ver < MIN_VERSION || ver > MAX_VERSION) - throw std::domain_error("Version value out of range"); - if (msk < -1 || msk > 7) - throw std::domain_error("Mask value out of range"); - size = ver * 4 + 17; - size_t sz = static_cast(size); - modules = vector >(sz, vector(sz)); // Initially all light - isFunction = vector >(sz, vector(sz)); - - // Compute ECC, draw modules - drawFunctionPatterns(); - const vector allCodewords = addEccAndInterleave(dataCodewords); - drawCodewords(allCodewords); - - // Do masking - if (msk == -1) { // Automatically choose best mask - long minPenalty = LONG_MAX; - for (int i = 0; i < 8; i++) { - applyMask(i); - drawFormatBits(i); - long penalty = getPenaltyScore(); - if (penalty < minPenalty) { - msk = i; - minPenalty = penalty; - } - applyMask(i); // Undoes the mask due to XOR - } - } - assert(0 <= msk && msk <= 7); - mask = msk; - applyMask(msk); // Apply the final choice of mask - drawFormatBits(msk); // Overwrite old format bits - - isFunction.clear(); - isFunction.shrink_to_fit(); -} - - -int QrCode::getVersion() const { - return version; -} - - -int QrCode::getSize() const { - return size; -} - - -QrCode::Ecc QrCode::getErrorCorrectionLevel() const { - return errorCorrectionLevel; -} - - -int QrCode::getMask() const { - return mask; -} - - -bool QrCode::getModule(int x, int y) const { - return 0 <= x && x < size && 0 <= y && y < size && module(x, y); -} - - -void QrCode::drawFunctionPatterns() { - // Draw horizontal and vertical timing patterns - for (int i = 0; i < size; i++) { - setFunctionModule(6, i, i % 2 == 0); - setFunctionModule(i, 6, i % 2 == 0); - } - - // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) - drawFinderPattern(3, 3); - drawFinderPattern(size - 4, 3); - drawFinderPattern(3, size - 4); - - // Draw numerous alignment patterns - const vector alignPatPos = getAlignmentPatternPositions(); - size_t numAlign = alignPatPos.size(); - for (size_t i = 0; i < numAlign; i++) { - for (size_t j = 0; j < numAlign; j++) { - // Don't draw on the three finder corners - if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0))) - drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j)); - } - } - - // Draw configuration data - drawFormatBits(0); // Dummy mask value; overwritten later in the constructor - drawVersion(); -} - - -void QrCode::drawFormatBits(int msk) { - // Calculate error correction code and pack bits - int data = getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3 - int rem = data; - for (int i = 0; i < 10; i++) - rem = (rem << 1) ^ ((rem >> 9) * 0x537); - int bits = (data << 10 | rem) ^ 0x5412; // uint15 - assert(bits >> 15 == 0); - - // Draw first copy - for (int i = 0; i <= 5; i++) - setFunctionModule(8, i, getBit(bits, i)); - setFunctionModule(8, 7, getBit(bits, 6)); - setFunctionModule(8, 8, getBit(bits, 7)); - setFunctionModule(7, 8, getBit(bits, 8)); - for (int i = 9; i < 15; i++) - setFunctionModule(14 - i, 8, getBit(bits, i)); - - // Draw second copy - for (int i = 0; i < 8; i++) - setFunctionModule(size - 1 - i, 8, getBit(bits, i)); - for (int i = 8; i < 15; i++) - setFunctionModule(8, size - 15 + i, getBit(bits, i)); - setFunctionModule(8, size - 8, true); // Always dark -} - - -void QrCode::drawVersion() { - if (version < 7) - return; - - // Calculate error correction code and pack bits - int rem = version; // version is uint6, in the range [7, 40] - for (int i = 0; i < 12; i++) - rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); - long bits = static_cast(version) << 12 | rem; // uint18 - assert(bits >> 18 == 0); - - // Draw two copies - for (int i = 0; i < 18; i++) { - bool bit = getBit(bits, i); - int a = size - 11 + i % 3; - int b = i / 3; - setFunctionModule(a, b, bit); - setFunctionModule(b, a, bit); - } -} - - -void QrCode::drawFinderPattern(int x, int y) { - for (int dy = -4; dy <= 4; dy++) { - for (int dx = -4; dx <= 4; dx++) { - int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm - int xx = x + dx, yy = y + dy; - if (0 <= xx && xx < size && 0 <= yy && yy < size) - setFunctionModule(xx, yy, dist != 2 && dist != 4); - } - } -} - - -void QrCode::drawAlignmentPattern(int x, int y) { - for (int dy = -2; dy <= 2; dy++) { - for (int dx = -2; dx <= 2; dx++) - setFunctionModule(x + dx, y + dy, std::max(std::abs(dx), std::abs(dy)) != 1); - } -} - - -void QrCode::setFunctionModule(int x, int y, bool isDark) { - size_t ux = static_cast(x); - size_t uy = static_cast(y); - modules .at(uy).at(ux) = isDark; - isFunction.at(uy).at(ux) = true; -} - - -bool QrCode::module(int x, int y) const { - return modules.at(static_cast(y)).at(static_cast(x)); -} - - -vector QrCode::addEccAndInterleave(const vector &data) const { - if (data.size() != static_cast(getNumDataCodewords(version, errorCorrectionLevel))) - throw std::invalid_argument("Invalid argument"); - - // Calculate parameter numbers - int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast(errorCorrectionLevel)][version]; - int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast(errorCorrectionLevel)][version]; - int rawCodewords = getNumRawDataModules(version) / 8; - int numShortBlocks = numBlocks - rawCodewords % numBlocks; - int shortBlockLen = rawCodewords / numBlocks; - - // Split data into blocks and append ECC to each block - vector > blocks; - const vector rsDiv = reedSolomonComputeDivisor(blockEccLen); - for (int i = 0, k = 0; i < numBlocks; i++) { - vector dat(data.cbegin() + k, data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1))); - k += static_cast(dat.size()); - const vector ecc = reedSolomonComputeRemainder(dat, rsDiv); - if (i < numShortBlocks) - dat.push_back(0); - dat.insert(dat.end(), ecc.cbegin(), ecc.cend()); - blocks.push_back(std::move(dat)); - } - - // Interleave (not concatenate) the bytes from every block into a single sequence - vector result; - for (size_t i = 0; i < blocks.at(0).size(); i++) { - for (size_t j = 0; j < blocks.size(); j++) { - // Skip the padding byte in short blocks - if (i != static_cast(shortBlockLen - blockEccLen) || j >= static_cast(numShortBlocks)) - result.push_back(blocks.at(j).at(i)); - } - } - assert(result.size() == static_cast(rawCodewords)); - return result; -} - - -void QrCode::drawCodewords(const vector &data) { - if (data.size() != static_cast(getNumRawDataModules(version) / 8)) - throw std::invalid_argument("Invalid argument"); - - size_t i = 0; // Bit index into the data - // Do the funny zigzag scan - for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair - if (right == 6) - right = 5; - for (int vert = 0; vert < size; vert++) { // Vertical counter - for (int j = 0; j < 2; j++) { - size_t x = static_cast(right - j); // Actual x coordinate - bool upward = ((right + 1) & 2) == 0; - size_t y = static_cast(upward ? size - 1 - vert : vert); // Actual y coordinate - if (!isFunction.at(y).at(x) && i < data.size() * 8) { - modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast(i & 7)); - i++; + // Returns a string of SVG code for an image depicting the given QR Code, with the given number + // of border modules. The string always uses Unix newlines (\n), regardless of the platform. + std::string toSvgString(const QrCode &qr, int border) { + if (border < 0) + throw std::domain_error("Border must be non-negative"); + if (border > INT_MAX / 2 || border * 2 > INT_MAX - qr.getSize()) + throw std::overflow_error("Border too large"); + + std::ostringstream sb; + sb << "\n"; + sb << "\n"; + sb << "\n"; + sb << "\t\n"; + sb << "\t\n"; + sb << "\n"; + return sb.str(); } - assert(i == data.size() * 8); -} - -void QrCode::applyMask(int msk) { - if (msk < 0 || msk > 7) - throw std::domain_error("Mask value out of range"); - size_t sz = static_cast(size); - for (size_t y = 0; y < sz; y++) { - for (size_t x = 0; x < sz; x++) { - bool invert; - switch (msk) { - case 0: invert = (x + y) % 2 == 0; break; - case 1: invert = y % 2 == 0; break; - case 2: invert = x % 3 == 0; break; - case 3: invert = (x + y) % 3 == 0; break; - case 4: invert = (x / 3 + y / 2) % 2 == 0; break; - case 5: invert = x * y % 2 + x * y % 3 == 0; break; - case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; - case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; - default: throw std::logic_error("Unreachable"); + // Prints the given QrCode object to the console. + void printQr(const QrCode &qr) { + int border = 4; + for (int y = -border; y < qr.getSize() + border; y++) { + for (int x = -border; x < qr.getSize() + border; x++) { + std::cout << (qr.getModule(x, y) ? "##" : " "); } - modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x)); + std::cout << std::endl; } + std::cout << std::endl; } -} + /*---- Class QrSegment ----*/ -long QrCode::getPenaltyScore() const { - long result = 0; - - // Adjacent modules in row having same color, and finder-like patterns - for (int y = 0; y < size; y++) { - bool runColor = false; - int runX = 0; - std::array runHistory = {}; - for (int x = 0; x < size; x++) { - if (module(x, y) == runColor) { - runX++; - if (runX == 5) - result += PENALTY_N1; - else if (runX > 5) - result++; - } else { - finderPenaltyAddHistory(runX, runHistory); - if (!runColor) - result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; - runColor = module(x, y); - runX = 1; + QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) : modeBits(mode) { + numBitsCharCount[0] = cc0; + numBitsCharCount[1] = cc1; + numBitsCharCount[2] = cc2; + } + + int QrSegment::Mode::getModeBits() const { return modeBits; } + + int QrSegment::Mode::numCharCountBits(int ver) const { + return numBitsCharCount[(ver + 7) / 17]; + } + + const QrSegment::Mode QrSegment::Mode::NUMERIC(0x1, 10, 12, 14); + const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13); + const QrSegment::Mode QrSegment::Mode::BYTE(0x4, 8, 16, 16); + const QrSegment::Mode QrSegment::Mode::KANJI(0x8, 8, 10, 12); + const QrSegment::Mode QrSegment::Mode::ECI(0x7, 0, 0, 0); + + QrSegment QrSegment::makeBytes(const vector &data) { + if (data.size() > static_cast(INT_MAX)) + throw std::length_error("Data too long"); + BitBuffer bb; + for (uint8_t b : data) + bb.appendBits(b, 8); + return QrSegment(Mode::BYTE, static_cast(data.size()), std::move(bb)); + } + + QrSegment QrSegment::makeNumeric(const char *digits) { + BitBuffer bb; + int accumData = 0; + int accumCount = 0; + int charCount = 0; + for (; *digits != '\0'; digits++, charCount++) { + char c = *digits; + if (c < '0' || c > '9') + throw std::domain_error("String contains non-numeric characters"); + accumData = accumData * 10 + (c - '0'); + accumCount++; + if (accumCount == 3) { + bb.appendBits(static_cast(accumData), 10); + accumData = 0; + accumCount = 0; } } - result += finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3; + if (accumCount > 0) // 1 or 2 digits remaining + bb.appendBits(static_cast(accumData), accumCount * 3 + 1); + return QrSegment(Mode::NUMERIC, charCount, std::move(bb)); } - // Adjacent modules in column having same color, and finder-like patterns - for (int x = 0; x < size; x++) { - bool runColor = false; - int runY = 0; - std::array runHistory = {}; - for (int y = 0; y < size; y++) { - if (module(x, y) == runColor) { - runY++; - if (runY == 5) - result += PENALTY_N1; - else if (runY > 5) - result++; - } else { - finderPenaltyAddHistory(runY, runHistory); - if (!runColor) - result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; - runColor = module(x, y); - runY = 1; + + QrSegment QrSegment::makeAlphanumeric(const char *text) { + BitBuffer bb; + int accumData = 0; + int accumCount = 0; + int charCount = 0; + for (; *text != '\0'; text++, charCount++) { + const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text); + if (temp == nullptr) + throw std::domain_error( + "String contains unencodable characters in alphanumeric mode"); + accumData = accumData * 45 + static_cast(temp - ALPHANUMERIC_CHARSET); + accumCount++; + if (accumCount == 2) { + bb.appendBits(static_cast(accumData), 11); + accumData = 0; + accumCount = 0; } } - result += finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3; + if (accumCount > 0) // 1 character remaining + bb.appendBits(static_cast(accumData), 6); + return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb)); } - - // 2*2 blocks of modules having same color - for (int y = 0; y < size - 1; y++) { - for (int x = 0; x < size - 1; x++) { - bool color = module(x, y); - if ( color == module(x + 1, y) && - color == module(x, y + 1) && - color == module(x + 1, y + 1)) - result += PENALTY_N2; - } - } - - // Balance of dark and light modules - int dark = 0; - for (const vector &row : modules) { - for (bool color : row) { - if (color) - dark++; - } - } - int total = size * size; // Note that size is odd, so dark/total != 1/2 - // Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)% - int k = static_cast((std::abs(dark * 20L - total * 10L) + total - 1) / total) - 1; - assert(0 <= k && k <= 9); - result += k * PENALTY_N4; - assert(0 <= result && result <= 2568888L); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4 - return result; -} - -vector QrCode::getAlignmentPatternPositions() const { - if (version == 1) - return vector(); - else { - int numAlign = version / 7 + 2; - int step = (version == 32) ? 26 : - (version * 4 + numAlign * 2 + 1) / (numAlign * 2 - 2) * 2; - vector result; - for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) - result.insert(result.begin(), pos); - result.insert(result.begin(), 6); + vector QrSegment::makeSegments(const char *text) { + // Select the most efficient segment encoding automatically + vector result; + if (*text == '\0') + ; // Leave result empty + else if (isNumeric(text)) + result.push_back(makeNumeric(text)); + else if (isAlphanumeric(text)) + result.push_back(makeAlphanumeric(text)); + else { + vector bytes; + for (; *text != '\0'; text++) + bytes.push_back(static_cast(*text)); + result.push_back(makeBytes(bytes)); + } return result; } -} - -int QrCode::getNumRawDataModules(int ver) { - if (ver < MIN_VERSION || ver > MAX_VERSION) - throw std::domain_error("Version number out of range"); - int result = (16 * ver + 128) * ver + 64; - if (ver >= 2) { - int numAlign = ver / 7 + 2; - result -= (25 * numAlign - 10) * numAlign - 55; - if (ver >= 7) - result -= 36; + QrSegment QrSegment::makeEci(long assignVal) { + BitBuffer bb; + if (assignVal < 0) + throw std::domain_error("ECI assignment value out of range"); + else if (assignVal < (1 << 7)) + bb.appendBits(static_cast(assignVal), 8); + else if (assignVal < (1 << 14)) { + bb.appendBits(2, 2); + bb.appendBits(static_cast(assignVal), 14); + } else if (assignVal < 1000000L) { + bb.appendBits(6, 3); + bb.appendBits(static_cast(assignVal), 21); + } else + throw std::domain_error("ECI assignment value out of range"); + return QrSegment(Mode::ECI, 0, std::move(bb)); } - assert(208 <= result && result <= 29648); - return result; -} + QrSegment::QrSegment(const Mode &md, int numCh, const std::vector &dt) + : mode(&md), numChars(numCh), data(dt) { + if (numCh < 0) + throw std::domain_error("Invalid value"); + } -int QrCode::getNumDataCodewords(int ver, Ecc ecl) { - return getNumRawDataModules(ver) / 8 - - ECC_CODEWORDS_PER_BLOCK [static_cast(ecl)][ver] - * NUM_ERROR_CORRECTION_BLOCKS[static_cast(ecl)][ver]; -} + QrSegment::QrSegment(const Mode &md, int numCh, std::vector &&dt) + : mode(&md), numChars(numCh), data(std::move(dt)) { + if (numCh < 0) + throw std::domain_error("Invalid value"); + } - -vector QrCode::reedSolomonComputeDivisor(int degree) { - if (degree < 1 || degree > 255) - throw std::domain_error("Degree out of range"); - // Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1. - // For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. - vector result(static_cast(degree)); - result.at(result.size() - 1) = 1; // Start off with the monomial x^0 - - // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), - // and drop the highest monomial term which is always 1x^degree. - // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). - uint8_t root = 1; - for (int i = 0; i < degree; i++) { - // Multiply the current product by (x - r^i) - for (size_t j = 0; j < result.size(); j++) { - result.at(j) = reedSolomonMultiply(result.at(j), root); - if (j + 1 < result.size()) - result.at(j) ^= result.at(j + 1); + int QrSegment::getTotalBits(const vector &segs, int version) { + int result = 0; + for (const QrSegment &seg : segs) { + int ccbits = seg.mode->numCharCountBits(version); + if (seg.numChars >= (1L << ccbits)) + return -1; // The segment's length doesn't fit the field's bit width + if (4 + ccbits > INT_MAX - result) + return -1; // The sum will overflow an int type + result += 4 + ccbits; + if (seg.data.size() > static_cast(INT_MAX - result)) + return -1; // The sum will overflow an int type + result += static_cast(seg.data.size()); } - root = reedSolomonMultiply(root, 0x02); + return result; } - return result; -} - -vector QrCode::reedSolomonComputeRemainder(const vector &data, const vector &divisor) { - vector result(divisor.size()); - for (uint8_t b : data) { // Polynomial division - uint8_t factor = b ^ result.at(0); - result.erase(result.begin()); - result.push_back(0); - for (size_t i = 0; i < result.size(); i++) - result.at(i) ^= reedSolomonMultiply(divisor.at(i), factor); + bool QrSegment::isNumeric(const char *text) { + for (; *text != '\0'; text++) { + char c = *text; + if (c < '0' || c > '9') + return false; + } + return true; } - return result; -} - -uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) { - // Russian peasant multiplication - int z = 0; - for (int i = 7; i >= 0; i--) { - z = (z << 1) ^ ((z >> 7) * 0x11D); - z ^= ((y >> i) & 1) * x; + bool QrSegment::isAlphanumeric(const char *text) { + for (; *text != '\0'; text++) { + if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr) + return false; + } + return true; } - assert(z >> 8 == 0); - return static_cast(z); -} + const QrSegment::Mode &QrSegment::getMode() const { return *mode; } -int QrCode::finderPenaltyCountPatterns(const std::array &runHistory) const { - int n = runHistory.at(1); - assert(n <= size * 3); - bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && runHistory.at(4) == n && runHistory.at(5) == n; - return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0) - + (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0); -} + int QrSegment::getNumChars() const { return numChars; } + const std::vector &QrSegment::getData() const { return data; } -int QrCode::finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array &runHistory) const { - if (currentRunColor) { // Terminate dark run + const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; + + /*---- Class QrCode ----*/ + + int QrCode::getFormatBits(Ecc ecl) { + switch (ecl) { + case Ecc::LOW: + return 1; + case Ecc::MEDIUM: + return 0; + case Ecc::QUARTILE: + return 3; + case Ecc::HIGH: + return 2; + default: + throw std::logic_error("Unreachable"); + } + } + + QrCode QrCode::encodeText(const char *text, Ecc ecl) { + vector segs = QrSegment::makeSegments(text); + return encodeSegments(segs, ecl); + } + + QrCode QrCode::encodeBinary(const vector &data, Ecc ecl) { + vector segs{QrSegment::makeBytes(data)}; + return encodeSegments(segs, ecl); + } + + QrCode QrCode::encodeSegments(const vector &segs, Ecc ecl, int minVersion, + int maxVersion, int mask, bool boostEcl) { + if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || + mask < -1 || mask > 7) + throw std::invalid_argument("Invalid value"); + + // Find the minimal version number to use + int version, dataUsedBits; + for (version = minVersion;; version++) { + int dataCapacityBits = + getNumDataCodewords(version, ecl) * 8; // Number of data bits available + dataUsedBits = QrSegment::getTotalBits(segs, version); + if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits) + break; // This version number is found to be suitable + if (version >= maxVersion) { // All versions in the range could not fit the given data + std::ostringstream sb; + if (dataUsedBits == -1) + sb << "Segment too long"; + else { + sb << "Data length = " << dataUsedBits << " bits, "; + sb << "Max capacity = " << dataCapacityBits << " bits"; + } + throw data_too_long(sb.str()); + } + } + assert(dataUsedBits != -1); + + // Increase the error correction level while the data still fits in the current version + // number + for (Ecc newEcl : {Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high + if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8) + ecl = newEcl; + } + + // Concatenate all segments to create the data bit string + BitBuffer bb; + for (const QrSegment &seg : segs) { + bb.appendBits(static_cast(seg.getMode().getModeBits()), 4); + bb.appendBits(static_cast(seg.getNumChars()), + seg.getMode().numCharCountBits(version)); + bb.insert(bb.end(), seg.getData().begin(), seg.getData().end()); + } + assert(bb.size() == static_cast(dataUsedBits)); + + // Add terminator and pad up to a byte if applicable + size_t dataCapacityBits = static_cast(getNumDataCodewords(version, ecl)) * 8; + assert(bb.size() <= dataCapacityBits); + bb.appendBits(0, std::min(4, static_cast(dataCapacityBits - bb.size()))); + bb.appendBits(0, (8 - static_cast(bb.size() % 8)) % 8); + assert(bb.size() % 8 == 0); + + // Pad with alternating bytes until data capacity is reached + for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11) + bb.appendBits(padByte, 8); + + // Pack bits into bytes in big endian + vector dataCodewords(bb.size() / 8); + for (size_t i = 0; i < bb.size(); i++) + dataCodewords.at(i >> 3) |= (bb.at(i) ? 1 : 0) << (7 - (i & 7)); + + // Create the QR Code object + return QrCode(version, ecl, dataCodewords, mask); + } + + QrCode::QrCode(int ver, Ecc ecl, const vector &dataCodewords, int msk) + : // Initialize fields and check arguments + version(ver), errorCorrectionLevel(ecl) { + if (ver < MIN_VERSION || ver > MAX_VERSION) + throw std::domain_error("Version value out of range"); + if (msk < -1 || msk > 7) + throw std::domain_error("Mask value out of range"); + size = ver * 4 + 17; + size_t sz = static_cast(size); + modules = vector>(sz, vector(sz)); // Initially all light + isFunction = vector>(sz, vector(sz)); + + // Compute ECC, draw modules + drawFunctionPatterns(); + const vector allCodewords = addEccAndInterleave(dataCodewords); + drawCodewords(allCodewords); + + // Do masking + if (msk == -1) { // Automatically choose best mask + long minPenalty = LONG_MAX; + for (int i = 0; i < 8; i++) { + applyMask(i); + drawFormatBits(i); + long penalty = getPenaltyScore(); + if (penalty < minPenalty) { + msk = i; + minPenalty = penalty; + } + applyMask(i); // Undoes the mask due to XOR + } + } + assert(0 <= msk && msk <= 7); + mask = msk; + applyMask(msk); // Apply the final choice of mask + drawFormatBits(msk); // Overwrite old format bits + + isFunction.clear(); + isFunction.shrink_to_fit(); + } + + int QrCode::getVersion() const { return version; } + + int QrCode::getSize() const { return size; } + + QrCode::Ecc QrCode::getErrorCorrectionLevel() const { return errorCorrectionLevel; } + + int QrCode::getMask() const { return mask; } + + bool QrCode::getModule(int x, int y) const { + return 0 <= x && x < size && 0 <= y && y < size && module(x, y); + } + + void QrCode::drawFunctionPatterns() { + // Draw horizontal and vertical timing patterns + for (int i = 0; i < size; i++) { + setFunctionModule(6, i, i % 2 == 0); + setFunctionModule(i, 6, i % 2 == 0); + } + + // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) + drawFinderPattern(3, 3); + drawFinderPattern(size - 4, 3); + drawFinderPattern(3, size - 4); + + // Draw numerous alignment patterns + const vector alignPatPos = getAlignmentPatternPositions(); + size_t numAlign = alignPatPos.size(); + for (size_t i = 0; i < numAlign; i++) { + for (size_t j = 0; j < numAlign; j++) { + // Don't draw on the three finder corners + if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || + (i == numAlign - 1 && j == 0))) + drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j)); + } + } + + // Draw configuration data + drawFormatBits(0); // Dummy mask value; overwritten later in the constructor + drawVersion(); + } + + void QrCode::drawFormatBits(int msk) { + // Calculate error correction code and pack bits + int data = + getFormatBits(errorCorrectionLevel) << 3 | msk; // errCorrLvl is uint2, msk is uint3 + int rem = data; + for (int i = 0; i < 10; i++) + rem = (rem << 1) ^ ((rem >> 9) * 0x537); + int bits = (data << 10 | rem) ^ 0x5412; // uint15 + assert(bits >> 15 == 0); + + // Draw first copy + for (int i = 0; i <= 5; i++) + setFunctionModule(8, i, getBit(bits, i)); + setFunctionModule(8, 7, getBit(bits, 6)); + setFunctionModule(8, 8, getBit(bits, 7)); + setFunctionModule(7, 8, getBit(bits, 8)); + for (int i = 9; i < 15; i++) + setFunctionModule(14 - i, 8, getBit(bits, i)); + + // Draw second copy + for (int i = 0; i < 8; i++) + setFunctionModule(size - 1 - i, 8, getBit(bits, i)); + for (int i = 8; i < 15; i++) + setFunctionModule(8, size - 15 + i, getBit(bits, i)); + setFunctionModule(8, size - 8, true); // Always dark + } + + void QrCode::drawVersion() { + if (version < 7) + return; + + // Calculate error correction code and pack bits + int rem = version; // version is uint6, in the range [7, 40] + for (int i = 0; i < 12; i++) + rem = (rem << 1) ^ ((rem >> 11) * 0x1F25); + long bits = static_cast(version) << 12 | rem; // uint18 + assert(bits >> 18 == 0); + + // Draw two copies + for (int i = 0; i < 18; i++) { + bool bit = getBit(bits, i); + int a = size - 11 + i % 3; + int b = i / 3; + setFunctionModule(a, b, bit); + setFunctionModule(b, a, bit); + } + } + + void QrCode::drawFinderPattern(int x, int y) { + for (int dy = -4; dy <= 4; dy++) { + for (int dx = -4; dx <= 4; dx++) { + int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm + int xx = x + dx, yy = y + dy; + if (0 <= xx && xx < size && 0 <= yy && yy < size) + setFunctionModule(xx, yy, dist != 2 && dist != 4); + } + } + } + + void QrCode::drawAlignmentPattern(int x, int y) { + for (int dy = -2; dy <= 2; dy++) { + for (int dx = -2; dx <= 2; dx++) + setFunctionModule(x + dx, y + dy, std::max(std::abs(dx), std::abs(dy)) != 1); + } + } + + void QrCode::setFunctionModule(int x, int y, bool isDark) { + size_t ux = static_cast(x); + size_t uy = static_cast(y); + modules.at(uy).at(ux) = isDark; + isFunction.at(uy).at(ux) = true; + } + + bool QrCode::module(int x, int y) const { + return modules.at(static_cast(y)).at(static_cast(x)); + } + + vector QrCode::addEccAndInterleave(const vector &data) const { + if (data.size() != + static_cast(getNumDataCodewords(version, errorCorrectionLevel))) + throw std::invalid_argument("Invalid argument"); + + // Calculate parameter numbers + int numBlocks = + NUM_ERROR_CORRECTION_BLOCKS[static_cast(errorCorrectionLevel)][version]; + int blockEccLen = ECC_CODEWORDS_PER_BLOCK[static_cast(errorCorrectionLevel)][version]; + int rawCodewords = getNumRawDataModules(version) / 8; + int numShortBlocks = numBlocks - rawCodewords % numBlocks; + int shortBlockLen = rawCodewords / numBlocks; + + // Split data into blocks and append ECC to each block + vector> blocks; + const vector rsDiv = reedSolomonComputeDivisor(blockEccLen); + for (int i = 0, k = 0; i < numBlocks; i++) { + vector dat( + data.cbegin() + k, + data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1))); + k += static_cast(dat.size()); + const vector ecc = reedSolomonComputeRemainder(dat, rsDiv); + if (i < numShortBlocks) + dat.push_back(0); + dat.insert(dat.end(), ecc.cbegin(), ecc.cend()); + blocks.push_back(std::move(dat)); + } + + // Interleave (not concatenate) the bytes from every block into a single sequence + vector result; + for (size_t i = 0; i < blocks.at(0).size(); i++) { + for (size_t j = 0; j < blocks.size(); j++) { + // Skip the padding byte in short blocks + if (i != static_cast(shortBlockLen - blockEccLen) || + j >= static_cast(numShortBlocks)) + result.push_back(blocks.at(j).at(i)); + } + } + assert(result.size() == static_cast(rawCodewords)); + return result; + } + + void QrCode::drawCodewords(const vector &data) { + if (data.size() != static_cast(getNumRawDataModules(version) / 8)) + throw std::invalid_argument("Invalid argument"); + + size_t i = 0; // Bit index into the data + // Do the funny zigzag scan + for (int right = size - 1; right >= 1; + right -= 2) { // Index of right column in each column pair + if (right == 6) + right = 5; + for (int vert = 0; vert < size; vert++) { // Vertical counter + for (int j = 0; j < 2; j++) { + size_t x = static_cast(right - j); // Actual x coordinate + bool upward = ((right + 1) & 2) == 0; + size_t y = + static_cast(upward ? size - 1 - vert : vert); // Actual y coordinate + if (!isFunction.at(y).at(x) && i < data.size() * 8) { + modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast(i & 7)); + i++; + } + // If this QR Code has any remainder bits (0 to 7), they were assigned as + // 0/false/light by the constructor and are left unchanged by this method + } + } + } + assert(i == data.size() * 8); + } + + void QrCode::applyMask(int msk) { + if (msk < 0 || msk > 7) + throw std::domain_error("Mask value out of range"); + size_t sz = static_cast(size); + for (size_t y = 0; y < sz; y++) { + for (size_t x = 0; x < sz; x++) { + bool invert; + switch (msk) { + case 0: + invert = (x + y) % 2 == 0; + break; + case 1: + invert = y % 2 == 0; + break; + case 2: + invert = x % 3 == 0; + break; + case 3: + invert = (x + y) % 3 == 0; + break; + case 4: + invert = (x / 3 + y / 2) % 2 == 0; + break; + case 5: + invert = x * y % 2 + x * y % 3 == 0; + break; + case 6: + invert = (x * y % 2 + x * y % 3) % 2 == 0; + break; + case 7: + invert = ((x + y) % 2 + x * y % 3) % 2 == 0; + break; + default: + throw std::logic_error("Unreachable"); + } + modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x)); + } + } + } + + long QrCode::getPenaltyScore() const { + long result = 0; + + // Adjacent modules in row having same color, and finder-like patterns + for (int y = 0; y < size; y++) { + bool runColor = false; + int runX = 0; + std::array runHistory = {}; + for (int x = 0; x < size; x++) { + if (module(x, y) == runColor) { + runX++; + if (runX == 5) + result += PENALTY_N1; + else if (runX > 5) + result++; + } else { + finderPenaltyAddHistory(runX, runHistory); + if (!runColor) + result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; + runColor = module(x, y); + runX = 1; + } + } + result += finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3; + } + // Adjacent modules in column having same color, and finder-like patterns + for (int x = 0; x < size; x++) { + bool runColor = false; + int runY = 0; + std::array runHistory = {}; + for (int y = 0; y < size; y++) { + if (module(x, y) == runColor) { + runY++; + if (runY == 5) + result += PENALTY_N1; + else if (runY > 5) + result++; + } else { + finderPenaltyAddHistory(runY, runHistory); + if (!runColor) + result += finderPenaltyCountPatterns(runHistory) * PENALTY_N3; + runColor = module(x, y); + runY = 1; + } + } + result += finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3; + } + + // 2*2 blocks of modules having same color + for (int y = 0; y < size - 1; y++) { + for (int x = 0; x < size - 1; x++) { + bool color = module(x, y); + if (color == module(x + 1, y) && color == module(x, y + 1) && + color == module(x + 1, y + 1)) + result += PENALTY_N2; + } + } + + // Balance of dark and light modules + int dark = 0; + for (const vector &row : modules) { + for (bool color : row) { + if (color) + dark++; + } + } + int total = size * size; // Note that size is odd, so dark/total != 1/2 + // Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)% + int k = static_cast((std::abs(dark * 20L - total * 10L) + total - 1) / total) - 1; + assert(0 <= k && k <= 9); + result += k * PENALTY_N4; + assert( + 0 <= result && + result <= + 2568888L); // Non-tight upper bound based on default values of PENALTY_N1, ..., N4 + return result; + } + + vector QrCode::getAlignmentPatternPositions() const { + if (version == 1) + return vector(); + else { + int numAlign = version / 7 + 2; + int step = + (version == 32) ? 26 : (version * 4 + numAlign * 2 + 1) / (numAlign * 2 - 2) * 2; + vector result; + for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) + result.insert(result.begin(), pos); + result.insert(result.begin(), 6); + return result; + } + } + + int QrCode::getNumRawDataModules(int ver) { + if (ver < MIN_VERSION || ver > MAX_VERSION) + throw std::domain_error("Version number out of range"); + int result = (16 * ver + 128) * ver + 64; + if (ver >= 2) { + int numAlign = ver / 7 + 2; + result -= (25 * numAlign - 10) * numAlign - 55; + if (ver >= 7) + result -= 36; + } + assert(208 <= result && result <= 29648); + return result; + } + + int QrCode::getNumDataCodewords(int ver, Ecc ecl) { + return getNumRawDataModules(ver) / 8 - + ECC_CODEWORDS_PER_BLOCK[static_cast(ecl)][ver] * + NUM_ERROR_CORRECTION_BLOCKS[static_cast(ecl)][ver]; + } + + vector QrCode::reedSolomonComputeDivisor(int degree) { + if (degree < 1 || degree > 255) + throw std::domain_error("Degree out of range"); + // Polynomial coefficients are stored from highest to lowest power, excluding the leading + // term which is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as + // the uint8 array {255, 8, 93}. + vector result(static_cast(degree)); + result.at(result.size() - 1) = 1; // Start off with the monomial x^0 + + // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - + // r^{degree-1}), and drop the highest monomial term which is always 1x^degree. Note that r + // = 0x02, which is a generator element of this field GF(2^8/0x11D). + uint8_t root = 1; + for (int i = 0; i < degree; i++) { + // Multiply the current product by (x - r^i) + for (size_t j = 0; j < result.size(); j++) { + result.at(j) = reedSolomonMultiply(result.at(j), root); + if (j + 1 < result.size()) + result.at(j) ^= result.at(j + 1); + } + root = reedSolomonMultiply(root, 0x02); + } + return result; + } + + vector QrCode::reedSolomonComputeRemainder(const vector &data, + const vector &divisor) { + vector result(divisor.size()); + for (uint8_t b : data) { // Polynomial division + uint8_t factor = b ^ result.at(0); + result.erase(result.begin()); + result.push_back(0); + for (size_t i = 0; i < result.size(); i++) + result.at(i) ^= reedSolomonMultiply(divisor.at(i), factor); + } + return result; + } + + uint8_t QrCode::reedSolomonMultiply(uint8_t x, uint8_t y) { + // Russian peasant multiplication + int z = 0; + for (int i = 7; i >= 0; i--) { + z = (z << 1) ^ ((z >> 7) * 0x11D); + z ^= ((y >> i) & 1) * x; + } + assert(z >> 8 == 0); + return static_cast(z); + } + + int QrCode::finderPenaltyCountPatterns(const std::array &runHistory) const { + int n = runHistory.at(1); + assert(n <= size * 3); + bool core = n > 0 && runHistory.at(2) == n && runHistory.at(3) == n * 3 && + runHistory.at(4) == n && runHistory.at(5) == n; + return (core && runHistory.at(0) >= n * 4 && runHistory.at(6) >= n ? 1 : 0) + + (core && runHistory.at(6) >= n * 4 && runHistory.at(0) >= n ? 1 : 0); + } + + int QrCode::finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, + std::array &runHistory) const { + if (currentRunColor) { // Terminate dark run + finderPenaltyAddHistory(currentRunLength, runHistory); + currentRunLength = 0; + } + currentRunLength += size; // Add light border to final run finderPenaltyAddHistory(currentRunLength, runHistory); - currentRunLength = 0; + return finderPenaltyCountPatterns(runHistory); } - currentRunLength += size; // Add light border to final run - finderPenaltyAddHistory(currentRunLength, runHistory); - return finderPenaltyCountPatterns(runHistory); -} + void QrCode::finderPenaltyAddHistory(int currentRunLength, + std::array &runHistory) const { + if (runHistory.at(0) == 0) + currentRunLength += size; // Add light border to initial run + std::copy_backward(runHistory.cbegin(), runHistory.cend() - 1, runHistory.end()); + runHistory.at(0) = currentRunLength; + } -void QrCode::finderPenaltyAddHistory(int currentRunLength, std::array &runHistory) const { - if (runHistory.at(0) == 0) - currentRunLength += size; // Add light border to initial run - std::copy_backward(runHistory.cbegin(), runHistory.cend() - 1, runHistory.end()); - runHistory.at(0) = currentRunLength; -} + bool QrCode::getBit(long x, int i) { return ((x >> i) & 1) != 0; } + /*---- Tables of constants ----*/ -bool QrCode::getBit(long x, int i) { - return ((x >> i) & 1) != 0; -} + const int QrCode::PENALTY_N1 = 3; + const int QrCode::PENALTY_N2 = 3; + const int QrCode::PENALTY_N3 = 40; + const int QrCode::PENALTY_N4 = 10; + const int8_t + QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = + { + // Version: (note that index 0 is for padding, and is set to an illegal value) + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + // 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + // 40 Error correction level + { + -1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, + 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low + { + -1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, + 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium + { + -1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, + 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile + { + -1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, + 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High + }; -/*---- Tables of constants ----*/ + const int8_t + QrCode::NUM_ERROR_CORRECTION_BLOCKS + [4][41] = + { + // Version: (note that index 0 is for padding, and is set to an illegal value) + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + // 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 + // Error correction level + { + -1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, + 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, + 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low + {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, + 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, + 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium + {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, + 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, + 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile + {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, + 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, + 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High + }; -const int QrCode::PENALTY_N1 = 3; -const int QrCode::PENALTY_N2 = 3; -const int QrCode::PENALTY_N3 = 40; -const int QrCode::PENALTY_N4 = 10; + data_too_long::data_too_long(const std::string &msg) : std::length_error(msg) {} + /*---- Class BitBuffer ----*/ -const int8_t QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low - {-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium - {-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile - {-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High -}; + BitBuffer::BitBuffer() : std::vector() {} -const int8_t QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = { - // Version: (note that index 0 is for padding, and is set to an illegal value) - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level - {-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low - {-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium - {-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile - {-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High -}; + void BitBuffer::appendBits(std::uint32_t val, int len) { + if (len < 0 || len > 31 || val >> len != 0) + throw std::domain_error("Value out of range"); + for (int i = len - 1; i >= 0; i--) // Append bit by bit + this->push_back(((val >> i) & 1) != 0); + } - -data_too_long::data_too_long(const std::string &msg) : - std::length_error(msg) {} - - - -/*---- Class BitBuffer ----*/ - -BitBuffer::BitBuffer() - : std::vector() {} - - -void BitBuffer::appendBits(std::uint32_t val, int len) { - if (len < 0 || len > 31 || val >> len != 0) - throw std::domain_error("Value out of range"); - for (int i = len - 1; i >= 0; i--) // Append bit by bit - this->push_back(((val >> i) & 1) != 0); -} - -} +} // namespace qrcodegen diff --git a/src/seclibs/qrcode/qrcodegen.hpp b/src/seclibs/qrcode/qrcodegen.hpp index 01dafaa..8805f56 100644 --- a/src/seclibs/qrcode/qrcodegen.hpp +++ b/src/seclibs/qrcode/qrcodegen.hpp @@ -1,9 +1,9 @@ -/* +/* * QR Code generator library (C++) - * + * * Copyright (c) Project Nayuki. (MIT License) * https://www.nayuki.io/page/qr-code-generator-library - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to @@ -29,532 +29,564 @@ #include #include - /* - Usage... + Usage... - qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText("https://www.arilia.com", qrcodegen::QrCode::Ecc::MEDIUM); - std::string svg = qrcodegen::toSvgString(qr0, 4); // See QrCodeGeneratorDemo + qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText("https://www.arilia.com", + qrcodegen::QrCode::Ecc::MEDIUM); std::string svg = qrcodegen::toSvgString(qr0, 4); // See + QrCodeGeneratorDemo */ - namespace qrcodegen { -/* - * A segment of character/binary/control data in a QR Code symbol. - * Instances of this class are immutable. - * The mid-level way to create a segment is to take the payload data - * and call a static factory function such as QrSegment::makeNumeric(). - * The low-level way to create a segment is to custom-make the bit buffer - * and call the QrSegment() constructor with appropriate values. - * This segment class imposes no length restrictions, but QR Codes have restrictions. - * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. - * Any segment longer than this is meaningless for the purpose of generating QR Codes. - */ -class QrSegment final { - - /*---- Public helper enumeration ----*/ - - /* - * Describes how a segment's data bits are interpreted. Immutable. + /* + * A segment of character/binary/control data in a QR Code symbol. + * Instances of this class are immutable. + * The mid-level way to create a segment is to take the payload data + * and call a static factory function such as QrSegment::makeNumeric(). + * The low-level way to create a segment is to custom-make the bit buffer + * and call the QrSegment() constructor with appropriate values. + * This segment class imposes no length restrictions, but QR Codes have restrictions. + * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. + * Any segment longer than this is meaningless for the purpose of generating QR Codes. */ - public: class Mode final { - - /*-- Constants --*/ - - public: static const Mode NUMERIC; - public: static const Mode ALPHANUMERIC; - public: static const Mode BYTE; - public: static const Mode KANJI; - public: static const Mode ECI; - - - /*-- Fields --*/ - - // The mode indicator bits, which is a uint4 value (range 0 to 15). - private: int modeBits; - - // Number of character count bits for three different version ranges. - private: int numBitsCharCount[3]; - - - /*-- Constructor --*/ - - private: Mode(int mode, int cc0, int cc1, int cc2); - - - /*-- Methods --*/ - - /* - * (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15). + class QrSegment final { + + /*---- Public helper enumeration ----*/ + + /* + * Describes how a segment's data bits are interpreted. Immutable. */ - public: int getModeBits() const; - - /* - * (Package-private) Returns the bit width of the character count field for a segment in - * this mode in a QR Code at the given version number. The result is in the range [0, 16]. + public: + class Mode final { + + /*-- Constants --*/ + + public: + static const Mode NUMERIC; + + public: + static const Mode ALPHANUMERIC; + + public: + static const Mode BYTE; + + public: + static const Mode KANJI; + + public: + static const Mode ECI; + + /*-- Fields --*/ + + // The mode indicator bits, which is a uint4 value (range 0 to 15). + private: + int modeBits; + + // Number of character count bits for three different version ranges. + private: + int numBitsCharCount[3]; + + /*-- Constructor --*/ + + private: + Mode(int mode, int cc0, int cc1, int cc2); + + /*-- Methods --*/ + + /* + * (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value + * (range 0 to 15). + */ + public: + int getModeBits() const; + + /* + * (Package-private) Returns the bit width of the character count field for a segment in + * this mode in a QR Code at the given version number. The result is in the range [0, + * 16]. + */ + public: + int numCharCountBits(int ver) const; + }; + + /*---- Static factory functions (mid level) ----*/ + + /* + * Returns a segment representing the given binary data encoded in + * byte mode. All input byte vectors are acceptable. Any text string + * can be converted to UTF-8 bytes and encoded as a byte mode segment. */ - public: int numCharCountBits(int ver) const; - + public: + static QrSegment makeBytes(const std::vector &data); + + /* + * Returns a segment representing the given string of decimal digits encoded in numeric + * mode. + */ + public: + static QrSegment makeNumeric(const char *digits); + + /* + * Returns a segment representing the given text string encoded in alphanumeric mode. + * The characters allowed are: 0 to 9, A to Z (uppercase only), space, + * dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ + public: + static QrSegment makeAlphanumeric(const char *text); + + /* + * Returns a list of zero or more segments to represent the given text string. The result + * may use various segment modes and switch modes to optimize the length of the bit stream. + */ + public: + static std::vector makeSegments(const char *text); + + /* + * Returns a segment representing an Extended Channel Interpretation + * (ECI) designator with the given assignment value. + */ + public: + static QrSegment makeEci(long assignVal); + + /*---- Public static helper functions ----*/ + + /* + * Tests whether the given string can be encoded as a segment in numeric mode. + * A string is encodable iff each character is in the range 0 to 9. + */ + public: + static bool isNumeric(const char *text); + + /* + * Tests whether the given string can be encoded as a segment in alphanumeric mode. + * A string is encodable iff each character is in the following set: 0 to 9, A to Z + * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. + */ + public: + static bool isAlphanumeric(const char *text); + + /*---- Instance fields ----*/ + + /* The mode indicator of this segment. Accessed through getMode(). */ + private: + const Mode *mode; + + /* The length of this segment's unencoded data. Measured in characters for + * numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. + * Always zero or positive. Not the same as the data's bit length. + * Accessed through getNumChars(). */ + private: + int numChars; + + /* The data bits of this segment. Accessed through getData(). */ + private: + std::vector data; + + /*---- Constructors (low level) ----*/ + + /* + * Creates a new QR Code segment with the given attributes and data. + * The character count (numCh) must agree with the mode and the bit buffer length, + * but the constraint isn't checked. The given bit buffer is copied and stored. + */ + public: + QrSegment(const Mode &md, int numCh, const std::vector &dt); + + /* + * Creates a new QR Code segment with the given parameters and data. + * The character count (numCh) must agree with the mode and the bit buffer length, + * but the constraint isn't checked. The given bit buffer is moved and stored. + */ + public: + QrSegment(const Mode &md, int numCh, std::vector &&dt); + + /*---- Methods ----*/ + + /* + * Returns the mode field of this segment. + */ + public: + const Mode &getMode() const; + + /* + * Returns the character count field of this segment. + */ + public: + int getNumChars() const; + + /* + * Returns the data bits of this segment. + */ + public: + const std::vector &getData() const; + + // (Package-private) Calculates the number of bits needed to encode the given segments at + // the given version. Returns a non-negative number if successful. Otherwise returns -1 if a + // segment has too many characters to fit its length field, or the total bits exceeds + // INT_MAX. + public: + static int getTotalBits(const std::vector &segs, int version); + + /*---- Private constant ----*/ + + /* The set of all legal characters in alphanumeric mode, where + * each character value maps to the index in the string. */ + private: + static const char *ALPHANUMERIC_CHARSET; }; - - - - /*---- Static factory functions (mid level) ----*/ - - /* - * Returns a segment representing the given binary data encoded in - * byte mode. All input byte vectors are acceptable. Any text string - * can be converted to UTF-8 bytes and encoded as a byte mode segment. - */ - public: static QrSegment makeBytes(const std::vector &data); - - - /* - * Returns a segment representing the given string of decimal digits encoded in numeric mode. - */ - public: static QrSegment makeNumeric(const char *digits); - - - /* - * Returns a segment representing the given text string encoded in alphanumeric mode. - * The characters allowed are: 0 to 9, A to Z (uppercase only), space, - * dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ - public: static QrSegment makeAlphanumeric(const char *text); - - - /* - * Returns a list of zero or more segments to represent the given text string. The result - * may use various segment modes and switch modes to optimize the length of the bit stream. - */ - public: static std::vector makeSegments(const char *text); - - - /* - * Returns a segment representing an Extended Channel Interpretation - * (ECI) designator with the given assignment value. - */ - public: static QrSegment makeEci(long assignVal); - - - /*---- Public static helper functions ----*/ - - /* - * Tests whether the given string can be encoded as a segment in numeric mode. - * A string is encodable iff each character is in the range 0 to 9. - */ - public: static bool isNumeric(const char *text); - - - /* - * Tests whether the given string can be encoded as a segment in alphanumeric mode. - * A string is encodable iff each character is in the following set: 0 to 9, A to Z - * (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon. - */ - public: static bool isAlphanumeric(const char *text); - - - - /*---- Instance fields ----*/ - - /* The mode indicator of this segment. Accessed through getMode(). */ - private: const Mode *mode; - - /* The length of this segment's unencoded data. Measured in characters for - * numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode. - * Always zero or positive. Not the same as the data's bit length. - * Accessed through getNumChars(). */ - private: int numChars; - - /* The data bits of this segment. Accessed through getData(). */ - private: std::vector data; - - - /*---- Constructors (low level) ----*/ - - /* - * Creates a new QR Code segment with the given attributes and data. - * The character count (numCh) must agree with the mode and the bit buffer length, - * but the constraint isn't checked. The given bit buffer is copied and stored. - */ - public: QrSegment(const Mode &md, int numCh, const std::vector &dt); - - - /* - * Creates a new QR Code segment with the given parameters and data. - * The character count (numCh) must agree with the mode and the bit buffer length, - * but the constraint isn't checked. The given bit buffer is moved and stored. - */ - public: QrSegment(const Mode &md, int numCh, std::vector &&dt); - - - /*---- Methods ----*/ - - /* - * Returns the mode field of this segment. - */ - public: const Mode &getMode() const; - - - /* - * Returns the character count field of this segment. - */ - public: int getNumChars() const; - - - /* - * Returns the data bits of this segment. - */ - public: const std::vector &getData() const; - - - // (Package-private) Calculates the number of bits needed to encode the given segments at - // the given version. Returns a non-negative number if successful. Otherwise returns -1 if a - // segment has too many characters to fit its length field, or the total bits exceeds INT_MAX. - public: static int getTotalBits(const std::vector &segs, int version); - - - /*---- Private constant ----*/ - - /* The set of all legal characters in alphanumeric mode, where - * each character value maps to the index in the string. */ - private: static const char *ALPHANUMERIC_CHARSET; - -}; - - -/* - * A QR Code symbol, which is a type of two-dimension barcode. - * Invented by Denso Wave and described in the ISO/IEC 18004 standard. - * Instances of this class represent an immutable square grid of dark and light cells. - * The class provides static factory functions to create a QR Code from text or binary data. - * The class covers the QR Code Model 2 specification, supporting all versions (sizes) - * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. - * - * Ways to create a QR Code object: - * - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary(). - * - Mid level: Custom-make the list of segments and call QrCode::encodeSegments(). - * - Low level: Custom-make the array of data codeword bytes (including - * segment headers and final padding, excluding error correction codewords), - * supply the appropriate version number, and call the QrCode() constructor. - * (Note that all ways require supplying the desired error correction level.) - */ -class QrCode final { - - /*---- Public helper enumeration ----*/ - - /* - * The error correction level in a QR Code symbol. + /* + * A QR Code symbol, which is a type of two-dimension barcode. + * Invented by Denso Wave and described in the ISO/IEC 18004 standard. + * Instances of this class represent an immutable square grid of dark and light cells. + * The class provides static factory functions to create a QR Code from text or binary data. + * The class covers the QR Code Model 2 specification, supporting all versions (sizes) + * from 1 to 40, all 4 error correction levels, and 4 character encoding modes. + * + * Ways to create a QR Code object: + * - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary(). + * - Mid level: Custom-make the list of segments and call QrCode::encodeSegments(). + * - Low level: Custom-make the array of data codeword bytes (including + * segment headers and final padding, excluding error correction codewords), + * supply the appropriate version number, and call the QrCode() constructor. + * (Note that all ways require supplying the desired error correction level.) */ - public: enum class Ecc { - LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords - MEDIUM , // The QR Code can tolerate about 15% erroneous codewords - QUARTILE, // The QR Code can tolerate about 25% erroneous codewords - HIGH , // The QR Code can tolerate about 30% erroneous codewords + class QrCode final { + + /*---- Public helper enumeration ----*/ + + /* + * The error correction level in a QR Code symbol. + */ + public: + enum class Ecc { + LOW = 0, // The QR Code can tolerate about 7% erroneous codewords + MEDIUM, // The QR Code can tolerate about 15% erroneous codewords + QUARTILE, // The QR Code can tolerate about 25% erroneous codewords + HIGH, // The QR Code can tolerate about 30% erroneous codewords + }; + + // Returns a value in the range 0 to 3 (unsigned 2-bit integer). + private: + static int getFormatBits(Ecc ecl); + + /*---- Static factory functions (high level) ----*/ + + /* + * Returns a QR Code representing the given Unicode text string at the given error + * correction level. As a conservative upper bound, this function is guaranteed to succeed + * for strings that have 2953 or fewer UTF-8 code units (not Unicode code points) if the low + * error correction level is used. The smallest possible QR Code version is automatically + * chosen for the output. The ECC level of the result may be higher than the ecl argument if + * it can be done without increasing the version. + */ + public: + static QrCode encodeText(const char *text, Ecc ecl); + + /* + * Returns a QR Code representing the given binary data at the given error correction level. + * This function always encodes using the binary segment mode, not any text mode. The + * maximum number of bytes allowed is 2953. The smallest possible QR Code version is + * automatically chosen for the output. The ECC level of the result may be higher than the + * ecl argument if it can be done without increasing the version. + */ + public: + static QrCode encodeBinary(const std::vector &data, Ecc ecl); + + /*---- Static factory functions (mid level) ----*/ + + /* + * Returns a QR Code representing the given segments with the given encoding parameters. + * The smallest possible QR Code version within the given range is automatically + * chosen for the output. Iff boostEcl is true, then the ECC level of the result + * may be higher than the ecl argument if it can be done without increasing the + * version. The mask number is either between 0 to 7 (inclusive) to force that + * mask, or -1 to automatically choose an appropriate mask (which may be slow). + * This function allows the user to create a custom sequence of segments that switches + * between modes (such as alphanumeric and byte) to encode text in less space. + * This is a mid-level API; the high-level API is encodeText() and encodeBinary(). + */ + public: + static QrCode encodeSegments(const std::vector &segs, Ecc ecl, + int minVersion = 1, int maxVersion = 40, int mask = -1, + bool boostEcl = true); // All optional parameters + + /*---- Instance fields ----*/ + + // Immutable scalar parameters: + + /* The version number of this QR Code, which is between 1 and 40 (inclusive). + * This determines the size of this barcode. */ + private: + int version; + + /* The width and height of this QR Code, measured in modules, between + * 21 and 177 (inclusive). This is equal to version * 4 + 17. */ + private: + int size; + + /* The error correction level used in this QR Code. */ + private: + Ecc errorCorrectionLevel; + + /* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive). + * Even if a QR Code is created with automatic masking requested (mask = -1), + * the resulting object still has a mask value between 0 and 7. */ + private: + int mask; + + // Private grids of modules/pixels, with dimensions of size*size: + + // The modules of this QR Code (false = light, true = dark). + // Immutable after constructor finishes. Accessed through getModule(). + private: + std::vector> modules; + + // Indicates function modules that are not subjected to masking. Discarded when constructor + // finishes. + private: + std::vector> isFunction; + + /*---- Constructor (low level) ----*/ + + /* + * Creates a new QR Code with the given version number, + * error correction level, data codeword bytes, and mask number. + * This is a low-level API that most users should not use directly. + * A mid-level API is the encodeSegments() function. + */ + public: + QrCode(int ver, Ecc ecl, const std::vector &dataCodewords, int msk); + + /*---- Public instance methods ----*/ + + /* + * Returns this QR Code's version, in the range [1, 40]. + */ + public: + int getVersion() const; + + /* + * Returns this QR Code's size, in the range [21, 177]. + */ + public: + int getSize() const; + + /* + * Returns this QR Code's error correction level. + */ + public: + Ecc getErrorCorrectionLevel() const; + + /* + * Returns this QR Code's mask, in the range [0, 7]. + */ + public: + int getMask() const; + + /* + * Returns the color of the module (pixel) at the given coordinates, which is false + * for light or true for dark. The top left corner has the coordinates (x=0, y=0). + * If the given coordinates are out of bounds, then false (light) is returned. + */ + public: + bool getModule(int x, int y) const; + + /*---- Private helper methods for constructor: Drawing function modules ----*/ + + // Reads this object's version field, and draws and marks all function modules. + private: + void drawFunctionPatterns(); + + // Draws two copies of the format bits (with its own error correction code) + // based on the given mask and this object's error correction level field. + private: + void drawFormatBits(int msk); + + // Draws two copies of the version bits (with its own error correction code), + // based on this object's version field, iff 7 <= version <= 40. + private: + void drawVersion(); + + // Draws a 9*9 finder pattern including the border separator, + // with the center module at (x, y). Modules can be out of bounds. + private: + void drawFinderPattern(int x, int y); + + // Draws a 5*5 alignment pattern, with the center module + // at (x, y). All modules must be in bounds. + private: + void drawAlignmentPattern(int x, int y); + + // Sets the color of a module and marks it as a function module. + // Only used by the constructor. Coordinates must be in bounds. + private: + void setFunctionModule(int x, int y, bool isDark); + + // Returns the color of the module at the given coordinates, which must be in range. + private: + bool module(int x, int y) const; + + /*---- Private helper methods for constructor: Codewords and masking ----*/ + + // Returns a new byte string representing the given data with the appropriate error + // correction codewords appended to it, based on this object's version and error correction + // level. + private: + std::vector addEccAndInterleave(const std::vector &data) const; + + // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire + // data area of this QR Code. Function modules need to be marked off before this is called. + private: + void drawCodewords(const std::vector &data); + + // XORs the codeword modules in this QR Code with the given mask pattern. + // The function modules must be marked and the codeword bits must be drawn + // before masking. Due to the arithmetic of XOR, calling applyMask() with + // the same mask value a second time will undo the mask. A final well-formed + // QR Code needs exactly one (not zero, two, etc.) mask applied. + private: + void applyMask(int msk); + + // Calculates and returns the penalty score based on state of this QR Code's current + // modules. This is used by the automatic mask choice algorithm to find the mask pattern + // that yields the lowest score. + private: + long getPenaltyScore() const; + + /*---- Private helper functions ----*/ + + // Returns an ascending list of positions of alignment patterns for this version number. + // Each position is in the range [0,177), and are used on both the x and y axes. + // This could be implemented as lookup table of 40 variable-length lists of unsigned bytes. + private: + std::vector getAlignmentPatternPositions() const; + + // Returns the number of data bits that can be stored in a QR Code of the given version + // number, after all function modules are excluded. This includes remainder bits, so it + // might not be a multiple of 8. The result is in the range [208, 29648]. This could be + // implemented as a 40-entry lookup table. + private: + static int getNumRawDataModules(int ver); + + // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any + // QR Code of the given version number and error correction level, with remainder bits + // discarded. This stateless pure function could be implemented as a (40*4)-cell lookup + // table. + private: + static int getNumDataCodewords(int ver, Ecc ecl); + + // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be + // implemented as a lookup table over all possible parameter values, instead of as an + // algorithm. + private: + static std::vector reedSolomonComputeDivisor(int degree); + + // Returns the Reed-Solomon error correction codeword for the given data and divisor + // polynomials. + private: + static std::vector + reedSolomonComputeRemainder(const std::vector &data, + const std::vector &divisor); + + // Returns the product of the two given field elements modulo GF(2^8/0x11D). + // All inputs are valid. This could be implemented as a 256*256 lookup table. + private: + static std::uint8_t reedSolomonMultiply(std::uint8_t x, std::uint8_t y); + + // Can only be called immediately after a light run is added, and + // returns either 0, 1, or 2. A helper function for getPenaltyScore(). + private: + int finderPenaltyCountPatterns(const std::array &runHistory) const; + + // Must be called at the end of a line (row or column) of modules. A helper function for + // getPenaltyScore(). + private: + int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, + std::array &runHistory) const; + + // Pushes the given value to the front and drops the last value. A helper function for + // getPenaltyScore(). + private: + void finderPenaltyAddHistory(int currentRunLength, std::array &runHistory) const; + + // Returns true iff the i'th bit of x is set to 1. + private: + static bool getBit(long x, int i); + + /*---- Constants and tables ----*/ + + // The minimum version number supported in the QR Code Model 2 standard. + public: + static constexpr int MIN_VERSION = 1; + + // The maximum version number supported in the QR Code Model 2 standard. + public: + static constexpr int MAX_VERSION = 40; + + // For use in getPenaltyScore(), when evaluating which mask is best. + private: + static const int PENALTY_N1; + + private: + static const int PENALTY_N2; + + private: + static const int PENALTY_N3; + + private: + static const int PENALTY_N4; + + private: + static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41]; + + private: + static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41]; }; - - - // Returns a value in the range 0 to 3 (unsigned 2-bit integer). - private: static int getFormatBits(Ecc ecl); - - - - /*---- Static factory functions (high level) ----*/ - - /* - * Returns a QR Code representing the given Unicode text string at the given error correction level. - * As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer - * UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible - * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than - * the ecl argument if it can be done without increasing the version. - */ - public: static QrCode encodeText(const char *text, Ecc ecl); - - - /* - * Returns a QR Code representing the given binary data at the given error correction level. - * This function always encodes using the binary segment mode, not any text mode. The maximum number of - * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output. - * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. - */ - public: static QrCode encodeBinary(const std::vector &data, Ecc ecl); - - - /*---- Static factory functions (mid level) ----*/ - - /* - * Returns a QR Code representing the given segments with the given encoding parameters. - * The smallest possible QR Code version within the given range is automatically - * chosen for the output. Iff boostEcl is true, then the ECC level of the result - * may be higher than the ecl argument if it can be done without increasing the - * version. The mask number is either between 0 to 7 (inclusive) to force that - * mask, or -1 to automatically choose an appropriate mask (which may be slow). - * This function allows the user to create a custom sequence of segments that switches - * between modes (such as alphanumeric and byte) to encode text in less space. - * This is a mid-level API; the high-level API is encodeText() and encodeBinary(). - */ - public: static QrCode encodeSegments(const std::vector &segs, Ecc ecl, - int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters - - - - /*---- Instance fields ----*/ - - // Immutable scalar parameters: - - /* The version number of this QR Code, which is between 1 and 40 (inclusive). - * This determines the size of this barcode. */ - private: int version; - - /* The width and height of this QR Code, measured in modules, between - * 21 and 177 (inclusive). This is equal to version * 4 + 17. */ - private: int size; - - /* The error correction level used in this QR Code. */ - private: Ecc errorCorrectionLevel; - - /* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive). - * Even if a QR Code is created with automatic masking requested (mask = -1), - * the resulting object still has a mask value between 0 and 7. */ - private: int mask; - - // Private grids of modules/pixels, with dimensions of size*size: - - // The modules of this QR Code (false = light, true = dark). - // Immutable after constructor finishes. Accessed through getModule(). - private: std::vector > modules; - - // Indicates function modules that are not subjected to masking. Discarded when constructor finishes. - private: std::vector > isFunction; - - - - /*---- Constructor (low level) ----*/ - - /* - * Creates a new QR Code with the given version number, - * error correction level, data codeword bytes, and mask number. - * This is a low-level API that most users should not use directly. - * A mid-level API is the encodeSegments() function. - */ - public: QrCode(int ver, Ecc ecl, const std::vector &dataCodewords, int msk); - - - - /*---- Public instance methods ----*/ - - /* - * Returns this QR Code's version, in the range [1, 40]. - */ - public: int getVersion() const; - - - /* - * Returns this QR Code's size, in the range [21, 177]. - */ - public: int getSize() const; - - - /* - * Returns this QR Code's error correction level. - */ - public: Ecc getErrorCorrectionLevel() const; - - - /* - * Returns this QR Code's mask, in the range [0, 7]. - */ - public: int getMask() const; - - - /* - * Returns the color of the module (pixel) at the given coordinates, which is false - * for light or true for dark. The top left corner has the coordinates (x=0, y=0). - * If the given coordinates are out of bounds, then false (light) is returned. - */ - public: bool getModule(int x, int y) const; - - - - /*---- Private helper methods for constructor: Drawing function modules ----*/ - - // Reads this object's version field, and draws and marks all function modules. - private: void drawFunctionPatterns(); - - - // Draws two copies of the format bits (with its own error correction code) - // based on the given mask and this object's error correction level field. - private: void drawFormatBits(int msk); - - - // Draws two copies of the version bits (with its own error correction code), - // based on this object's version field, iff 7 <= version <= 40. - private: void drawVersion(); - - - // Draws a 9*9 finder pattern including the border separator, - // with the center module at (x, y). Modules can be out of bounds. - private: void drawFinderPattern(int x, int y); - - - // Draws a 5*5 alignment pattern, with the center module - // at (x, y). All modules must be in bounds. - private: void drawAlignmentPattern(int x, int y); - - - // Sets the color of a module and marks it as a function module. - // Only used by the constructor. Coordinates must be in bounds. - private: void setFunctionModule(int x, int y, bool isDark); - - - // Returns the color of the module at the given coordinates, which must be in range. - private: bool module(int x, int y) const; - - - /*---- Private helper methods for constructor: Codewords and masking ----*/ - - // Returns a new byte string representing the given data with the appropriate error correction - // codewords appended to it, based on this object's version and error correction level. - private: std::vector addEccAndInterleave(const std::vector &data) const; - - - // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire - // data area of this QR Code. Function modules need to be marked off before this is called. - private: void drawCodewords(const std::vector &data); - - - // XORs the codeword modules in this QR Code with the given mask pattern. - // The function modules must be marked and the codeword bits must be drawn - // before masking. Due to the arithmetic of XOR, calling applyMask() with - // the same mask value a second time will undo the mask. A final well-formed - // QR Code needs exactly one (not zero, two, etc.) mask applied. - private: void applyMask(int msk); - - - // Calculates and returns the penalty score based on state of this QR Code's current modules. - // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. - private: long getPenaltyScore() const; - - - - /*---- Private helper functions ----*/ - - // Returns an ascending list of positions of alignment patterns for this version number. - // Each position is in the range [0,177), and are used on both the x and y axes. - // This could be implemented as lookup table of 40 variable-length lists of unsigned bytes. - private: std::vector getAlignmentPatternPositions() const; - - - // Returns the number of data bits that can be stored in a QR Code of the given version number, after - // all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. - // The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. - private: static int getNumRawDataModules(int ver); - - - // Returns the number of 8-bit data (i.e. not error correction) codewords contained in any - // QR Code of the given version number and error correction level, with remainder bits discarded. - // This stateless pure function could be implemented as a (40*4)-cell lookup table. - private: static int getNumDataCodewords(int ver, Ecc ecl); - - - // Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be - // implemented as a lookup table over all possible parameter values, instead of as an algorithm. - private: static std::vector reedSolomonComputeDivisor(int degree); - - - // Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials. - private: static std::vector reedSolomonComputeRemainder(const std::vector &data, const std::vector &divisor); - - - // Returns the product of the two given field elements modulo GF(2^8/0x11D). - // All inputs are valid. This could be implemented as a 256*256 lookup table. - private: static std::uint8_t reedSolomonMultiply(std::uint8_t x, std::uint8_t y); - - - // Can only be called immediately after a light run is added, and - // returns either 0, 1, or 2. A helper function for getPenaltyScore(). - private: int finderPenaltyCountPatterns(const std::array &runHistory) const; - - - // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore(). - private: int finderPenaltyTerminateAndCount(bool currentRunColor, int currentRunLength, std::array &runHistory) const; - - - // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore(). - private: void finderPenaltyAddHistory(int currentRunLength, std::array &runHistory) const; - - - // Returns true iff the i'th bit of x is set to 1. - private: static bool getBit(long x, int i); - - - /*---- Constants and tables ----*/ - - // The minimum version number supported in the QR Code Model 2 standard. - public: static constexpr int MIN_VERSION = 1; - - // The maximum version number supported in the QR Code Model 2 standard. - public: static constexpr int MAX_VERSION = 40; - - - // For use in getPenaltyScore(), when evaluating which mask is best. - private: static const int PENALTY_N1; - private: static const int PENALTY_N2; - private: static const int PENALTY_N3; - private: static const int PENALTY_N4; - - - private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41]; - private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41]; - -}; - std::string toSvgString(const QrCode &qr, int border); - void printQr(const QrCode &qr); + std::string toSvgString(const QrCode &qr, int border); + void printQr(const QrCode &qr); + /*---- Public exception class ----*/ -/*---- Public exception class ----*/ + /* + * Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception + * include: + * - Decrease the error correction level if it was greater than Ecc::LOW. + * - If the encodeSegments() function was called with a maxVersion argument, then increase + * it if it was less than QrCode::MAX_VERSION. (This advice does not apply to the other + * factory functions because they search all versions up to QrCode::MAX_VERSION.) + * - Split the text data into better or optimal segments in order to reduce the number of bits + * required. + * - Change the text or binary data to be shorter. + * - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric). + * - Propagate the error upward to the caller/user. + */ + class data_too_long : public std::length_error { -/* - * Thrown when the supplied data does not fit any QR Code version. Ways to handle this exception include: - * - Decrease the error correction level if it was greater than Ecc::LOW. - * - If the encodeSegments() function was called with a maxVersion argument, then increase - * it if it was less than QrCode::MAX_VERSION. (This advice does not apply to the other - * factory functions because they search all versions up to QrCode::MAX_VERSION.) - * - Split the text data into better or optimal segments in order to reduce the number of bits required. - * - Change the text or binary data to be shorter. - * - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric). - * - Propagate the error upward to the caller/user. - */ -class data_too_long : public std::length_error { - - public: explicit data_too_long(const std::string &msg); - -}; + public: + explicit data_too_long(const std::string &msg); + }; + /* + * An appendable sequence of bits (0s and 1s). Mainly used by QrSegment. + */ + class BitBuffer final : public std::vector { + /*---- Constructor ----*/ -/* - * An appendable sequence of bits (0s and 1s). Mainly used by QrSegment. - */ -class BitBuffer final : public std::vector { - - /*---- Constructor ----*/ - - // Creates an empty bit buffer (length 0). - public: BitBuffer(); - - - - /*---- Method ----*/ - - // Appends the given number of low-order bits of the given value - // to this buffer. Requires 0 <= len <= 31 and val < 2^len. - public: void appendBits(std::uint32_t val, int len); - -}; + // Creates an empty bit buffer (length 0). + public: + BitBuffer(); -} + /*---- Method ----*/ + + // Appends the given number of low-order bits of the given value + // to this buffer. Requires 0 <= len <= 31 and val < 2^len. + public: + void appendBits(std::uint32_t val, int len); + }; + +} // namespace qrcodegen diff --git a/src/storage/orm_actionLinks.cpp b/src/storage/orm_actionLinks.cpp index e1e170c..9537187 100644 --- a/src/storage/orm_actionLinks.cpp +++ b/src/storage/orm_actionLinks.cpp @@ -22,118 +22,112 @@ */ namespace OpenWifi { - static ORM::FieldVec ActionLinksDB_Fields{ - ORM::Field{"id", 36, true}, - ORM::Field{"action", ORM::FieldType::FT_BIGINT}, - ORM::Field{"userId", ORM::FieldType::FT_TEXT}, - ORM::Field{"actionTemplate", ORM::FieldType::FT_TEXT}, - ORM::Field{"variables", ORM::FieldType::FT_TEXT}, - ORM::Field{"locale", ORM::FieldType::FT_TEXT}, - ORM::Field{"message", ORM::FieldType::FT_TEXT}, - ORM::Field{"sent", ORM::FieldType::FT_BIGINT}, - ORM::Field{"created", ORM::FieldType::FT_BIGINT}, - ORM::Field{"expires", ORM::FieldType::FT_BIGINT}, - ORM::Field{"completed", ORM::FieldType::FT_BIGINT}, - ORM::Field{"canceled", ORM::FieldType::FT_BIGINT}, - ORM::Field{"userAction", ORM::FieldType::FT_BOOLEAN} - }; + static ORM::FieldVec ActionLinksDB_Fields{ORM::Field{"id", 36, true}, + ORM::Field{"action", ORM::FieldType::FT_BIGINT}, + ORM::Field{"userId", ORM::FieldType::FT_TEXT}, + ORM::Field{"actionTemplate", ORM::FieldType::FT_TEXT}, + ORM::Field{"variables", ORM::FieldType::FT_TEXT}, + ORM::Field{"locale", ORM::FieldType::FT_TEXT}, + ORM::Field{"message", ORM::FieldType::FT_TEXT}, + ORM::Field{"sent", ORM::FieldType::FT_BIGINT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"expires", ORM::FieldType::FT_BIGINT}, + ORM::Field{"completed", ORM::FieldType::FT_BIGINT}, + ORM::Field{"canceled", ORM::FieldType::FT_BIGINT}, + ORM::Field{"userAction", ORM::FieldType::FT_BOOLEAN}}; - ActionLinkDB::ActionLinkDB(const std::string &Name, const std::string &ShortName, OpenWifi::DBType T, - Poco::Data::SessionPool &P, Poco::Logger &L) : - DB(T, Name.c_str(), ActionLinksDB_Fields,{}, P, L, ShortName.c_str()) { - } + ActionLinkDB::ActionLinkDB(const std::string &Name, const std::string &ShortName, + OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, Name.c_str(), ActionLinksDB_Fields, {}, P, L, ShortName.c_str()) {} - bool ActionLinkDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { - std::vector Statements{ - "alter table " + TableName_ + " add column userAction BOOLEAN default true;" - }; - RunScript(Statements); - to = 1; - return true; + bool ActionLinkDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + std::vector Statements{"alter table " + TableName_ + + " add column userAction BOOLEAN default true;"}; + RunScript(Statements); + to = 1; + return true; - return true; - } - bool ActionLinkDB::CreateAction( SecurityObjects::ActionLink & A) { - return CreateRecord(A); - } + return true; + } + bool ActionLinkDB::CreateAction(SecurityObjects::ActionLink &A) { return CreateRecord(A); } - bool ActionLinkDB::GetActions(std::vector &Links, uint64_t Max) { - return GetRecords(0,Max,Links," sent=0 "); - } + bool ActionLinkDB::GetActions(std::vector &Links, uint64_t Max) { + return GetRecords(0, Max, Links, " sent=0 "); + } - bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) { - return GetRecord("id",ActionId,A); - } + bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) { + return GetRecord("id", ActionId, A); + } - bool ActionLinkDB::SentAction(std::string &ActionId) { - SecurityObjects::ActionLink A; - if(GetRecord("id",ActionId,A)) { - A.sent = OpenWifi::Now(); - return UpdateRecord("id",ActionId,A); - } - return false; - } + bool ActionLinkDB::SentAction(std::string &ActionId) { + SecurityObjects::ActionLink A; + if (GetRecord("id", ActionId, A)) { + A.sent = OpenWifi::Now(); + return UpdateRecord("id", ActionId, A); + } + return false; + } - bool ActionLinkDB::DeleteAction(std::string &ActionId) { - return DeleteRecord("id",ActionId); - } + bool ActionLinkDB::DeleteAction(std::string &ActionId) { return DeleteRecord("id", ActionId); } - bool ActionLinkDB::CompleteAction(std::string &ActionId) { - SecurityObjects::ActionLink A; - if(GetRecord("id",ActionId,A)) { - A.completed = OpenWifi::Now(); - return UpdateRecord("id",ActionId,A); - } - return false; - } + bool ActionLinkDB::CompleteAction(std::string &ActionId) { + SecurityObjects::ActionLink A; + if (GetRecord("id", ActionId, A)) { + A.completed = OpenWifi::Now(); + return UpdateRecord("id", ActionId, A); + } + return false; + } - bool ActionLinkDB::CancelAction(std::string &ActionId) { - SecurityObjects::ActionLink A; - if(GetRecord("id",ActionId,A)) { - A.canceled = OpenWifi::Now(); - return UpdateRecord("id",ActionId,A); - } - return false; - } + bool ActionLinkDB::CancelAction(std::string &ActionId) { + SecurityObjects::ActionLink A; + if (GetRecord("id", ActionId, A)) { + A.canceled = OpenWifi::Now(); + return UpdateRecord("id", ActionId, A); + } + return false; + } - void ActionLinkDB::CleanOldActionLinks() { - uint64_t CutOff = OpenWifi::Now() - (30 * 24 * 60 * 60); - std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "}; - DeleteRecords(WhereClause); - } + void ActionLinkDB::CleanOldActionLinks() { + uint64_t CutOff = OpenWifi::Now() - (30 * 24 * 60 * 60); + std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "}; + DeleteRecords(WhereClause); + } +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::ActionLinkRecordTuple &T, OpenWifi::SecurityObjects::ActionLink &U) { + U.id = T.get<0>(); + U.action = T.get<1>(); + U.userId = T.get<2>(); + U.actionTemplate = T.get<3>(); + U.variables = OpenWifi::RESTAPI_utils::to_stringpair_array(T.get<4>()); + U.locale = T.get<5>(); + U.message = T.get<6>(); + U.sent = T.get<7>(); + U.created = T.get<8>(); + U.expires = T.get<9>(); + U.completed = T.get<10>(); + U.canceled = T.get<11>(); + U.userAction = T.get<12>(); } -template<> void ORM::DB::Convert(const OpenWifi::ActionLinkRecordTuple &T, OpenWifi::SecurityObjects::ActionLink &U) { - U.id = T.get<0>(); - U.action = T.get<1>(); - U.userId = T.get<2>(); - U.actionTemplate = T.get<3>(); - U.variables = OpenWifi::RESTAPI_utils::to_stringpair_array(T.get<4>()); - U.locale = T.get<5>(); - U.message = T.get<6>(); - U.sent = T.get<7>(); - U.created = T.get<8>(); - U.expires = T.get<9>(); - U.completed = T.get<10>(); - U.canceled = T.get<11>(); - U.userAction = T.get<12>(); -} - -template<> void ORM::DB::Convert(const OpenWifi::SecurityObjects::ActionLink &U, OpenWifi::ActionLinkRecordTuple &T) { - T.set<0>(U.id); - T.set<1>(U.action); - T.set<2>(U.userId); - T.set<3>(U.actionTemplate); - T.set<4>(OpenWifi::RESTAPI_utils::to_string(U.variables)); - T.set<5>(U.locale); - T.set<6>(U.message); - T.set<7>(U.sent); - T.set<8>(U.created); - T.set<9>(U.expires); - T.set<10>(U.completed); - T.set<11>(U.canceled); - T.set<12>(U.userAction); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::ActionLink &U, OpenWifi::ActionLinkRecordTuple &T) { + T.set<0>(U.id); + T.set<1>(U.action); + T.set<2>(U.userId); + T.set<3>(U.actionTemplate); + T.set<4>(OpenWifi::RESTAPI_utils::to_string(U.variables)); + T.set<5>(U.locale); + T.set<6>(U.message); + T.set<7>(U.sent); + T.set<8>(U.created); + T.set<9>(U.expires); + T.set<10>(U.completed); + T.set<11>(U.canceled); + T.set<12>(U.userAction); } diff --git a/src/storage/orm_actionLinks.h b/src/storage/orm_actionLinks.h index 83fa36d..466b04d 100644 --- a/src/storage/orm_actionLinks.h +++ b/src/storage/orm_actionLinks.h @@ -4,46 +4,45 @@ #pragma once -#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { - typedef Poco::Tuple < - std::string, // id - uint64_t, // action - std::string, // userId - std::string, // actionTemplate - std::string, // variables - std::string, // locale - std::string, // message - uint64_t, // sent - uint64_t, // created - uint64_t, // expires - uint64_t, // completed - uint64_t, // canceled - bool // userAction - > ActionLinkRecordTuple; - typedef std::vector ActionLinkRecordTupleList; + typedef Poco::Tuple + ActionLinkRecordTuple; + typedef std::vector ActionLinkRecordTupleList; - class ActionLinkDB : public ORM::DB { - public: - ActionLinkDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); - virtual ~ActionLinkDB() {} - bool CreateAction( SecurityObjects::ActionLink & A); - bool DeleteAction(std::string &ActionId); - bool CompleteAction(std::string &ActionId); - bool CancelAction(std::string &ActionId); - bool SentAction(std::string &ActionId); - bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A); - bool GetActions(std::vector &Links, uint64_t Max=200); - void CleanOldActionLinks(); + class ActionLinkDB : public ORM::DB { + public: + ActionLinkDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~ActionLinkDB() {} + bool CreateAction(SecurityObjects::ActionLink &A); + bool DeleteAction(std::string &ActionId); + bool CompleteAction(std::string &ActionId); + bool CancelAction(std::string &ActionId); + bool SentAction(std::string &ActionId); + bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A); + bool GetActions(std::vector &Links, uint64_t Max = 200); + void CleanOldActionLinks(); - inline uint32_t Version() override { return 1;} - bool Upgrade(uint32_t from, uint32_t &to) override; - - private: - - }; -} + inline uint32_t Version() override { return 1; } + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + }; +} // namespace OpenWifi diff --git a/src/storage/orm_apikeys.cpp b/src/storage/orm_apikeys.cpp index 4cd7295..7ed6eb9 100644 --- a/src/storage/orm_apikeys.cpp +++ b/src/storage/orm_apikeys.cpp @@ -3,105 +3,98 @@ // #include "orm_apikeys.h" -#include "framework/RESTAPI_utils.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" -#include "framework/orm.h" #include "AuthService.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "StorageService.h" #include "fmt/format.h" +#include "framework/RESTAPI_utils.h" +#include "framework/orm.h" namespace OpenWifi { - static ORM::FieldVec ApiKeyDB_Fields{ - ORM::Field{"id", 36, true}, - ORM::Field{"userUuid", ORM::FieldType::FT_TEXT}, - ORM::Field{"name", ORM::FieldType::FT_TEXT}, - ORM::Field{"description", ORM::FieldType::FT_TEXT}, - ORM::Field{"apiKey", ORM::FieldType::FT_TEXT}, - ORM::Field{"salt", ORM::FieldType::FT_TEXT}, - ORM::Field{"created", ORM::FieldType::FT_BIGINT}, - ORM::Field{"expiresOn", ORM::FieldType::FT_BIGINT}, - ORM::Field{"rights", ORM::FieldType::FT_TEXT}, - ORM::Field{"lastUse", ORM::FieldType::FT_BIGINT} - }; + static ORM::FieldVec ApiKeyDB_Fields{ORM::Field{"id", 36, true}, + ORM::Field{"userUuid", ORM::FieldType::FT_TEXT}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"description", ORM::FieldType::FT_TEXT}, + ORM::Field{"apiKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"salt", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"expiresOn", ORM::FieldType::FT_BIGINT}, + ORM::Field{"rights", ORM::FieldType::FT_TEXT}, + ORM::Field{"lastUse", ORM::FieldType::FT_BIGINT}}; - static ORM::IndexVec MakeIndices(const std::string & shortname) { - return ORM::IndexVec{ - {std::string(shortname + "_username_index"), - ORM::IndexEntryVec{ - { - std::string("userUuid"), - ORM::Indextype::ASC }}}, - {std::string(shortname + "_apikey_index"), - ORM::IndexEntryVec{ - { - std::string("apiKey"), - ORM::Indextype::ASC} - } - } - }; - }; + static ORM::IndexVec MakeIndices(const std::string &shortname) { + return ORM::IndexVec{{std::string(shortname + "_username_index"), + ORM::IndexEntryVec{{std::string("userUuid"), ORM::Indextype::ASC}}}, + {std::string(shortname + "_apikey_index"), + ORM::IndexEntryVec{{std::string("apiKey"), ORM::Indextype::ASC}}}}; + }; - ApiKeyDB::ApiKeyDB( const std::string &TableName, const std::string &Shortname ,OpenWifi::DBType T, - Poco::Data::SessionPool &P, Poco::Logger &L) : - DB(T, TableName.c_str(), ApiKeyDB_Fields, MakeIndices(Shortname), P, L, Shortname.c_str()) { - } + ApiKeyDB::ApiKeyDB(const std::string &TableName, const std::string &Shortname, + OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, TableName.c_str(), ApiKeyDB_Fields, MakeIndices(Shortname), P, L, + Shortname.c_str()) {} - bool ApiKeyDB::RemoveAllApiKeys(const std::string & user_uuid) { - SecurityObjects::ApiKeyEntryList Keys; - if(StorageService()->ApiKeyDB().GetRecords(0,500,Keys.apiKeys,fmt::format(" userUuid='{}' ", user_uuid))) { - for(const auto &key:Keys.apiKeys) { - AuthService()->RemoveTokenSystemWide(key.apiKey); - } - } - return true; - } + bool ApiKeyDB::RemoveAllApiKeys(const std::string &user_uuid) { + SecurityObjects::ApiKeyEntryList Keys; + if (StorageService()->ApiKeyDB().GetRecords(0, 500, Keys.apiKeys, + fmt::format(" userUuid='{}' ", user_uuid))) { + for (const auto &key : Keys.apiKeys) { + AuthService()->RemoveTokenSystemWide(key.apiKey); + } + } + return true; + } - bool ApiKeyDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { - to = Version(); - std::vector Script{ - }; + bool ApiKeyDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + to = Version(); + std::vector Script{}; - for(const auto &i:Script) { - try { - auto Session = Pool_.get(); - Session << i , Poco::Data::Keywords::now; - } catch (...) { + for (const auto &i : Script) { + try { + auto Session = Pool_.get(); + Session << i, Poco::Data::Keywords::now; + } catch (...) { + } + } + return true; + } - } - } - return true; - } + bool ApiKeyDB::RemoveExpiredAPIKeys() { + std::string WhereClause{" expiresOn <= " + std::to_string(OpenWifi::Now())}; + DeleteRecords(WhereClause); + return true; + } - bool ApiKeyDB::RemoveExpiredAPIKeys() { - std::string WhereClause{" expiresOn <= " + std::to_string(OpenWifi::Now())}; - DeleteRecords( WhereClause ); - return true; - } +} // namespace OpenWifi -} // OpenWifi - -template<> void ORM::DB::Convert(const OpenWifi::ApiKeyRecordTuple &In, OpenWifi::SecurityObjects::ApiKeyEntry &Out) { - Out.id = In.get<0>(); - Out.userUuid = In.get<1>(); - Out.name = In.get<2>(); - Out.description = In.get<3>(); - Out.apiKey = In.get<4>(); - Out.salt = In.get<5>(); - Out.created = In.get<6>(); - Out.expiresOn = In.get<7>(); - Out.rights.acls = OpenWifi::RESTAPI_utils::to_object_array(In.get<8>()); - Out.lastUse = In.get<9>(); +template <> +void ORM::DB::Convert( + const OpenWifi::ApiKeyRecordTuple &In, OpenWifi::SecurityObjects::ApiKeyEntry &Out) { + Out.id = In.get<0>(); + Out.userUuid = In.get<1>(); + Out.name = In.get<2>(); + Out.description = In.get<3>(); + Out.apiKey = In.get<4>(); + Out.salt = In.get<5>(); + Out.created = In.get<6>(); + Out.expiresOn = In.get<7>(); + Out.rights.acls = + OpenWifi::RESTAPI_utils::to_object_array( + In.get<8>()); + Out.lastUse = In.get<9>(); } -template<> void ORM::DB::Convert(const OpenWifi::SecurityObjects::ApiKeyEntry &In, OpenWifi::ApiKeyRecordTuple &Out) { - Out.set<0>(In.id); - Out.set<1>(In.userUuid); - Out.set<2>(In.name); - Out.set<3>(In.description); - Out.set<4>(In.apiKey); - Out.set<5>(In.salt); - Out.set<6>(In.created); - Out.set<7>(In.expiresOn); - Out.set<8>(OpenWifi::RESTAPI_utils::to_string(In.rights.acls)); - Out.set<9>(In.lastUse); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::ApiKeyEntry &In, OpenWifi::ApiKeyRecordTuple &Out) { + Out.set<0>(In.id); + Out.set<1>(In.userUuid); + Out.set<2>(In.name); + Out.set<3>(In.description); + Out.set<4>(In.apiKey); + Out.set<5>(In.salt); + Out.set<6>(In.created); + Out.set<7>(In.expiresOn); + Out.set<8>(OpenWifi::RESTAPI_utils::to_string(In.rights.acls)); + Out.set<9>(In.lastUse); } diff --git a/src/storage/orm_apikeys.h b/src/storage/orm_apikeys.h index 18f5d5b..83a23cc 100644 --- a/src/storage/orm_apikeys.h +++ b/src/storage/orm_apikeys.h @@ -4,37 +4,35 @@ #pragma once -#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { - typedef Poco::Tuple< - std::string, // id - std::string, // userUuid - std::string, // name - std::string, // description - std::string, // apiKey - std::string, // salt - uint64_t, // created = 0; - uint64_t, // expiresOn = 0; - std::string, // rights - std::uint64_t // lastUse - > ApiKeyRecordTuple; - typedef std::vector ApiKeyRecordTupleTupleList; + typedef Poco::Tuple + ApiKeyRecordTuple; + typedef std::vector ApiKeyRecordTupleTupleList; - class ApiKeyDB : public ORM::DB { - public: - ApiKeyDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); - virtual ~ApiKeyDB() {} - inline uint32_t Version() override { - return 1; - } + class ApiKeyDB : public ORM::DB { + public: + ApiKeyDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~ApiKeyDB() {} + inline uint32_t Version() override { return 1; } - bool Upgrade(uint32_t from, uint32_t &to) override; - bool RemoveAllApiKeys(const std::string & user_uuid); - bool RemoveExpiredAPIKeys(); + bool Upgrade(uint32_t from, uint32_t &to) override; + bool RemoveAllApiKeys(const std::string &user_uuid); + bool RemoveExpiredAPIKeys(); + }; - }; - -} +} // namespace OpenWifi diff --git a/src/storage/orm_avatar.cpp b/src/storage/orm_avatar.cpp index 1c1d845..9fd2c7b 100644 --- a/src/storage/orm_avatar.cpp +++ b/src/storage/orm_avatar.cpp @@ -7,101 +7,96 @@ #include "StorageService.h" /* - std::string id; - std::string type; - uint64_t created=0; - std::string name; - Poco::Data::LOB avatar; + std::string id; + std::string type; + uint64_t created=0; + std::string name; + Poco::Data::LOB avatar; */ namespace OpenWifi { - static ORM::FieldVec AvatarDB_Fields{ - ORM::Field{"id", 36, true}, - ORM::Field{"type", ORM::FieldType::FT_TEXT}, - ORM::Field{"created", ORM::FieldType::FT_BIGINT}, - ORM::Field{"name", ORM::FieldType::FT_TEXT}, - ORM::Field{"avatar", ORM::FieldType::FT_BLOB} - }; + static ORM::FieldVec AvatarDB_Fields{ + ORM::Field{"id", 36, true}, ORM::Field{"type", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, ORM::Field{"avatar", ORM::FieldType::FT_BLOB}}; - AvatarDB::AvatarDB(const std::string &Name, const std::string &ShortName, OpenWifi::DBType T, - Poco::Data::SessionPool &P, Poco::Logger &L) : - DB(T, Name.c_str(), AvatarDB_Fields,{}, P, L, ShortName.c_str()) { - } + AvatarDB::AvatarDB(const std::string &Name, const std::string &ShortName, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, Name.c_str(), AvatarDB_Fields, {}, P, L, ShortName.c_str()) {} - bool AvatarDB::SetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, const std::string & AvatarContent, - std::string &Type, std::string &Name) { + bool AvatarDB::SetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, + const std::string &AvatarContent, std::string &Type, + std::string &Name) { - try { - SecurityObjects::Avatar A; - A.id = Id; - A.type = Type; - A.name = Name; - A.created = OpenWifi::Now(); - A.avatar.appendRaw((const unsigned char *)AvatarContent.c_str(),AvatarContent.size()); + try { + SecurityObjects::Avatar A; + A.id = Id; + A.type = Type; + A.name = Name; + A.created = OpenWifi::Now(); + A.avatar.appendRaw((const unsigned char *)AvatarContent.c_str(), AvatarContent.size()); - if (Exists("id", Id)) { - return UpdateRecord("id", Id, A); - } - return CreateRecord(A); - } catch (const Poco::Exception &E) { - Logger().log(E); - } catch (...) { + if (Exists("id", Id)) { + return UpdateRecord("id", Id, A); + } + return CreateRecord(A); + } catch (const Poco::Exception &E) { + Logger().log(E); + } catch (...) { + } + return false; + } - } - return false; - } + inline uint8_t fromhex(const char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; + } - inline uint8_t fromhex(const char c) { - if(c>='0' && c<='9') - return c-'0'; - if(c>='a' && c<='f') - return c-'a'+10; - if(c>='A' && c<='F') - return c-'A'+10; - return 0; - } + bool AvatarDB::GetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, + std::string &AvatarContent, std::string &Type, std::string &Name) { + SecurityObjects::Avatar A; + try { + if (GetRecord("id", Id, A)) { + Type = A.type; + Name = A.name; + AvatarContent = ORM::to_string(A.avatar); + return true; + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } catch (...) { + } + return false; + } - bool AvatarDB::GetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, std::string & AvatarContent, - std::string &Type, std::string &Name) { - SecurityObjects::Avatar A; - try { - if(GetRecord("id",Id,A)) { - Type = A.type; - Name = A.name; - AvatarContent = ORM::to_string(A.avatar); - return true; - } - } catch (const Poco::Exception &E) { - Logger().log(E); - } catch (...) { + bool AvatarDB::DeleteAvatar([[maybe_unused]] const std::string &Admin, std::string &Id) { + return DeleteRecord("id", Id); + } - } - return false; - } - - bool AvatarDB::DeleteAvatar([[maybe_unused]] const std::string &Admin, std::string &Id) { - return DeleteRecord("id",Id); - } +} // namespace OpenWifi +template <> +void ORM::DB::Convert( + const OpenWifi::AvatarRecordTuple &T, OpenWifi::SecurityObjects::Avatar &U) { + U.id = T.get<0>(); + U.type = T.get<1>(); + U.created = T.get<2>(); + U.name = T.get<3>(); + U.avatar = T.get<4>(); } -template<> void ORM::DB::Convert(const OpenWifi::AvatarRecordTuple &T, - OpenWifi::SecurityObjects::Avatar &U) { - U.id = T.get<0>(); - U.type = T.get<1>(); - U.created = T.get<2>(); - U.name = T.get<3>(); - U.avatar = T.get<4>(); -} - -template<> void ORM::DB::Convert(const OpenWifi::SecurityObjects::Avatar &U, - OpenWifi::AvatarRecordTuple &T) { - T.set<0>(U.id); - T.set<1>(U.type); - T.set<2>(U.created); - T.set<3>(U.name); - T.set<4>(U.avatar); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::Avatar &U, OpenWifi::AvatarRecordTuple &T) { + T.set<0>(U.id); + T.set<1>(U.type); + T.set<2>(U.created); + T.set<3>(U.name); + T.set<4>(U.avatar); } diff --git a/src/storage/orm_avatar.h b/src/storage/orm_avatar.h index 4535192..5b15fce 100644 --- a/src/storage/orm_avatar.h +++ b/src/storage/orm_avatar.h @@ -4,38 +4,40 @@ #pragma once -#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { -/* - std::string id; - std::string type; - uint64_t created=0; - std::string name; - Poco::Data::LOB avatar; -*/ + /* + std::string id; + std::string type; + uint64_t created=0; + std::string name; + Poco::Data::LOB avatar; + */ - typedef Poco::Tuple < - std::string, // id - std::string, // type - uint64_t, // created - std::string, // name - Poco::Data::BLOB // avatar - > AvatarRecordTuple; - typedef std::vector AvatarRecordTupleList; + typedef Poco::Tuple + AvatarRecordTuple; + typedef std::vector AvatarRecordTupleList; - class AvatarDB : public ORM::DB { - public: - AvatarDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); - virtual ~AvatarDB() {} + class AvatarDB : public ORM::DB { + public: + AvatarDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~AvatarDB() {} - bool SetAvatar(const std::string & Admin, std::string &Id, const std::string & AvatarContent, std::string &Type, std::string & Name); - bool GetAvatar(const std::string & Admin, std::string &Id, std::string & AvatarContent, std::string &Type, std::string & Name); - bool DeleteAvatar(const std::string & Admin, std::string &Id); + bool SetAvatar(const std::string &Admin, std::string &Id, const std::string &AvatarContent, + std::string &Type, std::string &Name); + bool GetAvatar(const std::string &Admin, std::string &Id, std::string &AvatarContent, + std::string &Type, std::string &Name); + bool DeleteAvatar(const std::string &Admin, std::string &Id); - private: - - }; -} + private: + }; +} // namespace OpenWifi diff --git a/src/storage/orm_logins.cpp b/src/storage/orm_logins.cpp index b58281c..90abcff 100644 --- a/src/storage/orm_logins.cpp +++ b/src/storage/orm_logins.cpp @@ -7,66 +7,63 @@ namespace OpenWifi { - static ORM::FieldVec LoginDB_Fields{ - ORM::Field{"session", 64, true}, - ORM::Field{"userId", ORM::FieldType::FT_TEXT}, - ORM::Field{"email", ORM::FieldType::FT_TEXT}, - ORM::Field{"login", ORM::FieldType::FT_BIGINT}, - ORM::Field{"logout", ORM::FieldType::FT_BIGINT} - }; + static ORM::FieldVec LoginDB_Fields{ORM::Field{"session", 64, true}, + ORM::Field{"userId", ORM::FieldType::FT_TEXT}, + ORM::Field{"email", ORM::FieldType::FT_TEXT}, + ORM::Field{"login", ORM::FieldType::FT_BIGINT}, + ORM::Field{"logout", ORM::FieldType::FT_BIGINT}}; - static ORM::IndexVec MakeIndices(const std::string & shortname) { - return ORM::IndexVec{ - {std::string(shortname + "_userid_index"), - ORM::IndexEntryVec{ - {std::string("userId"), - ORM::Indextype::ASC}}} - }; - } + static ORM::IndexVec MakeIndices(const std::string &shortname) { + return ORM::IndexVec{{std::string(shortname + "_userid_index"), + ORM::IndexEntryVec{{std::string("userId"), ORM::Indextype::ASC}}}}; + } - LoginDB::LoginDB( const std::string &TableName, const std::string &Shortname ,OpenWifi::DBType T, - Poco::Data::SessionPool &P, Poco::Logger &L) : - DB(T, TableName.c_str(), LoginDB_Fields, MakeIndices(Shortname), P, L, Shortname.c_str()) { - } + LoginDB::LoginDB(const std::string &TableName, const std::string &Shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, TableName.c_str(), LoginDB_Fields, MakeIndices(Shortname), P, L, + Shortname.c_str()) {} - static std::string MakeSessionId(const std::string & token) { - return Utils::ComputeHash(token); - } + static std::string MakeSessionId(const std::string &token) { return Utils::ComputeHash(token); } - void LoginDB::AddLogin( const std::string & userId, const std::string & email, const std::string &token) { - SecurityObjects::LoginRecordInfo R; + void LoginDB::AddLogin(const std::string &userId, const std::string &email, + const std::string &token) { + SecurityObjects::LoginRecordInfo R; - R.sessionId = MakeSessionId(token); - R.userId = userId; - R.email = email; - R.login = OpenWifi::Now(); - R.logout = 0; - CreateRecord(R); - } + R.sessionId = MakeSessionId(token); + R.userId = userId; + R.email = email; + R.login = OpenWifi::Now(); + R.logout = 0; + CreateRecord(R); + } - void LoginDB::AddLogout(const std::string &token) { - auto Session = MakeSessionId(token); - SecurityObjects::LoginRecordInfo R; + void LoginDB::AddLogout(const std::string &token) { + auto Session = MakeSessionId(token); + SecurityObjects::LoginRecordInfo R; - if(GetRecord("session", Session, R)) { - R.logout = OpenWifi::Now(); - UpdateRecord("session", Session, R); - } - } + if (GetRecord("session", Session, R)) { + R.logout = OpenWifi::Now(); + UpdateRecord("session", Session, R); + } + } +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::LoginInfoRecordTuple &R, OpenWifi::SecurityObjects::LoginRecordInfo &P) { + P.sessionId = R.get<0>(); + P.userId = R.get<1>(); + P.email = R.get<2>(); + P.login = R.get<3>(); + P.logout = R.get<4>(); } -template<> void ORM::DB::Convert(const OpenWifi::LoginInfoRecordTuple &R, OpenWifi::SecurityObjects::LoginRecordInfo &P ) { - P.sessionId = R.get<0>(); - P.userId = R.get<1>(); - P.email = R.get<2>(); - P.login = R.get<3>(); - P.logout = R.get<4>(); -} - -template<> void ORM::DB::Convert(const OpenWifi::SecurityObjects::LoginRecordInfo &P, OpenWifi::LoginInfoRecordTuple &R ) { - R.set<0>(P.sessionId); - R.set<1>(P.userId); - R.set<2>(P.email); - R.set<3>(P.login); - R.set<4>(P.logout); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::LoginRecordInfo &P, OpenWifi::LoginInfoRecordTuple &R) { + R.set<0>(P.sessionId); + R.set<1>(P.userId); + R.set<2>(P.email); + R.set<3>(P.login); + R.set<4>(P.logout); } diff --git a/src/storage/orm_logins.h b/src/storage/orm_logins.h index 8e72af1..d80fea3 100644 --- a/src/storage/orm_logins.h +++ b/src/storage/orm_logins.h @@ -4,28 +4,28 @@ #pragma once -#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { - typedef Poco::Tuple< - std::string, // SessionId - std::string, // UserID - std::string, // UserEMail - uint64_t, // login = 0; - uint64_t // logout = 0; - > LoginInfoRecordTuple; - typedef std::vector LoginInfoRecordTupleList; + typedef Poco::Tuple + LoginInfoRecordTuple; + typedef std::vector LoginInfoRecordTupleList; - class LoginDB : public ORM::DB { - public: - LoginDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); - virtual ~LoginDB() {} + class LoginDB : public ORM::DB { + public: + LoginDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~LoginDB() {} - void AddLogin(const std::string & id, const std::string & email, const std::string &token); - void AddLogout(const std::string &token); - }; - -} + void AddLogin(const std::string &id, const std::string &email, const std::string &token); + void AddLogout(const std::string &token); + }; +} // namespace OpenWifi diff --git a/src/storage/orm_preferences.cpp b/src/storage/orm_preferences.cpp index bba0b99..db33a4d 100644 --- a/src/storage/orm_preferences.cpp +++ b/src/storage/orm_preferences.cpp @@ -6,46 +6,48 @@ #include "framework/RESTAPI_utils.h" /* - "Id varchar(36) UNIQUE PRIMARY KEY," - "modified bigint," - "data text"}; + "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} - }; + 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()) { - } + 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::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::SetPreferences(SecurityObjects::Preferences &P) { + return ReplaceRecord("id", P.id, P); + } - bool PreferencesDB::DeletePreferences([[maybe_unused]] const std::string &AdminId, std::string &Id) { - return DeleteRecord("id",Id); - } + bool PreferencesDB::DeletePreferences([[maybe_unused]] const std::string &AdminId, + std::string &Id) { + return DeleteRecord("id", Id); + } +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const 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::Convert(const 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::Convert(const 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)); +template <> +void ORM::DB::Convert( + const 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)); } diff --git a/src/storage/orm_preferences.h b/src/storage/orm_preferences.h index 155e14c..ed01fec 100644 --- a/src/storage/orm_preferences.h +++ b/src/storage/orm_preferences.h @@ -4,28 +4,28 @@ #pragma once -#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { - typedef Poco::Tuple< - std::string, // id - uint64_t, // modified - std::string // data - > PreferencesRecordTuple; - typedef std::vector PreferencesRecordTupleList; + typedef Poco::Tuple + PreferencesRecordTuple; + typedef std::vector PreferencesRecordTupleList; - class PreferencesDB : public ORM::DB { - public: - PreferencesDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); + class PreferencesDB : public ORM::DB { + 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); - virtual ~PreferencesDB() {} - - private: - }; -} + bool GetPreferences(std::string &Id, SecurityObjects::Preferences &P); + bool SetPreferences(SecurityObjects::Preferences &P); + bool DeletePreferences(const std::string &AdminId, std::string &Id); + virtual ~PreferencesDB() {} + private: + }; +} // namespace OpenWifi diff --git a/src/storage/orm_tokens.cpp b/src/storage/orm_tokens.cpp index 23d878c..ead327a 100644 --- a/src/storage/orm_tokens.cpp +++ b/src/storage/orm_tokens.cpp @@ -8,204 +8,206 @@ #include "framework/RESTAPI_utils.h" /* - "Token TEXT PRIMARY KEY, " - "RefreshToken TEXT, " - "TokenType TEXT, " - "UserName TEXT, " - "Created BIGINT, " - "Expires BIGINT, " - "IdleTimeOut BIGINT, " - "RevocationDate BIGINT " + "Token TEXT PRIMARY KEY, " + "RefreshToken TEXT, " + "TokenType TEXT, " + "UserName TEXT, " + "Created BIGINT, " + "Expires BIGINT, " + "IdleTimeOut BIGINT, " + "RevocationDate BIGINT " */ namespace OpenWifi { - static ORM::FieldVec BaseTokenDB_Fields{ - ORM::Field{"token", ORM::FT_TEXT, 0, true}, - ORM::Field{"refreshToken", ORM::FieldType::FT_TEXT}, - ORM::Field{"tokenType", ORM::FieldType::FT_TEXT}, - ORM::Field{"userName", ORM::FieldType::FT_TEXT}, - ORM::Field{"created", ORM::FieldType::FT_BIGINT}, - ORM::Field{"expires", ORM::FieldType::FT_BIGINT}, - ORM::Field{"idleTimeOut", ORM::FieldType::FT_BIGINT}, - ORM::Field{"revocationDate", ORM::FieldType::FT_BIGINT}, - ORM::Field{"lastRefresh", ORM::FieldType::FT_BIGINT} - }; + static ORM::FieldVec BaseTokenDB_Fields{ORM::Field{"token", ORM::FT_TEXT, 0, true}, + ORM::Field{"refreshToken", ORM::FieldType::FT_TEXT}, + ORM::Field{"tokenType", ORM::FieldType::FT_TEXT}, + ORM::Field{"userName", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"expires", ORM::FieldType::FT_BIGINT}, + ORM::Field{"idleTimeOut", ORM::FieldType::FT_BIGINT}, + ORM::Field{"revocationDate", ORM::FieldType::FT_BIGINT}, + ORM::Field{"lastRefresh", ORM::FieldType::FT_BIGINT}}; - static ORM::IndexVec MakeIndices(const std::string &shortname) { - return ORM::IndexVec{ - {std::string(shortname + "_user_id_index"), - ORM::IndexEntryVec{ - {std::string("userName"), - ORM::Indextype::ASC}}}, - {std::string(shortname + "_refresh_index"), - ORM::IndexEntryVec{ - {std::string("refreshToken"), - ORM::Indextype::ASC}}} - }; - } + static ORM::IndexVec MakeIndices(const std::string &shortname) { + return ORM::IndexVec{ + {std::string(shortname + "_user_id_index"), + ORM::IndexEntryVec{{std::string("userName"), ORM::Indextype::ASC}}}, + {std::string(shortname + "_refresh_index"), + ORM::IndexEntryVec{{std::string("refreshToken"), ORM::Indextype::ASC}}}}; + } - BaseTokenDB::BaseTokenDB(const std::string &Name, const std::string &ShortName, OpenWifi::DBType T, - Poco::Data::SessionPool &P, Poco::Logger &L, TokenCache *Cache, [[maybe_unused]] bool Users) : - DB(T, Name.c_str(), BaseTokenDB_Fields, MakeIndices(ShortName), P, L, ShortName.c_str(), Cache) { - } + BaseTokenDB::BaseTokenDB(const std::string &Name, const std::string &ShortName, + OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L, + TokenCache *Cache, [[maybe_unused]] bool Users) + : DB(T, Name.c_str(), BaseTokenDB_Fields, MakeIndices(ShortName), P, L, ShortName.c_str(), + Cache) {} - bool BaseTokenDB::AddToken(std::string &UserID, std::string &Token, std::string &RefreshToken, [[maybe_unused]] std::string & TokenType, uint64_t Expires, uint64_t TimeOut) { - SecurityObjects::Token T{.token=Token, .refreshToken=RefreshToken, .tokenType="Bearer", .userName=UserID, - .created=(uint64_t) OpenWifi::Now(), .expires=Expires, .idleTimeout=TimeOut,.revocationDate=0}; - return CreateRecord(T); - } + bool BaseTokenDB::AddToken(std::string &UserID, std::string &Token, std::string &RefreshToken, + [[maybe_unused]] std::string &TokenType, uint64_t Expires, + uint64_t TimeOut) { + SecurityObjects::Token T{.token = Token, + .refreshToken = RefreshToken, + .tokenType = "Bearer", + .userName = UserID, + .created = (uint64_t)OpenWifi::Now(), + .expires = Expires, + .idleTimeout = TimeOut, + .revocationDate = 0}; + return CreateRecord(T); + } - bool BaseTokenDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { - std::vector Statements{ - "alter table " + TableName_ + " add column lastRefresh BIGINT default 0;" - }; - RunScript(Statements); - to = 1; - return true; + bool BaseTokenDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + std::vector Statements{"alter table " + TableName_ + + " add column lastRefresh BIGINT default 0;"}; + RunScript(Statements); + to = 1; + return true; - return true; - } + return true; + } - bool BaseTokenDB::GetToken(std::string &Token, SecurityObjects::WebToken &WT, std::string & UserId, uint64_t &RevocationDate) { - SecurityObjects::Token T; + bool BaseTokenDB::GetToken(std::string &Token, SecurityObjects::WebToken &WT, + std::string &UserId, uint64_t &RevocationDate) { + SecurityObjects::Token T; - if(GetRecord("token", Token, T)) { - WT.access_token_ = T.token; - WT.refresh_token_ = T.refreshToken; - WT.token_type_ = T.tokenType; - WT.username_ = T.userName; - WT.created_ = T.created; - WT.expires_in_ = T.expires; - WT.idle_timeout_ = T.idleTimeout; - WT.lastRefresh_ = T.lastRefresh; - RevocationDate = T.revocationDate; - UserId = T.userName; - return true; - } - return false; - } + if (GetRecord("token", Token, T)) { + WT.access_token_ = T.token; + WT.refresh_token_ = T.refreshToken; + WT.token_type_ = T.tokenType; + WT.username_ = T.userName; + WT.created_ = T.created; + WT.expires_in_ = T.expires; + WT.idle_timeout_ = T.idleTimeout; + WT.lastRefresh_ = T.lastRefresh; + RevocationDate = T.revocationDate; + UserId = T.userName; + return true; + } + return false; + } - bool BaseTokenDB::RefreshToken(const std::string &OldToken, const std::string &NewToken, const std::string &NewRefreshToken, uint64_t LastRefresh ) { - SecurityObjects::Token T; + bool BaseTokenDB::RefreshToken(const std::string &OldToken, const std::string &NewToken, + const std::string &NewRefreshToken, uint64_t LastRefresh) { + SecurityObjects::Token T; - if(GetRecord("token", OldToken, T)) { - T.token = NewToken; - T.refreshToken = NewRefreshToken; - T.lastRefresh = LastRefresh; - T.created = OpenWifi::Now(); - UpdateRecord("token",OldToken,T); - Cache_->Delete("token",OldToken); - Cache_->UpdateCache(T); - return true; - } - return false; - } + if (GetRecord("token", OldToken, T)) { + T.token = NewToken; + T.refreshToken = NewRefreshToken; + T.lastRefresh = LastRefresh; + T.created = OpenWifi::Now(); + UpdateRecord("token", OldToken, T); + Cache_->Delete("token", OldToken); + Cache_->UpdateCache(T); + return true; + } + return false; + } - bool BaseTokenDB::IsTokenRevoked(std::string &Token) { - SecurityObjects::Token T; + bool BaseTokenDB::IsTokenRevoked(std::string &Token) { + SecurityObjects::Token T; - if(GetRecord("token",Token,T)) { - return false; - } - return true; - } + if (GetRecord("token", Token, T)) { + return false; + } + return true; + } - bool BaseTokenDB::RevokeToken(std::string &Token) { - return DeleteRecord("token", Token); - } + bool BaseTokenDB::RevokeToken(std::string &Token) { return DeleteRecord("token", Token); } - bool BaseTokenDB::CleanExpiredTokens() { - std::string WhereClause{" (created + expires) <= " + std::to_string(OpenWifi::Now())}; - DeleteRecords( WhereClause ); - return true; - } + bool BaseTokenDB::CleanExpiredTokens() { + std::string WhereClause{" (created + expires) <= " + std::to_string(OpenWifi::Now())}; + DeleteRecords(WhereClause); + return true; + } - bool BaseTokenDB::RevokeAllTokens(std::string & UserId) { - std::string WhereClause{" userName='" + UserId + "' "}; - DeleteRecords( WhereClause ); - Cache_->Delete("userName", UserId); - return true; - } + bool BaseTokenDB::RevokeAllTokens(std::string &UserId) { + std::string WhereClause{" userName='" + UserId + "' "}; + DeleteRecords(WhereClause); + Cache_->Delete("userName", UserId); + return true; + } - TokenCache::TokenCache(unsigned Size, unsigned TimeOut, [[maybe_unused]] bool Users) : - ORM::DBCache(Size,TimeOut) - { - CacheByToken_ = std::make_unique>(Size,TimeOut); - } + TokenCache::TokenCache(unsigned Size, unsigned TimeOut, [[maybe_unused]] bool Users) + : ORM::DBCache(Size, TimeOut) { + CacheByToken_ = std::make_unique>( + Size, TimeOut); + } - void TokenCache::UpdateCache(const SecurityObjects::Token &R) { - std::lock_guard M(Mutex_); - // std::cout << "Updating token: " << R.token << std::endl; - CacheByToken_->update(R.token,R); - } + void TokenCache::UpdateCache(const SecurityObjects::Token &R) { + std::lock_guard M(Mutex_); + // std::cout << "Updating token: " << R.token << std::endl; + CacheByToken_->update(R.token, R); + } - void TokenCache::Create([[maybe_unused]] const SecurityObjects::Token &R) { + void TokenCache::Create([[maybe_unused]] const SecurityObjects::Token &R) {} - } + bool TokenCache::GetFromCache(const std::string &FieldName, const std::string &Value, + SecurityObjects::Token &R) { + std::lock_guard M(Mutex_); + // std::cout << "Getting token: " << Value << std::endl; + if (FieldName == "token") { + auto Entry = CacheByToken_->get(Value); + if (Entry.isNull()) { + // std::cout << "Getting Token: " << Value << " not found in cache." << std::endl; + return false; + } + R = *Entry; + // std::cout << "Getting Token: " << Value << " found in cache." << std::endl; + return true; + } + // std::cout << "Getting Token: " << FieldName << " not known." << std::endl; + return false; + } - bool TokenCache::GetFromCache(const std::string &FieldName, const std::string &Value, SecurityObjects::Token &R) { - std::lock_guard M(Mutex_); - // std::cout << "Getting token: " << Value << std::endl; - if(FieldName=="token") { - auto Entry = CacheByToken_->get(Value); - if(Entry.isNull()) { - // std::cout << "Getting Token: " << Value << " not found in cache." << std::endl; - return false; - } - R = *Entry; - // std::cout << "Getting Token: " << Value << " found in cache." << std::endl; - return true; - } - // std::cout << "Getting Token: " << FieldName << " not known." << std::endl; - return false; - } + void TokenCache::Delete(const std::string &FieldName, const std::string &Value) { + std::lock_guard M(Mutex_); + // std::cout << "Deleting token: " << Value << std::endl; + if (FieldName == "token") { + AuthService()->RemoveTokenSystemWide(Value); + CacheByToken_->remove(Value); + } else if (FieldName == "userName") { + std::vector TokenToRemove; - void TokenCache::Delete(const std::string &FieldName, const std::string &Value) { - std::lock_guard M(Mutex_); - // std::cout << "Deleting token: " << Value << std::endl; - if(FieldName=="token") { - AuthService()->RemoveTokenSystemWide(Value); - CacheByToken_->remove(Value); - } else if(FieldName=="userName") { - std::vector TokenToRemove; + CacheByToken_->forEach( + [&TokenToRemove, Value](const std::string &Key, + const SecurityObjects::Token &TokenRecord) { + if (TokenRecord.userName == Value) + TokenToRemove.push_back(Key); + }); + for (const auto &i : TokenToRemove) { + AuthService()->RemoveTokenSystemWide(i); + CacheByToken_->remove(i); + } + } + } - CacheByToken_->forEach([&TokenToRemove,Value](const std::string &Key, const SecurityObjects::Token &TokenRecord) { - if(TokenRecord.userName==Value) - TokenToRemove.push_back(Key); - }); - for(const auto &i:TokenToRemove) { - AuthService()->RemoveTokenSystemWide(i); - CacheByToken_->remove(i); - } - } - } +} // namespace OpenWifi +template <> +void ORM::DB::Convert( + const OpenWifi::TokenRecordTuple &T, OpenWifi::SecurityObjects::Token &U) { + U.token = T.get<0>(); + U.refreshToken = T.get<1>(); + U.tokenType = T.get<2>(); + U.userName = T.get<3>(); + U.created = T.get<4>(); + U.expires = T.get<5>(); + U.idleTimeout = T.get<6>(); + U.revocationDate = T.get<7>(); + U.lastRefresh = T.get<8>(); } -template<> void ORM::DB::Convert(const OpenWifi::TokenRecordTuple &T, - OpenWifi::SecurityObjects::Token &U) { - U.token = T.get<0>(); - U.refreshToken = T.get<1>(); - U.tokenType = T.get<2>(); - U.userName = T.get<3>(); - U.created = T.get<4>(); - U.expires = T.get<5>(); - U.idleTimeout = T.get<6>(); - U.revocationDate = T.get<7>(); - U.lastRefresh = T.get<8>(); -} - -template<> void ORM::DB< OpenWifi::TokenRecordTuple, - OpenWifi::SecurityObjects::Token>::Convert(const OpenWifi::SecurityObjects::Token &U, - OpenWifi::TokenRecordTuple &T) { - T.set<0>(U.token); - T.set<1>(U.refreshToken); - T.set<2>(U.tokenType); - T.set<3>(U.userName); - T.set<4>(U.created); - T.set<5>(U.expires); - T.set<6>(U.idleTimeout); - T.set<7>(U.revocationDate); - T.set<8>(U.lastRefresh); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::Token &U, OpenWifi::TokenRecordTuple &T) { + T.set<0>(U.token); + T.set<1>(U.refreshToken); + T.set<2>(U.tokenType); + T.set<3>(U.userName); + T.set<4>(U.created); + T.set<5>(U.expires); + T.set<6>(U.idleTimeout); + T.set<7>(U.revocationDate); + T.set<8>(U.lastRefresh); } diff --git a/src/storage/orm_tokens.h b/src/storage/orm_tokens.h index 68febf1..f04e79a 100644 --- a/src/storage/orm_tokens.h +++ b/src/storage/orm_tokens.h @@ -4,69 +4,71 @@ #pragma once -#include "framework/orm.h" -#include "RESTObjects/RESTAPI_SecurityObjects.h" #include "Poco/ExpireLRUCache.h" +#include "RESTObjects/RESTAPI_SecurityObjects.h" +#include "framework/orm.h" namespace OpenWifi { -/* - "Token TEXT PRIMARY KEY, " - "RefreshToken TEXT, " - "TokenType TEXT, " - "UserName TEXT, " - "Created BIGINT, " - "Expires BIGINT, " - "IdleTimeOut BIGINT, " - "RevocationDate BIGINT " -*/ + /* + "Token TEXT PRIMARY KEY, " + "RefreshToken TEXT, " + "TokenType TEXT, " + "UserName TEXT, " + "Created BIGINT, " + "Expires BIGINT, " + "IdleTimeOut BIGINT, " + "RevocationDate BIGINT " + */ - typedef Poco::Tuple< - std::string, // token - std::string, // RefreshToken; - std::string, // TokenType; - std::string, // UserId; - uint64_t, // Created = 0; - uint64_t, // Expires = 0; - uint64_t, // IdleTimeOut = 0; - uint64_t, // RevocationDate = 0; - uint64_t // lastRefresh - > TokenRecordTuple; - typedef std::vector TokenRecordTupleList; + typedef Poco::Tuple + TokenRecordTuple; + typedef std::vector TokenRecordTupleList; - class TokenCache : public ORM::DBCache { - public: + class TokenCache : public ORM::DBCache { + public: + TokenCache(unsigned Size, unsigned TimeOut, bool Users); + virtual ~TokenCache() {} + void UpdateCache(const SecurityObjects::Token &R) override; + void Create(const SecurityObjects::Token &R) override; + bool GetFromCache(const std::string &FieldName, const std::string &Value, + SecurityObjects::Token &R) override; + void Delete(const std::string &FieldName, const std::string &Value) override; - TokenCache(unsigned Size, unsigned TimeOut, bool Users); - virtual ~TokenCache() {} - void UpdateCache(const SecurityObjects::Token &R) override; - void Create(const SecurityObjects::Token &R) override; - bool GetFromCache(const std::string &FieldName, const std::string &Value, SecurityObjects::Token &R) override; - void Delete(const std::string &FieldName, const std::string &Value) override; - private: - std::mutex Mutex_; - std::unique_ptr> CacheByToken_; - }; + private: + std::mutex Mutex_; + std::unique_ptr> CacheByToken_; + }; + class BaseTokenDB : public ORM::DB { + public: + BaseTokenDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L, TokenCache *Cache, bool User); + virtual ~BaseTokenDB() {} - class BaseTokenDB : public ORM::DB { - public: - BaseTokenDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L, TokenCache * Cache, bool User); - virtual ~BaseTokenDB() {} + bool AddToken(std::string &UserId, std::string &Token, std::string &RefreshToken, + std::string &TokenType, uint64_t Expires, uint64_t TimeOut); + bool RevokeToken(std::string &Token); + bool IsTokenRevoked(std::string &Token); + bool CleanExpiredTokens(); + bool RevokeAllTokens(std::string &UserName); + bool GetToken(std::string &Token, SecurityObjects::WebToken &WT, std::string &UserId, + uint64_t &RevocationDate); + bool RefreshToken(const std::string &OldToken, const std::string &NewToken, + const std::string &NewRefreshToken, uint64_t LstRefresh); + inline uint32_t Version() override { return 1; } + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + }; - bool AddToken(std::string &UserId, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut); - bool RevokeToken( std::string & Token ); - bool IsTokenRevoked( std::string & Token ); - bool CleanExpiredTokens(); - bool RevokeAllTokens( std::string & UserName ); - bool GetToken(std::string &Token, SecurityObjects::WebToken &WT, std::string & UserId, uint64_t &RevocationDate); - bool RefreshToken(const std::string &OldToken, const std::string &NewToken, const std::string &NewRefreshToken, uint64_t LstRefresh ); - inline uint32_t Version() override { return 1;} - bool Upgrade(uint32_t from, uint32_t &to) override; - - private: - }; - -} - +} // namespace OpenWifi diff --git a/src/storage/orm_users.cpp b/src/storage/orm_users.cpp index 9124990..f9136af 100644 --- a/src/storage/orm_users.cpp +++ b/src/storage/orm_users.cpp @@ -6,357 +6,360 @@ #include "AuthService.h" #include "RESTObjects/RESTAPI_CertObjects.h" #include "StorageService.h" -#include "framework/RESTAPI_utils.h" #include "framework/MicroServiceFuncs.h" +#include "framework/RESTAPI_utils.h" /* - 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; - uint64_t, // modified - std::string // signingUp + 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; + uint64_t, // modified + std::string // signingUp */ namespace OpenWifi { - static ORM::FieldVec BaseUserDB_Fields{ - // object info - ORM::Field{"id", 36, true}, - ORM::Field{"name", ORM::FieldType::FT_TEXT}, - ORM::Field{"description", ORM::FieldType::FT_TEXT}, - ORM::Field{"avatar", ORM::FieldType::FT_TEXT}, - ORM::Field{"email", ORM::FieldType::FT_TEXT}, - ORM::Field{"validated", ORM::FieldType::FT_BOOLEAN}, - ORM::Field{"validationEmail", ORM::FieldType::FT_TEXT}, - ORM::Field{"validationDate", ORM::FieldType::FT_BIGINT}, - ORM::Field{"creationDate", ORM::FieldType::FT_BIGINT}, - ORM::Field{"validationURI", ORM::FieldType::FT_TEXT}, - ORM::Field{"changePassword", ORM::FieldType::FT_BOOLEAN}, - ORM::Field{"lastLogin", ORM::FieldType::FT_BIGINT}, - ORM::Field{"currentLoginURI", ORM::FieldType::FT_TEXT}, - ORM::Field{"lastPasswordChange", ORM::FieldType::FT_BIGINT}, - ORM::Field{"lastEmailCheck", ORM::FieldType::FT_BIGINT}, - ORM::Field{"waitingForEmailCheck", ORM::FieldType::FT_BOOLEAN}, - ORM::Field{"locale", ORM::FieldType::FT_TEXT}, - ORM::Field{"notes", ORM::FieldType::FT_TEXT}, - ORM::Field{"location", ORM::FieldType::FT_TEXT}, - ORM::Field{"owner", ORM::FieldType::FT_TEXT}, - ORM::Field{"suspended", ORM::FieldType::FT_BOOLEAN}, - ORM::Field{"blackListed", ORM::FieldType::FT_BOOLEAN}, - ORM::Field{"userRole", ORM::FieldType::FT_TEXT}, - ORM::Field{"userTypeProprietaryInfo", ORM::FieldType::FT_TEXT}, - ORM::Field{"securityPolicy", ORM::FieldType::FT_TEXT}, - ORM::Field{"securityPolicyChange", ORM::FieldType::FT_BIGINT}, - ORM::Field{"currentPassword", ORM::FieldType::FT_TEXT}, - ORM::Field{"lastPasswords", ORM::FieldType::FT_TEXT}, - ORM::Field{"oauthType", ORM::FieldType::FT_TEXT}, - ORM::Field{"oauthUserInfo", ORM::FieldType::FT_TEXT}, - ORM::Field{"modified", ORM::FieldType::FT_TEXT}, - ORM::Field{"signingUp", ORM::FieldType::FT_TEXT} - }; + static ORM::FieldVec BaseUserDB_Fields{ + // object info + ORM::Field{"id", 36, true}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"description", ORM::FieldType::FT_TEXT}, + ORM::Field{"avatar", ORM::FieldType::FT_TEXT}, + ORM::Field{"email", ORM::FieldType::FT_TEXT}, + ORM::Field{"validated", ORM::FieldType::FT_BOOLEAN}, + ORM::Field{"validationEmail", ORM::FieldType::FT_TEXT}, + ORM::Field{"validationDate", ORM::FieldType::FT_BIGINT}, + ORM::Field{"creationDate", ORM::FieldType::FT_BIGINT}, + ORM::Field{"validationURI", ORM::FieldType::FT_TEXT}, + ORM::Field{"changePassword", ORM::FieldType::FT_BOOLEAN}, + ORM::Field{"lastLogin", ORM::FieldType::FT_BIGINT}, + ORM::Field{"currentLoginURI", ORM::FieldType::FT_TEXT}, + ORM::Field{"lastPasswordChange", ORM::FieldType::FT_BIGINT}, + ORM::Field{"lastEmailCheck", ORM::FieldType::FT_BIGINT}, + ORM::Field{"waitingForEmailCheck", ORM::FieldType::FT_BOOLEAN}, + ORM::Field{"locale", ORM::FieldType::FT_TEXT}, + ORM::Field{"notes", ORM::FieldType::FT_TEXT}, + ORM::Field{"location", ORM::FieldType::FT_TEXT}, + ORM::Field{"owner", ORM::FieldType::FT_TEXT}, + ORM::Field{"suspended", ORM::FieldType::FT_BOOLEAN}, + ORM::Field{"blackListed", ORM::FieldType::FT_BOOLEAN}, + ORM::Field{"userRole", ORM::FieldType::FT_TEXT}, + ORM::Field{"userTypeProprietaryInfo", ORM::FieldType::FT_TEXT}, + ORM::Field{"securityPolicy", ORM::FieldType::FT_TEXT}, + ORM::Field{"securityPolicyChange", ORM::FieldType::FT_BIGINT}, + ORM::Field{"currentPassword", ORM::FieldType::FT_TEXT}, + ORM::Field{"lastPasswords", ORM::FieldType::FT_TEXT}, + ORM::Field{"oauthType", ORM::FieldType::FT_TEXT}, + ORM::Field{"oauthUserInfo", ORM::FieldType::FT_TEXT}, + ORM::Field{"modified", ORM::FieldType::FT_TEXT}, + ORM::Field{"signingUp", ORM::FieldType::FT_TEXT}}; - static ORM::IndexVec MakeIndices(const std::string & shortname) { - return ORM::IndexVec{ - {std::string(shortname + "_user_email_index"), - ORM::IndexEntryVec{ - {std::string("email"), - ORM::Indextype::ASC}}}, - {std::string(shortname + "_user_name_index"), - ORM::IndexEntryVec{ - {std::string("name"), - ORM::Indextype::ASC}}} - }; - } + static ORM::IndexVec MakeIndices(const std::string &shortname) { + return ORM::IndexVec{{std::string(shortname + "_user_email_index"), + ORM::IndexEntryVec{{std::string("email"), ORM::Indextype::ASC}}}, + {std::string(shortname + "_user_name_index"), + ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}}; + } - BaseUserDB::BaseUserDB(const std::string &Name, const std::string & ShortName, OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L, UserCache * Cache, bool Users) : - DB(T, Name.c_str(), BaseUserDB_Fields, MakeIndices(ShortName), P, L, ShortName.c_str(), Cache), - UsersOnly_(Users) { - } + BaseUserDB::BaseUserDB(const std::string &Name, const std::string &ShortName, + OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L, + UserCache *Cache, bool Users) + : DB(T, Name.c_str(), BaseUserDB_Fields, MakeIndices(ShortName), P, L, ShortName.c_str(), + Cache), + UsersOnly_(Users) {} - bool BaseUserDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { - std::vector Statements{ - "alter table " + TableName_ + " add column modified BIGINT;", - "alter table " + TableName_ + " add column signingUp TEXT default '';" - }; - RunScript(Statements); - to = CurrentVersion; - return true; - } + bool BaseUserDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + std::vector Statements{ + "alter table " + TableName_ + " add column modified BIGINT;", + "alter table " + TableName_ + " add column signingUp TEXT default '';"}; + RunScript(Statements); + to = CurrentVersion; + return true; + } - bool BaseUserDB::CreateUser([[maybe_unused]] const std::string & Admin, SecurityObjects::UserInfo & NewUser, bool PasswordHashedAlready ) { - try { - Poco::toLowerInPlace(NewUser.email); - if(Exists("email", NewUser.email)) { - return false; - } + bool BaseUserDB::CreateUser([[maybe_unused]] const std::string &Admin, + SecurityObjects::UserInfo &NewUser, bool PasswordHashedAlready) { + try { + Poco::toLowerInPlace(NewUser.email); + if (Exists("email", NewUser.email)) { + return false; + } - Poco::Data::Session Sess = Pool_.get(); + Poco::Data::Session Sess = Pool_.get(); - if(!PasswordHashedAlready) { - NewUser.id = MicroServiceCreateUUID(); - NewUser.creationDate = OpenWifi::Now(); - } + if (!PasswordHashedAlready) { + NewUser.id = MicroServiceCreateUUID(); + NewUser.creationDate = OpenWifi::Now(); + } - // 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()) { + // 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 = OpenWifi::Now(); - NewUser.validated = true; - } - } - return CreateRecord(NewUser); + } else { + if (!PasswordHashedAlready) { + NewUser.currentPassword = AuthService()->ComputeNewPasswordHash( + NewUser.email, NewUser.currentPassword); + NewUser.lastPasswords.clear(); + NewUser.lastPasswords.push_back(NewUser.currentPassword); + NewUser.lastPasswordChange = OpenWifi::Now(); + NewUser.validated = true; + } + } + return CreateRecord(NewUser); - } catch (const Poco::Exception &E) { - std::cout << "What: " << E.what() << " name: " << E.name() << std::endl; - Logger().log(E); - } - return false; - } + } catch (const Poco::Exception &E) { + std::cout << "What: " << E.what() << " name: " << E.name() << std::endl; + Logger().log(E); + } + return false; + } - bool BaseUserDB::GetUserByEmail(const std::string & email, SecurityObjects::UserInfo & User) { - try { - return GetRecord("email", email, User); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + bool BaseUserDB::GetUserByEmail(const std::string &email, SecurityObjects::UserInfo &User) { + try { + return GetRecord("email", email, User); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - bool BaseUserDB::GetUserById(const std::string &Id, SecurityObjects::UserInfo &User) { - try { - return GetRecord("id", Id, User); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + bool BaseUserDB::GetUserById(const std::string &Id, SecurityObjects::UserInfo &User) { + try { + return GetRecord("id", Id, User); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - bool BaseUserDB::GetUsers( uint64_t Offset, uint64_t HowMany, SecurityObjects::UserInfoVec & Users, const std::string & WhereClause) { - try { - return GetRecords(Offset, HowMany, Users, WhereClause); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + bool BaseUserDB::GetUsers(uint64_t Offset, uint64_t HowMany, + SecurityObjects::UserInfoVec &Users, const std::string &WhereClause) { + try { + return GetRecords(Offset, HowMany, Users, WhereClause); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - bool BaseUserDB::SetAvatar(const std::string &Id, const std::string &Value) { - try { - SecurityObjects::UserInfo User; - if(GetRecord("id",Id,User)) { - if(Value.empty()) { - User.avatar = "0"; - } else { - User.avatar = std::to_string(OpenWifi::Now()); - } - return UpdateRecord("id",Id,User); - } - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + bool BaseUserDB::SetAvatar(const std::string &Id, const std::string &Value) { + try { + SecurityObjects::UserInfo User; + if (GetRecord("id", Id, User)) { + if (Value.empty()) { + User.avatar = "0"; + } else { + User.avatar = std::to_string(OpenWifi::Now()); + } + return UpdateRecord("id", Id, User); + } + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - bool BaseUserDB::UpdateUserInfo([[maybe_unused]] const std::string & Admin, SecurityObjects::USER_ID_TYPE & Id, const SecurityObjects::UserInfo &UInfo) { - try { - return UpdateRecord("id", Id, UInfo); - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + bool BaseUserDB::UpdateUserInfo([[maybe_unused]] const std::string &Admin, + SecurityObjects::USER_ID_TYPE &Id, + const SecurityObjects::UserInfo &UInfo) { + try { + return UpdateRecord("id", Id, UInfo); + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - bool BaseUserDB::DeleteUser([[maybe_unused]] const std::string & Admin, const SecurityObjects::USER_ID_TYPE & Id) { - return DeleteRecord("id", Id); - } + bool BaseUserDB::DeleteUser([[maybe_unused]] const std::string &Admin, + const SecurityObjects::USER_ID_TYPE &Id) { + return DeleteRecord("id", Id); + } - bool BaseUserDB::DeleteUsers([[maybe_unused]] const std::string & Admin, const std::string & owner) { - std::string WhereClause{ " owner='" + owner +"' "}; - return DeleteRecords(WhereClause); - } + bool BaseUserDB::DeleteUsers([[maybe_unused]] const std::string &Admin, + const std::string &owner) { + std::string WhereClause{" owner='" + owner + "' "}; + return DeleteRecords(WhereClause); + } - bool BaseUserDB::SetLastLogin(const std::string &Id) { - try { - Poco::Data::Session Sess = Pool_.get(); - Poco::Data::Statement Update(Sess); + bool BaseUserDB::SetLastLogin(const std::string &Id) { + try { + Poco::Data::Session Sess = Pool_.get(); + Poco::Data::Statement Update(Sess); - auto tId{Id}; + auto tId{Id}; - std::string St1{"update " + TableName_ + " set lastLogin=? where id=?"}; - uint64_t Now=OpenWifi::Now(); - Update << ConvertParams(St1), - Poco::Data::Keywords::use(Now), - Poco::Data::Keywords::use(tId); - Update.execute(); - return true; - } catch (const Poco::Exception &E) { - Logger().log(E); - } - return false; - } + std::string St1{"update " + TableName_ + " set lastLogin=? where id=?"}; + uint64_t Now = OpenWifi::Now(); + Update << ConvertParams(St1), Poco::Data::Keywords::use(Now), + Poco::Data::Keywords::use(tId); + Update.execute(); + return true; + } catch (const Poco::Exception &E) { + Logger().log(E); + } + return false; + } - UserCache::UserCache(unsigned Size, unsigned TimeOut, bool Users) : - ORM::DBCache(Size,TimeOut), - UsersOnly_(Users) - { - CacheById_ = std::make_unique>(Size,TimeOut); - CacheByEMail_ = std::make_unique>(Size,TimeOut); - } + UserCache::UserCache(unsigned Size, unsigned TimeOut, bool Users) + : ORM::DBCache(Size, TimeOut), UsersOnly_(Users) { + CacheById_ = std::make_unique>( + Size, TimeOut); + CacheByEMail_ = + std::make_unique>(Size, TimeOut); + } - void UserCache::UpdateCache(const SecurityObjects::UserInfo &R) { - // std::cout << "Update user cache:" << R.Id << std::endl; - CacheById_->update(R.id,R); - CacheByEMail_->update(R.email,R.id); - if(UsersOnly_) - StorageService()->UserTokenDB().DeleteRecordsFromCache("userName", R.id); - else - StorageService()->SubTokenDB().DeleteRecordsFromCache("userName", R.id); - } + void UserCache::UpdateCache(const SecurityObjects::UserInfo &R) { + // std::cout << "Update user cache:" << R.Id << std::endl; + CacheById_->update(R.id, R); + CacheByEMail_->update(R.email, R.id); + if (UsersOnly_) + StorageService()->UserTokenDB().DeleteRecordsFromCache("userName", R.id); + else + StorageService()->SubTokenDB().DeleteRecordsFromCache("userName", R.id); + } - inline void UserCache::Create([[maybe_unused]] const SecurityObjects::UserInfo &R) { - } + inline void UserCache::Create([[maybe_unused]] const SecurityObjects::UserInfo &R) {} - inline bool UserCache::GetFromCache(const std::string &FieldName, const std::string &Value, SecurityObjects::UserInfo &R) { - std::lock_guard M(Mutex_); - if(FieldName=="id") { - auto Entry = CacheById_->get(Value); - if(Entry.isNull()) - return false; - R = *Entry; - return true; - } else if(FieldName=="email") { - auto Entry = CacheByEMail_->get(Value); - if(Entry.isNull()) - return false; - auto Record = CacheById_->get(*Entry); - if(Record.isNull()) - return false; - R = *Record; - return true; - } - return false; - } + inline bool UserCache::GetFromCache(const std::string &FieldName, const std::string &Value, + SecurityObjects::UserInfo &R) { + std::lock_guard M(Mutex_); + if (FieldName == "id") { + auto Entry = CacheById_->get(Value); + if (Entry.isNull()) + return false; + R = *Entry; + return true; + } else if (FieldName == "email") { + auto Entry = CacheByEMail_->get(Value); + if (Entry.isNull()) + return false; + auto Record = CacheById_->get(*Entry); + if (Record.isNull()) + return false; + R = *Record; + return true; + } + return false; + } - inline void UserCache::Delete(const std::string &FieldName, const std::string &Value) { - std::lock_guard M(Mutex_); - // std::cout << "Delete user cache:" << Value << std::endl; - if(FieldName=="id") { - auto E = CacheById_->get(Value); - if(!E.isNull()) - CacheByEMail_->remove(E->email); - CacheById_->remove(Value); - } else if(FieldName=="email") { - auto E = CacheByEMail_->get(Value); - if(!E.isNull()) { - CacheById_->remove(*E); - CacheByEMail_->remove(Value); - } - } - } + inline void UserCache::Delete(const std::string &FieldName, const std::string &Value) { + std::lock_guard M(Mutex_); + // std::cout << "Delete user cache:" << Value << std::endl; + if (FieldName == "id") { + auto E = CacheById_->get(Value); + if (!E.isNull()) + CacheByEMail_->remove(E->email); + CacheById_->remove(Value); + } else if (FieldName == "email") { + auto E = CacheByEMail_->get(Value); + if (!E.isNull()) { + CacheById_->remove(*E); + CacheByEMail_->remove(Value); + } + } + } +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::UserInfoRecordTuple &T, OpenWifi::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 = + OpenWifi::RESTAPI_utils::to_object_array(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 = OpenWifi::SecurityObjects::UserTypeFromString(T.get<22>()); + U.userTypeProprietaryInfo = + OpenWifi::RESTAPI_utils::to_object( + T.get<23>()); + U.securityPolicy = T.get<24>(); + U.securityPolicyChange = T.get<25>(); + U.currentPassword = T.get<26>(); + U.lastPasswords = OpenWifi::RESTAPI_utils::to_object_array(T.get<27>()); + U.oauthType = T.get<28>(); + U.oauthUserInfo = T.get<29>(); + U.modified = T.get<30>(); + U.signingUp = T.get<31>(); } -template<> void ORM::DB::Convert(const OpenWifi::UserInfoRecordTuple &T, - OpenWifi::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 = OpenWifi::RESTAPI_utils::to_object_array(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 = OpenWifi::SecurityObjects::UserTypeFromString(T.get<22>()); - U.userTypeProprietaryInfo = OpenWifi::RESTAPI_utils::to_object(T.get<23>()); - U.securityPolicy = T.get<24>(); - U.securityPolicyChange = T.get<25>(); - U.currentPassword = T.get<26>(); - U.lastPasswords = OpenWifi::RESTAPI_utils::to_object_array(T.get<27>()); - U.oauthType = T.get<28>(); - U.oauthUserInfo = T.get<29>(); - U.modified = T.get<30>(); - U.signingUp = T.get<31>(); -} - -template<> void ORM::DB< OpenWifi::UserInfoRecordTuple, - OpenWifi::SecurityObjects::UserInfo>::Convert(const OpenWifi::SecurityObjects::UserInfo &U, - OpenWifi::UserInfoRecordTuple &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>(OpenWifi::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>(OpenWifi::SecurityObjects::UserTypeToString(U.userRole)); - T.set<23>(OpenWifi::RESTAPI_utils::to_string(U.userTypeProprietaryInfo)); - T.set<24>(U.securityPolicy); - T.set<25>(U.securityPolicyChange); - T.set<26>(U.currentPassword); - T.set<27>(OpenWifi::RESTAPI_utils::to_string(U.lastPasswords)); - T.set<28>(U.oauthType); - T.set<29>(U.oauthUserInfo); - T.set<30>(U.modified); - T.set<31>(U.signingUp); +template <> +void ORM::DB::Convert( + const OpenWifi::SecurityObjects::UserInfo &U, OpenWifi::UserInfoRecordTuple &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>(OpenWifi::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>(OpenWifi::SecurityObjects::UserTypeToString(U.userRole)); + T.set<23>(OpenWifi::RESTAPI_utils::to_string(U.userTypeProprietaryInfo)); + T.set<24>(U.securityPolicy); + T.set<25>(U.securityPolicyChange); + T.set<26>(U.currentPassword); + T.set<27>(OpenWifi::RESTAPI_utils::to_string(U.lastPasswords)); + T.set<28>(U.oauthType); + T.set<29>(U.oauthUserInfo); + T.set<30>(U.modified); + T.set<31>(U.signingUp); } diff --git a/src/storage/orm_users.h b/src/storage/orm_users.h index 8cbf019..b1045de 100644 --- a/src/storage/orm_users.h +++ b/src/storage/orm_users.h @@ -4,87 +4,91 @@ #pragma once -#include "framework/orm.h" #include "Poco/ExpireLRUCache.h" +#include "framework/orm.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" namespace OpenWifi { - 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; - uint64_t, // modified - std::string // signingUp; - > UserInfoRecordTuple; + typedef Poco::Tuple + UserInfoRecordTuple; - typedef std::vector UserInfoRecordTupleList; + typedef std::vector UserInfoRecordTupleList; - class UserCache : public ORM::DBCache { - public: - UserCache(unsigned Size, unsigned TimeOut, bool Users); - virtual ~UserCache() {} - void UpdateCache(const SecurityObjects::UserInfo &R) override; - void Create(const SecurityObjects::UserInfo &R) override; - bool GetFromCache(const std::string &FieldName, const std::string &Value, SecurityObjects::UserInfo &R) override; - void Delete(const std::string &FieldName, const std::string &Value) override; - private: - std::mutex Mutex_; - bool UsersOnly_; - std::unique_ptr> CacheById_; - std::unique_ptr> CacheByEMail_; + class UserCache : public ORM::DBCache { + public: + UserCache(unsigned Size, unsigned TimeOut, bool Users); + virtual ~UserCache() {} + void UpdateCache(const SecurityObjects::UserInfo &R) override; + void Create(const SecurityObjects::UserInfo &R) override; + bool GetFromCache(const std::string &FieldName, const std::string &Value, + SecurityObjects::UserInfo &R) override; + void Delete(const std::string &FieldName, const std::string &Value) override; - }; + private: + std::mutex Mutex_; + bool UsersOnly_; + std::unique_ptr> CacheById_; + std::unique_ptr> CacheByEMail_; + }; - class BaseUserDB : public ORM::DB { - public: - const uint32_t CurrentVersion = 2; - BaseUserDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L, UserCache * Cache, bool users); - virtual ~BaseUserDB() {} + class BaseUserDB : public ORM::DB { + public: + const uint32_t CurrentVersion = 2; + BaseUserDB(const std::string &name, const std::string &shortname, OpenWifi::DBType T, + Poco::Data::SessionPool &P, Poco::Logger &L, UserCache *Cache, bool users); + virtual ~BaseUserDB() {} - bool CreateUser(const std::string & Admin, SecurityObjects::UserInfo & NewUser, bool PasswordHashedAlready = false ); - bool GetUserByEmail(const std::string & email, SecurityObjects::UserInfo & User); - bool GetUserById(const std::string &Id, SecurityObjects::UserInfo &User); - bool GetUsers( uint64_t Offset, uint64_t HowMany, SecurityObjects::UserInfoVec & Users, const std::string & WhereClause=""); - bool UpdateUserInfo(const std::string & Admin, SecurityObjects::USER_ID_TYPE & Id, const SecurityObjects::UserInfo &UInfo); - bool DeleteUser(const std::string & Admin, const SecurityObjects::USER_ID_TYPE & Id); - bool DeleteUsers(const std::string & Admin, const std::string & owner); - bool SetLastLogin(const std::string &Id); - bool SetAvatar(const std::string &Id, const std::string &Value); + bool CreateUser(const std::string &Admin, SecurityObjects::UserInfo &NewUser, + bool PasswordHashedAlready = false); + bool GetUserByEmail(const std::string &email, SecurityObjects::UserInfo &User); + bool GetUserById(const std::string &Id, SecurityObjects::UserInfo &User); + bool GetUsers(uint64_t Offset, uint64_t HowMany, SecurityObjects::UserInfoVec &Users, + const std::string &WhereClause = ""); + bool UpdateUserInfo(const std::string &Admin, SecurityObjects::USER_ID_TYPE &Id, + const SecurityObjects::UserInfo &UInfo); + bool DeleteUser(const std::string &Admin, const SecurityObjects::USER_ID_TYPE &Id); + bool DeleteUsers(const std::string &Admin, const std::string &owner); + bool SetLastLogin(const std::string &Id); + bool SetAvatar(const std::string &Id, const std::string &Value); - inline uint32_t Version() override { return CurrentVersion;} - bool Upgrade(uint32_t from, uint32_t &to) override; + inline uint32_t Version() override { return CurrentVersion; } + bool Upgrade(uint32_t from, uint32_t &to) override; - bool UsersOnly_; - }; - -} + bool UsersOnly_; + }; +} // namespace OpenWifi