mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-11-01 19:27:59 +00:00
Fixes for cache issues.
This commit is contained in:
@@ -76,7 +76,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!CallToken.empty()) {
|
if(!CallToken.empty()) {
|
||||||
auto Client = UserCache_.get(CallToken);
|
auto Client = UserCacheTokenToSharedID_.get(CallToken);
|
||||||
if( Client.isNull() ) {
|
if( Client.isNull() ) {
|
||||||
SecurityObjects::WebToken WT;
|
SecurityObjects::WebToken WT;
|
||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
@@ -86,8 +86,9 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
||||||
if(StorageService()->GetUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->GetUserById(UserId,UInfo.userinfo)) {
|
||||||
|
UserCacheTokenToSharedID_.update(CallToken, { WT, UserId});
|
||||||
|
UserCacheIDToUserInfo_.update(UserId, UInfo.userinfo);
|
||||||
UInfo.webtoken = WT;
|
UInfo.webtoken = WT;
|
||||||
UserCache_.update(CallToken, UInfo);
|
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -96,8 +97,16 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
if(!Expired) {
|
if(!Expired) {
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
UInfo = *Client ;
|
UInfo.webtoken = Client->WT ;
|
||||||
return true;
|
auto UInfoCacheEntry = UserCacheIDToUserInfo_.get(Client->ID);
|
||||||
|
if(UInfoCacheEntry.isNull()) {
|
||||||
|
if(!StorageService()->GetUserById(Client->ID,UInfo.userinfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UInfo.userinfo = *UInfoCacheEntry;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
RevokeToken(CallToken);
|
RevokeToken(CallToken);
|
||||||
return false;
|
return false;
|
||||||
@@ -120,18 +129,19 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!CallToken.empty()) {
|
if(!CallToken.empty()) {
|
||||||
auto Client = SubUserCache_.get(CallToken);
|
auto Client = SubUserCacheTokenToSharedID_.get(CallToken);
|
||||||
if( Client.isNull() ) {
|
if( Client.isNull() ) {
|
||||||
SecurityObjects::WebToken WT;
|
SecurityObjects::WebToken WT;
|
||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
std::string UserId;
|
std::string UserId;
|
||||||
if(StorageService()->GetSubToken(CallToken,WT, UserId, RevocationDate)) {
|
if(StorageService()->GetSubToken(CallToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0)
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
||||||
if(StorageService()->GetSubUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->GetSubUserById(UserId,UInfo.userinfo)) {
|
||||||
|
SubUserCacheTokenToSharedID_.update(CallToken, { WT, UserId});
|
||||||
|
SubUserCacheIDToUserInfo_.update(UserId, UInfo.userinfo);
|
||||||
UInfo.webtoken = WT;
|
UInfo.webtoken = WT;
|
||||||
SubUserCache_.update(CallToken, UInfo);
|
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -140,7 +150,15 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
if(!Expired) {
|
if(!Expired) {
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
UInfo = *Client ;
|
UInfo.webtoken = Client->WT ;
|
||||||
|
auto UInfoCacheEntry = SubUserCacheIDToUserInfo_.get(Client->ID);
|
||||||
|
if(UInfoCacheEntry.isNull()) {
|
||||||
|
if(!StorageService()->GetSubUserById(Client->ID,UInfo.userinfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
UInfo.userinfo = *UInfoCacheEntry;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
RevokeSubToken(CallToken);
|
RevokeSubToken(CallToken);
|
||||||
@@ -153,45 +171,47 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::RevokeToken(std::string & Token) {
|
void AuthService::RevokeToken(std::string & Token) {
|
||||||
UserCache_.remove(Token);
|
UserCacheTokenToSharedID_.remove(Token);
|
||||||
StorageService()->RevokeToken(Token);
|
StorageService()->RevokeToken(Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::RevokeSubToken(std::string & Token) {
|
void AuthService::RevokeSubToken(std::string & Token) {
|
||||||
SubUserCache_.remove(Token);
|
SubUserCacheTokenToSharedID_.remove(Token);
|
||||||
StorageService()->RevokeSubToken(Token);
|
StorageService()->RevokeSubToken(Token);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::DeleteUserFromCache(const std::string &UserName) {
|
bool AuthService::DeleteUserFromCache(const std::string &Id) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
std::vector<std::string> OldTokens;
|
std::vector<std::string> OldTokens;
|
||||||
|
UserCacheIDToUserInfo_.remove(Id);
|
||||||
|
|
||||||
UserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
|
UserCacheTokenToSharedID_.forEach([&OldTokens,Id](const std::string &token, const SharedTokenID & O) -> void
|
||||||
{ if(O.userinfo.email==UserName)
|
{ if(O.ID==Id)
|
||||||
OldTokens.push_back(token);
|
OldTokens.push_back(token);
|
||||||
});
|
});
|
||||||
|
|
||||||
for(const auto &i:OldTokens) {
|
for(const auto &i:OldTokens) {
|
||||||
Logout(i,false);
|
Logout(i,false);
|
||||||
UserCache_.remove(i);
|
UserCacheTokenToSharedID_.remove(i);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::DeleteSubUserFromCache(const std::string &UserName) {
|
bool AuthService::DeleteSubUserFromCache(const std::string &Id) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
std::vector<std::string> OldTokens;
|
std::vector<std::string> OldTokens;
|
||||||
|
SubUserCacheIDToUserInfo_.remove(Id);
|
||||||
|
|
||||||
SubUserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
|
SubUserCacheTokenToSharedID_.forEach([&OldTokens,Id](const std::string &token, const SharedTokenID & O) -> void
|
||||||
{ if(O.userinfo.email==UserName)
|
{ if(O.ID==Id)
|
||||||
OldTokens.push_back(token);
|
OldTokens.push_back(token);
|
||||||
});
|
});
|
||||||
|
|
||||||
for(const auto &i:OldTokens) {
|
for(const auto &i:OldTokens) {
|
||||||
SubLogout(i,false);
|
Logout(i,false);
|
||||||
SubUserCache_.remove(i);
|
SubUserCacheTokenToSharedID_.remove(i);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -289,7 +309,8 @@ 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);
|
UserCacheTokenToSharedID_.update(UInfo.webtoken.access_token_,{UInfo.webtoken,UInfo.userinfo.Id});
|
||||||
|
UserCacheIDToUserInfo_.update(UInfo.userinfo.Id, UInfo.userinfo);
|
||||||
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
StorageService()->SetLastLogin(UInfo.userinfo.Id);
|
||||||
StorageService()->AddToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
|
StorageService()->AddToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
|
||||||
UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
|
UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
|
||||||
@@ -313,7 +334,8 @@ 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;
|
||||||
SubUserCache_.update(UInfo.webtoken.access_token_,UInfo);
|
SubUserCacheTokenToSharedID_.update(UInfo.webtoken.access_token_,{UInfo.webtoken,UInfo.userinfo.Id});
|
||||||
|
SubUserCacheIDToUserInfo_.update(UInfo.userinfo.Id, UInfo.userinfo);
|
||||||
StorageService()->SetSubLastLogin(UInfo.userinfo.Id);
|
StorageService()->SetSubLastLogin(UInfo.userinfo.Id);
|
||||||
StorageService()->AddSubToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
|
StorageService()->AddSubToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
|
||||||
UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
|
UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
|
||||||
@@ -625,61 +647,74 @@ namespace OpenWifi {
|
|||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Expired = false;
|
Expired = false;
|
||||||
|
|
||||||
auto Client = UserCache_.get(Token);
|
auto Client = UserCacheTokenToSharedID_.get(Token);
|
||||||
if(!Client.isNull()) {
|
if(!Client.isNull()) {
|
||||||
Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < std::time(nullptr);
|
Expired = (Client->WT.created_ + Client->WT.expires_in_) < std::time(nullptr);
|
||||||
WebToken = Client->webtoken;
|
WebToken = Client->WT;
|
||||||
UserInfo = Client->userinfo;
|
auto CachedUserInfo = UserCacheIDToUserInfo_.get(Client->ID);
|
||||||
|
if(!CachedUserInfo.isNull()) {
|
||||||
|
UserInfo = *CachedUserInfo;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!StorageService()->GetUserById(Client->ID,UserInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TToken{Token}, UserId;
|
std::string TToken{Token}, UserId;
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
|
||||||
SecurityObjects::WebToken WT;
|
SecurityObjects::WebToken WT;
|
||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
if(StorageService()->GetToken(TToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->GetToken(TToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0)
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
||||||
if(StorageService()->GetUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->GetUserById(UserId,UserInfo)) {
|
||||||
WebToken = WT;
|
WebToken = WT;
|
||||||
UserCache_.update(UInfo.webtoken.access_token_, UInfo);
|
UserCacheTokenToSharedID_.update(Token, {WebToken, UserId});
|
||||||
|
UserCacheIDToUserInfo_.update(UserId, UserInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsValidSubToken(Token, WebToken, UserInfo, Expired);
|
return IsValidSubToken(Token, WebToken, UserInfo, Expired);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
auto Now = std::time(nullptr);
|
|
||||||
|
|
||||||
Expired = false;
|
Expired = false;
|
||||||
auto Client = SubUserCache_.get(Token);
|
|
||||||
|
auto Client = SubUserCacheTokenToSharedID_.get(Token);
|
||||||
if(!Client.isNull()) {
|
if(!Client.isNull()) {
|
||||||
Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < Now ;
|
Expired = (Client->WT.created_ + Client->WT.expires_in_) < std::time(nullptr);
|
||||||
WebToken = Client->webtoken;
|
WebToken = Client->WT;
|
||||||
UserInfo = Client->userinfo;
|
auto CachedUserInfo = SubUserCacheIDToUserInfo_.get(Client->ID);
|
||||||
|
if(!CachedUserInfo.isNull()) {
|
||||||
|
UserInfo = *CachedUserInfo;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(!StorageService()->GetSubUserById(Client->ID,UserInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TToken{Token}, UserId;
|
std::string TToken{Token}, UserId;
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
|
||||||
SecurityObjects::WebToken WT;
|
SecurityObjects::WebToken WT;
|
||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
if(StorageService()->GetSubToken(TToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->GetSubToken(TToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0)
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
||||||
if(StorageService()->GetSubUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->GetSubUserById(UserId,UserInfo)) {
|
||||||
WebToken = WT;
|
WebToken = WT;
|
||||||
UserCache_.update(UInfo.webtoken.access_token_, UInfo);
|
SubUserCacheTokenToSharedID_.update(Token, {WebToken, UserId});
|
||||||
|
SubUserCacheIDToUserInfo_.update(UserId, UserInfo);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,14 @@ namespace OpenWifi{
|
|||||||
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
||||||
void Logout(const std::string &token, bool EraseFromCache=true);
|
void Logout(const std::string &token, bool EraseFromCache=true);
|
||||||
|
|
||||||
|
inline void UpdateUserCache(const SecurityObjects::UserInfo &UI) {
|
||||||
|
UserCacheIDToUserInfo_.update(UI.Id,UI);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UpdateSubUserCache(const SecurityObjects::UserInfo &UI) {
|
||||||
|
SubUserCacheIDToUserInfo_.update(UI.Id,UI);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
|
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
|
||||||
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||||
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
@@ -114,8 +122,16 @@ namespace OpenWifi{
|
|||||||
Poco::JWT::Signer Signer_;
|
Poco::JWT::Signer Signer_;
|
||||||
Poco::SHA2Engine SHA2_;
|
Poco::SHA2Engine SHA2_;
|
||||||
|
|
||||||
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy> UserCache_{256,1200000};
|
struct SharedTokenID {
|
||||||
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy> SubUserCache_{4096,1200000};
|
SecurityObjects::WebToken WT; // Web token
|
||||||
|
std::string ID; // user.Id
|
||||||
|
};
|
||||||
|
|
||||||
|
Poco::ExpireLRUCache<std::string,SharedTokenID> UserCacheTokenToSharedID_{256,1200000};
|
||||||
|
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfo> UserCacheIDToUserInfo_{256,1200000};
|
||||||
|
|
||||||
|
Poco::ExpireLRUCache<std::string,SharedTokenID> SubUserCacheTokenToSharedID_{4096,1200000};
|
||||||
|
Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfo> SubUserCacheIDToUserInfo_{256,1200000};
|
||||||
|
|
||||||
std::string AccessPolicy_;
|
std::string AccessPolicy_;
|
||||||
std::string PasswordPolicy_;
|
std::string PasswordPolicy_;
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#include "RESTAPI_subuser_handler.h"
|
#include "RESTAPI_subuser_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.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"
|
#include "ACLProcessor.h"
|
||||||
|
#include "AuthService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ namespace OpenWifi {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(AuthService()->DeleteSubUserFromCache(TargetUser.email)) {
|
if(AuthService()->DeleteSubUserFromCache(Id)) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +234,7 @@ namespace OpenWifi {
|
|||||||
if(StorageService()->UpdateSubUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
if(StorageService()->UpdateSubUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
||||||
SecurityObjects::UserInfo NewUserInfo;
|
SecurityObjects::UserInfo NewUserInfo;
|
||||||
StorageService()->GetSubUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
StorageService()->GetSubUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||||
|
AuthService()->UpdateSubUserCache(NewUserInfo);
|
||||||
Poco::JSON::Object ModifiedObject;
|
Poco::JSON::Object ModifiedObject;
|
||||||
FilterCredentials(NewUserInfo);
|
FilterCredentials(NewUserInfo);
|
||||||
NewUserInfo.to_json(ModifiedObject);
|
NewUserInfo.to_json(ModifiedObject);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ namespace OpenWifi {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(AuthService()->DeleteUserFromCache(UInfo.email)) {
|
if(AuthService()->DeleteUserFromCache(Id)) {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user