mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-30 18:27:49 +00:00
Compare commits
1 Commits
v2.4.0-RC4
...
feature/wi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05d06fce53 |
@@ -30,20 +30,9 @@ else()
|
|||||||
file(WRITE build ${BUILD_NUM})
|
file(WRITE build ${BUILD_NUM})
|
||||||
endif()
|
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)
|
set(BUILD_SHARED_LIBS 1)
|
||||||
|
|
||||||
|
add_definitions(-DAPP_VERSION="${CMAKE_PROJECT_VERSION}" -DBUILD_NUMBER="${BUILD_NUM}")
|
||||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
||||||
|
|
||||||
set(Boost_USE_STATIC_LIBS OFF)
|
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)
|
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
|
add_executable( owsec
|
||||||
build
|
build
|
||||||
src/ow_version.h.in
|
|
||||||
src/framework/CountryCodes.h
|
src/framework/CountryCodes.h
|
||||||
src/framework/KafkaTopics.h
|
src/framework/KafkaTopics.h
|
||||||
src/framework/MicroService.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_actionLinks.cpp src/storage/storage_actionLinks.h
|
||||||
src/storage/storage_tokens.h
|
src/storage/storage_tokens.h
|
||||||
src/ActionLinkManager.cpp src/ActionLinkManager.h
|
src/ActionLinkManager.cpp src/ActionLinkManager.h
|
||||||
src/ACLProcessor.h)
|
)
|
||||||
|
|
||||||
if(NOT SMALL_BUILD)
|
if(NOT SMALL_BUILD)
|
||||||
target_link_libraries(owsec PUBLIC
|
target_link_libraries(owsec PUBLIC
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ RUN make install
|
|||||||
ADD CMakeLists.txt build /owsec/
|
ADD CMakeLists.txt build /owsec/
|
||||||
ADD cmake /owsec/cmake
|
ADD cmake /owsec/cmake
|
||||||
ADD src /owsec/src
|
ADD src /owsec/src
|
||||||
ADD .git /owgw/.git
|
|
||||||
|
|
||||||
WORKDIR /owsec
|
WORKDIR /owsec
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owsec:
|
owsec:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
||||||
tag: v2.4.0-RC4
|
tag: main
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ components:
|
|||||||
- 6 # INTERNAL_ERROR,
|
- 6 # INTERNAL_ERROR,
|
||||||
- 7 # ACCESS_DENIED,
|
- 7 # ACCESS_DENIED,
|
||||||
- 8 # INVALID_TOKEN
|
- 8 # INVALID_TOKEN
|
||||||
- 9 # expired token
|
|
||||||
- 10 # rate limit exceeded
|
|
||||||
ErrorDetails:
|
ErrorDetails:
|
||||||
type: string
|
type: string
|
||||||
ErrorDescription:
|
ErrorDescription:
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ openwifi.system.commandchannel = /tmp/app.ucentralsec
|
|||||||
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
||||||
openwifi.service.key.password = mypassword
|
openwifi.service.key.password = mypassword
|
||||||
|
|
||||||
smssender.enabled = false
|
|
||||||
smssender.provider = aws
|
smssender.provider = aws
|
||||||
smssender.aws.secretkey = ***************************************
|
smssender.aws.secretkey = ***************************************
|
||||||
smssender.aws.accesskey = ***************************************
|
smssender.aws.accesskey = ***************************************
|
||||||
@@ -54,7 +53,6 @@ smssender.aws.region = **************
|
|||||||
#
|
#
|
||||||
# Security Microservice Specific Section
|
# Security Microservice Specific Section
|
||||||
#
|
#
|
||||||
mailer.enabled = false
|
|
||||||
mailer.hostname = smtp.gmail.com
|
mailer.hostname = smtp.gmail.com
|
||||||
mailer.username = ************************
|
mailer.username = ************************
|
||||||
mailer.password = ************************
|
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 ActionLinkManager * instance() {
|
||||||
static auto * instance_ = new ActionLinkManager;
|
static ActionLinkManager instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() final;
|
int Start() final;
|
||||||
|
|||||||
@@ -56,10 +56,9 @@ namespace OpenWifi {
|
|||||||
Logger_.notice("Stopping...");
|
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_);
|
std::lock_guard Guard(Mutex_);
|
||||||
Expired = false;
|
|
||||||
try {
|
try {
|
||||||
std::string CallToken;
|
std::string CallToken;
|
||||||
Poco::Net::OAuth20Credentials Auth(Request);
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
@@ -68,29 +67,27 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!CallToken.empty()) {
|
if(!CallToken.empty()) {
|
||||||
auto Client = UserCache_.get(CallToken);
|
if(StorageService()->IsTokenRevoked(CallToken))
|
||||||
if( Client.isNull() ) {
|
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo2;
|
|
||||||
uint64_t RevocationDate=0;
|
|
||||||
if(StorageService()->GetToken(CallToken,UInfo2,RevocationDate)) {
|
|
||||||
if(RevocationDate!=0)
|
|
||||||
return false;
|
return false;
|
||||||
Expired = (UInfo2.webtoken.created_ + UInfo2.webtoken.expires_in_) < time(nullptr);
|
auto Client = UserCache_.find(CallToken);
|
||||||
if(StorageService()->GetUserById(UInfo2.userinfo.Id,UInfo.userinfo)) {
|
if( Client == UserCache_.end() ) {
|
||||||
UInfo.webtoken = UInfo2.webtoken;
|
if(StorageService()->GetToken(SessionToken,UInfo)) {
|
||||||
UserCache_.update(CallToken, UInfo);
|
if(StorageService()->GetUserById(UInfo.userinfo.email,UInfo.userinfo)) {
|
||||||
SessionToken = CallToken;
|
UserCache_[UInfo.webtoken.access_token_] = UInfo;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!Expired) {
|
|
||||||
|
if((Client->second.webtoken.created_ + Client->second.webtoken.expires_in_) > time(nullptr)) {
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
UInfo = *Client ;
|
UInfo = Client->second ;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
RevokeToken(CallToken);
|
|
||||||
|
UserCache_.erase(Client);
|
||||||
|
StorageService()->RevokeToken(CallToken);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch(const Poco::Exception &E) {
|
} catch(const Poco::Exception &E) {
|
||||||
@@ -99,24 +96,16 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::RevokeToken(std::string & Token) {
|
|
||||||
UserCache_.remove(Token);
|
|
||||||
StorageService()->RevokeToken(Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthService::DeleteUserFromCache(const std::string &UserName) {
|
bool AuthService::DeleteUserFromCache(const std::string &UserName) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
std::vector<std::string> OldTokens;
|
for(auto i=UserCache_.begin();i!=UserCache_.end();) {
|
||||||
|
if (i->second.userinfo.email==UserName) {
|
||||||
UserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
|
Logout(i->first, false);
|
||||||
{ if(O.userinfo.email==UserName)
|
i = UserCache_.erase(i);
|
||||||
OldTokens.push_back(token);
|
} else {
|
||||||
});
|
++i;
|
||||||
|
}
|
||||||
for(const auto &i:OldTokens) {
|
|
||||||
Logout(i,false);
|
|
||||||
UserCache_.remove(i);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -132,6 +121,9 @@ namespace OpenWifi {
|
|||||||
void AuthService::Logout(const std::string &token, bool EraseFromCache) {
|
void AuthService::Logout(const std::string &token, bool EraseFromCache) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
|
if(EraseFromCache)
|
||||||
|
UserCache_.erase(token);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Poco::JSON::Object Obj;
|
Poco::JSON::Object Obj;
|
||||||
Obj.set("event", "remove-token");
|
Obj.set("event", "remove-token");
|
||||||
@@ -140,7 +132,7 @@ namespace OpenWifi {
|
|||||||
std::stringstream ResultText;
|
std::stringstream ResultText;
|
||||||
Poco::JSON::Stringifier::stringify(Obj, ResultText);
|
Poco::JSON::Stringifier::stringify(Obj, ResultText);
|
||||||
std::string Tmp{token};
|
std::string Tmp{token};
|
||||||
RevokeToken(Tmp);
|
StorageService()->RevokeToken(Tmp);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
|
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
|
||||||
false);
|
false);
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
@@ -191,9 +183,9 @@ namespace OpenWifi {
|
|||||||
UInfo.webtoken.username_ = UserName;
|
UInfo.webtoken.username_ = UserName;
|
||||||
UInfo.webtoken.errorCode = 0;
|
UInfo.webtoken.errorCode = 0;
|
||||||
UInfo.webtoken.userMustChangePassword = false;
|
UInfo.webtoken.userMustChangePassword = false;
|
||||||
UserCache_.update(UInfo.webtoken.access_token_,UInfo);
|
UserCache_[UInfo.webtoken.access_token_] = UInfo;
|
||||||
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
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.refresh_token_, UInfo.webtoken.token_type_,
|
||||||
UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
|
UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
|
||||||
}
|
}
|
||||||
@@ -261,7 +253,7 @@ namespace OpenWifi {
|
|||||||
return false;
|
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_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
@@ -299,7 +291,6 @@ namespace OpenWifi {
|
|||||||
UInfo.userinfo.lastLogin=std::time(nullptr);
|
UInfo.userinfo.lastLogin=std::time(nullptr);
|
||||||
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
||||||
CreateToken(UserName, UInfo );
|
CreateToken(UserName, UInfo );
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +337,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
|
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
|
||||||
A.userId = UInfo.email;
|
A.userId = UInfo.email;
|
||||||
A.id = MicroService::CreateUUID();
|
A.id = MicroService::instance().CreateUUID();
|
||||||
A.created = std::time(nullptr);
|
A.created = std::time(nullptr);
|
||||||
A.expires = A.created + 24*60*60;
|
A.expires = A.created + 24*60*60;
|
||||||
StorageService()->CreateAction(A);
|
StorageService()->CreateAction(A);
|
||||||
@@ -354,39 +345,16 @@ namespace OpenWifi {
|
|||||||
return true;
|
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_);
|
std::lock_guard G(Mutex_);
|
||||||
|
auto It = UserCache_.find(Token);
|
||||||
|
|
||||||
Expired = false;
|
if(It==UserCache_.end())
|
||||||
|
return false;
|
||||||
auto Client = UserCache_.get(Token);
|
WebToken = It->second.webtoken;
|
||||||
if(!Client.isNull()) {
|
UserInfo = It->second.userinfo;
|
||||||
Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < std::time(nullptr);
|
|
||||||
WebToken = Client->webtoken;
|
|
||||||
UserInfo = Client->userinfo;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TToken{Token};
|
|
||||||
if(StorageService()->IsTokenRevoked(TToken)) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#include "Poco/SHA2Engine.h"
|
#include "Poco/SHA2Engine.h"
|
||||||
#include "Poco/Crypto/DigestEngine.h"
|
#include "Poco/Crypto/DigestEngine.h"
|
||||||
#include "Poco/HMACEngine.h"
|
#include "Poco/HMACEngine.h"
|
||||||
#include "Poco/ExpireLRUCache.h"
|
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
@@ -45,15 +44,15 @@ namespace OpenWifi{
|
|||||||
static int AccessTypeToInt(ACCESS_TYPE T);
|
static int AccessTypeToInt(ACCESS_TYPE T);
|
||||||
|
|
||||||
static AuthService *instance() {
|
static AuthService *instance() {
|
||||||
static auto * instance_ = new AuthService;
|
static AuthService instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, 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, bool & Expired );
|
[[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);
|
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
||||||
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
||||||
@@ -61,7 +60,8 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
bool ValidatePassword(const std::string &pwd);
|
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 GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
|
||||||
[[nodiscard]] std::string GenerateTokenHMAC(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]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
||||||
[[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
|
[[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
|
||||||
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
void RevokeToken(std::string & Token);
|
|
||||||
|
|
||||||
[[nodiscard]] static inline const std::string GetLogoAssetURI() {
|
[[nodiscard]] static inline const std::string GetLogoAssetURI() {
|
||||||
return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
|
return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline const std::string GetLogoAssetFileName() {
|
[[nodiscard]] static inline const std::string GetLogoAssetFileName() {
|
||||||
return MicroService::instance().WWWAssetsDir() + "/the_logo.png";
|
return MicroService::instance().DataDir() + "/wwwassets/the_logo.png";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::JWT::Signer Signer_;
|
Poco::JWT::Signer Signer_;
|
||||||
Poco::SHA2Engine SHA2_;
|
Poco::SHA2Engine SHA2_;
|
||||||
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy> UserCache_{2048,1200000};
|
SecurityObjects::UserInfoCache UserCache_;
|
||||||
// SecurityObjects::UserInfoCache UserCache_;
|
|
||||||
std::string PasswordValidationStr_;
|
std::string PasswordValidationStr_;
|
||||||
std::regex PasswordValidation_;
|
std::regex PasswordValidation_;
|
||||||
uint64_t TokenAging_ = 30 * 24 * 60 * 60;
|
uint64_t TokenAging_ = 30 * 24 * 60 * 60;
|
||||||
@@ -121,8 +119,8 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
inline AuthService * AuthService() { return AuthService::instance(); }
|
inline AuthService * AuthService() { return AuthService::instance(); }
|
||||||
|
|
||||||
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired) {
|
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
|
||||||
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
|
return AuthService()->IsAuthorized(Request, SessionToken, UInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string Challenge = MakeChallenge();
|
std::string Challenge = MakeChallenge();
|
||||||
std::string uuid = MicroService::CreateUUID();
|
std::string uuid = MicroService::instance().CreateUUID();
|
||||||
uint64_t Created = std::time(nullptr);
|
uint64_t Created = std::time(nullptr);
|
||||||
|
|
||||||
ChallengeStart.set("uuid",uuid);
|
ChallengeStart.set("uuid",uuid);
|
||||||
@@ -71,9 +71,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto uuid = ChallengeResponse->get("uuid").toString();
|
auto uuid = ChallengeResponse->get("uuid").toString();
|
||||||
auto Hint = Cache_.find(uuid);
|
auto Hint = Cache_.find(uuid);
|
||||||
if(Hint == end(Cache_)) {
|
if(Hint == end(Cache_))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
auto answer = ChallengeResponse->get("answer").toString();
|
auto answer = ChallengeResponse->get("answer").toString();
|
||||||
if(Hint->second.Answer!=answer) {
|
if(Hint->second.Answer!=answer) {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ namespace OpenWifi {
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
static MFAServer *instance() {
|
static MFAServer *instance() {
|
||||||
static auto * instance_ = new MFAServer;
|
static MFAServer instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
|
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 bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
|
||||||
|
|
||||||
static inline std::string MakeChallenge() {
|
static inline std::string MakeChallenge() {
|
||||||
return std::to_string(MicroService::instance().Random(1,999999));
|
return std::to_string(rand() % 999999);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
Internal,
|
Internal,
|
||||||
false,
|
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"}; };
|
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
|
||||||
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
||||||
void CompleteResetPassword();
|
void CompleteResetPassword();
|
||||||
|
|||||||
@@ -17,38 +17,23 @@
|
|||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static void FilterCredentials(SecurityObjects::UserInfo & U) {
|
|
||||||
U.currentPassword.clear();
|
|
||||||
U.lastPasswords.clear();
|
|
||||||
U.oauthType.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_oauth2Handler::DoGet() {
|
void RESTAPI_oauth2Handler::DoGet() {
|
||||||
bool Expired = false;
|
if (!IsAuthorized()) {
|
||||||
if (!IsAuthorized(Expired)) {
|
|
||||||
if(Expired)
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
|
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
|
||||||
}
|
}
|
||||||
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
||||||
if(GetMe) {
|
if(GetMe) {
|
||||||
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
||||||
Poco::JSON::Object Me;
|
Poco::JSON::Object Me;
|
||||||
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
UserInfo_.userinfo.to_json(Me);
|
||||||
FilterCredentials(ReturnedUser);
|
|
||||||
ReturnedUser.to_json(Me);
|
|
||||||
return ReturnObject(Me);
|
return ReturnObject(Me);
|
||||||
}
|
}
|
||||||
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
|
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_oauth2Handler::DoDelete() {
|
void RESTAPI_oauth2Handler::DoDelete() {
|
||||||
bool Expired = false;
|
if (!IsAuthorized()) {
|
||||||
if (!IsAuthorized(Expired)) {
|
return UnAuthorized("Not authorized.");
|
||||||
if(Expired)
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
|
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
|
||||||
@@ -86,7 +71,7 @@ namespace OpenWifi {
|
|||||||
SecurityObjects::ActionLink NewLink;
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
|
||||||
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
||||||
NewLink.id = MicroService::CreateUUID();
|
NewLink.id = MicroService::instance().CreateUUID();
|
||||||
NewLink.userId = UInfo1.Id;
|
NewLink.userId = UInfo1.Id;
|
||||||
NewLink.created = std::time(nullptr);
|
NewLink.created = std::time(nullptr);
|
||||||
NewLink.expires = NewLink.created + (24*60*60);
|
NewLink.expires = NewLink.created + (24*60*60);
|
||||||
@@ -108,8 +93,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
|
||||||
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
||||||
if(Obj->has("uuid")) {
|
if(Obj->has(RESTAPI::Protocol::UUID)) {
|
||||||
auto uuid = Obj->get("uuid").toString();
|
auto uuid = Obj->get(RESTAPI::Protocol::UUID).toString();
|
||||||
if(MFAServer().ResendCode(uuid))
|
if(MFAServer().ResendCode(uuid))
|
||||||
return OK();
|
return OK();
|
||||||
}
|
}
|
||||||
@@ -118,7 +103,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
||||||
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
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;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
|
if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
|
||||||
Poco::JSON::Object ReturnObj;
|
Poco::JSON::Object ReturnObj;
|
||||||
@@ -130,8 +115,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
bool Expired=false;
|
auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo);
|
||||||
auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired);
|
|
||||||
if (Code==SUCCESS) {
|
if (Code==SUCCESS) {
|
||||||
Poco::JSON::Object ReturnObj;
|
Poco::JSON::Object ReturnObj;
|
||||||
if(AuthService()->RequiresMFA(UInfo)) {
|
if(AuthService()->RequiresMFA(UInfo)) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
|||||||
Poco::Net::HTTPRequest::HTTP_GET,
|
Poco::Net::HTTPRequest::HTTP_GET,
|
||||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||||
Server,
|
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"}; };
|
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
|
|||||||
@@ -7,16 +7,8 @@
|
|||||||
#include "Poco/JSON/Parser.h"
|
#include "Poco/JSON/Parser.h"
|
||||||
#include "framework/RESTAPI_errors.h"
|
#include "framework/RESTAPI_errors.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "ACLProcessor.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static void FilterCredentials(SecurityObjects::UserInfo & U) {
|
|
||||||
U.currentPassword.clear();
|
|
||||||
U.lastPasswords.clear();
|
|
||||||
U.oauthType.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_user_handler::DoGet() {
|
void RESTAPI_user_handler::DoGet() {
|
||||||
std::string Id = GetBinding("id", "");
|
std::string Id = GetBinding("id", "");
|
||||||
if(Id.empty()) {
|
if(Id.empty()) {
|
||||||
@@ -35,7 +27,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Poco::JSON::Object UserInfoObject;
|
Poco::JSON::Object UserInfoObject;
|
||||||
FilterCredentials(UInfo);
|
UInfo.currentPassword.clear();
|
||||||
|
UInfo.lastPasswords.clear();
|
||||||
|
UInfo.oauthType.clear();
|
||||||
UInfo.to_json(UserInfoObject);
|
UInfo.to_json(UserInfoObject);
|
||||||
ReturnObject(UserInfoObject);
|
ReturnObject(UserInfoObject);
|
||||||
}
|
}
|
||||||
@@ -46,12 +40,20 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::MissingUserID);
|
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;
|
SecurityObjects::UserInfo UInfo;
|
||||||
if(!StorageService()->GetUserById(Id,UInfo)) {
|
if(!StorageService()->GetUserById(Id,UInfo)) {
|
||||||
return NotFound();
|
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);
|
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,9 +64,6 @@ namespace OpenWifi {
|
|||||||
if(AuthService()->DeleteUserFromCache(UInfo.email)) {
|
if(AuthService()->DeleteUserFromCache(UInfo.email)) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
|
|
||||||
|
|
||||||
Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
|
Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
|
||||||
StorageService()->RevokeAllTokens(UInfo.email);
|
StorageService()->RevokeAllTokens(UInfo.email);
|
||||||
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.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);
|
return BadRequest(RESTAPI::Errors::IdMustBe0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewUser;
|
SecurityObjects::UserInfo UInfo;
|
||||||
RESTAPI_utils::from_request(NewUser,*Request);
|
RESTAPI_utils::from_request(UInfo,*Request);
|
||||||
|
|
||||||
if(NewUser.userRole == SecurityObjects::UNKNOWN) {
|
if(UInfo.userRole == SecurityObjects::UNKNOWN) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
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);
|
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::toLowerInPlace(NewUser.email);
|
if(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && UInfo.userRole == SecurityObjects::ROOT) {
|
||||||
if(!Utils::ValidEMailAddress(NewUser.email)) {
|
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::toLowerInPlace(UInfo.email);
|
||||||
|
if(!Utils::ValidEMailAddress(UInfo.email)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!NewUser.currentPassword.empty()) {
|
if(!UInfo.currentPassword.empty()) {
|
||||||
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
|
if(!AuthService()->ValidatePassword(UInfo.currentPassword)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidPassword);
|
return BadRequest(RESTAPI::Errors::InvalidPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NewUser.name.empty())
|
if(UInfo.name.empty())
|
||||||
NewUser.name = NewUser.email;
|
UInfo.name = UInfo.email;
|
||||||
|
|
||||||
if(!StorageService()->CreateUser(NewUser.email,NewUser)) {
|
if(!StorageService()->CreateUser(UInfo.email,UInfo)) {
|
||||||
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
|
Logger_.information(Poco::format("Could not add user '%s'.",UInfo.email));
|
||||||
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetParameter("email_verification","false")=="true") {
|
if(GetParameter("email_verification","false")=="true") {
|
||||||
if(AuthService::VerifyEmail(NewUser))
|
if(AuthService::VerifyEmail(UInfo))
|
||||||
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
|
Logger_.information(Poco::format("Verification e-mail requested for %s",UInfo.email));
|
||||||
StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,NewUser.Id,NewUser);
|
StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,UInfo.Id,UInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!StorageService()->GetUserByEmail(NewUser.email, NewUser)) {
|
if(!StorageService()->GetUserByEmail(UInfo.email, UInfo)) {
|
||||||
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
|
Logger_.information(Poco::format("User '%s' but not retrieved.",UInfo.email));
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::JSON::Object UserInfoObject;
|
Poco::JSON::Object UserInfoObject;
|
||||||
FilterCredentials(NewUser);
|
UInfo.to_json(UserInfoObject);
|
||||||
NewUser.to_json(UserInfoObject);
|
|
||||||
ReturnObject(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() {
|
void RESTAPI_user_handler::DoPut() {
|
||||||
@@ -136,8 +140,12 @@ namespace OpenWifi {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
||||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
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;
|
SecurityObjects::UserInfo NewUser;
|
||||||
@@ -216,23 +224,15 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!NewUser.userTypeProprietaryInfo.mfa.method.empty()) {
|
if(NewUser.userTypeProprietaryInfo.mfa.method=="email") {
|
||||||
if(NewUser.userTypeProprietaryInfo.mfa.method!="email" && NewUser.userTypeProprietaryInfo.mfa.method!="sms" ) {
|
|
||||||
return BadRequest("Unknown MFA method");
|
|
||||||
}
|
|
||||||
Existing.userTypeProprietaryInfo.mfa.method=NewUser.userTypeProprietaryInfo.mfa.method;
|
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)) {
|
if(StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
||||||
SecurityObjects::UserInfo NewUserInfo;
|
SecurityObjects::UserInfo NewUserInfo;
|
||||||
StorageService()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
StorageService()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||||
Poco::JSON::Object ModifiedObject;
|
Poco::JSON::Object ModifiedObject;
|
||||||
FilterCredentials(NewUserInfo);
|
|
||||||
NewUserInfo.to_json(ModifiedObject);
|
NewUserInfo.to_json(ModifiedObject);
|
||||||
return ReturnObject(ModifiedObject);
|
return ReturnObject(ModifiedObject);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ namespace OpenWifi {
|
|||||||
if (i.first == "token") {
|
if (i.first == "token") {
|
||||||
// can we find this token?
|
// can we find this token?
|
||||||
SecurityObjects::UserInfoAndPolicy SecObj;
|
SecurityObjects::UserInfoAndPolicy SecObj;
|
||||||
bool Expired = false;
|
if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo)) {
|
||||||
if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo, Expired)) {
|
|
||||||
Poco::JSON::Object Obj;
|
Poco::JSON::Object Obj;
|
||||||
SecObj.to_json(Obj);
|
SecObj.to_json(Obj);
|
||||||
return ReturnObject(Obj);
|
return ReturnObject(Obj);
|
||||||
|
|||||||
@@ -562,7 +562,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
}
|
}
|
||||||
I.notes = N;
|
I.notes = N;
|
||||||
I.modified = I.created = Now;
|
I.modified = I.created = Now;
|
||||||
I.id = MicroService::CreateUUID();
|
I.id = MicroService::instance().CreateUUID();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,15 +59,15 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
|
|
||||||
struct MobilePhoneNumber {
|
struct MobilePhoneNumber {
|
||||||
std::string number;
|
std::string number;
|
||||||
bool verified = false;
|
bool verified;
|
||||||
bool primary = false;
|
bool primary;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MfaAuthInfo {
|
struct MfaAuthInfo {
|
||||||
bool enabled = false;
|
bool enabled;
|
||||||
std::string method;
|
std::string method;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
@@ -86,7 +86,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
std::string uuid;
|
std::string uuid;
|
||||||
std::string question;
|
std::string question;
|
||||||
std::string method;
|
std::string method;
|
||||||
uint64_t created = std::time(nullptr);
|
uint64_t created;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|||||||
@@ -16,16 +16,13 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int SMSSender::Start() {
|
int SMSSender::Start() {
|
||||||
Enabled_ = MicroService::instance().ConfigGetBool("smssender.enabled",false);
|
Provider_ = MicroService::instance().ConfigGetString("sms.provider","aws");
|
||||||
if(Enabled_) {
|
|
||||||
Provider_ = MicroService::instance().ConfigGetString("smssender.provider","aws");
|
|
||||||
if(Provider_=="aws") {
|
if(Provider_=="aws") {
|
||||||
ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
|
ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
|
||||||
} else if(Provider_=="twilio") {
|
} else if(Provider_=="twilio") {
|
||||||
ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
|
ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
|
||||||
}
|
}
|
||||||
Enabled_ = ProviderImpl_->Initialize();
|
Enabled_ = ProviderImpl_->Initialize();
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ namespace OpenWifi {
|
|||||||
std::string Number;
|
std::string Number;
|
||||||
std::string Code;
|
std::string Code;
|
||||||
std::string UserName;
|
std::string UserName;
|
||||||
uint64_t Created = std::time(nullptr);
|
uint64_t Created;
|
||||||
bool Validated = false;
|
bool Validated=false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SMSSender : public SubSystemServer {
|
class SMSSender : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
static SMSSender *instance() {
|
static SMSSender *instance() {
|
||||||
static auto *instance_ = new SMSSender;
|
static SMSSender instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() final;
|
int Start() final;
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ namespace OpenWifi {
|
|||||||
if(!Running_)
|
if(!Running_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try {
|
|
||||||
Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
|
Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
|
||||||
Aws::SNS::Model::PublishRequest psms_req;
|
Aws::SNS::Model::PublishRequest psms_req;
|
||||||
psms_req.SetMessage(Message.c_str());
|
psms_req.SetMessage(Message.c_str());
|
||||||
@@ -57,11 +56,6 @@ namespace OpenWifi {
|
|||||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
||||||
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
||||||
return false;
|
return false;
|
||||||
} catch (...) {
|
|
||||||
|
|
||||||
}
|
|
||||||
Logger_.debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,12 @@
|
|||||||
#include "Poco/Net/SMTPClientSession.h"
|
#include "Poco/Net/SMTPClientSession.h"
|
||||||
#include "Poco/Net/SecureSMTPClientSession.h"
|
#include "Poco/Net/SecureSMTPClientSession.h"
|
||||||
#include "Poco/Net/StringPartSource.h"
|
#include "Poco/Net/StringPartSource.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Net/SSLManager.h"
|
#include "Poco/Net/SSLManager.h"
|
||||||
#include "Poco/Net/Context.h"
|
#include "Poco/Net/Context.h"
|
||||||
|
#include "Poco/Net/InvalidCertificateHandler.h"
|
||||||
|
#include "Poco/Net/AcceptCertificateHandler.h"
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
@@ -20,8 +23,6 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void SMTPMailerService::LoadMyConfig() {
|
void SMTPMailerService::LoadMyConfig() {
|
||||||
Enabled_ = MicroService::instance().ConfigGetBool("mailer.enabled",false);
|
|
||||||
if(Enabled_) {
|
|
||||||
MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
|
MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
|
||||||
SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
|
SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
|
||||||
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
||||||
@@ -29,11 +30,8 @@ namespace OpenWifi {
|
|||||||
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
||||||
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
|
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
|
||||||
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
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());
|
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int SMTPMailerService::Start() {
|
int SMTPMailerService::Start() {
|
||||||
LoadMyConfig();
|
LoadMyConfig();
|
||||||
@@ -55,46 +53,57 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
|
bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
|
||||||
std::lock_guard G(Mutex_);
|
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,
|
.LastTry=0,
|
||||||
.Sent=0,
|
.Sent=0,
|
||||||
.File=Poco::File(TemplateDir_ + "/" +Name),
|
.File=Poco::File(TemplateDir_ + "/" +Name),
|
||||||
.Attrs=Attrs});
|
.Attrs=Attrs});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTPMailerService::run() {
|
void SMTPMailerService::run() {
|
||||||
|
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
|
|
||||||
Poco::Thread::trySleep(10000);
|
Poco::Thread::trySleep(10000);
|
||||||
if(!Running_)
|
if(!Running_)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Messages_.splice(Messages_.end(),PendingMessages_);
|
|
||||||
|
uint64_t Now = std::time(nullptr);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto i=Messages_.begin();i!=Messages_.end();) {
|
// Clean the list
|
||||||
if(!Running_)
|
std::remove_if(Messages_.begin(),Messages_.end(),[Now](MessageEvent &E){ return (E.Sent!=0 || ((Now-E.LastTry)>(15*60)));});
|
||||||
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;
|
|
||||||
}
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,12 +115,10 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
||||||
std::string Recipient;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Poco::Net::MailMessage Message;
|
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);
|
auto H1 = Msg.Attrs.find(SENDER);
|
||||||
std::string TheSender;
|
std::string TheSender;
|
||||||
@@ -122,6 +129,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
Message.setSender( TheSender );
|
Message.setSender( TheSender );
|
||||||
Logger_.information(Poco::format("Sending message to:%s from %s",Recipient,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.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
||||||
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
|
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
|
||||||
|
|
||||||
@@ -138,26 +146,21 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto Logo = Msg.Attrs.find(LOGO);
|
auto Logo = Msg.Attrs.find(LOGO);
|
||||||
if(Logo!=Msg.Attrs.end()) {
|
if(Logo!=Msg.Attrs.end()) {
|
||||||
try {
|
|
||||||
Poco::File LogoFile(AuthService::GetLogoAssetFileName());
|
Poco::File LogoFile(AuthService::GetLogoAssetFileName());
|
||||||
std::ifstream IF(LogoFile.path());
|
std::ifstream IF(LogoFile.path());
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
Poco::StreamCopier::copyStream(IF, OS);
|
Poco::StreamCopier::copyStream(IF, OS);
|
||||||
Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
|
Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/jpeg"));
|
||||||
} catch (...) {
|
|
||||||
Logger_.warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName()));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Poco::SharedPtr<Poco::Net::AcceptCertificateHandler> ptrHandler_ = new Poco::Net::AcceptCertificateHandler(false);
|
|
||||||
|
|
||||||
Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
|
Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
|
||||||
|
Poco::Net::Context::Params P;
|
||||||
auto ptrContext = Poco::AutoPtr<Poco::Net::Context>
|
auto ptrContext = Poco::AutoPtr<Poco::Net::Context>
|
||||||
(new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
|
(new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
|
||||||
Poco::Net::Context::VERIFY_RELAXED, 9, true,
|
Poco::Net::Context::VERIFY_RELAXED, 9, true,
|
||||||
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"));
|
"ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"));
|
||||||
Poco::Net::SSLManager::instance().initializeClient(nullptr,
|
Poco::Net::SSLManager::instance().initializeClient(nullptr,
|
||||||
ptrHandler_,
|
&ptrHandler_,
|
||||||
ptrContext);
|
ptrContext);
|
||||||
session.login();
|
session.login();
|
||||||
session.startTLS(ptrContext);
|
session.startTLS(ptrContext);
|
||||||
@@ -174,9 +177,6 @@ namespace OpenWifi {
|
|||||||
{
|
{
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
}
|
}
|
||||||
catch (const std::exception &E) {
|
|
||||||
Logger_.warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what()));
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ namespace OpenWifi {
|
|||||||
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
static SMTPMailerService *instance() {
|
static SMTPMailerService *instance() {
|
||||||
static auto * instance_ = new SMTPMailerService;
|
static SMTPMailerService instance;
|
||||||
return instance_;
|
return & instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MessageEvent {
|
struct MessageEvent {
|
||||||
@@ -71,35 +71,41 @@ namespace OpenWifi {
|
|||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MessageCacheEntry {
|
||||||
|
uint64_t LastRequest=0;
|
||||||
|
uint64_t HowManyRequests=0;
|
||||||
|
};
|
||||||
|
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
||||||
bool SendIt(const MessageEvent &Msg);
|
bool SendIt(const MessageEvent &Msg);
|
||||||
void LoadMyConfig();
|
void LoadMyConfig();
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
bool Enabled() const { return Enabled_; }
|
bool Enabled() const { return Enabled_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string MailHost_;
|
std::string MailHost_;
|
||||||
std::string Sender_;
|
std::string Sender_;
|
||||||
int MailHostPort_=25;
|
int MailHostPort_=25;
|
||||||
int MailRetry_=2*60;
|
|
||||||
int MailAbandon_=2*60*20;
|
|
||||||
std::string SenderLoginUserName_;
|
std::string SenderLoginUserName_;
|
||||||
std::string SenderLoginPassword_;
|
std::string SenderLoginPassword_;
|
||||||
std::string LoginMethod_ = "login";
|
std::string LoginMethod_ = "login";
|
||||||
|
std::string LogoFileName_;
|
||||||
std::string TemplateDir_;
|
std::string TemplateDir_;
|
||||||
std::list<MessageEvent> Messages_;
|
std::list<MessageEvent> Messages_;
|
||||||
std::list<MessageEvent> PendingMessages_;
|
std::map<std::string,MessageCacheEntry> Cache_;
|
||||||
Poco::Thread SenderThr_;
|
Poco::Thread SenderThr_;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_=false;
|
||||||
bool Enabled_=false;
|
bool Enabled_=false;
|
||||||
|
Poco::Net::AcceptCertificateHandler ptrHandler_;
|
||||||
|
|
||||||
SMTPMailerService() noexcept:
|
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();
|
StorageClass::Start();
|
||||||
Create_Tables();
|
Create_Tables();
|
||||||
InitializeDefaultUser();
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::Stop() {
|
void Storage::Stop() {
|
||||||
Logger_.notice("Stopping.");
|
Logger_.notice("Stopping.");
|
||||||
Timer_.stop();
|
|
||||||
StorageClass::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
|
// namespace
|
||||||
@@ -13,8 +13,6 @@
|
|||||||
#include "framework/StorageClass.h"
|
#include "framework/StorageClass.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
|
|
||||||
#include "Poco/Timer.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static const std::string AllEmailTemplatesFieldsForCreation {
|
static const std::string AllEmailTemplatesFieldsForCreation {
|
||||||
@@ -29,12 +27,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Archiver {
|
|
||||||
public:
|
|
||||||
void onTimer(Poco::Timer & timer);
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
class Storage : public StorageClass {
|
class Storage : public StorageClass {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -84,8 +76,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Storage *instance() {
|
static Storage *instance() {
|
||||||
static auto * instance_ = new Storage;
|
static Storage instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() override;
|
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 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 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 RevokeToken( std::string & Token );
|
||||||
bool IsTokenRevoked( std::string & Token );
|
bool IsTokenRevoked( std::string & Token );
|
||||||
bool CleanExpiredTokens();
|
bool CleanRevokedTokens( uint64_t Oldest );
|
||||||
bool RevokeAllTokens( std::string & UserName );
|
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
|
* All ActionLinks functions
|
||||||
@@ -129,7 +121,6 @@ namespace OpenWifi {
|
|||||||
bool SentAction(std::string &ActionId);
|
bool SentAction(std::string &ActionId);
|
||||||
bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
|
bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
|
||||||
bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
|
bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
|
||||||
void CleanOldActionLinks();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int Create_Tables();
|
int Create_Tables();
|
||||||
@@ -137,13 +128,6 @@ namespace OpenWifi {
|
|||||||
int Create_AvatarTable();
|
int Create_AvatarTable();
|
||||||
int Create_TokensTable();
|
int Create_TokensTable();
|
||||||
int Create_ActionLinkTable();
|
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(); };
|
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 "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
#include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
#include "ow_version.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
enum UNAUTHORIZED_REASON {
|
enum UNAUTHORIZED_REASON {
|
||||||
@@ -82,9 +80,7 @@ namespace OpenWifi {
|
|||||||
PASSWORD_INVALID,
|
PASSWORD_INVALID,
|
||||||
INTERNAL_ERROR,
|
INTERNAL_ERROR,
|
||||||
ACCESS_DENIED,
|
ACCESS_DENIED,
|
||||||
INVALID_TOKEN,
|
INVALID_TOKEN
|
||||||
EXPIRED_TOKEN,
|
|
||||||
RATE_LIMIT_EXCEEDED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppServiceRegistry {
|
class AppServiceRegistry {
|
||||||
@@ -92,8 +88,8 @@ namespace OpenWifi {
|
|||||||
inline AppServiceRegistry();
|
inline AppServiceRegistry();
|
||||||
|
|
||||||
static AppServiceRegistry & instance() {
|
static AppServiceRegistry & instance() {
|
||||||
static AppServiceRegistry *instance_= new AppServiceRegistry;
|
static AppServiceRegistry instance;
|
||||||
return *instance_;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~AppServiceRegistry() {
|
inline ~AppServiceRegistry() {
|
||||||
@@ -1437,8 +1433,8 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static RESTAPI_RateLimiter *instance() {
|
static RESTAPI_RateLimiter *instance() {
|
||||||
static RESTAPI_RateLimiter * instance_ = new RESTAPI_RateLimiter;
|
static RESTAPI_RateLimiter instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() final { return 0;};
|
inline int Start() final { return 0;};
|
||||||
@@ -1448,18 +1444,18 @@ namespace OpenWifi {
|
|||||||
Poco::URI uri(R.getURI());
|
Poco::URI uri(R.getURI());
|
||||||
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
|
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
|
||||||
auto E = Cache_.get(H);
|
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()) {
|
if(E.isNull()) {
|
||||||
Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
|
Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
|
||||||
|
Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if((Now-E->Start)<Period) {
|
if((Now-E->Start)<Period) {
|
||||||
E->Count++;
|
E->Count++;
|
||||||
Cache_.update(H,E);
|
Cache_.update(H,E);
|
||||||
if(E->Count > MaxCalls) {
|
if(E->Count > MaxCalls)
|
||||||
Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
E->Start = Now;
|
E->Start = Now;
|
||||||
@@ -1527,23 +1523,20 @@ namespace OpenWifi {
|
|||||||
Request = &RequestIn;
|
Request = &RequestIn;
|
||||||
Response = &ResponseIn;
|
Response = &ResponseIn;
|
||||||
|
|
||||||
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
|
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls))
|
||||||
return UnAuthorized("Rate limit exceeded.",RATE_LIMIT_EXCEEDED);
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!ContinueProcessing())
|
if (!ContinueProcessing())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool Expired=false;
|
if (AlwaysAuthorize_ && !IsAuthorized()) {
|
||||||
if (AlwaysAuthorize_ && !IsAuthorized(Expired)) {
|
return;
|
||||||
if(Expired)
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken, EXPIRED_TOKEN);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, ACCESS_DENIED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Reason;
|
std::string Reason;
|
||||||
if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) {
|
if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) {
|
||||||
return UnAuthorized(Reason, ACCESS_DENIED);
|
UnAuthorized(Reason, ACCESS_DENIED);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseParameters();
|
ParseParameters();
|
||||||
@@ -1881,7 +1874,7 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAuthorized(bool & Expired);
|
inline bool IsAuthorized();
|
||||||
|
|
||||||
inline void ReturnObject(Poco::JSON::Object &Object) {
|
inline void ReturnObject(Poco::JSON::Object &Object) {
|
||||||
PrepareResponse();
|
PrepareResponse();
|
||||||
@@ -1902,7 +1895,7 @@ namespace OpenWifi {
|
|||||||
QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||||
QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
|
QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
|
||||||
QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 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_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100);
|
||||||
QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
|
QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
|
||||||
QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
|
QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
|
||||||
@@ -1914,7 +1907,7 @@ namespace OpenWifi {
|
|||||||
QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false);
|
QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false);
|
||||||
|
|
||||||
if(QB_.Offset<1)
|
if(QB_.Offset<1)
|
||||||
QB_.Offset=0;
|
QB_.Offset=1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2083,50 +2076,6 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Object Body_;
|
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 {
|
class KafkaManager : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
struct KMessage {
|
struct KMessage {
|
||||||
@@ -2135,32 +2084,33 @@ namespace OpenWifi {
|
|||||||
PayLoad;
|
PayLoad;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class KafkaConsumer;
|
|
||||||
friend class KafkaProducer;
|
|
||||||
|
|
||||||
inline void initialize(Poco::Util::Application & self) override;
|
inline void initialize(Poco::Util::Application & self) override;
|
||||||
|
|
||||||
static KafkaManager *instance() {
|
static KafkaManager *instance() {
|
||||||
static KafkaManager * instance_ = new KafkaManager;
|
static KafkaManager instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() override {
|
inline int Start() override {
|
||||||
if(!KafkaEnabled_)
|
if(!KafkaEnabled_)
|
||||||
return 0;
|
return 0;
|
||||||
ConsumerThr_.Start();
|
ProducerThr_ = std::make_unique<std::thread>([this]() { this->ProducerThr(); });
|
||||||
ProducerThr_.Start();
|
ConsumerThr_ = std::make_unique<std::thread>([this]() { this->ConsumerThr(); });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() override {
|
inline void Stop() override {
|
||||||
if(KafkaEnabled_) {
|
if(KafkaEnabled_) {
|
||||||
ProducerThr_.Stop();
|
ProducerRunning_ = ConsumerRunning_ = false;
|
||||||
ConsumerThr_.Stop();
|
ProducerThr_->join();
|
||||||
|
ConsumerThr_->join();
|
||||||
return;
|
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 ) {
|
inline void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true ) {
|
||||||
if(KafkaEnabled_) {
|
if(KafkaEnabled_) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
@@ -2213,13 +2163,18 @@ namespace OpenWifi {
|
|||||||
// void WakeUp();
|
// void WakeUp();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::mutex ProducerMutex_;
|
||||||
|
std::mutex ConsumerMutex_;
|
||||||
bool KafkaEnabled_ = false;
|
bool KafkaEnabled_ = false;
|
||||||
|
std::atomic_bool ProducerRunning_ = false;
|
||||||
|
std::atomic_bool ConsumerRunning_ = false;
|
||||||
std::queue<KMessage> Queue_;
|
std::queue<KMessage> Queue_;
|
||||||
std::string SystemInfoWrapper_;
|
std::string SystemInfoWrapper_;
|
||||||
|
std::unique_ptr<std::thread> ConsumerThr_;
|
||||||
|
std::unique_ptr<std::thread> ProducerThr_;
|
||||||
int FunctionId_=1;
|
int FunctionId_=1;
|
||||||
Types::NotifyTable Notifiers_;
|
Types::NotifyTable Notifiers_;
|
||||||
KafkaProducer ProducerThr_;
|
std::unique_ptr<cppkafka::Configuration> Config_;
|
||||||
KafkaConsumer ConsumerThr_;
|
|
||||||
|
|
||||||
inline void PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
|
inline void PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
|
||||||
Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
|
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() {
|
||||||
static AuthClient * instance_ = new AuthClient;
|
static AuthClient instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() override {
|
inline int Start() override {
|
||||||
@@ -2253,20 +2208,25 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() override {
|
inline void Stop() override {
|
||||||
Cache_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RemovedCachedToken(const std::string &Token) {
|
inline void RemovedCachedToken(const std::string &Token) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Cache_.remove(Token);
|
UserCache_.erase(Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
|
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
|
||||||
return ((T.expires_in_+T.created_)<std::time(nullptr));
|
return ((T.expires_in_+T.created_)<std::time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool RetrieveTokenInformation(const std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
|
inline bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
|
||||||
try {
|
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;
|
Types::StringPairVec QueryData;
|
||||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||||
@@ -2276,39 +2236,49 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Object::Ptr Response;
|
Poco::JSON::Object::Ptr Response;
|
||||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||||
UInfo.from_json(Response);
|
SecurityObjects::UserInfoAndPolicy P;
|
||||||
if(IsTokenExpired(UInfo.webtoken)) {
|
P.from_json(Response);
|
||||||
Expired = true;
|
UserCache_[SessionToken] = P;
|
||||||
return false;
|
UInfo = P;
|
||||||
}
|
}
|
||||||
Expired = false;
|
|
||||||
Cache_.update(SessionToken, UInfo);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Expired = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
|
inline bool IsTokenAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo) {
|
||||||
auto User = Cache_.get(SessionToken);
|
std::lock_guard G(Mutex_);
|
||||||
if(!User.isNull()) {
|
|
||||||
if(IsTokenExpired(User->webtoken)) {
|
auto User = UserCache_.find(SessionToken);
|
||||||
Expired = true;
|
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||||
return false;
|
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;
|
||||||
}
|
}
|
||||||
Expired = false;
|
|
||||||
UInfo = *User;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return RetrieveTokenInformation(SessionToken, UInfo, Expired);
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{1024,1200000 };
|
OpenWifi::SecurityObjects::UserInfoCache UserCache_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline AuthClient * AuthClient() { return AuthClient::instance(); }
|
inline AuthClient * AuthClient() { return AuthClient::instance(); }
|
||||||
@@ -2368,14 +2338,14 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ALBHealthCheckServer *instance() {
|
static ALBHealthCheckServer *instance() {
|
||||||
static ALBHealthCheckServer * instance = new ALBHealthCheckServer;
|
static ALBHealthCheckServer instance;
|
||||||
return instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() override;
|
inline int Start() override;
|
||||||
|
|
||||||
inline void Stop() override {
|
inline void Stop() override {
|
||||||
if(Running_)
|
if(Server_)
|
||||||
Server_->stop();
|
Server_->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2383,7 +2353,6 @@ namespace OpenWifi {
|
|||||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||||
int Port_ = 0;
|
int Port_ = 0;
|
||||||
std::atomic_bool Running_=false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
|
||||||
@@ -2398,18 +2367,17 @@ namespace OpenWifi {
|
|||||||
class RESTAPI_server : public SubSystemServer {
|
class RESTAPI_server : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
static RESTAPI_server *instance() {
|
static RESTAPI_server *instance() {
|
||||||
static RESTAPI_server *instance_ = new RESTAPI_server;
|
static RESTAPI_server instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
int Start() override;
|
int Start() override;
|
||||||
inline void Stop() override {
|
inline void Stop() override {
|
||||||
Logger_.information("Stopping ");
|
Logger_.information("Stopping ");
|
||||||
for( const auto & svr : RESTServers_ )
|
for( const auto & svr : RESTServers_ )
|
||||||
svr->stop();
|
svr->stop();
|
||||||
Pool_.joinAll();
|
|
||||||
RESTServers_.clear();
|
RESTServers_.clear();
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
inline void reinitialize(Poco::Util::Application &self) override;
|
inline void reinitialize(Poco::Util::Application &self) override;
|
||||||
|
|
||||||
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
|
inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
|
||||||
@@ -2464,7 +2432,7 @@ namespace OpenWifi {
|
|||||||
if(!Svr.RootCA().empty())
|
if(!Svr.RootCA().empty())
|
||||||
Svr.LogCas(Logger_);
|
Svr.LogCas(Logger_);
|
||||||
|
|
||||||
Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams;
|
auto Params = new Poco::Net::HTTPServerParams;
|
||||||
Params->setMaxThreads(50);
|
Params->setMaxThreads(50);
|
||||||
Params->setMaxQueued(200);
|
Params->setMaxQueued(200);
|
||||||
Params->setKeepAlive(true);
|
Params->setKeepAlive(true);
|
||||||
@@ -2481,8 +2449,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static RESTAPI_InternalServer *instance() {
|
static RESTAPI_InternalServer *instance() {
|
||||||
static RESTAPI_InternalServer *instance_ = new RESTAPI_InternalServer;
|
static RESTAPI_InternalServer instance;
|
||||||
return instance_;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Start() override;
|
inline int Start() override;
|
||||||
@@ -2490,7 +2458,7 @@ namespace OpenWifi {
|
|||||||
Logger_.information("Stopping ");
|
Logger_.information("Stopping ");
|
||||||
for( const auto & svr : RESTServers_ )
|
for( const auto & svr : RESTServers_ )
|
||||||
svr->stop();
|
svr->stop();
|
||||||
Pool_.stopAll();
|
RESTServers_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void reinitialize(Poco::Util::Application &self) override;
|
inline void reinitialize(Poco::Util::Application &self) override;
|
||||||
@@ -2507,6 +2475,7 @@ namespace OpenWifi {
|
|||||||
RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
|
RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RESTAPI_InternalServer * RESTAPI_InternalServer() { return RESTAPI_InternalServer::instance(); };
|
inline RESTAPI_InternalServer * RESTAPI_InternalServer() { return RESTAPI_InternalServer::instance(); };
|
||||||
@@ -2524,7 +2493,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
Poco::Logger & Logger_;
|
Poco::Logger & Logger_;
|
||||||
RESTAPI_GenericServer & Server_;
|
RESTAPI_GenericServer &Server_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int RESTAPI_InternalServer::Start() {
|
inline int RESTAPI_InternalServer::Start() {
|
||||||
@@ -2585,13 +2554,11 @@ namespace OpenWifi {
|
|||||||
DAEMON_BUS_TIMER(BusTimer),
|
DAEMON_BUS_TIMER(BusTimer),
|
||||||
SubSystems_(std::move(Subsystems)) {
|
SubSystems_(std::move(Subsystems)) {
|
||||||
instance_ = this;
|
instance_ = this;
|
||||||
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string Version() { return Version_; }
|
[[nodiscard]] std::string Version() { return Version_; }
|
||||||
[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
|
[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
|
||||||
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
|
[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
|
||||||
[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; }
|
|
||||||
[[nodiscard]] bool Debug() const { return DebugMode_; }
|
[[nodiscard]] bool Debug() const { return DebugMode_; }
|
||||||
[[nodiscard]] uint64_t ID() const { return ID_; }
|
[[nodiscard]] uint64_t ID() const { return ID_; }
|
||||||
[[nodiscard]] std::string Hash() const { return MyHash_; };
|
[[nodiscard]] std::string Hash() const { return MyHash_; };
|
||||||
@@ -2604,13 +2571,6 @@ namespace OpenWifi {
|
|||||||
static inline uint64_t GetPID() { return Poco::Process::id(); };
|
static inline uint64_t GetPID() { return Poco::Process::id(); };
|
||||||
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
|
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
|
||||||
[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
|
[[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 Exit(int Reason);
|
||||||
inline void BusMessageReceived(const std::string &Key, const std::string & Message);
|
inline void BusMessageReceived(const std::string &Key, const std::string & Message);
|
||||||
@@ -2632,7 +2592,7 @@ namespace OpenWifi {
|
|||||||
inline void InitializeSubSystemServers();
|
inline void InitializeSubSystemServers();
|
||||||
inline void StartSubSystemServers();
|
inline void StartSubSystemServers();
|
||||||
inline void StopSubSystemServers();
|
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 bool SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
|
||||||
inline void Reload(const std::string &Sub);
|
inline void Reload(const std::string &Sub);
|
||||||
inline Types::StringVec GetSubSystems() const;
|
inline Types::StringVec GetSubSystems() const;
|
||||||
@@ -2662,10 +2622,9 @@ namespace OpenWifi {
|
|||||||
std::string ConfigFileName_;
|
std::string ConfigFileName_;
|
||||||
Poco::UUIDGenerator UUIDGenerator_;
|
Poco::UUIDGenerator UUIDGenerator_;
|
||||||
uint64_t ID_ = 1;
|
uint64_t ID_ = 1;
|
||||||
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
|
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_ = nullptr;
|
||||||
bool DebugMode_ = false;
|
bool DebugMode_ = false;
|
||||||
std::string DataDir_;
|
std::string DataDir_;
|
||||||
std::string WWWAssetsDir_;
|
|
||||||
SubSystemVec SubSystems_;
|
SubSystemVec SubSystems_;
|
||||||
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
|
||||||
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
Poco::Crypto::Cipher * Cipher_ = nullptr;
|
||||||
@@ -2675,10 +2634,9 @@ namespace OpenWifi {
|
|||||||
std::string MyPrivateEndPoint_;
|
std::string MyPrivateEndPoint_;
|
||||||
std::string MyPublicEndPoint_;
|
std::string MyPublicEndPoint_;
|
||||||
std::string UIURI_;
|
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_;
|
BusEventManager BusEventManager_;
|
||||||
std::mutex InfraMutex_;
|
std::mutex InfraMutex_;
|
||||||
std::default_random_engine RandomEngine_;
|
|
||||||
|
|
||||||
std::string DAEMON_PROPERTIES_FILENAME;
|
std::string DAEMON_PROPERTIES_FILENAME;
|
||||||
std::string DAEMON_ROOT_ENV_VAR;
|
std::string DAEMON_ROOT_ENV_VAR;
|
||||||
@@ -2855,9 +2813,6 @@ namespace OpenWifi {
|
|||||||
logger().log(E);
|
logger().log(E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets","");
|
|
||||||
if(WWWAssetsDir_.empty())
|
|
||||||
WWWAssetsDir_ = DataDir_;
|
|
||||||
|
|
||||||
LoadMyConfig();
|
LoadMyConfig();
|
||||||
|
|
||||||
@@ -2964,41 +2919,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline void MicroService::StopSubSystemServers() {
|
inline void MicroService::StopSubSystemServers() {
|
||||||
BusEventManager_.Stop();
|
BusEventManager_.Stop();
|
||||||
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) {
|
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i)
|
||||||
(*i)->Stop();
|
(*i)->Stop();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline std::string MicroService::CreateUUID() {
|
[[nodiscard]] inline std::string MicroService::CreateUUID() {
|
||||||
static std::random_device rd;
|
return UUIDGenerator_.create().toString();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
|
inline bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
|
||||||
@@ -3012,6 +2938,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << "Sub:" << SubSystem << " Level:" << Level << std::endl;
|
||||||
for (auto i : SubSystems_) {
|
for (auto i : SubSystems_) {
|
||||||
if (Sub == Poco::toLower(i->Name())) {
|
if (Sub == Poco::toLower(i->Name())) {
|
||||||
i->Logger().setLevel(P);
|
i->Logger().setLevel(P);
|
||||||
@@ -3161,6 +3088,7 @@ namespace OpenWifi {
|
|||||||
StartSubSystemServers();
|
StartSubSystemServers();
|
||||||
waitForTerminationRequest();
|
waitForTerminationRequest();
|
||||||
StopSubSystemServers();
|
StopSubSystemServers();
|
||||||
|
|
||||||
logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
|
logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3240,7 +3168,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline int ALBHealthCheckServer::Start() {
|
inline int ALBHealthCheckServer::Start() {
|
||||||
if(MicroService::instance().ConfigGetBool("alb.enable",false)) {
|
if(MicroService::instance().ConfigGetBool("alb.enable",false)) {
|
||||||
Running_=true;
|
|
||||||
Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015);
|
Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015);
|
||||||
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
|
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
|
||||||
auto Params = new Poco::Net::HTTPServerParams;
|
auto Params = new Poco::Net::HTTPServerParams;
|
||||||
@@ -3285,42 +3212,41 @@ namespace OpenWifi {
|
|||||||
KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
|
KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void KafkaProducer::run() {
|
inline void KafkaManager::ProducerThr() {
|
||||||
cppkafka::Configuration Config({
|
cppkafka::Configuration Config({
|
||||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
|
{ "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()) +
|
std::to_string(MicroService::instance().ID()) +
|
||||||
R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
|
R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
|
||||||
R"lit(" } , "payload" : )lit" ;
|
R"lit(" } , "payload" : )lit" ;
|
||||||
cppkafka::Producer Producer(Config);
|
cppkafka::Producer Producer(Config);
|
||||||
Running_ = true;
|
ProducerRunning_ = true;
|
||||||
while(Running_) {
|
while(ProducerRunning_) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(ProducerMutex_);
|
||||||
auto Num=0;
|
auto Num=0;
|
||||||
while (!KafkaManager()->Queue_.empty()) {
|
while (!Queue_.empty()) {
|
||||||
const auto M = KafkaManager()->Queue_.front();
|
const auto M = Queue_.front();
|
||||||
Producer.produce(
|
Producer.produce(
|
||||||
cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
|
cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
|
||||||
KafkaManager()->Queue_.pop();
|
Queue_.pop();
|
||||||
Num++;
|
Num++;
|
||||||
}
|
}
|
||||||
if(Num)
|
if(Num)
|
||||||
Producer.flush();
|
Producer.flush();
|
||||||
} catch (const cppkafka::HandleException &E ) {
|
} 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) {
|
} 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({
|
cppkafka::Configuration Config({
|
||||||
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
{ "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
|
||||||
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
|
{ "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
|
||||||
@@ -3340,13 +3266,13 @@ namespace OpenWifi {
|
|||||||
cppkafka::Consumer Consumer(Config);
|
cppkafka::Consumer Consumer(Config);
|
||||||
Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
|
Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
|
||||||
if(!partitions.empty()) {
|
if(!partitions.empty()) {
|
||||||
KafkaManager()->Logger_.information(Poco::format("Partition assigned: %Lu...",
|
Logger_.information(Poco::format("Partition assigned: %Lu...",
|
||||||
(uint64_t)partitions.front().get_partition()));
|
(uint64_t)partitions.front().get_partition()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
|
Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
|
||||||
if(!partitions.empty()) {
|
if(!partitions.empty()) {
|
||||||
KafkaManager()->Logger_.information(Poco::format("Partition revocation: %Lu...",
|
Logger_.information(Poco::format("Partition revocation: %Lu...",
|
||||||
(uint64_t)partitions.front().get_partition()));
|
(uint64_t)partitions.front().get_partition()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -3355,13 +3281,13 @@ namespace OpenWifi {
|
|||||||
auto BatchSize = MicroService::instance().ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
|
auto BatchSize = MicroService::instance().ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
|
||||||
|
|
||||||
Types::StringVec Topics;
|
Types::StringVec Topics;
|
||||||
for(const auto &i:KafkaManager()->Notifiers_)
|
for(const auto &i:Notifiers_)
|
||||||
Topics.push_back(i.first);
|
Topics.push_back(i.first);
|
||||||
|
|
||||||
Consumer.subscribe(Topics);
|
Consumer.subscribe(Topics);
|
||||||
|
|
||||||
Running_ = true;
|
ConsumerRunning_ = true;
|
||||||
while(Running_) {
|
while(ConsumerRunning_) {
|
||||||
try {
|
try {
|
||||||
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
|
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
|
||||||
for(auto const &Msg:MsgVec) {
|
for(auto const &Msg:MsgVec) {
|
||||||
@@ -3369,14 +3295,14 @@ namespace OpenWifi {
|
|||||||
continue;
|
continue;
|
||||||
if (Msg.get_error()) {
|
if (Msg.get_error()) {
|
||||||
if (!Msg.is_eof()) {
|
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)
|
}if(!AutoCommit)
|
||||||
Consumer.async_commit(Msg);
|
Consumer.async_commit(Msg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(ConsumerMutex_);
|
||||||
auto It = KafkaManager()->Notifiers_.find(Msg.get_topic());
|
auto It = Notifiers_.find(Msg.get_topic());
|
||||||
if (It != KafkaManager()->Notifiers_.end()) {
|
if (It != Notifiers_.end()) {
|
||||||
Types::TopicNotifyFunctionList &FL = It->second;
|
Types::TopicNotifyFunctionList &FL = It->second;
|
||||||
std::string Key{Msg.get_key()};
|
std::string Key{Msg.get_key()};
|
||||||
std::string Payload{Msg.get_payload()};
|
std::string Payload{Msg.get_payload()};
|
||||||
@@ -3389,12 +3315,11 @@ namespace OpenWifi {
|
|||||||
Consumer.async_commit(Msg);
|
Consumer.async_commit(Msg);
|
||||||
}
|
}
|
||||||
} catch (const cppkafka::HandleException &E) {
|
} 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) {
|
} catch (const Poco::Exception &E) {
|
||||||
KafkaManager()->Logger_.log(E);
|
Logger_.log(E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Consumer.unsubscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void RESTAPI_server::reinitialize(Poco::Util::Application &self) {
|
inline void RESTAPI_server::reinitialize(Poco::Util::Application &self) {
|
||||||
@@ -3615,9 +3540,11 @@ namespace OpenWifi {
|
|||||||
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
// std::cout << "Response OK" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
// std::cout << "Response: " << Response.getStatus() << std::endl;
|
||||||
}
|
}
|
||||||
return Response.getStatus();
|
return Response.getStatus();
|
||||||
}
|
}
|
||||||
@@ -3663,9 +3590,11 @@ namespace OpenWifi {
|
|||||||
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
// std::cout << "Response OK" << std::endl;
|
||||||
} else {
|
} else {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
// std::cout << "Response: " << Response.getStatus() << std::endl;
|
||||||
}
|
}
|
||||||
return Response.getStatus();
|
return Response.getStatus();
|
||||||
}
|
}
|
||||||
@@ -3691,9 +3620,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TIP_SECURITY_SERVICE
|
#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
|
#endif
|
||||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired ) {
|
inline bool RESTAPIHandler::IsAuthorized() {
|
||||||
if(Internal_) {
|
if(Internal_) {
|
||||||
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
|
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
|
||||||
if(!Allowed) {
|
if(!Allowed) {
|
||||||
@@ -3723,9 +3652,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef TIP_SECURITY_SERVICE
|
#ifdef TIP_SECURITY_SERVICE
|
||||||
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired)) {
|
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_)) {
|
||||||
#else
|
#else
|
||||||
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired)) {
|
if (AuthClient()->IsAuthorized(*Request, SessionToken_, UserInfo_)) {
|
||||||
#endif
|
#endif
|
||||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
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",
|
||||||
@@ -3742,6 +3671,7 @@ namespace OpenWifi {
|
|||||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||||
Request->getMethod(), Request->getURI()));
|
Request->getMethod(), Request->getURI()));
|
||||||
}
|
}
|
||||||
|
UnAuthorized("Invalid token", INVALID_TOKEN);
|
||||||
}
|
}
|
||||||
return false;
|
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 UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
|
||||||
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
|
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
|
||||||
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
|
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
|
#endif //OWPROV_RESTAPI_ERRORS_H
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Created by stephane bourque on 2021-10-06.
|
// 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/Session.h"
|
||||||
#include "Poco/Data/SessionPool.h"
|
#include "Poco/Data/SessionPool.h"
|
||||||
@@ -25,6 +26,13 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class StorageClass : public SubSystemServer {
|
class StorageClass : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
/* static StorageClass *instance() {
|
||||||
|
if (instance_ == nullptr) {
|
||||||
|
instance_ = new StorageClass;
|
||||||
|
}
|
||||||
|
return instance_;
|
||||||
|
}
|
||||||
|
*/
|
||||||
StorageClass() noexcept:
|
StorageClass() noexcept:
|
||||||
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
|
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
|
||||||
{
|
{
|
||||||
@@ -48,18 +56,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Stop() override {
|
void Stop() override {
|
||||||
Pool_->shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
||||||
if(dbType_==sqlite) {
|
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) {
|
} 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) {
|
} 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 {
|
inline std::string ConvertParams(const std::string & S) const {
|
||||||
@@ -88,10 +96,10 @@ namespace OpenWifi {
|
|||||||
inline int Setup_PostgreSQL();
|
inline int Setup_PostgreSQL();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Poco::SharedPtr<Poco::Data::SessionPool> Pool_;
|
std::unique_ptr<Poco::Data::SessionPool> Pool_;
|
||||||
Poco::Data::SQLite::Connector SQLiteConn_;
|
std::unique_ptr<Poco::Data::SQLite::Connector> SQLiteConn_;
|
||||||
Poco::Data::PostgreSQL::Connector PostgresConn_;
|
std::unique_ptr<Poco::Data::PostgreSQL::Connector> PostgresConn_;
|
||||||
Poco::Data::MySQL::Connector MySQLConn_;
|
std::unique_ptr<Poco::Data::MySQL::Connector> MySQLConn_;
|
||||||
DBType dbType_ = sqlite;
|
DBType dbType_ = sqlite;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,8 +114,9 @@ namespace OpenWifi {
|
|||||||
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
|
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
|
||||||
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
|
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
|
||||||
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
|
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
|
||||||
SQLiteConn_.registerConnector();
|
SQLiteConn_ = std::make_unique<Poco::Data::SQLite::Connector>();
|
||||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime));
|
SQLiteConn_->registerConnector();
|
||||||
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_->name(), DBName, 4, NumSessions, IdleTime);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,8 +139,9 @@ namespace OpenWifi {
|
|||||||
";port=" + Port +
|
";port=" + Port +
|
||||||
";compress=true;auto-reconnect=true";
|
";compress=true;auto-reconnect=true";
|
||||||
|
|
||||||
MySQLConn_.registerConnector();
|
MySQLConn_ = std::make_unique<Poco::Data::MySQL::Connector>();
|
||||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
|
MySQLConn_->registerConnector();
|
||||||
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -156,11 +166,14 @@ namespace OpenWifi {
|
|||||||
" port=" + Port +
|
" port=" + Port +
|
||||||
" connect_timeout=" + ConnectionTimeout;
|
" connect_timeout=" + ConnectionTimeout;
|
||||||
|
|
||||||
PostgresConn_.registerConnector();
|
PostgresConn_ = std::make_unique<Poco::Data::PostgreSQL::Connector>();
|
||||||
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
|
PostgresConn_->registerConnector();
|
||||||
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
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 "
|
"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 {
|
try {
|
||||||
Poco::Data::Session Sess = Pool_->get();
|
Poco::Data::Session Sess = Pool_->get();
|
||||||
Poco::Data::Statement Insert(Sess);
|
Poco::Data::Statement Insert(Sess);
|
||||||
@@ -29,7 +29,7 @@ namespace OpenWifi {
|
|||||||
Poco::Data::Keywords::use(Token),
|
Poco::Data::Keywords::use(Token),
|
||||||
Poco::Data::Keywords::use(RefreshToken),
|
Poco::Data::Keywords::use(RefreshToken),
|
||||||
Poco::Data::Keywords::use(TokenType),
|
Poco::Data::Keywords::use(TokenType),
|
||||||
Poco::Data::Keywords::use(UserID),
|
Poco::Data::Keywords::use(UserName),
|
||||||
Poco::Data::Keywords::use(Now),
|
Poco::Data::Keywords::use(Now),
|
||||||
Poco::Data::Keywords::use(Expires),
|
Poco::Data::Keywords::use(Expires),
|
||||||
Poco::Data::Keywords::use(TimeOut),
|
Poco::Data::Keywords::use(TimeOut),
|
||||||
@@ -42,24 +42,29 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate) {
|
bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Poco::Data::Session Sess = Pool_->get();
|
Poco::Data::Session Sess = Pool_->get();
|
||||||
Poco::Data::Statement Select(Sess);
|
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),
|
Select << ConvertParams(St2),
|
||||||
Poco::Data::Keywords::into(UInfo.webtoken.access_token_),
|
Poco::Data::Keywords::into(UInfo.webtoken.access_token_),
|
||||||
Poco::Data::Keywords::into(UInfo.webtoken.refresh_token_),
|
Poco::Data::Keywords::into(UInfo.webtoken.refresh_token_),
|
||||||
Poco::Data::Keywords::into(UInfo.webtoken.token_type_),
|
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.created_),
|
||||||
Poco::Data::Keywords::into(UInfo.webtoken.expires_in_),
|
Poco::Data::Keywords::into(UInfo.webtoken.expires_in_),
|
||||||
Poco::Data::Keywords::into(UInfo.webtoken.idle_timeout_),
|
Poco::Data::Keywords::into(UInfo.webtoken.idle_timeout_),
|
||||||
Poco::Data::Keywords::into(RevocationDate),
|
Poco::Data::Keywords::into(RevocationDate),
|
||||||
Poco::Data::Keywords::use(Token);
|
Poco::Data::Keywords::use(Token);
|
||||||
Select.execute();
|
Select.execute();
|
||||||
|
|
||||||
|
if(RevocationDate>0)
|
||||||
|
return false;
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
@@ -111,15 +116,15 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Storage::CleanExpiredTokens() {
|
bool Storage::CleanRevokedTokens(uint64_t Oldest) {
|
||||||
try {
|
try {
|
||||||
Poco::Data::Session Sess = Pool_->get();
|
Poco::Data::Session Sess = Pool_->get();
|
||||||
Poco::Data::Statement Delete(Sess);
|
Poco::Data::Statement Delete(Sess);
|
||||||
uint64_t Now = std::time(nullptr);
|
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),
|
Delete << ConvertParams(St2),
|
||||||
Poco::Data::Keywords::use(Now);
|
Poco::Data::Keywords::use(Oldest);
|
||||||
Delete.execute();
|
Delete.execute();
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
@@ -128,14 +133,14 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Storage::RevokeAllTokens(std::string & UserId) {
|
bool Storage::RevokeAllTokens(std::string & username) {
|
||||||
try {
|
try {
|
||||||
Poco::Data::Session Sess = Pool_->get();
|
Poco::Data::Session Sess = Pool_->get();
|
||||||
Poco::Data::Statement Delete(Sess);
|
Poco::Data::Statement Delete(Sess);
|
||||||
|
|
||||||
std::string St2{"DELETE From Tokens WHERE Username=?"};
|
std::string St2{"DELETE From Tokens WHERE Username=?"};
|
||||||
Delete << ConvertParams(St2),
|
Delete << ConvertParams(St2),
|
||||||
Poco::Data::Keywords::use(UserId);
|
Poco::Data::Keywords::use(username);
|
||||||
Delete.execute();
|
Delete.execute();
|
||||||
return true;
|
return true;
|
||||||
} catch(const Poco::Exception &E) {
|
} catch(const Poco::Exception &E) {
|
||||||
|
|||||||
@@ -80,23 +80,7 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string OldDefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
|
std::string DefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
|
||||||
std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"};
|
|
||||||
|
|
||||||
void Storage::ReplaceOldDefaultUUID() {
|
|
||||||
try {
|
|
||||||
Poco::Data::Session Sess = Pool_->get();
|
|
||||||
std::string St1{"update users set id=? where id=?"};
|
|
||||||
|
|
||||||
Poco::Data::Statement Update(Sess);
|
|
||||||
Update << ConvertParams(St1),
|
|
||||||
Poco::Data::Keywords::use(NewDefaultUseridStockUUID),
|
|
||||||
Poco::Data::Keywords::use(OldDefaultUseridStockUUID);
|
|
||||||
Update.execute();
|
|
||||||
} catch (...) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we do not find a default user, then we need to create one based on the
|
// 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.
|
// 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;
|
SecurityObjects::UserInfo U;
|
||||||
bool DefaultUserCreated = false;
|
bool DefaultUserCreated = false;
|
||||||
|
|
||||||
ReplaceOldDefaultUUID();
|
|
||||||
AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
|
AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
|
||||||
if(!GetUserById(NewDefaultUseridStockUUID,U) && !DefaultUserCreated) {
|
if(!GetUserById(DefaultUseridStockUUID,U) && !DefaultUserCreated) {
|
||||||
U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
|
U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
|
||||||
U.lastPasswords.push_back(U.currentPassword);
|
U.lastPasswords.push_back(U.currentPassword);
|
||||||
U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
|
U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
|
||||||
U.Id = NewDefaultUseridStockUUID;
|
U.Id = DefaultUseridStockUUID;
|
||||||
U.userRole = SecurityObjects::ROOT;
|
U.userRole = SecurityObjects::ROOT;
|
||||||
U.creationDate = std::time(nullptr);
|
U.creationDate = std::time(nullptr);
|
||||||
U.validated = true;
|
U.validated = true;
|
||||||
@@ -149,7 +132,7 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!PasswordHashedAlready) {
|
if(!PasswordHashedAlready) {
|
||||||
NewUser.Id = MicroService::CreateUUID();
|
NewUser.Id = MicroService::instance().CreateUUID();
|
||||||
NewUser.creationDate = std::time(nullptr);
|
NewUser.creationDate = std::time(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,23 +15,23 @@ namespace OpenWifi {
|
|||||||
"description varchar,"
|
"description varchar,"
|
||||||
"avatar varchar,"
|
"avatar varchar,"
|
||||||
"email varchar,"
|
"email varchar,"
|
||||||
"validated boolean,"
|
"validated int,"
|
||||||
"validationEmail varchar,"
|
"validationEmail varchar,"
|
||||||
"validationDate bigint,"
|
"validationDate bigint,"
|
||||||
"creationDate bigint,"
|
"creationDate bigint,"
|
||||||
"validationURI varchar,"
|
"validationURI varchar,"
|
||||||
"changePassword boolean,"
|
"changePassword int,"
|
||||||
"lastLogin bigint,"
|
"lastLogin bigint,"
|
||||||
"currentLoginURI varchar,"
|
"currentLoginURI varchar,"
|
||||||
"lastPasswordChange bigint,"
|
"lastPasswordChange bigint,"
|
||||||
"lastEmailCheck bigint,"
|
"lastEmailCheck bigint,"
|
||||||
"waitingForEmailCheck boolean,"
|
"waitingForEmailCheck int,"
|
||||||
"locale varchar,"
|
"locale varchar,"
|
||||||
"notes text,"
|
"notes text,"
|
||||||
"location varchar,"
|
"location varchar,"
|
||||||
"owner varchar,"
|
"owner varchar,"
|
||||||
"suspended boolean,"
|
"suspended int,"
|
||||||
"blackListed boolean,"
|
"blackListed int,"
|
||||||
"userRole varchar,"
|
"userRole varchar,"
|
||||||
"userTypeProprietaryInfo text,"
|
"userTypeProprietaryInfo text,"
|
||||||
"securityPolicy text,"
|
"securityPolicy text,"
|
||||||
@@ -111,23 +111,23 @@ namespace OpenWifi {
|
|||||||
std::string, // description;
|
std::string, // description;
|
||||||
std::string, // avatar;
|
std::string, // avatar;
|
||||||
std::string, // email;
|
std::string, // email;
|
||||||
bool, // bool validated = false;
|
uint64_t, // bool validated = false;
|
||||||
std::string, // validationEmail;
|
std::string, // validationEmail;
|
||||||
uint64_t, // validationDate = 0;
|
uint64_t, // validationDate = 0;
|
||||||
uint64_t, // creationDate = 0;
|
uint64_t, // creationDate = 0;
|
||||||
std::string, // validationURI;
|
std::string, // validationURI;
|
||||||
bool, // bool changePassword = true;
|
uint64_t, // bool changePassword = true;
|
||||||
uint64_t, // lastLogin = 0;
|
uint64_t, // lastLogin = 0;
|
||||||
std::string, // currentLoginURI;
|
std::string, // currentLoginURI;
|
||||||
uint64_t, // lastPasswordChange = 0;
|
uint64_t, // lastPasswordChange = 0;
|
||||||
uint64_t, // lastEmailCheck = 0;
|
uint64_t, // lastEmailCheck = 0;
|
||||||
bool, // bool waitingForEmailCheck = false;
|
uint64_t, // bool waitingForEmailCheck = false;
|
||||||
std::string, // locale;
|
std::string, // locale;
|
||||||
std::string, // notes;
|
std::string, // notes;
|
||||||
std::string, // location;
|
std::string, // location;
|
||||||
std::string, // owner;
|
std::string, // owner;
|
||||||
bool, // bool suspended = false;
|
uint64_t, // bool suspended = false;
|
||||||
bool, // bool blackListed = false;
|
uint64_t, // bool blackListed = false;
|
||||||
std::string, // userRole;
|
std::string, // userRole;
|
||||||
std::string, // userTypeProprietaryInfo;
|
std::string, // userTypeProprietaryInfo;
|
||||||
std::string, // securityPolicy;
|
std::string, // securityPolicy;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ fi
|
|||||||
token=""
|
token=""
|
||||||
result_file=result.json
|
result_file=result.json
|
||||||
username="tip@ucentral.com"
|
username="tip@ucentral.com"
|
||||||
password="Snoopy99!!!"
|
password="openwifi"
|
||||||
#username="stephb@incognito.com"
|
#username="stephb@incognito.com"
|
||||||
#password="Snoopy98!"
|
#password="Snoopy98!"
|
||||||
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
|
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
|
||||||
|
|||||||
Reference in New Issue
Block a user