Initial MicroService Tests

This commit is contained in:
stephb9959
2021-07-04 09:09:34 -07:00
parent 7aa9751379
commit c4f04f5f8d
11 changed files with 170 additions and 112 deletions

View File

@@ -1 +1,36 @@
# ucentralsec # ucentralsec
uCentralSec is the Authentication & Resource Policy Access service for the uCentral system. In order to use the uCentral system
you must have at least 1 uCentralSec. uCentralSec is the first point of contact for the entire architecture. We strongly recommend using Docker
to deploy all the uCentral services. If you would like to develop and play with the source, please do.
## OpenAPI
Like all other uCentral services, uCentralSec is defined through an OpenAPI. You can use this API to build your own applications or integration modules
into your own systems. If all you need it to access the uCentralGW for example (the service that manages the APs), you will need to:
- get a token (`/oauth2`)
- find the endpoints on the system (`/systemEndpoints`)
- choose one to manage (pick an endpoint that matches what you are trying to do by looking at its `type`. For the gateway, type = ucentrtalgw)
- make your calls (use the PublicEndPoint of the corresponding entry to make your calls, do not forget to add `/api/v1` as the root os the call)
The CLI for the [uCentralGW](https://github.com/telecominfraproject/wlan-cloud-ucentralgw/blob/main/test_scripts/curl/cli) has a very good example of this. Loog for the `setgateway`
function.
## Firewall Considerations
The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port
access
- Security
- Public: 16001
- Private: 17001
- ALB: 16101
- Gateway:
- Public: 16002
- Private: 17002
- ALB: 16102
- Firmware:
- Public: 16004
- Private: 17004
- ALB: 16104

View File

@@ -57,7 +57,7 @@ namespace uCentral {
Logger_.notice("Stopping..."); Logger_.notice("Stopping...");
} }
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::WebToken & UserInfo ) bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo )
{ {
if(!Secure_) if(!Secure_)
return true; return true;
@@ -81,24 +81,23 @@ namespace uCentral {
if(CallToken.empty()) if(CallToken.empty())
return false; return false;
auto Client = Tokens_.find(CallToken); auto Client = UserCache_.find(CallToken);
if( Client == Tokens_.end() ) if( Client == UserCache_.end() )
return ValidateToken(CallToken, CallToken, UserInfo); return ValidateToken(CallToken, CallToken, UInfo);
if((Client->second.created_ + Client->second.expires_in_) > time(nullptr)) { if((Client->second.webtoken.created_ + Client->second.webtoken.expires_in_) > time(nullptr)) {
SessionToken = CallToken; SessionToken = CallToken;
UserInfo = Client->second ; UInfo = Client->second ;
return true; return true;
} }
UserCache_.erase(CallToken);
Tokens_.erase(CallToken);
return false; return false;
} }
void AuthService::Logout(const std::string &token) { void AuthService::Logout(const std::string &token) {
SubMutexGuard Guard(Mutex_); SubMutexGuard Guard(Mutex_);
Tokens_.erase(token); UserCache_.erase(token);
try { try {
Poco::JSON::Object Obj; Poco::JSON::Object Obj;
@@ -134,7 +133,7 @@ namespace uCentral {
return JWT; return JWT;
} }
bool AuthService::ValidateToken(const std::string & Token, std::string & SessionToken, SecurityObjects::WebToken & UserInfo ) { bool AuthService::ValidateToken(const std::string & Token, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
SubMutexGuard Guard(Mutex_); SubMutexGuard Guard(Mutex_);
Poco::JWT::Token DecryptedToken; Poco::JWT::Token DecryptedToken;
@@ -146,26 +145,26 @@ namespace uCentral {
auto IssuedAt = DecryptedToken.getIssuedAt(); auto IssuedAt = DecryptedToken.getIssuedAt();
auto Subject = DecryptedToken.getSubject(); auto Subject = DecryptedToken.getSubject();
UserInfo.access_token_ = Token; UInfo.webtoken.access_token_ = Token;
UserInfo.refresh_token_= Token; UInfo.webtoken.refresh_token_= Token;
UserInfo.username_ = Identity; UInfo.webtoken.username_ = Identity;
UserInfo.id_token_ = Token; UInfo.webtoken.id_token_ = Token;
UserInfo.token_type_ = "Bearer"; UInfo.webtoken.token_type_ = "Bearer";
UserInfo.created_ = IssuedAt.epochTime(); UInfo.webtoken.created_ = IssuedAt.epochTime();
UserInfo.expires_in_ = Expires.epochTime() - IssuedAt.epochTime(); UInfo.webtoken.expires_in_ = Expires.epochTime() - IssuedAt.epochTime();
UserInfo.idle_timeout_ = 5*60; UInfo.webtoken.idle_timeout_ = 5*60;
if(Storage()->GetIdentityRights(Identity, UserInfo.acl_template_)) { if(Storage()->GetIdentityRights(Identity, UInfo.webtoken.acl_template_)) {
} else { } else {
// we can get in but we have no given rights... something is very wrong // we can get in but we have no given rights... something is very wrong
UserInfo.acl_template_.Read_ = true ; UInfo.webtoken.acl_template_.Read_ = true ;
UserInfo.acl_template_.ReadWriteCreate_ = UInfo.webtoken.acl_template_.ReadWriteCreate_ =
UserInfo.acl_template_.ReadWrite_ = UInfo.webtoken.acl_template_.ReadWrite_ =
UserInfo.acl_template_.Delete_ = false; UInfo.webtoken.acl_template_.Delete_ = false;
UserInfo.acl_template_.PortalLogin_ = true; UInfo.webtoken.acl_template_.PortalLogin_ = true;
} }
Tokens_[UserInfo.access_token_] = UserInfo; UserCache_[UInfo.webtoken.access_token_] = UInfo;
return true; return true;
} }
@@ -176,27 +175,24 @@ namespace uCentral {
return false; return false;
} }
void AuthService::CreateToken(const std::string & UserName, SecurityObjects::WebToken & UserInfo, SecurityObjects::AclTemplate & ACL) void AuthService::CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo)
{ {
SubMutexGuard Guard(Mutex_); SubMutexGuard Guard(Mutex_);
std::string Token = GenerateToken(UserName,USERNAME,30); std::string Token = GenerateToken(UserName,USERNAME,30);
UInfo.webtoken.expires_in_ = 30 * 24 * 60 * 60 ;
UInfo.webtoken.idle_timeout_ = 5 * 60;
UInfo.webtoken.token_type_ = "Bearer";
UInfo.webtoken.access_token_ = Token;
UInfo.webtoken.id_token_ = Token;
UInfo.webtoken.refresh_token_ = Token;
UInfo.webtoken.created_ = time(nullptr);
UInfo.webtoken.username_ = UserName;
UserInfo.acl_template_ = ACL; UserCache_[Token] = UInfo;
UserInfo.expires_in_ = 30 * 24 * 60 * 60 ;
UserInfo.idle_timeout_ = 5 * 60;
UserInfo.token_type_ = "Bearer";
UserInfo.access_token_ = Token;
UserInfo.id_token_ = Token;
UserInfo.refresh_token_ = Token;
UserInfo.created_ = time(nullptr);
UserInfo.username_ = UserName;
Tokens_[UserInfo.access_token_] = UserInfo;
} }
bool AuthService::Authorize( const std::string & UserName, const std::string & Password, SecurityObjects::WebToken & ResultToken ) bool AuthService::Authorize( const std::string & UserName, const std::string & Password, SecurityObjects::UserInfoAndPolicy & UInfo )
{ {
SubMutexGuard Guard(Mutex_); SubMutexGuard Guard(Mutex_);
SecurityObjects::AclTemplate ACL; SecurityObjects::AclTemplate ACL;
@@ -206,7 +202,11 @@ namespace uCentral {
if(((UserName == DefaultUserName_) && (DefaultPassword_== ComputePasswordHash(UserName,Password))) || !Secure_) if(((UserName == DefaultUserName_) && (DefaultPassword_== ComputePasswordHash(UserName,Password))) || !Secure_)
{ {
ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true; ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true;
CreateToken(UserName, ResultToken, ACL); UInfo.webtoken.acl_template_ = ACL;
UInfo.userinfo.email = DefaultUserName_;
UInfo.userinfo.currentPassword = DefaultPassword_;
UInfo.userinfo.name = DefaultUserName_;
CreateToken(UserName, UInfo );
return true; return true;
} }
} else if (Mechanism_=="db") { } else if (Mechanism_=="db") {
@@ -214,7 +214,7 @@ namespace uCentral {
std::string TUser{UserName}; std::string TUser{UserName};
if(Storage()->GetIdentity(TUser,PasswordHash,USERNAME,ACL)) { if(Storage()->GetIdentity(TUser,PasswordHash,USERNAME,ACL)) {
CreateToken(UserName, ResultToken, ACL); CreateToken(UserName, UInfo);
return true; return true;
} }
} }

View File

@@ -24,7 +24,6 @@ namespace uCentral{
class AuthService : public SubSystemServer { class AuthService : public SubSystemServer {
public: public:
typedef std::map<std::string, SecurityObjects::WebToken> WebTokenMap;
enum ACCESS_TYPE { enum ACCESS_TYPE {
USERNAME, USERNAME,
SERVER, SERVER,
@@ -43,10 +42,14 @@ namespace uCentral{
int Start() override; int Start() override;
void Stop() override; void Stop() override;
bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::WebToken & UserInfo );
void CreateToken(const std::string & UserName, SecurityObjects::WebToken & ResultToken, SecurityObjects::AclTemplate & ACL); [[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo );
bool Authorize( const std::string & UserName, const std::string & Password, SecurityObjects::WebToken & ResultToken ); [[nodiscard]] bool Authorize( const std::string & UserName, const std::string & Password, SecurityObjects::UserInfoAndPolicy & UInfo );
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
[[nodiscard]] bool ValidateToken(const std::string & Token, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UserInfo );
void Logout(const std::string &token); void Logout(const std::string &token);
[[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo); [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo);
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); [[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
[[nodiscard]] std::string GenerateToken(const std::string & UserName, ACCESS_TYPE Type, int NumberOfDays); [[nodiscard]] std::string GenerateToken(const std::string & UserName, ACCESS_TYPE Type, int NumberOfDays);
@@ -54,15 +57,16 @@ namespace uCentral{
[[nodiscard]] std::string ComputePasswordHash(const std::string &UserName, const std::string &Password); [[nodiscard]] std::string ComputePasswordHash(const std::string &UserName, const std::string &Password);
[[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword);
[[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName); [[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName);
private: private:
static AuthService *instance_; static AuthService *instance_;
WebTokenMap Tokens_;
bool Secure_ = false ; bool Secure_ = false ;
std::string DefaultUserName_; std::string DefaultUserName_;
std::string DefaultPassword_; std::string DefaultPassword_;
std::string Mechanism_; std::string Mechanism_;
Poco::JWT::Signer Signer_; Poco::JWT::Signer Signer_;
Poco::SHA2Engine SHA2_; Poco::SHA2Engine SHA2_;
SecurityObjects::UserInfoCache UserCache_;
AuthService() noexcept: AuthService() noexcept:
SubSystemServer("Authentication", "AUTH-SVR", "authentication") SubSystemServer("Authentication", "AUTH-SVR", "authentication")

View File

@@ -13,5 +13,24 @@ namespace uCentral::KafkaTopics {
static const std::string ALERTS{"alerts"}; static const std::string ALERTS{"alerts"};
static const std::string COMMAND{"command"}; static const std::string COMMAND{"command"};
static const std::string SERVICE_EVENTS{"service_events"}; static const std::string SERVICE_EVENTS{"service_events"};
namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"};
static const std::string EVENT_LEAVE{"leave"};
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
namespace Fields {
static const std::string EVENT{"event"};
static const std::string ID{"id"};
static const std::string TYPE{"type"};
static const std::string PUBLIC{"publicEndPoint"};
static const std::string PRIVATE{"privateEndPoint"};
static const std::string KEY{"key"};
static const std::string VERSION{"version"};
static const std::string TOKEN{"token"};
}
}
} }
#endif // UCENTRALGW_KAFKA_TOPICS_H #endif // UCENTRALGW_KAFKA_TOPICS_H

View File

@@ -56,57 +56,61 @@ namespace uCentral {
std::exit(Reason); std::exit(Reason);
} }
void MicroService::BusMessageReceived(std::string Key, std::string Message) { void MicroService::BusMessageReceived(const std::string &Key, const std::string & Message) {
SubMutexGuard G(InfraMutex_); SubMutexGuard G(InfraMutex_);
// std::cout << "Message arrived:" << Key << " ," << Message << std::endl;
try { try {
Poco::JSON::Parser P; Poco::JSON::Parser P;
auto Object = P.parse(Message).extract<Poco::JSON::Object::Ptr>(); auto Object = P.parse(Message).extract<Poco::JSON::Object::Ptr>();
if (Object->has("id")) { if (Object->has(KafkaTopics::ServiceEvents::Fields::ID) &&
uint64_t ID = Object->get("id"); Object->has(KafkaTopics::ServiceEvents::Fields::EVENT)) {
uint64_t ID = Object->get(KafkaTopics::ServiceEvents::Fields::ID);
auto Event = Object->get(KafkaTopics::ServiceEvents::Fields::EVENT).toString();
if (ID != ID_) { if (ID != ID_) {
if (Object->has("event") && Object->has("type") && if( Event==KafkaTopics::ServiceEvents::EVENT_JOIN ||
Object->has("publicEndPoint") && Object->has("privateEndPoint") && Event==KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE ||
Object->has("version") && Object->has("key")) { Event==KafkaTopics::ServiceEvents::EVENT_LEAVE ) {
auto Event = Object->get("event").toString(); if( Object->has(KafkaTopics::ServiceEvents::Fields::TYPE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::PUBLIC) &&
Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::VERSION) &&
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
if (Event == "keep-alive" && Services_.find(ID) != Services_.end()) { if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(ID) != Services_.end()) {
// std::cout << "Keep-alive from " << ID << std::endl; Services_[ID].LastUpdate = std::time(nullptr);
Services_[ID].LastUpdate = std::time(nullptr); } else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
} else if (Event == "leave") { Services_.erase(ID);
Services_.erase(ID); logger().information(Poco::format("Service %s ID=%Lu leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
std::cout << "Leave from " << ID << std::endl; } else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
} else if (Event == "join" || Event == "keep-alive") { logger().information(Poco::format("Service %s ID=%Lu joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
std::cout << "Join from " << ID << std::endl; Services_[ID] = MicroServiceMeta{
Services_[ID] = MicroServiceMeta{ .Id = ID,
.Id = ID, .Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
.Type = Poco::toLower(Object->get("type").toString()), .PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
.PrivateEndPoint = Object->get("privateEndPoint").toString(), .PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
.PublicEndPoint = Object->get("publicEndPoint").toString(), .AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
.AccessKey = Object->get("key").toString(), .Version = Object->get(KafkaTopics::ServiceEvents::Fields::VERSION).toString(),
.Version = Object->get("version").toString(), .LastUpdate = (uint64_t)std::time(nullptr)};
.LastUpdate = (uint64_t)std::time(nullptr)}; for (const auto &[Id, Svc] : Services_) {
for (const auto &[Id, Svc] : Services_) logger().information(Poco::format("ID: %Lu Type: %s EndPoint: %s",Id,Svc.Type,Svc.PrivateEndPoint));
std::cout << "ID:" << Id << " Type:" << Svc.Type }
<< " EndPoint:" << Svc.PublicEndPoint << std::endl; }
} else { } else {
std::cout << "Bad packet 2 ..." << Event << std::endl; logger().error(Poco::format("KAFKA-MSG: invalid event '%s', missing a field.",Event));
logger().error(Poco::format("Malformed event from device %Lu, event=%s",
ID, Event));
} }
} else if (Object->has("event") && } else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
Object->get("event").toString() == "remove-token" && if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
Object->has("token")) {
#ifndef TIP_SECURITY_SERVICE #ifndef TIP_SECURITY_SERVICE
AuthClient()->RemovedCachedToken(Object->get("token").toString()); AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif #endif
} else } else {
std::cout << "Bad packet 1 ..." << std::endl; logger().error(Poco::format("KAFKA-MSG: invalid event '%s', missing token",Event));
logger().error(Poco::format("Malformed event from device %Lu", ID)); }
} else {
logger().error(Poco::format("Unknown Event: %s Source: %Lu", Event, ID));
}
} }
} else { } else {
// std::cout << "Ignoring my own messages..." << std::endl; logger().error("Bad bus message.");
} }
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
logger().log(E); logger().log(E);
@@ -396,13 +400,13 @@ namespace uCentral {
std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const { std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
Poco::JSON::Object Obj; Poco::JSON::Object Obj;
Obj.set("event",Type); Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type);
Obj.set("id",ID_); Obj.set(KafkaTopics::ServiceEvents::Fields::ID,ID_);
Obj.set("type",Poco::toLower(DAEMON_APP_NAME)); Obj.set(KafkaTopics::ServiceEvents::Fields::TYPE,Poco::toLower(DAEMON_APP_NAME));
Obj.set("publicEndPoint",MyPublicEndPoint_); Obj.set(KafkaTopics::ServiceEvents::Fields::PUBLIC,MyPublicEndPoint_);
Obj.set("privateEndPoint",MyPrivateEndPoint_); Obj.set(KafkaTopics::ServiceEvents::Fields::PRIVATE,MyPrivateEndPoint_);
Obj.set("key",MyHash_); Obj.set(KafkaTopics::ServiceEvents::Fields::KEY,MyHash_);
Obj.set("version",Version_); Obj.set(KafkaTopics::ServiceEvents::Fields::VERSION,Version_);
std::stringstream ResultText; std::stringstream ResultText;
Poco::JSON::Stringifier::stringify(Obj, ResultText); Poco::JSON::Stringifier::stringify(Obj, ResultText);
return ResultText.str(); return ResultText.str();
@@ -410,17 +414,16 @@ namespace uCentral {
void BusEventManager::run() { void BusEventManager::run() {
Running_ = true; Running_ = true;
auto Msg = Daemon()->MakeSystemEventMessage("join"); auto Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
while(Running_) { while(Running_) {
Poco::Thread::trySleep((unsigned long)Daemon()->DaemonBusTimer()); Poco::Thread::trySleep((unsigned long)Daemon()->DaemonBusTimer());
if(!Running_) if(!Running_)
break; break;
// std::cout << "Sending keep-alive:" << Daemon()->DaemonBusTimer() << std::endl; auto Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
auto Msg = Daemon()->MakeSystemEventMessage("keep-alive");
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
} }
Msg = Daemon()->MakeSystemEventMessage("leave"); Msg = Daemon()->MakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false); KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,Daemon()->PrivateEndPoint(),Msg, false);
}; };

View File

@@ -124,7 +124,7 @@ namespace uCentral {
[[nodiscard]] std::string MakeSystemEventMessage( const std::string & Type ) const ; [[nodiscard]] std::string MakeSystemEventMessage( const std::string & Type ) const ;
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; }; inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
void BusMessageReceived( std::string Key, std::string Message); void BusMessageReceived( const std::string & Key, const std::string & Message);
[[nodiscard]] MicroServiceMetaVec GetServices(const std::string & type); [[nodiscard]] MicroServiceMetaVec GetServices(const std::string & type);
[[nodiscard]] MicroServiceMetaVec GetServices(); [[nodiscard]] MicroServiceMetaVec GetServices();
[[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request); [[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);

View File

@@ -114,6 +114,9 @@ namespace uCentral::SecurityObjects {
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); bool from_json(const Poco::JSON::Object::Ptr &Obj);
}; };
typedef std::map<std::string,SecurityObjects::UserInfoAndPolicy> UserInfoCache;
} }
#endif //UCENTRAL_RESTAPI_SECURITYOBJECTS_H #endif //UCENTRAL_RESTAPI_SECURITYOBJECTS_H

View File

@@ -283,7 +283,7 @@ namespace uCentral {
#else #else
if (AuthClient()->IsAuthorized(Request, SessionToken_, UserInfo_)) { if (AuthClient()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
#endif #endif
UserName = UserInfo_.username_; UserName = UserInfo_.webtoken.username_;
return true; return true;
} else { } else {
UnAuthorized(Request, Response); UnAuthorized(Request, Response);

View File

@@ -87,8 +87,8 @@ namespace uCentral {
BindingMap Bindings_; BindingMap Bindings_;
Poco::URI::QueryParameters Parameters_; Poco::URI::QueryParameters Parameters_;
Poco::Logger &Logger_; Poco::Logger &Logger_;
std::string SessionToken_; std::string SessionToken_;
SecurityObjects::WebToken UserInfo_; SecurityObjects::UserInfoAndPolicy UserInfo_;
std::vector<std::string> Methods_; std::vector<std::string> Methods_;
QueryBlock QB_; QueryBlock QB_;
}; };

View File

@@ -31,11 +31,11 @@ namespace uCentral {
auto password = GetS(uCentral::RESTAPI::Protocol::PASSWORD, Obj); auto password = GetS(uCentral::RESTAPI::Protocol::PASSWORD, Obj);
Poco::toLowerInPlace(userId); Poco::toLowerInPlace(userId);
SecurityObjects::WebToken Token; SecurityObjects::UserInfoAndPolicy UInfo;
if (AuthService()->Authorize(userId, password, Token)) { if (AuthService()->Authorize(userId, password, UInfo)) {
Poco::JSON::Object ReturnObj; Poco::JSON::Object ReturnObj;
Token.to_json(ReturnObj); UInfo.webtoken.to_json(ReturnObj);
ReturnObject(Request, ReturnObj, Response); ReturnObject(Request, ReturnObj, Response);
} else { } else {
UnAuthorized(Request, Response); UnAuthorized(Request, Response);

View File

@@ -29,15 +29,9 @@ ucentral.internal.restapi.host.0.key.password = mypassword
# NLB Support # NLB Support
# #
alb.enable = true alb.enable = true
alb.port = 15017 alb.port = 16101
authentication.enabled = true
authentication.default.username = tip@ucentral.com
authentication.default.password = openwifi
authentication.default.access = master
authentication.service.type = internal
system.directory.data = $UCENTRALSEC_ROOT/data system.directory.data = $UCENTRALSEC_ROOT/data
ucentral.service.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem ucentral.service.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
ucentral.system.debug = true ucentral.system.debug = true
ucentral.system.uri = https://localhost:16002 ucentral.system.uri = https://localhost:16002
@@ -45,7 +39,7 @@ ucentral.system.commandchannel = /tmp/app.ucentralsec
mailer.hostname = smtp.gmail.com mailer.hostname = smtp.gmail.com
mailer.username = no-reply@arilia.com mailer.username = no-reply@arilia.com
mailer.password = pink-elephants-play-hockey mailer.password = **************************
mailer.loginmethod = login mailer.loginmethod = login
mailer.port = 587 mailer.port = 587