mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-30 10:22:22 +00:00
Compare commits
1 Commits
v2.4.0-RC5
...
feature/wi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05d06fce53 |
@@ -30,20 +30,9 @@ else()
|
||||
file(WRITE build ${BUILD_NUM})
|
||||
endif()
|
||||
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
RESULT_VARIABLE GIT_RESULT
|
||||
OUTPUT_VARIABLE GIT_HASH)
|
||||
if(NOT GIT_RESULT EQUAL "0")
|
||||
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
|
||||
endif()
|
||||
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
|
||||
endif()
|
||||
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
|
||||
|
||||
set(BUILD_SHARED_LIBS 1)
|
||||
|
||||
add_definitions(-DAPP_VERSION="${CMAKE_PROJECT_VERSION}" -DBUILD_NUMBER="${BUILD_NUM}")
|
||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
||||
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
@@ -61,11 +50,8 @@ find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataS
|
||||
|
||||
include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
|
||||
|
||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
||||
|
||||
add_executable( owsec
|
||||
build
|
||||
src/ow_version.h.in
|
||||
src/framework/CountryCodes.h
|
||||
src/framework/KafkaTopics.h
|
||||
src/framework/MicroService.h
|
||||
@@ -104,7 +90,7 @@ add_executable( owsec
|
||||
src/storage/storage_actionLinks.cpp src/storage/storage_actionLinks.h
|
||||
src/storage/storage_tokens.h
|
||||
src/ActionLinkManager.cpp src/ActionLinkManager.h
|
||||
src/ACLProcessor.h)
|
||||
)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
target_link_libraries(owsec PUBLIC
|
||||
|
||||
@@ -53,12 +53,9 @@ RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
|
||||
ADD CMakeLists.txt build /owsec/
|
||||
ADD cmake /owsec/cmake
|
||||
ADD src /owsec/src
|
||||
ADD .git /owsec/.git
|
||||
|
||||
|
||||
WORKDIR /owsec
|
||||
RUN mkdir cmake-build
|
||||
|
||||
@@ -8,7 +8,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owsec:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
||||
tag: v2.4.0-RC5
|
||||
tag: main
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
|
||||
@@ -61,8 +61,6 @@ components:
|
||||
- 6 # INTERNAL_ERROR,
|
||||
- 7 # ACCESS_DENIED,
|
||||
- 8 # INVALID_TOKEN
|
||||
- 9 # expired token
|
||||
- 10 # rate limit exceeded
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
|
||||
@@ -40,7 +40,6 @@ openwifi.system.commandchannel = /tmp/app.ucentralsec
|
||||
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
||||
openwifi.service.key.password = mypassword
|
||||
|
||||
smssender.enabled = false
|
||||
smssender.provider = aws
|
||||
smssender.aws.secretkey = ***************************************
|
||||
smssender.aws.accesskey = ***************************************
|
||||
@@ -54,7 +53,6 @@ smssender.aws.region = **************
|
||||
#
|
||||
# Security Microservice Specific Section
|
||||
#
|
||||
mailer.enabled = false
|
||||
mailer.hostname = smtp.gmail.com
|
||||
mailer.username = ************************
|
||||
mailer.password = ************************
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-11-12.
|
||||
//
|
||||
|
||||
#ifndef OWSEC_ACLPROCESSOR_H
|
||||
#define OWSEC_ACLPROCESSOR_H
|
||||
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class ACLProcessor {
|
||||
public:
|
||||
enum ACL_OPS {
|
||||
READ,
|
||||
MODIFY,
|
||||
DELETE,
|
||||
CREATE
|
||||
};
|
||||
static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
|
||||
if(User.Id == Target.Id && Op==DELETE)
|
||||
return false;
|
||||
|
||||
if(User.userRole==SecurityObjects::ROOT)
|
||||
return true;
|
||||
|
||||
if(User.Id == Target.Id)
|
||||
return true;
|
||||
|
||||
if(User.userRole!=SecurityObjects::ADMIN && User.userRole!=SecurityObjects::ROOT && Op!=READ)
|
||||
return false;
|
||||
|
||||
if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //OWSEC_ACLPROCESSOR_H
|
||||
@@ -18,8 +18,8 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
static ActionLinkManager * instance() {
|
||||
static auto * instance_ = new ActionLinkManager;
|
||||
return instance_;
|
||||
static ActionLinkManager instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
int Start() final;
|
||||
|
||||
@@ -56,10 +56,9 @@ namespace OpenWifi {
|
||||
Logger_.notice("Stopping...");
|
||||
}
|
||||
|
||||
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
|
||||
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo )
|
||||
{
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Expired = false;
|
||||
try {
|
||||
std::string CallToken;
|
||||
Poco::Net::OAuth20Credentials Auth(Request);
|
||||
@@ -68,29 +67,27 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if(!CallToken.empty()) {
|
||||
auto Client = UserCache_.get(CallToken);
|
||||
if( Client.isNull() ) {
|
||||
SecurityObjects::UserInfoAndPolicy UInfo2;
|
||||
uint64_t RevocationDate=0;
|
||||
if(StorageService()->GetToken(CallToken,UInfo2,RevocationDate)) {
|
||||
if(RevocationDate!=0)
|
||||
return false;
|
||||
Expired = (UInfo2.webtoken.created_ + UInfo2.webtoken.expires_in_) < time(nullptr);
|
||||
if(StorageService()->GetUserById(UInfo2.userinfo.Id,UInfo.userinfo)) {
|
||||
UInfo.webtoken = UInfo2.webtoken;
|
||||
UserCache_.update(CallToken, UInfo);
|
||||
SessionToken = CallToken;
|
||||
if(StorageService()->IsTokenRevoked(CallToken))
|
||||
return false;
|
||||
auto Client = UserCache_.find(CallToken);
|
||||
if( Client == UserCache_.end() ) {
|
||||
if(StorageService()->GetToken(SessionToken,UInfo)) {
|
||||
if(StorageService()->GetUserById(UInfo.userinfo.email,UInfo.userinfo)) {
|
||||
UserCache_[UInfo.webtoken.access_token_] = UInfo;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(!Expired) {
|
||||
|
||||
if((Client->second.webtoken.created_ + Client->second.webtoken.expires_in_) > time(nullptr)) {
|
||||
SessionToken = CallToken;
|
||||
UInfo = *Client ;
|
||||
UInfo = Client->second ;
|
||||
return true;
|
||||
}
|
||||
RevokeToken(CallToken);
|
||||
|
||||
UserCache_.erase(Client);
|
||||
StorageService()->RevokeToken(CallToken);
|
||||
return false;
|
||||
}
|
||||
} catch(const Poco::Exception &E) {
|
||||
@@ -99,24 +96,16 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AuthService::RevokeToken(std::string & Token) {
|
||||
UserCache_.remove(Token);
|
||||
StorageService()->RevokeToken(Token);
|
||||
}
|
||||
|
||||
bool AuthService::DeleteUserFromCache(const std::string &UserName) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
std::vector<std::string> OldTokens;
|
||||
|
||||
UserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
|
||||
{ if(O.userinfo.email==UserName)
|
||||
OldTokens.push_back(token);
|
||||
});
|
||||
|
||||
for(const auto &i:OldTokens) {
|
||||
Logout(i,false);
|
||||
UserCache_.remove(i);
|
||||
for(auto i=UserCache_.begin();i!=UserCache_.end();) {
|
||||
if (i->second.userinfo.email==UserName) {
|
||||
Logout(i->first, false);
|
||||
i = UserCache_.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -132,6 +121,9 @@ namespace OpenWifi {
|
||||
void AuthService::Logout(const std::string &token, bool EraseFromCache) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
if(EraseFromCache)
|
||||
UserCache_.erase(token);
|
||||
|
||||
try {
|
||||
Poco::JSON::Object Obj;
|
||||
Obj.set("event", "remove-token");
|
||||
@@ -140,7 +132,7 @@ namespace OpenWifi {
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(Obj, ResultText);
|
||||
std::string Tmp{token};
|
||||
RevokeToken(Tmp);
|
||||
StorageService()->RevokeToken(Tmp);
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
|
||||
false);
|
||||
} catch (const Poco::Exception &E) {
|
||||
@@ -191,9 +183,9 @@ namespace OpenWifi {
|
||||
UInfo.webtoken.username_ = UserName;
|
||||
UInfo.webtoken.errorCode = 0;
|
||||
UInfo.webtoken.userMustChangePassword = false;
|
||||
UserCache_.update(UInfo.webtoken.access_token_,UInfo);
|
||||
UserCache_[UInfo.webtoken.access_token_] = UInfo;
|
||||
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
||||
StorageService()->AddToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
|
||||
StorageService()->AddToken(UInfo.webtoken.username_, UInfo.webtoken.access_token_,
|
||||
UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
|
||||
UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
|
||||
}
|
||||
@@ -261,7 +253,7 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
|
||||
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo )
|
||||
{
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
@@ -299,7 +291,6 @@ namespace OpenWifi {
|
||||
UInfo.userinfo.lastLogin=std::time(nullptr);
|
||||
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
||||
CreateToken(UserName, UInfo );
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -346,7 +337,7 @@ namespace OpenWifi {
|
||||
|
||||
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
|
||||
A.userId = UInfo.email;
|
||||
A.id = MicroService::CreateUUID();
|
||||
A.id = MicroService::instance().CreateUUID();
|
||||
A.created = std::time(nullptr);
|
||||
A.expires = A.created + 24*60*60;
|
||||
StorageService()->CreateAction(A);
|
||||
@@ -354,38 +345,15 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
||||
bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo) {
|
||||
std::lock_guard G(Mutex_);
|
||||
auto It = UserCache_.find(Token);
|
||||
|
||||
Expired = false;
|
||||
|
||||
auto Client = UserCache_.get(Token);
|
||||
if(!Client.isNull()) {
|
||||
Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < std::time(nullptr);
|
||||
WebToken = Client->webtoken;
|
||||
UserInfo = Client->userinfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string TToken{Token};
|
||||
if(StorageService()->IsTokenRevoked(TToken)) {
|
||||
if(It==UserCache_.end())
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the token from disk...
|
||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||
uint64_t RevocationDate=0;
|
||||
if(StorageService()->GetToken(TToken, UInfo, RevocationDate)) {
|
||||
if(RevocationDate!=0)
|
||||
return false;
|
||||
Expired = (UInfo.webtoken.created_ + UInfo.webtoken.expires_in_) < std::time(nullptr);
|
||||
if(StorageService()->GetUserById(UInfo.userinfo.Id,UInfo.userinfo)) {
|
||||
WebToken = UInfo.webtoken;
|
||||
UserCache_.update(UInfo.webtoken.access_token_, UInfo);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
WebToken = It->second.webtoken;
|
||||
UserInfo = It->second.userinfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include "Poco/SHA2Engine.h"
|
||||
#include "Poco/Crypto/DigestEngine.h"
|
||||
#include "Poco/HMACEngine.h"
|
||||
#include "Poco/ExpireLRUCache.h"
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
@@ -45,15 +44,15 @@ namespace OpenWifi{
|
||||
static int AccessTypeToInt(ACCESS_TYPE T);
|
||||
|
||||
static AuthService *instance() {
|
||||
static auto * instance_ = new AuthService;
|
||||
return instance_;
|
||||
static AuthService instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
|
||||
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
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_;};
|
||||
@@ -61,7 +60,8 @@ namespace OpenWifi{
|
||||
|
||||
bool ValidatePassword(const std::string &pwd);
|
||||
|
||||
[[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired);
|
||||
[[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo);
|
||||
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
|
||||
[[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
|
||||
[[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type);
|
||||
|
||||
@@ -75,21 +75,19 @@ namespace OpenWifi{
|
||||
[[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
||||
[[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
|
||||
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||
void RevokeToken(std::string & Token);
|
||||
|
||||
[[nodiscard]] static inline const std::string GetLogoAssetURI() {
|
||||
return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline const std::string GetLogoAssetFileName() {
|
||||
return MicroService::instance().WWWAssetsDir() + "/the_logo.png";
|
||||
return MicroService::instance().DataDir() + "/wwwassets/the_logo.png";
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::JWT::Signer Signer_;
|
||||
Poco::SHA2Engine SHA2_;
|
||||
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy> UserCache_{2048,1200000};
|
||||
// SecurityObjects::UserInfoCache UserCache_;
|
||||
SecurityObjects::UserInfoCache UserCache_;
|
||||
std::string PasswordValidationStr_;
|
||||
std::regex PasswordValidation_;
|
||||
uint64_t TokenAging_ = 30 * 24 * 60 * 60;
|
||||
@@ -121,8 +119,8 @@ namespace OpenWifi{
|
||||
|
||||
inline AuthService * AuthService() { return AuthService::instance(); }
|
||||
|
||||
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired) {
|
||||
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
|
||||
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
|
||||
return AuthService()->IsAuthorized(Request, SessionToken, UInfo );
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
|
||||
return false;
|
||||
|
||||
std::string Challenge = MakeChallenge();
|
||||
std::string uuid = MicroService::CreateUUID();
|
||||
std::string uuid = MicroService::instance().CreateUUID();
|
||||
uint64_t Created = std::time(nullptr);
|
||||
|
||||
ChallengeStart.set("uuid",uuid);
|
||||
@@ -71,9 +71,8 @@ namespace OpenWifi {
|
||||
|
||||
auto uuid = ChallengeResponse->get("uuid").toString();
|
||||
auto Hint = Cache_.find(uuid);
|
||||
if(Hint == end(Cache_)) {
|
||||
if(Hint == end(Cache_))
|
||||
return false;
|
||||
}
|
||||
|
||||
auto answer = ChallengeResponse->get("answer").toString();
|
||||
if(Hint->second.Answer!=answer) {
|
||||
|
||||
@@ -24,8 +24,8 @@ namespace OpenWifi {
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
static MFAServer *instance() {
|
||||
static auto * instance_ = new MFAServer;
|
||||
return instance_;
|
||||
static MFAServer instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
|
||||
@@ -35,7 +35,7 @@ namespace OpenWifi {
|
||||
static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
|
||||
|
||||
static inline std::string MakeChallenge() {
|
||||
return std::to_string(MicroService::instance().Random(1,999999));
|
||||
return std::to_string(rand() % 999999);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
Internal,
|
||||
false,
|
||||
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
||||
true, RateLimit{.Interval=1000,.MaxCalls=5}) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
|
||||
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
||||
void CompleteResetPassword();
|
||||
|
||||
@@ -17,39 +17,24 @@
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static void FilterCredentials(SecurityObjects::UserInfo & U) {
|
||||
U.currentPassword.clear();
|
||||
U.lastPasswords.clear();
|
||||
U.oauthType.clear();
|
||||
}
|
||||
|
||||
void RESTAPI_oauth2Handler::DoGet() {
|
||||
bool Expired = false;
|
||||
if (!IsAuthorized(Expired)) {
|
||||
if(Expired)
|
||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
||||
if (!IsAuthorized()) {
|
||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
|
||||
}
|
||||
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
||||
if(GetMe) {
|
||||
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
||||
Poco::JSON::Object Me;
|
||||
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
||||
FilterCredentials(ReturnedUser);
|
||||
ReturnedUser.to_json(Me);
|
||||
UserInfo_.userinfo.to_json(Me);
|
||||
return ReturnObject(Me);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
|
||||
}
|
||||
|
||||
void RESTAPI_oauth2Handler::DoDelete() {
|
||||
bool Expired = false;
|
||||
if (!IsAuthorized(Expired)) {
|
||||
if(Expired)
|
||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
|
||||
}
|
||||
if (!IsAuthorized()) {
|
||||
return UnAuthorized("Not authorized.");
|
||||
}
|
||||
|
||||
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
|
||||
if (Token == SessionToken_) {
|
||||
@@ -86,7 +71,7 @@ namespace OpenWifi {
|
||||
SecurityObjects::ActionLink NewLink;
|
||||
|
||||
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
||||
NewLink.id = MicroService::CreateUUID();
|
||||
NewLink.id = MicroService::instance().CreateUUID();
|
||||
NewLink.userId = UInfo1.Id;
|
||||
NewLink.created = std::time(nullptr);
|
||||
NewLink.expires = NewLink.created + (24*60*60);
|
||||
@@ -108,8 +93,8 @@ namespace OpenWifi {
|
||||
|
||||
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
|
||||
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
||||
if(Obj->has("uuid")) {
|
||||
auto uuid = Obj->get("uuid").toString();
|
||||
if(Obj->has(RESTAPI::Protocol::UUID)) {
|
||||
auto uuid = Obj->get(RESTAPI::Protocol::UUID).toString();
|
||||
if(MFAServer().ResendCode(uuid))
|
||||
return OK();
|
||||
}
|
||||
@@ -118,7 +103,7 @@ namespace OpenWifi {
|
||||
|
||||
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
||||
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
||||
if(Obj->has("uuid")) {
|
||||
if(Obj->has(RESTAPI::Protocol::UUID)) {
|
||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||
if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
|
||||
Poco::JSON::Object ReturnObj;
|
||||
@@ -130,8 +115,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||
bool Expired=false;
|
||||
auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired);
|
||||
auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo);
|
||||
if (Code==SUCCESS) {
|
||||
Poco::JSON::Object ReturnObj;
|
||||
if(AuthService()->RequiresMFA(UInfo)) {
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
||||
Internal, false, true , RateLimit{.Interval=2000,.MaxCalls=5}) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
|
||||
@@ -7,16 +7,8 @@
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "framework/RESTAPI_errors.h"
|
||||
#include "SMSSender.h"
|
||||
#include "ACLProcessor.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static void FilterCredentials(SecurityObjects::UserInfo & U) {
|
||||
U.currentPassword.clear();
|
||||
U.lastPasswords.clear();
|
||||
U.oauthType.clear();
|
||||
}
|
||||
|
||||
void RESTAPI_user_handler::DoGet() {
|
||||
std::string Id = GetBinding("id", "");
|
||||
if(Id.empty()) {
|
||||
@@ -35,7 +27,9 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
Poco::JSON::Object UserInfoObject;
|
||||
FilterCredentials(UInfo);
|
||||
UInfo.currentPassword.clear();
|
||||
UInfo.lastPasswords.clear();
|
||||
UInfo.oauthType.clear();
|
||||
UInfo.to_json(UserInfoObject);
|
||||
ReturnObject(UserInfoObject);
|
||||
}
|
||||
@@ -46,12 +40,20 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingUserID);
|
||||
}
|
||||
|
||||
if(UserInfo_.userinfo.userRole!= SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||
}
|
||||
|
||||
if(UserInfo_.userinfo.Id == Id) {
|
||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||
}
|
||||
|
||||
SecurityObjects::UserInfo UInfo;
|
||||
if(!StorageService()->GetUserById(Id,UInfo)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) {
|
||||
if(UInfo.userRole==SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||
}
|
||||
|
||||
@@ -62,9 +64,6 @@ namespace OpenWifi {
|
||||
if(AuthService()->DeleteUserFromCache(UInfo.email)) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
|
||||
|
||||
Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
|
||||
StorageService()->RevokeAllTokens(UInfo.email);
|
||||
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
|
||||
@@ -77,52 +76,57 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::IdMustBe0);
|
||||
}
|
||||
|
||||
SecurityObjects::UserInfo NewUser;
|
||||
RESTAPI_utils::from_request(NewUser,*Request);
|
||||
SecurityObjects::UserInfo UInfo;
|
||||
RESTAPI_utils::from_request(UInfo,*Request);
|
||||
|
||||
if(NewUser.userRole == SecurityObjects::UNKNOWN) {
|
||||
if(UInfo.userRole == SecurityObjects::UNKNOWN) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
||||
}
|
||||
|
||||
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
|
||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
||||
}
|
||||
|
||||
Poco::toLowerInPlace(NewUser.email);
|
||||
if(!Utils::ValidEMailAddress(NewUser.email)) {
|
||||
if(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && UInfo.userRole == SecurityObjects::ROOT) {
|
||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
||||
}
|
||||
|
||||
Poco::toLowerInPlace(UInfo.email);
|
||||
if(!Utils::ValidEMailAddress(UInfo.email)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
||||
}
|
||||
|
||||
if(!NewUser.currentPassword.empty()) {
|
||||
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
|
||||
if(!UInfo.currentPassword.empty()) {
|
||||
if(!AuthService()->ValidatePassword(UInfo.currentPassword)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidPassword);
|
||||
}
|
||||
}
|
||||
|
||||
if(NewUser.name.empty())
|
||||
NewUser.name = NewUser.email;
|
||||
if(UInfo.name.empty())
|
||||
UInfo.name = UInfo.email;
|
||||
|
||||
if(!StorageService()->CreateUser(NewUser.email,NewUser)) {
|
||||
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
|
||||
if(!StorageService()->CreateUser(UInfo.email,UInfo)) {
|
||||
Logger_.information(Poco::format("Could not add user '%s'.",UInfo.email));
|
||||
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
if(GetParameter("email_verification","false")=="true") {
|
||||
if(AuthService::VerifyEmail(NewUser))
|
||||
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
|
||||
StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,NewUser.Id,NewUser);
|
||||
if(AuthService::VerifyEmail(UInfo))
|
||||
Logger_.information(Poco::format("Verification e-mail requested for %s",UInfo.email));
|
||||
StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,UInfo.Id,UInfo);
|
||||
}
|
||||
|
||||
if(!StorageService()->GetUserByEmail(NewUser.email, NewUser)) {
|
||||
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
|
||||
if(!StorageService()->GetUserByEmail(UInfo.email, UInfo)) {
|
||||
Logger_.information(Poco::format("User '%s' but not retrieved.",UInfo.email));
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object UserInfoObject;
|
||||
FilterCredentials(NewUser);
|
||||
NewUser.to_json(UserInfoObject);
|
||||
UInfo.to_json(UserInfoObject);
|
||||
|
||||
ReturnObject(UserInfoObject);
|
||||
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
|
||||
|
||||
Logger_.information(Poco::format("User '%s' has been added by '%s')",UInfo.email, UserInfo_.userinfo.email));
|
||||
}
|
||||
|
||||
void RESTAPI_user_handler::DoPut() {
|
||||
@@ -136,8 +140,12 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||
}
|
||||
|
||||
if(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole == SecurityObjects::ROOT) {
|
||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||
}
|
||||
|
||||
SecurityObjects::UserInfo NewUser;
|
||||
@@ -216,23 +224,15 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||
}
|
||||
|
||||
if(!NewUser.userTypeProprietaryInfo.mfa.method.empty()) {
|
||||
if(NewUser.userTypeProprietaryInfo.mfa.method!="email" && NewUser.userTypeProprietaryInfo.mfa.method!="sms" ) {
|
||||
return BadRequest("Unknown MFA method");
|
||||
}
|
||||
if(NewUser.userTypeProprietaryInfo.mfa.method=="email") {
|
||||
Existing.userTypeProprietaryInfo.mfa.method=NewUser.userTypeProprietaryInfo.mfa.method;
|
||||
}
|
||||
|
||||
if(Existing.userTypeProprietaryInfo.mfa.enabled && Existing.userTypeProprietaryInfo.mfa.method.empty()) {
|
||||
return BadRequest("Illegal MFA method");
|
||||
}
|
||||
}
|
||||
|
||||
if(StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
||||
SecurityObjects::UserInfo NewUserInfo;
|
||||
StorageService()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||
Poco::JSON::Object ModifiedObject;
|
||||
FilterCredentials(NewUserInfo);
|
||||
NewUserInfo.to_json(ModifiedObject);
|
||||
return ReturnObject(ModifiedObject);
|
||||
}
|
||||
|
||||
@@ -13,8 +13,7 @@ namespace OpenWifi {
|
||||
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)) {
|
||||
if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo)) {
|
||||
Poco::JSON::Object Obj;
|
||||
SecObj.to_json(Obj);
|
||||
return ReturnObject(Obj);
|
||||
|
||||
@@ -562,7 +562,7 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
I.notes = N;
|
||||
I.modified = I.created = Now;
|
||||
I.id = MicroService::CreateUUID();
|
||||
I.id = MicroService::instance().CreateUUID();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -59,15 +59,15 @@ namespace OpenWifi::SecurityObjects {
|
||||
|
||||
struct MobilePhoneNumber {
|
||||
std::string number;
|
||||
bool verified = false;
|
||||
bool primary = false;
|
||||
bool verified;
|
||||
bool primary;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct MfaAuthInfo {
|
||||
bool enabled = false;
|
||||
bool enabled;
|
||||
std::string method;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
@@ -86,7 +86,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
std::string uuid;
|
||||
std::string question;
|
||||
std::string method;
|
||||
uint64_t created = std::time(nullptr);
|
||||
uint64_t created;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
@@ -16,16 +16,13 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
int SMSSender::Start() {
|
||||
Enabled_ = MicroService::instance().ConfigGetBool("smssender.enabled",false);
|
||||
if(Enabled_) {
|
||||
Provider_ = MicroService::instance().ConfigGetString("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();
|
||||
Provider_ = MicroService::instance().ConfigGetString("sms.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;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,15 @@ namespace OpenWifi {
|
||||
std::string Number;
|
||||
std::string Code;
|
||||
std::string UserName;
|
||||
uint64_t Created = std::time(nullptr);
|
||||
bool Validated = false;
|
||||
uint64_t Created;
|
||||
bool Validated=false;
|
||||
};
|
||||
|
||||
class SMSSender : public SubSystemServer {
|
||||
public:
|
||||
static SMSSender *instance() {
|
||||
static auto *instance_ = new SMSSender;
|
||||
return instance_;
|
||||
static SMSSender instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
int Start() final;
|
||||
@@ -37,8 +37,8 @@ namespace OpenWifi {
|
||||
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::string Provider_;
|
||||
bool Enabled_=false;
|
||||
std::vector<SMSValidationCacheEntry> Cache_;
|
||||
std::unique_ptr<SMS_provider> ProviderImpl_;
|
||||
|
||||
|
||||
@@ -43,24 +43,18 @@ namespace OpenWifi {
|
||||
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());
|
||||
|
||||
auto psms_out = sns.Publish(psms_req);
|
||||
if (psms_out.IsSuccess()) {
|
||||
Logger_.debug(Poco::format("SMS sent to %s",PhoneNumber));
|
||||
return true;
|
||||
}
|
||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
||||
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
||||
return false;
|
||||
} catch (...) {
|
||||
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()) {
|
||||
Logger_.debug(Poco::format("SMS sent to %s",PhoneNumber));
|
||||
return true;
|
||||
}
|
||||
Logger_.debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber));
|
||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
||||
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,12 @@
|
||||
#include "Poco/Net/SMTPClientSession.h"
|
||||
#include "Poco/Net/SecureSMTPClientSession.h"
|
||||
#include "Poco/Net/StringPartSource.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/InvalidCertificateHandler.h"
|
||||
#include "Poco/Net/AcceptCertificateHandler.h"
|
||||
|
||||
#include "SMTPMailerService.h"
|
||||
#include "framework/MicroService.h"
|
||||
@@ -20,19 +23,14 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void SMTPMailerService::LoadMyConfig() {
|
||||
Enabled_ = MicroService::instance().ConfigGetBool("mailer.enabled",false);
|
||||
if(Enabled_) {
|
||||
MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
|
||||
SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
|
||||
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
||||
Sender_ = MicroService::instance().ConfigGetString("mailer.sender");
|
||||
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
||||
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
|
||||
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
||||
MailRetry_ = (int) MicroService::instance().ConfigGetInt("mailer.retry",2*60);
|
||||
MailAbandon_ = (int) MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
|
||||
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
||||
}
|
||||
MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
|
||||
SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
|
||||
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
||||
Sender_ = MicroService::instance().ConfigGetString("mailer.sender");
|
||||
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
||||
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
|
||||
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
||||
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
||||
}
|
||||
|
||||
int SMTPMailerService::Start() {
|
||||
@@ -55,46 +53,57 @@ namespace OpenWifi {
|
||||
|
||||
bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
|
||||
std::lock_guard G(Mutex_);
|
||||
PendingMessages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
|
||||
|
||||
/*
|
||||
uint64_t Now = std::time(nullptr);
|
||||
std::string RecipientLower = Poco::toLower(Recipient);
|
||||
auto CE = Cache_.find(RecipientLower);
|
||||
if(CE!=Cache_.end()) {
|
||||
// only allow messages to the same user within 2 minutes
|
||||
if(!((CE->second.LastRequest-Now)<30 && CE->second.HowManyRequests<10))
|
||||
return false;
|
||||
if(CE->second.LastRequest-Now>30) {
|
||||
CE->second.LastRequest = Now;
|
||||
CE->second.HowManyRequests=0;
|
||||
} else {
|
||||
CE->second.HowManyRequests++;
|
||||
}
|
||||
} else {
|
||||
Cache_[RecipientLower] = MessageCacheEntry{.LastRequest=Now, .HowManyRequests=0};
|
||||
}
|
||||
*/
|
||||
Messages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
|
||||
.LastTry=0,
|
||||
.Sent=0,
|
||||
.File=Poco::File(TemplateDir_ + "/" +Name),
|
||||
.Attrs=Attrs});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SMTPMailerService::run() {
|
||||
|
||||
Running_ = true;
|
||||
while(Running_) {
|
||||
|
||||
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 = std::time(nullptr);
|
||||
if((i->LastTry==0 || (Now-i->LastTry)>MailRetry_)) {
|
||||
if (SendIt(*i)) {
|
||||
Logger_.information(Poco::format("Attempting to deliver for mail '%s'.", Recipient));
|
||||
i = Messages_.erase(i);
|
||||
} else {
|
||||
i->LastTry = Now;
|
||||
++i;
|
||||
|
||||
for(auto &i:Messages_) {
|
||||
if(i.Sent==0 && (i.LastTry==0 || (Now-i.LastTry)>120)) {
|
||||
if (SendIt(i)) {
|
||||
i.LastTry = i.Sent = std::time(nullptr);
|
||||
} else
|
||||
i.LastTry = std::time(nullptr);
|
||||
}
|
||||
} else if ((Now-i->Posted)>MailAbandon_) {
|
||||
Logger_.information(Poco::format("Mail for '%s' has timed out and will not be sent.", Recipient));
|
||||
i = Messages_.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
|
||||
// Clean the list
|
||||
std::remove_if(Messages_.begin(),Messages_.end(),[Now](MessageEvent &E){ return (E.Sent!=0 || ((Now-E.LastTry)>(15*60)));});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,12 +115,10 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
||||
std::string Recipient;
|
||||
|
||||
try
|
||||
{
|
||||
Poco::Net::MailMessage Message;
|
||||
Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
||||
std::string Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
||||
|
||||
auto H1 = Msg.Attrs.find(SENDER);
|
||||
std::string TheSender;
|
||||
@@ -122,6 +129,7 @@ namespace OpenWifi {
|
||||
}
|
||||
Message.setSender( TheSender );
|
||||
Logger_.information(Poco::format("Sending message to:%s from %s",Recipient,TheSender));
|
||||
|
||||
Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
||||
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
|
||||
|
||||
@@ -138,26 +146,21 @@ namespace OpenWifi {
|
||||
|
||||
auto Logo = Msg.Attrs.find(LOGO);
|
||||
if(Logo!=Msg.Attrs.end()) {
|
||||
try {
|
||||
Poco::File LogoFile(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 (...) {
|
||||
Logger_.warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName()));
|
||||
}
|
||||
Poco::File LogoFile(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/jpeg"));
|
||||
}
|
||||
|
||||
Poco::SharedPtr<Poco::Net::AcceptCertificateHandler> ptrHandler_ = new Poco::Net::AcceptCertificateHandler(false);
|
||||
|
||||
Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
|
||||
Poco::Net::Context::Params P;
|
||||
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_,
|
||||
&ptrHandler_,
|
||||
ptrContext);
|
||||
session.login();
|
||||
session.startTLS(ptrContext);
|
||||
@@ -174,9 +177,6 @@ namespace OpenWifi {
|
||||
{
|
||||
Logger_.log(E);
|
||||
}
|
||||
catch (const std::exception &E) {
|
||||
Logger_.warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ namespace OpenWifi {
|
||||
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
static SMTPMailerService *instance() {
|
||||
static auto * instance_ = new SMTPMailerService;
|
||||
return instance_;
|
||||
static SMTPMailerService instance;
|
||||
return & instance;
|
||||
}
|
||||
|
||||
struct MessageEvent {
|
||||
@@ -71,35 +71,41 @@ namespace OpenWifi {
|
||||
MessageAttributes Attrs;
|
||||
};
|
||||
|
||||
struct MessageCacheEntry {
|
||||
uint64_t LastRequest=0;
|
||||
uint64_t HowManyRequests=0;
|
||||
};
|
||||
|
||||
void run() override;
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
||||
bool SendIt(const MessageEvent &Msg);
|
||||
void LoadMyConfig();
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
bool Enabled() const { return Enabled_; }
|
||||
|
||||
private:
|
||||
std::string MailHost_;
|
||||
std::string Sender_;
|
||||
int MailHostPort_=25;
|
||||
int MailRetry_=2*60;
|
||||
int MailAbandon_=2*60*20;
|
||||
std::string SenderLoginUserName_;
|
||||
std::string SenderLoginPassword_;
|
||||
std::string LoginMethod_ = "login";
|
||||
std::string LogoFileName_;
|
||||
std::string TemplateDir_;
|
||||
std::list<MessageEvent> Messages_;
|
||||
std::list<MessageEvent> PendingMessages_;
|
||||
std::map<std::string,MessageCacheEntry> Cache_;
|
||||
Poco::Thread SenderThr_;
|
||||
std::atomic_bool Running_=false;
|
||||
bool Enabled_=false;
|
||||
Poco::Net::AcceptCertificateHandler ptrHandler_;
|
||||
|
||||
SMTPMailerService() noexcept:
|
||||
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
|
||||
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer"),
|
||||
ptrHandler_(false)
|
||||
{
|
||||
std::string E{"SHA512"};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -16,28 +16,12 @@ namespace OpenWifi {
|
||||
StorageClass::Start();
|
||||
Create_Tables();
|
||||
InitializeDefaultUser();
|
||||
|
||||
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_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Storage::Stop() {
|
||||
Logger_.notice("Stopping.");
|
||||
Timer_.stop();
|
||||
StorageClass::Stop();
|
||||
}
|
||||
|
||||
void Archiver::onTimer(Poco::Timer &timer) {
|
||||
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
|
||||
logger.information("Squiggy the DB: removing old tokens.");
|
||||
StorageService()->CleanExpiredTokens();
|
||||
logger.information("Squiggy the DB: removing old actionLinks.");
|
||||
StorageService()->CleanOldActionLinks();
|
||||
}
|
||||
|
||||
}
|
||||
// namespace
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "framework/StorageClass.h"
|
||||
#include "AuthService.h"
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const std::string AllEmailTemplatesFieldsForCreation {
|
||||
@@ -29,12 +27,6 @@ namespace OpenWifi {
|
||||
|
||||
};
|
||||
|
||||
class Archiver {
|
||||
public:
|
||||
void onTimer(Poco::Timer & timer);
|
||||
private:
|
||||
};
|
||||
|
||||
class Storage : public StorageClass {
|
||||
public:
|
||||
|
||||
@@ -84,8 +76,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
static Storage *instance() {
|
||||
static auto * instance_ = new Storage;
|
||||
return instance_;
|
||||
static Storage instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
@@ -112,12 +104,12 @@ namespace OpenWifi {
|
||||
bool GetAvatar(const std::string & Admin, std::string &Id, Poco::TemporaryFile &FileName, std::string &Type, std::string & Name);
|
||||
bool DeleteAvatar(const std::string & Admin, std::string &Id);
|
||||
|
||||
bool AddToken(std::string &UserId, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut);
|
||||
bool AddToken(std::string &UserName, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut);
|
||||
bool RevokeToken( std::string & Token );
|
||||
bool IsTokenRevoked( std::string & Token );
|
||||
bool CleanExpiredTokens();
|
||||
bool CleanRevokedTokens( uint64_t Oldest );
|
||||
bool RevokeAllTokens( std::string & UserName );
|
||||
bool GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate);
|
||||
bool GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||
|
||||
/*
|
||||
* All ActionLinks functions
|
||||
@@ -129,7 +121,6 @@ namespace OpenWifi {
|
||||
bool SentAction(std::string &ActionId);
|
||||
bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
|
||||
bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
|
||||
void CleanOldActionLinks();
|
||||
|
||||
private:
|
||||
int Create_Tables();
|
||||
@@ -137,13 +128,6 @@ namespace OpenWifi {
|
||||
int Create_AvatarTable();
|
||||
int Create_TokensTable();
|
||||
int Create_ActionLinkTable();
|
||||
|
||||
Poco::Timer Timer_;
|
||||
Archiver Archiver_;
|
||||
std::unique_ptr<Poco::TimerCallback<Archiver>> Archivercallback_;
|
||||
|
||||
/// This is to support a mistake that was deployed...
|
||||
void ReplaceOldDefaultUUID();
|
||||
};
|
||||
|
||||
inline Storage * StorageService() { return Storage::instance(); };
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,46 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-09-14.
|
||||
//
|
||||
|
||||
#ifndef OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
#define OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
using nlohmann::json;
|
||||
using nlohmann::json_schema::json_validator;
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationValidator : public SubSystemServer {
|
||||
public:
|
||||
|
||||
static ConfigurationValidator *instance() {
|
||||
if(instance_== nullptr)
|
||||
instance_ = new ConfigurationValidator;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
bool Validate(const std::string &C, std::string &Error);
|
||||
static void my_format_checker(const std::string &format, const std::string &value);
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
private:
|
||||
static ConfigurationValidator * instance_;
|
||||
bool Initialized_=false;
|
||||
bool Working_=false;
|
||||
void Init();
|
||||
std::unique_ptr<json_validator> Validator_=std::make_unique<json_validator>(nullptr, my_format_checker);
|
||||
|
||||
ConfigurationValidator():
|
||||
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
|
||||
}
|
||||
};
|
||||
|
||||
inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
||||
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
|
||||
}
|
||||
|
||||
#endif //OWPROV_CONFIGURATIONVALIDATOR_H
|
||||
@@ -69,8 +69,6 @@ using namespace std::chrono_literals;
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
#include "ow_version.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
enum UNAUTHORIZED_REASON {
|
||||
@@ -82,9 +80,7 @@ namespace OpenWifi {
|
||||
PASSWORD_INVALID,
|
||||
INTERNAL_ERROR,
|
||||
ACCESS_DENIED,
|
||||
INVALID_TOKEN,
|
||||
EXPIRED_TOKEN,
|
||||
RATE_LIMIT_EXCEEDED
|
||||
INVALID_TOKEN
|
||||
};
|
||||
|
||||
class AppServiceRegistry {
|
||||
@@ -92,8 +88,8 @@ namespace OpenWifi {
|
||||
inline AppServiceRegistry();
|
||||
|
||||
static AppServiceRegistry & instance() {
|
||||
static AppServiceRegistry *instance_= new AppServiceRegistry;
|
||||
return *instance_;
|
||||
static AppServiceRegistry instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
inline ~AppServiceRegistry() {
|
||||
@@ -1437,8 +1433,8 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
static RESTAPI_RateLimiter *instance() {
|
||||
static RESTAPI_RateLimiter * instance_ = new RESTAPI_RateLimiter;
|
||||
return instance_;
|
||||
static RESTAPI_RateLimiter instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline int Start() final { return 0;};
|
||||
@@ -1448,18 +1444,18 @@ namespace OpenWifi {
|
||||
Poco::URI uri(R.getURI());
|
||||
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
|
||||
auto E = Cache_.get(H);
|
||||
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
const auto p1 = std::chrono::system_clock::now();
|
||||
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(p1.time_since_epoch()).count();
|
||||
if(E.isNull()) {
|
||||
Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
|
||||
Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
|
||||
return false;
|
||||
}
|
||||
if((Now-E->Start)<Period) {
|
||||
E->Count++;
|
||||
Cache_.update(H,E);
|
||||
if(E->Count > MaxCalls) {
|
||||
Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
|
||||
if(E->Count > MaxCalls)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
E->Start = Now;
|
||||
@@ -1527,23 +1523,20 @@ namespace OpenWifi {
|
||||
Request = &RequestIn;
|
||||
Response = &ResponseIn;
|
||||
|
||||
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
|
||||
return UnAuthorized("Rate limit exceeded.",RATE_LIMIT_EXCEEDED);
|
||||
}
|
||||
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls))
|
||||
return;
|
||||
|
||||
if (!ContinueProcessing())
|
||||
return;
|
||||
|
||||
bool Expired=false;
|
||||
if (AlwaysAuthorize_ && !IsAuthorized(Expired)) {
|
||||
if(Expired)
|
||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken, EXPIRED_TOKEN);
|
||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, ACCESS_DENIED);
|
||||
if (AlwaysAuthorize_ && !IsAuthorized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Reason;
|
||||
if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) {
|
||||
return UnAuthorized(Reason, ACCESS_DENIED);
|
||||
UnAuthorized(Reason, ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
ParseParameters();
|
||||
@@ -1881,7 +1874,7 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool IsAuthorized(bool & Expired);
|
||||
inline bool IsAuthorized();
|
||||
|
||||
inline void ReturnObject(Poco::JSON::Object &Object) {
|
||||
PrepareResponse();
|
||||
@@ -1902,7 +1895,7 @@ namespace OpenWifi {
|
||||
QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
|
||||
QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0);
|
||||
QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 0);
|
||||
QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 1);
|
||||
QB_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100);
|
||||
QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
|
||||
QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
|
||||
@@ -1914,7 +1907,7 @@ namespace OpenWifi {
|
||||
QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false);
|
||||
|
||||
if(QB_.Offset<1)
|
||||
QB_.Offset=0;
|
||||
QB_.Offset=1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2083,50 +2076,6 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object Body_;
|
||||
};
|
||||
|
||||
class KafkaProducer : public Poco::Runnable {
|
||||
public:
|
||||
inline void run();
|
||||
void Start() {
|
||||
if(!Running_) {
|
||||
Running_=true;
|
||||
Worker_.start(*this);
|
||||
}
|
||||
}
|
||||
void Stop() {
|
||||
if(Running_) {
|
||||
Running_=false;
|
||||
Worker_.wakeUp();
|
||||
Worker_.join();
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::mutex Mutex_;
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_=false;
|
||||
};
|
||||
|
||||
class KafkaConsumer : public Poco::Runnable {
|
||||
public:
|
||||
inline void run();
|
||||
void Start() {
|
||||
if(!Running_) {
|
||||
Running_=true;
|
||||
Worker_.start(*this);
|
||||
}
|
||||
}
|
||||
void Stop() {
|
||||
if(Running_) {
|
||||
Running_=false;
|
||||
Worker_.wakeUp();
|
||||
Worker_.join();
|
||||
}
|
||||
}
|
||||
private:
|
||||
std::mutex Mutex_;
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_=false;
|
||||
};
|
||||
|
||||
class KafkaManager : public SubSystemServer {
|
||||
public:
|
||||
struct KMessage {
|
||||
@@ -2135,32 +2084,33 @@ namespace OpenWifi {
|
||||
PayLoad;
|
||||
};
|
||||
|
||||
friend class KafkaConsumer;
|
||||
friend class KafkaProducer;
|
||||
|
||||
inline void initialize(Poco::Util::Application & self) override;
|
||||
|
||||
static KafkaManager *instance() {
|
||||
static KafkaManager * instance_ = new KafkaManager;
|
||||
return instance_;
|
||||
static KafkaManager instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
if(!KafkaEnabled_)
|
||||
return 0;
|
||||
ConsumerThr_.Start();
|
||||
ProducerThr_.Start();
|
||||
ProducerThr_ = std::make_unique<std::thread>([this]() { this->ProducerThr(); });
|
||||
ConsumerThr_ = std::make_unique<std::thread>([this]() { this->ConsumerThr(); });
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void Stop() override {
|
||||
if(KafkaEnabled_) {
|
||||
ProducerThr_.Stop();
|
||||
ConsumerThr_.Stop();
|
||||
ProducerRunning_ = ConsumerRunning_ = false;
|
||||
ProducerThr_->join();
|
||||
ConsumerThr_->join();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
inline void ProducerThr();
|
||||
inline void ConsumerThr();
|
||||
|
||||
inline void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true ) {
|
||||
if(KafkaEnabled_) {
|
||||
std::lock_guard G(Mutex_);
|
||||
@@ -2213,13 +2163,18 @@ namespace OpenWifi {
|
||||
// void WakeUp();
|
||||
|
||||
private:
|
||||
std::mutex ProducerMutex_;
|
||||
std::mutex ConsumerMutex_;
|
||||
bool KafkaEnabled_ = false;
|
||||
std::atomic_bool ProducerRunning_ = false;
|
||||
std::atomic_bool ConsumerRunning_ = false;
|
||||
std::queue<KMessage> Queue_;
|
||||
std::string SystemInfoWrapper_;
|
||||
std::unique_ptr<std::thread> ConsumerThr_;
|
||||
std::unique_ptr<std::thread> ProducerThr_;
|
||||
int FunctionId_=1;
|
||||
Types::NotifyTable Notifiers_;
|
||||
KafkaProducer ProducerThr_;
|
||||
KafkaConsumer ConsumerThr_;
|
||||
std::unique_ptr<cppkafka::Configuration> Config_;
|
||||
|
||||
inline void PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
|
||||
Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
|
||||
@@ -2244,8 +2199,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
static AuthClient *instance() {
|
||||
static AuthClient * instance_ = new AuthClient;
|
||||
return instance_;
|
||||
static AuthClient instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
@@ -2253,20 +2208,25 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline void Stop() override {
|
||||
Cache_.clear();
|
||||
}
|
||||
|
||||
inline void RemovedCachedToken(const std::string &Token) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Cache_.remove(Token);
|
||||
UserCache_.erase(Token);
|
||||
}
|
||||
|
||||
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
|
||||
return ((T.expires_in_+T.created_)<std::time(nullptr));
|
||||
}
|
||||
|
||||
inline bool RetrieveTokenInformation(const std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
|
||||
try {
|
||||
inline bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
auto User = UserCache_.find(SessionToken);
|
||||
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||
UInfo = User->second;
|
||||
return true;
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
@@ -2276,39 +2236,49 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||
UInfo.from_json(Response);
|
||||
if(IsTokenExpired(UInfo.webtoken)) {
|
||||
Expired = true;
|
||||
return false;
|
||||
}
|
||||
Expired = false;
|
||||
Cache_.update(SessionToken, UInfo);
|
||||
return true;
|
||||
SecurityObjects::UserInfoAndPolicy P;
|
||||
P.from_json(Response);
|
||||
UserCache_[SessionToken] = P;
|
||||
UInfo = P;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
Expired = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
|
||||
auto User = Cache_.get(SessionToken);
|
||||
if(!User.isNull()) {
|
||||
if(IsTokenExpired(User->webtoken)) {
|
||||
Expired = true;
|
||||
return false;
|
||||
inline bool IsTokenAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
auto User = UserCache_.find(SessionToken);
|
||||
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||
UInfo = User->second;
|
||||
return true;
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req(uSERVICE_SECURITY,
|
||||
"/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||
SecurityObjects::UserInfoAndPolicy P;
|
||||
P.from_json(Response);
|
||||
UserCache_[SessionToken] = P;
|
||||
UInfo = P;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Expired = false;
|
||||
UInfo = *User;
|
||||
return true;
|
||||
|
||||
}
|
||||
return RetrieveTokenInformation(SessionToken, UInfo, Expired);
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{1024,1200000 };
|
||||
OpenWifi::SecurityObjects::UserInfoCache UserCache_;
|
||||
};
|
||||
|
||||
inline AuthClient * AuthClient() { return AuthClient::instance(); }
|
||||
@@ -2368,14 +2338,14 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
static ALBHealthCheckServer *instance() {
|
||||
static ALBHealthCheckServer * instance = new ALBHealthCheckServer;
|
||||
return instance;
|
||||
static ALBHealthCheckServer instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline int Start() override;
|
||||
|
||||
inline void Stop() override {
|
||||
if(Running_)
|
||||
if(Server_)
|
||||
Server_->stop();
|
||||
}
|
||||
|
||||
@@ -2383,7 +2353,6 @@ namespace OpenWifi {
|
||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||
int Port_ = 0;
|
||||
std::atomic_bool Running_=false;
|
||||
};
|
||||
|
||||
inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
||||
@@ -2395,24 +2364,23 @@ namespace OpenWifi {
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S);
|
||||
|
||||
|
||||
class RESTAPI_ExtServer : public SubSystemServer {
|
||||
class RESTAPI_server : public SubSystemServer {
|
||||
public:
|
||||
static RESTAPI_ExtServer *instance() {
|
||||
static RESTAPI_ExtServer *instance_ = new RESTAPI_ExtServer;
|
||||
return instance_;
|
||||
static RESTAPI_server *instance() {
|
||||
static RESTAPI_server instance;
|
||||
return &instance;
|
||||
}
|
||||
int Start() override;
|
||||
inline void Stop() override {
|
||||
Logger_.information("Stopping ");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stop();
|
||||
Pool_.joinAll();
|
||||
RESTServers_.clear();
|
||||
}
|
||||
|
||||
}
|
||||
inline void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path, uint64_t Id) {
|
||||
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
|
||||
RESTAPIHandler::BindingMap Bindings;
|
||||
return RESTAPI_external_server(Path, Bindings, Logger_, Server_);
|
||||
}
|
||||
@@ -2422,19 +2390,19 @@ namespace OpenWifi {
|
||||
Poco::ThreadPool Pool_;
|
||||
RESTAPI_GenericServer Server_;
|
||||
|
||||
RESTAPI_ExtServer() noexcept:
|
||||
RESTAPI_server() noexcept:
|
||||
SubSystemServer("RESTAPIServer", "RESTAPIServer", "openwifi.restapi")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline RESTAPI_ExtServer * RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
|
||||
inline RESTAPI_server * RESTAPI_server() { return RESTAPI_server::instance(); };
|
||||
|
||||
class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
explicit ExtRequestHandlerFactory(RESTAPI_GenericServer & Server) :
|
||||
Logger_(RESTAPI_ExtServer::instance()->Logger()),
|
||||
Server_(Server)
|
||||
RequestHandlerFactory(RESTAPI_GenericServer & Server) :
|
||||
Logger_(RESTAPI_server::instance()->Logger()),
|
||||
Server_(Server)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -2442,16 +2410,15 @@ namespace OpenWifi {
|
||||
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
|
||||
Poco::URI uri(Request.getURI());
|
||||
auto *Path = uri.getPath().c_str();
|
||||
return RESTAPI_ExtServer()->CallServer(Path, TransactionId_++);
|
||||
return RESTAPI_server()->CallServer(Path);
|
||||
}
|
||||
|
||||
private:
|
||||
static inline std::atomic_uint64_t TransactionId_ = 1;
|
||||
Poco::Logger &Logger_;
|
||||
RESTAPI_GenericServer &Server_;
|
||||
Poco::Logger &Logger_;
|
||||
RESTAPI_GenericServer &Server_;
|
||||
};
|
||||
|
||||
inline int RESTAPI_ExtServer::Start() {
|
||||
inline int RESTAPI_server::Start() {
|
||||
Logger_.information("Starting.");
|
||||
Server_.InitLogging();
|
||||
|
||||
@@ -2465,12 +2432,12 @@ namespace OpenWifi {
|
||||
if(!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger_);
|
||||
|
||||
Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams;
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Params->setMaxThreads(50);
|
||||
Params->setMaxQueued(200);
|
||||
Params->setKeepAlive(true);
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory(Server_), Pool_, Sock, Params);
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new RequestHandlerFactory(Server_), Pool_, Sock, Params);
|
||||
NewServer->start();
|
||||
RESTServers_.push_back(std::move(NewServer));
|
||||
}
|
||||
@@ -2478,12 +2445,12 @@ namespace OpenWifi {
|
||||
return 0;
|
||||
}
|
||||
|
||||
class RESTAPI_IntServer : public SubSystemServer {
|
||||
class RESTAPI_InternalServer : public SubSystemServer {
|
||||
|
||||
public:
|
||||
static RESTAPI_IntServer *instance() {
|
||||
static RESTAPI_IntServer *instance_ = new RESTAPI_IntServer;
|
||||
return instance_;
|
||||
static RESTAPI_InternalServer *instance() {
|
||||
static RESTAPI_InternalServer instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
inline int Start() override;
|
||||
@@ -2491,13 +2458,12 @@ namespace OpenWifi {
|
||||
Logger_.information("Stopping ");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stop();
|
||||
Pool_.joinAll();
|
||||
RESTServers_.clear();
|
||||
RESTServers_.clear();
|
||||
}
|
||||
|
||||
inline void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path, uint64_t Id) {
|
||||
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
|
||||
RESTAPIHandler::BindingMap Bindings;
|
||||
return RESTAPI_internal_server(Path, Bindings, Logger_, Server_);
|
||||
}
|
||||
@@ -2506,31 +2472,31 @@ namespace OpenWifi {
|
||||
Poco::ThreadPool Pool_;
|
||||
RESTAPI_GenericServer Server_;
|
||||
|
||||
RESTAPI_IntServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
|
||||
RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline RESTAPI_IntServer * RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
|
||||
inline RESTAPI_InternalServer * RESTAPI_InternalServer() { return RESTAPI_InternalServer::instance(); };
|
||||
|
||||
class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
class InternalRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
explicit IntRequestHandlerFactory(RESTAPI_GenericServer & Server) :
|
||||
Logger_(RESTAPI_IntServer()->Logger()),
|
||||
InternalRequestHandlerFactory(RESTAPI_GenericServer & Server) :
|
||||
Logger_(RESTAPI_InternalServer()->Logger()),
|
||||
Server_(Server){}
|
||||
|
||||
inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
|
||||
Poco::URI uri(Request.getURI());
|
||||
auto *Path = uri.getPath().c_str();
|
||||
return RESTAPI_IntServer()->CallServer(Path, TransactionId_++);
|
||||
return RESTAPI_InternalServer()->CallServer(Path);
|
||||
}
|
||||
private:
|
||||
static inline std::atomic_uint64_t TransactionId_ = 1;
|
||||
Poco::Logger & Logger_;
|
||||
RESTAPI_GenericServer & Server_;
|
||||
RESTAPI_GenericServer &Server_;
|
||||
};
|
||||
|
||||
inline int RESTAPI_IntServer::Start() {
|
||||
inline int RESTAPI_InternalServer::Start() {
|
||||
Logger_.information("Starting.");
|
||||
Server_.InitLogging();
|
||||
|
||||
@@ -2548,7 +2514,7 @@ namespace OpenWifi {
|
||||
Params->setMaxQueued(200);
|
||||
Params->setKeepAlive(true);
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory(Server_), Pool_, Sock, Params);
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new InternalRequestHandlerFactory(Server_), Pool_, Sock, Params);
|
||||
NewServer->start();
|
||||
RESTServers_.push_back(std::move(NewServer));
|
||||
}
|
||||
@@ -2588,13 +2554,11 @@ namespace OpenWifi {
|
||||
DAEMON_BUS_TIMER(BusTimer),
|
||||
SubSystems_(std::move(Subsystems)) {
|
||||
instance_ = this;
|
||||
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string Version() { return Version_; }
|
||||
[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
|
||||
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
|
||||
[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; }
|
||||
[[nodiscard]] bool Debug() const { return DebugMode_; }
|
||||
[[nodiscard]] uint64_t ID() const { return ID_; }
|
||||
[[nodiscard]] std::string Hash() const { return MyHash_; };
|
||||
@@ -2607,13 +2571,6 @@ namespace OpenWifi {
|
||||
static inline uint64_t GetPID() { return Poco::Process::id(); };
|
||||
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
|
||||
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
|
||||
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
|
||||
return (RandomEngine_() % ceiling);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
|
||||
return ((RandomEngine_() % (max-min)) + min);
|
||||
}
|
||||
|
||||
inline void Exit(int Reason);
|
||||
inline void BusMessageReceived(const std::string &Key, const std::string & Message);
|
||||
@@ -2635,7 +2592,7 @@ namespace OpenWifi {
|
||||
inline void InitializeSubSystemServers();
|
||||
inline void StartSubSystemServers();
|
||||
inline void StopSubSystemServers();
|
||||
[[nodiscard]] static inline std::string CreateUUID();
|
||||
[[nodiscard]] inline std::string CreateUUID();
|
||||
inline bool SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
|
||||
inline void Reload(const std::string &Sub);
|
||||
inline Types::StringVec GetSubSystems() const;
|
||||
@@ -2665,10 +2622,9 @@ namespace OpenWifi {
|
||||
std::string ConfigFileName_;
|
||||
Poco::UUIDGenerator UUIDGenerator_;
|
||||
uint64_t ID_ = 1;
|
||||
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
|
||||
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_ = nullptr;
|
||||
bool DebugMode_ = false;
|
||||
std::string DataDir_;
|
||||
std::string WWWAssetsDir_;
|
||||
SubSystemVec SubSystems_;
|
||||
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
||||
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
||||
@@ -2678,10 +2634,9 @@ namespace OpenWifi {
|
||||
std::string MyPrivateEndPoint_;
|
||||
std::string MyPublicEndPoint_;
|
||||
std::string UIURI_;
|
||||
std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
|
||||
std::string Version_{std::string(APP_VERSION) + "("+ BUILD_NUMBER + ")"};
|
||||
BusEventManager BusEventManager_;
|
||||
std::mutex InfraMutex_;
|
||||
std::default_random_engine RandomEngine_;
|
||||
|
||||
std::string DAEMON_PROPERTIES_FILENAME;
|
||||
std::string DAEMON_ROOT_ENV_VAR;
|
||||
@@ -2829,8 +2784,8 @@ namespace OpenWifi {
|
||||
// add the default services
|
||||
SubSystems_.push_back(KafkaManager());
|
||||
SubSystems_.push_back(ALBHealthCheckServer());
|
||||
SubSystems_.push_back(RESTAPI_ExtServer());
|
||||
SubSystems_.push_back(RESTAPI_IntServer());
|
||||
SubSystems_.push_back(RESTAPI_server());
|
||||
SubSystems_.push_back(RESTAPI_InternalServer());
|
||||
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::HTTPStreamFactory::registerFactory();
|
||||
@@ -2858,9 +2813,6 @@ namespace OpenWifi {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets","");
|
||||
if(WWWAssetsDir_.empty())
|
||||
WWWAssetsDir_ = DataDir_;
|
||||
|
||||
LoadMyConfig();
|
||||
|
||||
@@ -2967,42 +2919,13 @@ namespace OpenWifi {
|
||||
|
||||
inline void MicroService::StopSubSystemServers() {
|
||||
BusEventManager_.Stop();
|
||||
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) {
|
||||
(*i)->Stop();
|
||||
}
|
||||
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i)
|
||||
(*i)->Stop();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string MicroService::CreateUUID() {
|
||||
static std::random_device rd;
|
||||
static std::mt19937_64 gen(rd());
|
||||
static std::uniform_int_distribution<> dis(0, 15);
|
||||
static std::uniform_int_distribution<> dis2(8, 11);
|
||||
|
||||
std::stringstream ss;
|
||||
int i;
|
||||
ss << std::hex;
|
||||
for (i = 0; i < 8; i++) {
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (i = 0; i < 4; i++) {
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-4";
|
||||
for (i = 0; i < 3; i++) {
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
ss << dis2(gen);
|
||||
for (i = 0; i < 3; i++) {
|
||||
ss << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (i = 0; i < 12; i++) {
|
||||
ss << dis(gen);
|
||||
};
|
||||
return ss.str();
|
||||
}
|
||||
return UUIDGenerator_.create().toString();
|
||||
}
|
||||
|
||||
inline bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
|
||||
try {
|
||||
@@ -3015,6 +2938,7 @@ namespace OpenWifi {
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// std::cout << "Sub:" << SubSystem << " Level:" << Level << std::endl;
|
||||
for (auto i : SubSystems_) {
|
||||
if (Sub == Poco::toLower(i->Name())) {
|
||||
i->Logger().setLevel(P);
|
||||
@@ -3164,6 +3088,7 @@ namespace OpenWifi {
|
||||
StartSubSystemServers();
|
||||
waitForTerminationRequest();
|
||||
StopSubSystemServers();
|
||||
|
||||
logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
|
||||
}
|
||||
|
||||
@@ -3243,7 +3168,6 @@ namespace OpenWifi {
|
||||
|
||||
inline int ALBHealthCheckServer::Start() {
|
||||
if(MicroService::instance().ConfigGetBool("alb.enable",false)) {
|
||||
Running_=true;
|
||||
Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015);
|
||||
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
@@ -3288,42 +3212,41 @@ namespace OpenWifi {
|
||||
KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
|
||||
}
|
||||
|
||||
inline void KafkaProducer::run() {
|
||||
inline void KafkaManager::ProducerThr() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
|
||||
});
|
||||
KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
|
||||
std::to_string(MicroService::instance().ID()) +
|
||||
R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
|
||||
R"lit(" } , "payload" : )lit" ;
|
||||
cppkafka::Producer Producer(Config);
|
||||
Running_ = true;
|
||||
while(Running_) {
|
||||
ProducerRunning_ = true;
|
||||
while(ProducerRunning_) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
try
|
||||
{
|
||||
std::lock_guard G(Mutex_);
|
||||
std::lock_guard G(ProducerMutex_);
|
||||
auto Num=0;
|
||||
while (!KafkaManager()->Queue_.empty()) {
|
||||
const auto M = KafkaManager()->Queue_.front();
|
||||
while (!Queue_.empty()) {
|
||||
const auto M = Queue_.front();
|
||||
Producer.produce(
|
||||
cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
|
||||
KafkaManager()->Queue_.pop();
|
||||
Queue_.pop();
|
||||
Num++;
|
||||
}
|
||||
if(Num)
|
||||
Producer.flush();
|
||||
} catch (const cppkafka::HandleException &E ) {
|
||||
KafkaManager()->Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
KafkaManager()->Logger_.log(E);
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
Producer.flush();
|
||||
}
|
||||
|
||||
inline void KafkaConsumer::run() {
|
||||
inline void KafkaManager::ConsumerThr() {
|
||||
cppkafka::Configuration Config({
|
||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
|
||||
@@ -3343,13 +3266,13 @@ namespace OpenWifi {
|
||||
cppkafka::Consumer Consumer(Config);
|
||||
Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
|
||||
if(!partitions.empty()) {
|
||||
KafkaManager()->Logger_.information(Poco::format("Partition assigned: %Lu...",
|
||||
Logger_.information(Poco::format("Partition assigned: %Lu...",
|
||||
(uint64_t)partitions.front().get_partition()));
|
||||
}
|
||||
});
|
||||
Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
|
||||
if(!partitions.empty()) {
|
||||
KafkaManager()->Logger_.information(Poco::format("Partition revocation: %Lu...",
|
||||
Logger_.information(Poco::format("Partition revocation: %Lu...",
|
||||
(uint64_t)partitions.front().get_partition()));
|
||||
}
|
||||
});
|
||||
@@ -3358,13 +3281,13 @@ namespace OpenWifi {
|
||||
auto BatchSize = MicroService::instance().ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
|
||||
|
||||
Types::StringVec Topics;
|
||||
for(const auto &i:KafkaManager()->Notifiers_)
|
||||
for(const auto &i:Notifiers_)
|
||||
Topics.push_back(i.first);
|
||||
|
||||
Consumer.subscribe(Topics);
|
||||
|
||||
Running_ = true;
|
||||
while(Running_) {
|
||||
ConsumerRunning_ = true;
|
||||
while(ConsumerRunning_) {
|
||||
try {
|
||||
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
|
||||
for(auto const &Msg:MsgVec) {
|
||||
@@ -3372,14 +3295,14 @@ namespace OpenWifi {
|
||||
continue;
|
||||
if (Msg.get_error()) {
|
||||
if (!Msg.is_eof()) {
|
||||
KafkaManager()->Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
|
||||
Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
|
||||
}if(!AutoCommit)
|
||||
Consumer.async_commit(Msg);
|
||||
continue;
|
||||
}
|
||||
std::lock_guard G(Mutex_);
|
||||
auto It = KafkaManager()->Notifiers_.find(Msg.get_topic());
|
||||
if (It != KafkaManager()->Notifiers_.end()) {
|
||||
std::lock_guard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(Msg.get_topic());
|
||||
if (It != Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList &FL = It->second;
|
||||
std::string Key{Msg.get_key()};
|
||||
std::string Payload{Msg.get_payload()};
|
||||
@@ -3392,22 +3315,21 @@ namespace OpenWifi {
|
||||
Consumer.async_commit(Msg);
|
||||
}
|
||||
} catch (const cppkafka::HandleException &E) {
|
||||
KafkaManager()->Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
|
||||
Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
|
||||
} catch (const Poco::Exception &E) {
|
||||
KafkaManager()->Logger_.log(E);
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
Consumer.unsubscribe();
|
||||
}
|
||||
|
||||
inline void RESTAPI_ExtServer::reinitialize(Poco::Util::Application &self) {
|
||||
inline void RESTAPI_server::reinitialize(Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger_.information("Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
|
||||
void RESTAPI_IntServer::reinitialize(Poco::Util::Application &self) {
|
||||
void RESTAPI_InternalServer::reinitialize(Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger_.information("Reinitializing.");
|
||||
Stop();
|
||||
@@ -3618,9 +3540,11 @@ namespace OpenWifi {
|
||||
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
Poco::JSON::Parser P;
|
||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||
// std::cout << "Response OK" << std::endl;
|
||||
} else {
|
||||
Poco::JSON::Parser P;
|
||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||
// std::cout << "Response: " << Response.getStatus() << std::endl;
|
||||
}
|
||||
return Response.getStatus();
|
||||
}
|
||||
@@ -3666,9 +3590,11 @@ namespace OpenWifi {
|
||||
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
Poco::JSON::Parser P;
|
||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||
// std::cout << "Response OK" << std::endl;
|
||||
} else {
|
||||
Poco::JSON::Parser P;
|
||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||
// std::cout << "Response: " << Response.getStatus() << std::endl;
|
||||
}
|
||||
return Response.getStatus();
|
||||
}
|
||||
@@ -3694,9 +3620,9 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
#endif
|
||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired ) {
|
||||
inline bool RESTAPIHandler::IsAuthorized() {
|
||||
if(Internal_) {
|
||||
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
|
||||
if(!Allowed) {
|
||||
@@ -3726,12 +3652,12 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired)) {
|
||||
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_)) {
|
||||
#else
|
||||
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired)) {
|
||||
if (AuthClient()->IsAuthorized(*Request, SessionToken_, UserInfo_)) {
|
||||
#endif
|
||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
||||
Logger_.debug(Poco::format("X-REQ-ALLOWED(%s): User='%s@%s' Method='%s' Path='%s'",
|
||||
Logger_.debug(Poco::format("X-REQ-ALLOWED(%s): User='%s@%s' Method='%s' Path='%s",
|
||||
UserInfo_.userinfo.email,
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||
Request->clientAddress().toString(),
|
||||
@@ -3741,10 +3667,11 @@ namespace OpenWifi {
|
||||
return true;
|
||||
} else {
|
||||
if(Server_.LogBadTokens(true)) {
|
||||
Logger_.debug(Poco::format("X-REQ-DENIED(%s): Method='%s' Path='%s'",
|
||||
Logger_.debug(Poco::format("X-REQ-DENIED(%s): Method='%s' Path='%s",
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||
Request->getMethod(), Request->getURI()));
|
||||
}
|
||||
UnAuthorized("Invalid token", INVALID_TOKEN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
|
||||
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
|
||||
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
|
||||
static const std::string ExpiredToken{"Token has expired, user must login."};
|
||||
}
|
||||
|
||||
#endif //OWPROV_RESTAPI_ERRORS_H
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// Created by stephane bourque on 2021-10-06.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#ifndef OPENWIFI_STORAGE_H
|
||||
#define OPENWIFI_STORAGE_H
|
||||
|
||||
#include "Poco/Data/Session.h"
|
||||
#include "Poco/Data/SessionPool.h"
|
||||
@@ -25,6 +26,13 @@ namespace OpenWifi {
|
||||
|
||||
class StorageClass : public SubSystemServer {
|
||||
public:
|
||||
/* static StorageClass *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new StorageClass;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
*/
|
||||
StorageClass() noexcept:
|
||||
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
|
||||
{
|
||||
@@ -48,18 +56,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void Stop() override {
|
||||
Pool_->shutdown();
|
||||
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
||||
if(dbType_==sqlite) {
|
||||
return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
|
||||
return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " ";
|
||||
} else if(dbType_==pgsql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
} else if(dbType_==mysql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
}
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
}
|
||||
|
||||
inline std::string ConvertParams(const std::string & S) const {
|
||||
@@ -88,11 +96,11 @@ namespace OpenWifi {
|
||||
inline int Setup_PostgreSQL();
|
||||
|
||||
protected:
|
||||
Poco::SharedPtr<Poco::Data::SessionPool> Pool_;
|
||||
Poco::Data::SQLite::Connector SQLiteConn_;
|
||||
Poco::Data::PostgreSQL::Connector PostgresConn_;
|
||||
Poco::Data::MySQL::Connector MySQLConn_;
|
||||
DBType dbType_ = sqlite;
|
||||
std::unique_ptr<Poco::Data::SessionPool> Pool_;
|
||||
std::unique_ptr<Poco::Data::SQLite::Connector> SQLiteConn_;
|
||||
std::unique_ptr<Poco::Data::PostgreSQL::Connector> PostgresConn_;
|
||||
std::unique_ptr<Poco::Data::MySQL::Connector> MySQLConn_;
|
||||
DBType dbType_ = sqlite;
|
||||
};
|
||||
|
||||
#ifdef SMALL_BUILD
|
||||
@@ -106,8 +114,9 @@ namespace OpenWifi {
|
||||
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
|
||||
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
|
||||
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
|
||||
SQLiteConn_.registerConnector();
|
||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime));
|
||||
SQLiteConn_ = std::make_unique<Poco::Data::SQLite::Connector>();
|
||||
SQLiteConn_->registerConnector();
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_->name(), DBName, 4, NumSessions, IdleTime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -130,8 +139,9 @@ namespace OpenWifi {
|
||||
";port=" + Port +
|
||||
";compress=true;auto-reconnect=true";
|
||||
|
||||
MySQLConn_.registerConnector();
|
||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
|
||||
MySQLConn_ = std::make_unique<Poco::Data::MySQL::Connector>();
|
||||
MySQLConn_->registerConnector();
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -156,11 +166,14 @@ namespace OpenWifi {
|
||||
" port=" + Port +
|
||||
" connect_timeout=" + ConnectionTimeout;
|
||||
|
||||
PostgresConn_.registerConnector();
|
||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
|
||||
PostgresConn_ = std::make_unique<Poco::Data::PostgreSQL::Connector>();
|
||||
PostgresConn_->registerConnector();
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif //OPENWIFI_STORAGE_H
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-12-06.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace OW_VERSION {
|
||||
inline static const std::string VERSION{"@CMAKE_PROJECT_VERSION@"};
|
||||
inline static const std::string BUILD{"@BUILD_NUM@"};
|
||||
inline static const std::string HASH{"@GIT_HASH@"};
|
||||
}
|
||||
@@ -183,19 +183,4 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Storage::CleanOldActionLinks() {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Delete(Sess);
|
||||
|
||||
uint64_t CutOff = std::time(nullptr) - (30 * 24 * 60 * 60);
|
||||
std::string St{"DELETE from ActionLinks where Created<=?"};
|
||||
Delete << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(CutOff);
|
||||
Delete.execute();
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace OpenWifi {
|
||||
"RevocationDate BIGINT "
|
||||
*/
|
||||
|
||||
bool Storage::AddToken(std::string &UserID, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
|
||||
bool Storage::AddToken(std::string &UserName, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Insert(Sess);
|
||||
@@ -29,7 +29,7 @@ namespace OpenWifi {
|
||||
Poco::Data::Keywords::use(Token),
|
||||
Poco::Data::Keywords::use(RefreshToken),
|
||||
Poco::Data::Keywords::use(TokenType),
|
||||
Poco::Data::Keywords::use(UserID),
|
||||
Poco::Data::Keywords::use(UserName),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Expires),
|
||||
Poco::Data::Keywords::use(TimeOut),
|
||||
@@ -42,24 +42,29 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate) {
|
||||
bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo) {
|
||||
try {
|
||||
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
RevocationDate = 0 ;
|
||||
std::string St2{"SELECT " + AllTokensFieldsForSelect + " From Tokens WHERE Token=?"};
|
||||
|
||||
uint32_t RevocationDate = 0 ;
|
||||
|
||||
std::string St2{"SELECT " + AllTokensValuesForSelect + " From Tokens WHERE Token=?"};
|
||||
Select << ConvertParams(St2),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.access_token_),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.refresh_token_),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.token_type_),
|
||||
Poco::Data::Keywords::into(UInfo.userinfo.Id),
|
||||
Poco::Data::Keywords::into(UInfo.userinfo.email),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.created_),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.expires_in_),
|
||||
Poco::Data::Keywords::into(UInfo.webtoken.idle_timeout_),
|
||||
Poco::Data::Keywords::into(RevocationDate),
|
||||
Poco::Data::Keywords::use(Token);
|
||||
Select.execute();
|
||||
|
||||
if(RevocationDate>0)
|
||||
return false;
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
@@ -111,15 +116,15 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::CleanExpiredTokens() {
|
||||
bool Storage::CleanRevokedTokens(uint64_t Oldest) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Delete(Sess);
|
||||
uint64_t Now = std::time(nullptr);
|
||||
|
||||
std::string St2{"DELETE From Tokens WHERE (Created+Expires) <= ?"};
|
||||
std::string St2{"DELETE From Tokens WHERE Created <= ?"};
|
||||
Delete << ConvertParams(St2),
|
||||
Poco::Data::Keywords::use(Now);
|
||||
Poco::Data::Keywords::use(Oldest);
|
||||
Delete.execute();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
@@ -128,14 +133,14 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::RevokeAllTokens(std::string & UserId) {
|
||||
bool Storage::RevokeAllTokens(std::string & username) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Delete(Sess);
|
||||
|
||||
std::string St2{"DELETE From Tokens WHERE Username=?"};
|
||||
Delete << ConvertParams(St2),
|
||||
Poco::Data::Keywords::use(UserId);
|
||||
Poco::Data::Keywords::use(username);
|
||||
Delete.execute();
|
||||
return true;
|
||||
} catch(const Poco::Exception &E) {
|
||||
|
||||
@@ -80,23 +80,7 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OldDefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
|
||||
std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"};
|
||||
|
||||
void Storage::ReplaceOldDefaultUUID() {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
std::string St1{"update users set id=? where id=?"};
|
||||
|
||||
Poco::Data::Statement Update(Sess);
|
||||
Update << ConvertParams(St1),
|
||||
Poco::Data::Keywords::use(NewDefaultUseridStockUUID),
|
||||
Poco::Data::Keywords::use(OldDefaultUseridStockUUID);
|
||||
Update.execute();
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
std::string DefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
|
||||
|
||||
// if we do not find a default user, then we need to create one based on the
|
||||
// property file. We must set its flag to "must change password", this user has root privilege.
|
||||
@@ -105,13 +89,12 @@ namespace OpenWifi {
|
||||
SecurityObjects::UserInfo U;
|
||||
bool DefaultUserCreated = false;
|
||||
|
||||
ReplaceOldDefaultUUID();
|
||||
AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
|
||||
if(!GetUserById(NewDefaultUseridStockUUID,U) && !DefaultUserCreated) {
|
||||
if(!GetUserById(DefaultUseridStockUUID,U) && !DefaultUserCreated) {
|
||||
U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
|
||||
U.lastPasswords.push_back(U.currentPassword);
|
||||
U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
|
||||
U.Id = NewDefaultUseridStockUUID;
|
||||
U.Id = DefaultUseridStockUUID;
|
||||
U.userRole = SecurityObjects::ROOT;
|
||||
U.creationDate = std::time(nullptr);
|
||||
U.validated = true;
|
||||
@@ -149,7 +132,7 @@ namespace OpenWifi {
|
||||
return false;
|
||||
|
||||
if(!PasswordHashedAlready) {
|
||||
NewUser.Id = MicroService::CreateUUID();
|
||||
NewUser.Id = MicroService::instance().CreateUUID();
|
||||
NewUser.creationDate = std::time(nullptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,23 +15,23 @@ namespace OpenWifi {
|
||||
"description varchar,"
|
||||
"avatar varchar,"
|
||||
"email varchar,"
|
||||
"validated boolean,"
|
||||
"validated int,"
|
||||
"validationEmail varchar,"
|
||||
"validationDate bigint,"
|
||||
"creationDate bigint,"
|
||||
"validationURI varchar,"
|
||||
"changePassword boolean,"
|
||||
"changePassword int,"
|
||||
"lastLogin bigint,"
|
||||
"currentLoginURI varchar,"
|
||||
"lastPasswordChange bigint,"
|
||||
"lastEmailCheck bigint,"
|
||||
"waitingForEmailCheck boolean,"
|
||||
"waitingForEmailCheck int,"
|
||||
"locale varchar,"
|
||||
"notes text,"
|
||||
"location varchar,"
|
||||
"owner varchar,"
|
||||
"suspended boolean,"
|
||||
"blackListed boolean,"
|
||||
"suspended int,"
|
||||
"blackListed int,"
|
||||
"userRole varchar,"
|
||||
"userTypeProprietaryInfo text,"
|
||||
"securityPolicy text,"
|
||||
@@ -111,23 +111,23 @@ namespace OpenWifi {
|
||||
std::string, // description;
|
||||
std::string, // avatar;
|
||||
std::string, // email;
|
||||
bool, // bool validated = false;
|
||||
uint64_t, // bool validated = false;
|
||||
std::string, // validationEmail;
|
||||
uint64_t, // validationDate = 0;
|
||||
uint64_t, // creationDate = 0;
|
||||
std::string, // validationURI;
|
||||
bool, // bool changePassword = true;
|
||||
uint64_t, // bool changePassword = true;
|
||||
uint64_t, // lastLogin = 0;
|
||||
std::string, // currentLoginURI;
|
||||
uint64_t, // lastPasswordChange = 0;
|
||||
uint64_t, // lastEmailCheck = 0;
|
||||
bool, // bool waitingForEmailCheck = false;
|
||||
uint64_t, // bool waitingForEmailCheck = false;
|
||||
std::string, // locale;
|
||||
std::string, // notes;
|
||||
std::string, // location;
|
||||
std::string, // owner;
|
||||
bool, // bool suspended = false;
|
||||
bool, // bool blackListed = false;
|
||||
uint64_t, // bool suspended = false;
|
||||
uint64_t, // bool blackListed = false;
|
||||
std::string, // userRole;
|
||||
std::string, // userTypeProprietaryInfo;
|
||||
std::string, // securityPolicy;
|
||||
|
||||
@@ -35,7 +35,7 @@ fi
|
||||
token=""
|
||||
result_file=result.json
|
||||
username="tip@ucentral.com"
|
||||
password="Snoopy99!!!"
|
||||
password="openwifi"
|
||||
#username="stephb@incognito.com"
|
||||
#password="Snoopy98!"
|
||||
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
|
||||
|
||||
Reference in New Issue
Block a user