stephb9959
2023-02-21 12:23:18 -08:00
parent daa264c984
commit 41ec3b3495
163 changed files with 19042 additions and 18764 deletions

2
build
View File

@@ -1 +1 @@
12
13

View File

@@ -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

View File

@@ -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<SecurityObjects::ActionLink> Links;
{
std::lock_guard G(Mutex_);
StorageService()->ActionLinksDB().GetActions(Links);
}
while (Running_) {
Poco::Thread::trySleep(2000);
if (!Running_)
break;
std::vector<SecurityObjects::ActionLink> 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);
}
}
}
}
}
}
} // namespace OpenWifi

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -10,193 +10,225 @@
#include <regex>
#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<SHA256Engine> HMAC_{"tipopenwifi"};
};
AuthService() noexcept : SubSystemServer("Authentication", "AUTH-SVR", "authentication") {}
};
Poco::HMACEngine<SHA256Engine> 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

View File

@@ -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 <aws/core/Aws.h>
#include <aws/s3/model/AccessControlPolicy.h>
#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 <SecretStore.h>
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

View File

@@ -4,52 +4,48 @@
#pragma once
#include <iostream>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <set>
#include <vector>
#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

View File

@@ -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;
}
}
}
}
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

View File

@@ -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<std::string> 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<std::string> 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<std::string, MFACacheEntry> MFAChallengeCache;
typedef std::map<std::string,MFACacheEntry> 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

View File

@@ -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<std::string> 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<std::string> 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

View File

@@ -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

View File

@@ -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<std::string>{
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<std::string>{"/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<std::string>{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<std::string>{"/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

View File

@@ -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);
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{
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<std::string>{"/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<std::string>{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<std::string>{"/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

View File

@@ -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);
}
}
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

View File

@@ -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<std::string>
{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<std::string>{"/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<std::string>{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<std::string>{"/wwwassets/{id}", "/favicon.ico"};
};
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
private:
};
} // namespace OpenWifi

View File

@@ -5,79 +5,85 @@
#include <fstream>
#include <iostream>
#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

View File

@@ -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<std::string>{
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<std::string>{"/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<std::string>{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<std::string>{"/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

View File

@@ -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();
}
}
inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User,
SecurityObjects::ApiKeyEntry &U) {
U.salt.clear();
}
} // namespace OpenWifi

View File

@@ -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);
}
}
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

View File

@@ -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<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/email"}; }
void DoGet() final{};
void DoPost() final;
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -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);
}
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{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<std::string>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
Server, TransactionId, Internal, false, true,
RateLimit{.Interval = 1000, .MaxCalls = 10}) {}
static auto PathName() {
return std::list<std::string>{"/api/v1/oauth2/{token}", "/api/v1/oauth2"};
};
void DoGet() final;
void DoPost() final;
void DoDelete() final;
void DoPut() final {};
void DoPut() final{};
};
}
} // namespace OpenWifi

View File

@@ -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);
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; };
void DoGet() final;
void DoPut() final;
void DoPost() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -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);
}
}
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

View File

@@ -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
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{
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<std::string>{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<std::string>{"/api/v1/signup"}; };
static auto PathName() { return std::list<std::string>{"/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

View File

@@ -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);
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/sms"}; }
void DoGet() final{};
void DoPost() final;
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -5,78 +5,84 @@
#include <fstream>
#include <iostream>
#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

View File

@@ -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<std::string>{
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<std::string>{"/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<std::string>{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<std::string>{"/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

View File

@@ -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

View File

@@ -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<std::string>{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<std::string>{"/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<std::string>{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<std::string>{"/api/v1/submfa"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final;
};
} // namespace OpenWifi

View File

@@ -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);
}
}
}
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

View File

@@ -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<std::string>{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<std::string>{"/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<std::string>{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<std::string>{"/api/v1/suboauth2/{token}", "/api/v1/suboauth2"};
};
void DoGet() final;
void DoPost() final;
void DoDelete() final;
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -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);
}
}
} // namespace OpenWifi

View File

@@ -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<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; };
void DoGet() final;
void DoPut() final;
void DoPost() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -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

View File

@@ -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<std::string>
{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS
},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final;
};
}
private:
};
} // namespace OpenWifi

View File

@@ -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<SecurityObjects::NoteInfo>(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<SecurityObjects::NoteInfo>(
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);
}
}
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

View File

@@ -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<std::string>
{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<std::string>{"/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<std::string>{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<std::string>{"/api/v1/subuser/{id}"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;
void DoPut() final;
};
}
private:
};
} // namespace OpenWifi

View File

@@ -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);
}
}
}
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

View File

@@ -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<std::string>
{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/subusers"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
}; // namespace OpenWifi

View File

@@ -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<std::pair<std::string,std::string>> 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<std::pair<std::string, std::string>> 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
} // namespace OpenWifi

View File

@@ -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<std::string>
{
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<std::string>{"/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<std::string>{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<std::string>{"/api/v1/systemSecret/{secret}"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final;
void DoPut() final;
};
}
private:
};
} // namespace OpenWifi

View File

@@ -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

View File

@@ -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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/systemEndpoints"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -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

View File

@@ -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<std::string>
{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS
},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/totp"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final;
};
}
private:
};
} // namespace OpenWifi

View File

@@ -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<SecurityObjects::NoteInfo>(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<SecurityObjects::NoteInfo>(
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);
}
}
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

View File

@@ -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<std::string>
{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<std::string>{"/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<std::string>{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<std::string>{"/api/v1/user/{id}"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;
void DoPut() final;
};
}
private:
};
} // namespace OpenWifi

View File

@@ -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);
}
}
}
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

View File

@@ -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<std::string>
{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/users"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
}; // namespace OpenWifi

View File

@@ -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
} // namespace OpenWifi

View File

@@ -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<std::string>
{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {};
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/validateApiKey"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -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();
}
}
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

View File

@@ -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<std::string>
{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {};
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/validateSubToken"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

View File

@@ -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();
}
}
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

View File

@@ -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<std::string>
{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {};
static auto PathName() { return std::list<std::string>{"/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<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/validateToken"}; };
void DoGet() final;
void DoPost() final{};
void DoDelete() final{};
void DoPut() final{};
};
} // namespace OpenWifi

File diff suppressed because it is too large Load Diff

View File

@@ -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<VenueInfo> 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<DeviceInfo> 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<TIDstat_entry> 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<UETimePoint> 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<SSIDTimePoint> ssid_data;
std::vector<RadioTimePoint> 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<DeviceTimePoint> points;
std::vector<DeviceTimePointAnalysis> 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 {
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<VenueInfo> 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<DeviceInfo> 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<TIDstat_entry> 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<UETimePoint> 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<SSIDTimePoint> ssid_data;
std::vector<RadioTimePoint> 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<DeviceTimePoint> points;
std::vector<DeviceTimePointAnalysis> 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

View File

@@ -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();
}
}
void Dashboard::reset() {
snapshot = 0;
numberOfRevokedCerts = numberOfIssuedCerts = 0;
activeCertsPerOrganization.clear();
revokedCertsPerOrganization.clear();
numberOfRedirectors.clear();
deviceTypes.clear();
monthlyNumberOfCerts.clear();
monthlyNumberOfCertsPerOrgPerYear.clear();
}
} // namespace OpenWifi::CertObjects

View File

@@ -4,121 +4,121 @@
#pragma once
#include <string>
#include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/OpenWifiTypes.h"
#include <string>
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<std::string> commonNames;
std::vector<std::string> 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<std::string> commonNames;
std::vector<std::string> 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<DashBoardYearlyStats> 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<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
void to_json(Poco::JSON::Object &Obj) const;
void reset();
};
void to_json(Poco::JSON::Object &Obj) const;
void reset();
};
}
} // namespace OpenWifi::CertObjects

View File

@@ -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

View File

@@ -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<Firmware> FirmwareVec;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Firmware> 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<DeviceType> DeviceTypeVec;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<DeviceType> 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<RevisionHistoryEntry> RevisionHistoryEntryVec;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<RevisionHistoryEntry> 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<DeviceCurrentInfo> devices;
struct DeviceCurrentInfoList {
std::vector<DeviceCurrentInfo> 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

View File

@@ -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

View File

@@ -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<std::string> 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<std::string> 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<ScriptEntry> scripts;
std::vector<ScriptEntry> 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<std::string> radsecCacerts;
std::vector<std::string> radsecRealms;
bool ignore=false;
std::vector<std::string> radsecCacerts;
std::vector<std::string> 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<std::string> methodParameters;
std::vector<RadiusProxyServerEntry> servers;
std::string strategy;
bool monitor = false;
std::string monitorMethod;
std::vector<std::string> methodParameters;
std::vector<RadiusProxyServerEntry> 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<RadiusProxyPool> pools;
std::vector<RadiusProxyPool> pools;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
} // namespace OpenWifi::GWObjects

View File

@@ -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

View File

@@ -5,73 +5,70 @@
#ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
#define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
#include <vector>
#include "Poco/JSON/Object.h"
#include <vector>
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<SimulationDetails> list;
struct SimulationDetailsList {
std::vector<SimulationDetails> 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,361 +8,364 @@
#pragma once
#include <string>
#include <type_traits>
#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 <string>
#include <type_traits>
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<AclTemplate> );
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<AclTemplate>);
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<NoteInfo> 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<NoteInfo> 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<MobilePhoneNumber> 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<MobilePhoneNumber> 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<UserInfo> 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<UserInfo> users;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<UserInfo> UserInfoVec;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct UserInfoList {
std::vector<UserInfo> 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<InternalServiceInfo> 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<InternalServiceInfo> 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<SystemEndpoint> 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<SystemEndpoint> 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<std::string,SecurityObjects::UserInfoAndPolicy> 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<std::string, SecurityObjects::UserInfoAndPolicy> 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<ProfileAction> 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<SecurityProfile> 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<ProfileAction> 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<SecurityProfile> 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<ApiKeyAccessRight> 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<ApiKeyAccessRight> 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<ApiKeyEntry> 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<ApiKeyEntry> apiKeys;
}
}
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
} // namespace SecurityObjects
} // namespace OpenWifi

File diff suppressed because it is too large Load Diff

View File

@@ -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<IPReservation> reservations;
uint64_t created = 0 ;
uint64_t modified = 0 ;
struct IPReservationList {
std::string id;
std::vector<IPReservation> 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<std::string> bands;
struct WifiNetwork {
std::string type; // main, guest
std::string name;
std::string password;
std::string encryption;
std::vector<std::string> 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<WifiNetwork> wifiNetworks;
uint64_t created=0;
uint64_t modified=0;
struct WifiNetworkList {
std::vector<WifiNetwork> 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<std::string> rangeList;
struct AccessTime {
std::string day;
std::vector<std::string> 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<AccessTime> schedule;
uint64_t created=0;
uint64_t modified=0;
struct AccessTimes {
std::vector<AccessTime> 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<AccessTimes> 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<AccessTimes> 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<SubscriberDevice> devices;
uint64_t created=0;
uint64_t modified=0;
struct SubscriberDeviceList {
std::vector<SubscriberDevice> 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<Association> associations;
uint64_t created=0;
uint64_t modified=0;
struct AssociationList {
std::vector<Association> 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<Client> clients;
uint64_t created=0;
uint64_t modified=0;
struct ClientList {
std::vector<Client> 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<std::string> addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
std::vector<std::string> phones;
std::vector<std::string> mobiles;
struct Location {
std::string buildingName;
std::vector<std::string> addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
std::vector<std::string> phones;
std::vector<std::string> 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<std::string> 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<std::string> 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<RadioInformation> 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<RadioInformation> 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<AccessPoint> list;
struct AccessPointList {
std::vector<AccessPoint> 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<StatsEntry> external, internal;
struct StatsBlock {
uint64_t modified = 0;
std::vector<StatsEntry> 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

View File

@@ -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<SMS_provider_aws>(Logger());
} else if(Provider_=="twilio") {
ProviderImpl_ = std::make_unique<SMS_provider_twilio>(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<SMS_provider_aws>(Logger());
} else if (Provider_ == "twilio") {
ProviderImpl_ = std::make_unique<SMS_provider_twilio>(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);
}
}
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

View File

@@ -5,51 +5,49 @@
#pragma once
#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#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<SMSValidationCacheEntry> Cache_;
std::unique_ptr<SMS_provider> 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<SMSValidationCacheEntry> Cache_;
std::unique_ptr<SMS_provider> 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

View File

@@ -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

View File

@@ -8,61 +8,55 @@
#include <aws/sns/model/PublishRequest.h>
#include <aws/sns/model/PublishResult.h>
#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;
}
}
} // namespace OpenWifi

View File

@@ -5,29 +5,30 @@
#pragma once
#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/s3/S3Client.h>
#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

View File

@@ -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;
}
}
}
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

View File

@@ -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

View File

@@ -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<Poco::Net::MailMessage>();
auto Message = std::make_unique<Poco::Net::MailMessage>();
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<Poco::Net::AcceptCertificateHandler> ptrHandler_ = new Poco::Net::AcceptCertificateHandler(false);
Poco::SharedPtr<Poco::Net::AcceptCertificateHandler> ptrHandler_ =
new Poco::Net::AcceptCertificateHandler(false);
Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
auto ptrContext = Poco::AutoPtr<Poco::Net::Context>
(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<Poco::Net::Context>(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

View File

@@ -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<MESSAGE_ATTRIBUTES,const std::string>
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<MESSAGE_ATTRIBUTES, const std::string> 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<MESSAGE_ATTRIBUTES, std::string> 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<MESSAGE_ATTRIBUTES, std::string> 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<MessageEvent> Messages_;
std::list<MessageEvent> 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<MessageEvent> Messages_;
std::list<MessageEvent> 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

View File

@@ -2,91 +2,92 @@
// Created by stephane bourque on 2023-01-25.
//
#include <fstream>
#include "SecretStore.h"
#include <framework/MicroServiceFuncs.h>
#include <Poco/File.h>
#include <Poco/JSON/Parser.h>
#include <framework/MicroServiceFuncs.h>
#include <fstream>
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<Poco::JSON::Object::Ptr>();
if(Doc->isArray("secrets")) {
auto Secrets = Doc->getArray("secrets");
for(const auto &secret:*Secrets) {
const auto &entry = secret.extract<Poco::JSON::Object::Ptr>();
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<Poco::JSON::Object::Ptr>();
if (Doc->isArray("secrets")) {
auto Secrets = Doc->getArray("secrets");
for (const auto &secret : *Secrets) {
const auto &entry = secret.extract<Poco::JSON::Object::Ptr>();
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
} // namespace OpenWifi

View File

@@ -8,34 +8,30 @@
namespace OpenWifi {
class SecretStore : public SubSystemServer {
public:
class SecretStore : public SubSystemServer {
public:
using SecretStoreType = std::map<std::string, std::string>;
static SecretStore *instance() {
static auto *instance_ = new SecretStore;
return instance_;
}
using SecretStoreType = std::map<std::string,std::string>;
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

View File

@@ -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;
}
}
}
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

View File

@@ -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<OpenWifi::UserCache>(64,1200000,true);
SubCache_ = std::make_unique<OpenWifi::UserCache>(2048,1200000,false);
UserTokenCache_ = std::make_unique<OpenWifi::TokenCache>(64,1200000, true);
SubTokenCache_ = std::make_unique<OpenWifi::TokenCache>(2048,1200000,false);
UserCache_ = std::make_unique<OpenWifi::UserCache>(64, 1200000, true);
SubCache_ = std::make_unique<OpenWifi::UserCache>(2048, 1200000, false);
UserTokenCache_ = std::make_unique<OpenWifi::TokenCache>(64, 1200000, true);
SubTokenCache_ = std::make_unique<OpenWifi::TokenCache>(2048, 1200000, false);
UserDB_ = std::make_unique<OpenWifi::BaseUserDB>("Users", "usr", dbType_,*Pool_, Logger(), UserCache_.get(), true);
SubDB_ = std::make_unique<OpenWifi::BaseUserDB>("Subscribers", "sub", dbType_,*Pool_, Logger(), SubCache_.get(), false);
UserTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("Tokens", "tok", dbType_,*Pool_, Logger(), UserTokenCache_.get(), true);
SubTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("SubTokens", "stk", dbType_,*Pool_, Logger(), SubTokenCache_.get(), false);
UserDB_ = std::make_unique<OpenWifi::BaseUserDB>("Users", "usr", dbType_, *Pool_, Logger(),
UserCache_.get(), true);
SubDB_ = std::make_unique<OpenWifi::BaseUserDB>("Subscribers", "sub", dbType_, *Pool_,
Logger(), SubCache_.get(), false);
UserTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>(
"Tokens", "tok", dbType_, *Pool_, Logger(), UserTokenCache_.get(), true);
SubTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>(
"SubTokens", "stk", dbType_, *Pool_, Logger(), SubTokenCache_.get(), false);
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger());
ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger());
AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", dbType_,*Pool_, Logger());
SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger());
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger());
SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
ApiKeyDB_ = std::make_unique<OpenWifi::ApiKeyDB>("ApiKeys", "api", dbType_,*Pool_, Logger());
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,
*Pool_, Logger());
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs",
dbType_, *Pool_, Logger());
ActionLinksDB_ =
std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_, *Pool_, Logger());
AvatarDB_ =
std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", dbType_, *Pool_, Logger());
SubAvatarDB_ =
std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_, *Pool_, Logger());
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_, *Pool_, Logger());
SubLoginDB_ =
std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_, *Pool_, Logger());
ApiKeyDB_ =
std::make_unique<OpenWifi::ApiKeyDB>("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<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes
Archivercallback_ =
std::make_unique<Poco::TimerCallback<Archiver>>(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
} // namespace OpenWifi
// namespace

View File

@@ -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<OpenWifi::BaseUserDB> UserDB_;
std::unique_ptr<OpenWifi::BaseUserDB> SubDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> UserTokenDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> SubTokenDB_;
std::unique_ptr<OpenWifi::PreferencesDB> PreferencesDB_;
std::unique_ptr<OpenWifi::PreferencesDB> SubPreferencesDB_;
std::unique_ptr<OpenWifi::ActionLinkDB> ActionLinksDB_;
std::unique_ptr<OpenWifi::AvatarDB> AvatarDB_;
std::unique_ptr<OpenWifi::AvatarDB> SubAvatarDB_;
std::unique_ptr<OpenWifi::LoginDB> LoginDB_;
std::unique_ptr<OpenWifi::LoginDB> SubLoginDB_;
std::unique_ptr<OpenWifi::ApiKeyDB> ApiKeyDB_;
class StorageService : public StorageClass {
public:
static auto instance() {
static auto instance_ = new StorageService;
return instance_;
}
std::unique_ptr<OpenWifi::UserCache> UserCache_;
std::unique_ptr<OpenWifi::UserCache> SubCache_;
std::unique_ptr<OpenWifi::TokenCache> UserTokenCache_;
std::unique_ptr<OpenWifi::TokenCache> SubTokenCache_;
int Start() override;
void Stop() override;
Poco::Timer Timer_;
Archiver Archiver_;
std::unique_ptr<Poco::TimerCallback<Archiver>> 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<OpenWifi::BaseUserDB> UserDB_;
std::unique_ptr<OpenWifi::BaseUserDB> SubDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> UserTokenDB_;
std::unique_ptr<OpenWifi::BaseTokenDB> SubTokenDB_;
std::unique_ptr<OpenWifi::PreferencesDB> PreferencesDB_;
std::unique_ptr<OpenWifi::PreferencesDB> SubPreferencesDB_;
std::unique_ptr<OpenWifi::ActionLinkDB> ActionLinksDB_;
std::unique_ptr<OpenWifi::AvatarDB> AvatarDB_;
std::unique_ptr<OpenWifi::AvatarDB> SubAvatarDB_;
std::unique_ptr<OpenWifi::LoginDB> LoginDB_;
std::unique_ptr<OpenWifi::LoginDB> SubLoginDB_;
std::unique_ptr<OpenWifi::ApiKeyDB> ApiKeyDB_;
} // namespace
std::unique_ptr<OpenWifi::UserCache> UserCache_;
std::unique_ptr<OpenWifi::UserCache> SubCache_;
std::unique_ptr<OpenWifi::TokenCache> UserTokenCache_;
std::unique_ptr<OpenWifi::TokenCache> SubTokenCache_;
Poco::Timer Timer_;
Archiver Archiver_;
std::unique_ptr<Poco::TimerCallback<Archiver>> Archivercallback_;
};
inline auto StorageService() { return StorageService::instance(); };
} // namespace OpenWifi

View File

@@ -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<std::string, Entry> Cache_;
std::string Issuer_;
private:
std::map<std::string,Entry> 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

View File

@@ -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<Poco::Net::ServerSocket>(SockAddr, Port_);
auto Params = new Poco::Net::HTTPServerParams;
Params->setName("ws:alb");
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_ = std::make_unique<Poco::Net::HTTPServer>(
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

View File

@@ -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<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0;
mutable std::atomic_bool Running_=false;
std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
int Port_ = 0;
mutable std::atomic_bool Running_ = false;
};
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
} // namespace OpenWifi

View File

@@ -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::Object::Ptr>();
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::Object::Ptr>();
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::Object::Ptr>();
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::Object::Ptr>();
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);
}
}
}
} catch (const Poco::Exception &E) {
Logger.log(E);
}
}
} // namespace OpenWifi

View File

@@ -4,13 +4,13 @@
#pragma once
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#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<bool>();
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<uint64_t>();
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<std::string>();
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(); }
}
} // namespace OpenWifi

View File

@@ -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

View File

@@ -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<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry> ApiKeyCache_{512,1200000 };
Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
512, 1200000};
Poco::ExpireLRUCache<std::string, ApiKeyCacheEntry> ApiKeyCache_{512, 1200000};
};
inline auto AuthClient() { return AuthClient::instance(); }
} // namespace OpenWifi

View File

@@ -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);
}
}
} // namespace OpenWifi::CIDR

View File

@@ -2,8 +2,8 @@
// Created by stephane bourque on 2021-09-14.
//
#include <iostream>
#include <fstream>
#include <iostream>
#include <regex>
#include "ConfigurationValidator.h"
@@ -17,14 +17,15 @@
#include "fmt/format.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
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<std::string> &Errors, bool Strict) {
if(Working_) {
try {
bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors,
bool Strict) {
if (Working_) {
try {
Poco::JSON::Parser P;
auto Doc = P.parse(C).extract<Poco::JSON::Object::Ptr>();
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

Some files were not shown because too many files have changed in this diff Show More