mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-31 18:57:51 +00:00 
			
		
		
		
	Compare commits
	
		
			22 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 35ff346901 | ||
|   | 03b39d9d1c | ||
|   | 1a15c4744b | ||
|   | 0417162858 | ||
|   | 75b2b30b67 | ||
|   | 73f96b3ad8 | ||
|   | abc06d7953 | ||
|   | 7993e7d345 | ||
|   | be4549fabb | ||
|   | 92c141e511 | ||
|   | 296713e853 | ||
|   | d6dee68880 | ||
|   | aaffa145ad | ||
|   | c8e894bf79 | ||
|   | 766a608e1b | ||
|   | 333316d7a9 | ||
|   | 6527b45f2f | ||
|   | 76ef41aefe | ||
|   | 7e988c5780 | ||
|   | 2080027d7c | ||
|   | 8966888e6b | ||
|   | f650a6fde4 | 
| @@ -16,6 +16,10 @@ into your own systems. If all you need it to access the uCentralGW for example ( | |||||||
| 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.  | 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.  | ||||||
| Look for the `setgateway` function. | Look for the `setgateway` function. | ||||||
|  |  | ||||||
|  | You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralsec/). | ||||||
|  |  | ||||||
|  | Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://validator.swagger.io/validator?url=https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralsec/main/openpapi/owsec.yaml)) to get interactive docs page. | ||||||
|  |  | ||||||
| ## Firewall Considerations | ## Firewall Considerations | ||||||
| The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port | The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port | ||||||
| access: | access: | ||||||
|   | |||||||
| @@ -9,7 +9,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: main |     tag: v2.8.0 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
|   | |||||||
| @@ -32,53 +32,102 @@ namespace OpenWifi { | |||||||
|  */ |  */ | ||||||
|         static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { |         static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { | ||||||
|  |  | ||||||
|             // rule 0 |             switch(Op) { | ||||||
|             if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE) |                 case DELETE: { | ||||||
|  |                     //  can a user delete themselves - yes - only if not root. We do not want a system to end up rootless | ||||||
|  |                     if(User.id==Target.id) { | ||||||
|  |                         return User.userRole != SecurityObjects::ROOT; | ||||||
|  |                     } | ||||||
|  |                     //  Root can delete anyone | ||||||
|  |                     switch (User.userRole) { | ||||||
|  |                         case SecurityObjects::ROOT: | ||||||
|                             return true; |                             return true; | ||||||
|  |                         case SecurityObjects::ADMIN: | ||||||
|             //  rule 1 |                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||||
|             if(User.id == Target.id && Op==DELETE) |                         case SecurityObjects::SUBSCRIBER: | ||||||
|  |                             return User.id==Target.id; | ||||||
|  |                         case SecurityObjects::CSR: | ||||||
|                             return false; |                             return false; | ||||||
|  |                         case SecurityObjects::SYSTEM: | ||||||
|             //  rule 2 |                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||||
|             if(User.userRole==SecurityObjects::ROOT) |                         case SecurityObjects::INSTALLER: | ||||||
|                 return true; |                             return User.id==Target.id; | ||||||
|  |                         case SecurityObjects::NOC: | ||||||
|             //  rule 3 |                             return Target.userRole==SecurityObjects::NOC; | ||||||
|             if(User.id == Target.id) |                         case SecurityObjects::ACCOUNTING: | ||||||
|                 return true; |                             return Target.userRole==SecurityObjects::ACCOUNTING; | ||||||
|  |                         case SecurityObjects::PARTNER: | ||||||
|             //  rule 4 |                             return Target.userRole!=SecurityObjects::ROOT; | ||||||
|             if(Target.userRole==SecurityObjects::ROOT && Op!=READ) |                         default: | ||||||
|                 return false; |  | ||||||
|  |  | ||||||
|             if(Op==CREATE) { |  | ||||||
|                 if(User.userRole==SecurityObjects::ROOT) |  | ||||||
|                     return true; |  | ||||||
|                 if(User.userRole==SecurityObjects::PARTNER && (Target.userRole==SecurityObjects::ADMIN || |  | ||||||
|                     Target.userRole==SecurityObjects::SUBSCRIBER || |  | ||||||
|                     Target.userRole==SecurityObjects::CSR || |  | ||||||
|                     Target.userRole==SecurityObjects::INSTALLER || |  | ||||||
|                     Target.userRole==SecurityObjects::NOC || |  | ||||||
|                     Target.userRole==SecurityObjects::ACCOUNTING)) |  | ||||||
|                     return true; |  | ||||||
|                 if(User.userRole==SecurityObjects::ADMIN && |  | ||||||
|                     (Target.userRole==SecurityObjects::ADMIN || |  | ||||||
|                     Target.userRole==SecurityObjects::SUBSCRIBER || |  | ||||||
|                     Target.userRole==SecurityObjects::CSR || |  | ||||||
|                     Target.userRole==SecurityObjects::INSTALLER || |  | ||||||
|                     Target.userRole==SecurityObjects::NOC || |  | ||||||
|                     Target.userRole==SecurityObjects::ACCOUNTING)) |  | ||||||
|                     return true; |  | ||||||
|                 if(User.userRole==SecurityObjects::ACCOUNTING && |  | ||||||
|                     (Target.userRole==SecurityObjects::SUBSCRIBER || |  | ||||||
|                     Target.userRole==SecurityObjects::INSTALLER || |  | ||||||
|                     Target.userRole==SecurityObjects::CSR)) |  | ||||||
|                     return true; |  | ||||||
|                             return false; |                             return false; | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |                 case READ: { | ||||||
|  |                     return  User.userRole == SecurityObjects::ROOT || | ||||||
|  |                             User.userRole == SecurityObjects::ADMIN || | ||||||
|  |                             User.userRole == SecurityObjects::PARTNER; | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |                 case CREATE: { | ||||||
|  |                     switch(User.userRole) { | ||||||
|  |                         case SecurityObjects::ROOT: | ||||||
|                             return true; |                             return true; | ||||||
|  |                         case SecurityObjects::ADMIN: | ||||||
|  |                             return  Target.userRole!=SecurityObjects::ROOT && | ||||||
|  |                                     Target.userRole!=SecurityObjects::PARTNER; | ||||||
|  |                         case SecurityObjects::SUBSCRIBER: | ||||||
|  |                             return false; | ||||||
|  |                         case SecurityObjects::CSR: | ||||||
|  |                             return Target.userRole==SecurityObjects::CSR; | ||||||
|  |                         case SecurityObjects::SYSTEM: | ||||||
|  |                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||||
|  |                         case SecurityObjects::INSTALLER: | ||||||
|  |                             return Target.userRole==SecurityObjects::INSTALLER; | ||||||
|  |                         case SecurityObjects::NOC: | ||||||
|  |                             return Target.userRole==SecurityObjects::NOC; | ||||||
|  |                         case SecurityObjects::ACCOUNTING: | ||||||
|  |                             return Target.userRole==SecurityObjects::ACCOUNTING; | ||||||
|  |                         case SecurityObjects::PARTNER: | ||||||
|  |                             return Target.userRole!=SecurityObjects::ROOT; | ||||||
|  |                         default: | ||||||
|  |                             return false; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|  |                 case MODIFY: { | ||||||
|  |                     switch(User.userRole) { | ||||||
|  |                         case SecurityObjects::ROOT: | ||||||
|  |                             return true; | ||||||
|  |                         case SecurityObjects::ADMIN: | ||||||
|  |                             return  Target.userRole!=SecurityObjects::ROOT && | ||||||
|  |                                     Target.userRole!=SecurityObjects::PARTNER; | ||||||
|  |                         case SecurityObjects::SUBSCRIBER: | ||||||
|  |                             return  User.id==Target.id; | ||||||
|  |                         case SecurityObjects::CSR: | ||||||
|  |                             return  Target.userRole==SecurityObjects::CSR; | ||||||
|  |                         case SecurityObjects::SYSTEM: | ||||||
|  |                             return  Target.userRole!=SecurityObjects::ROOT && | ||||||
|  |                                     Target.userRole!=SecurityObjects::PARTNER; | ||||||
|  |                         case SecurityObjects::INSTALLER: | ||||||
|  |                             return  Target.userRole==SecurityObjects::INSTALLER; | ||||||
|  |                         case SecurityObjects::NOC: | ||||||
|  |                             return  Target.userRole==SecurityObjects::NOC; | ||||||
|  |                         case SecurityObjects::ACCOUNTING: | ||||||
|  |                             return  Target.userRole==SecurityObjects::ACCOUNTING; | ||||||
|  |                         case SecurityObjects::PARTNER: | ||||||
|  |                             return  Target.userRole!=SecurityObjects::ROOT; | ||||||
|  |                         default: | ||||||
|  |                             return false; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                     break; | ||||||
|  |                 default: | ||||||
|  |                     return false; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -51,7 +51,9 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"modified", modified); | 		field_to_json(Obj,"modified", modified); | ||||||
| 		field_to_json(Obj,"locale", locale); | 		field_to_json(Obj,"locale", locale); | ||||||
| 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | ||||||
|  | 		field_to_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||||
|  | 		field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||||
|  | 		field_to_json(Obj,"restrictionDetails", restrictionDetails); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||||
| @@ -93,6 +95,9 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"entity", entity); | 			field_from_json(Obj,"entity", entity); | ||||||
| 			field_from_json(Obj,"locale", locale); | 			field_from_json(Obj,"locale", locale); | ||||||
| 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | ||||||
|  | 			field_from_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||||
|  | 			field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||||
|  | 			field_from_json(Obj,"restrictionDetails", restrictionDetails); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -394,6 +399,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"secret",secret); | 		field_to_json(Obj,"secret",secret); | ||||||
| 		field_to_json(Obj,"certificate",certificate); | 		field_to_json(Obj,"certificate",certificate); | ||||||
| 		field_to_json(Obj,"radsec",radsec); | 		field_to_json(Obj,"radsec",radsec); | ||||||
|  | 		field_to_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||||
| 		field_to_json(Obj,"radsecPort",radsecPort); | 		field_to_json(Obj,"radsecPort",radsecPort); | ||||||
| 		field_to_json(Obj,"radsecSecret",radsecSecret); | 		field_to_json(Obj,"radsecSecret",radsecSecret); | ||||||
| 		field_to_json(Obj,"radsecCacerts",radsecCacerts); | 		field_to_json(Obj,"radsecCacerts",radsecCacerts); | ||||||
| @@ -412,6 +418,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"secret",secret); | 			field_from_json(Obj,"secret",secret); | ||||||
| 			field_from_json(Obj,"certificate",certificate); | 			field_from_json(Obj,"certificate",certificate); | ||||||
| 			field_from_json(Obj,"radsec",radsec); | 			field_from_json(Obj,"radsec",radsec); | ||||||
|  | 			field_from_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||||
| 			field_from_json(Obj,"radsecSecret",radsecSecret); | 			field_from_json(Obj,"radsecSecret",radsecSecret); | ||||||
| 			field_from_json(Obj,"radsecPort",radsecPort); | 			field_from_json(Obj,"radsecPort",radsecPort); | ||||||
| 			field_from_json(Obj,"radsecCacerts",radsecCacerts); | 			field_from_json(Obj,"radsecCacerts",radsecCacerts); | ||||||
| @@ -439,6 +446,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"restricted", restricted); | 		field_to_json(Obj,"restricted", restricted); | ||||||
| 		field_to_json(Obj,"deferred", deferred); | 		field_to_json(Obj,"deferred", deferred); | ||||||
| 		field_to_json(Obj,"timeout", timeout); | 		field_to_json(Obj,"timeout", timeout); | ||||||
|  | 		field_to_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| @@ -456,6 +464,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj,"restricted", restricted); | 			field_from_json(Obj,"restricted", restricted); | ||||||
| 			field_from_json(Obj,"deferred", deferred); | 			field_from_json(Obj,"deferred", deferred); | ||||||
| 			field_from_json(Obj,"timeout", timeout); | 			field_from_json(Obj,"timeout", timeout); | ||||||
|  | 			field_from_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -475,5 +484,64 @@ namespace OpenWifi::GWObjects { | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj,"vendor", vendor); | ||||||
|  | 		field_to_json(Obj,"algo", algo); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj,"vendor", vendor); | ||||||
|  | 			field_from_json(Obj,"algo", algo); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj,"dfs", dfs); | ||||||
|  | 		field_to_json(Obj,"ssh", ssh); | ||||||
|  | 		field_to_json(Obj,"rtty", rtty); | ||||||
|  | 		field_to_json(Obj,"tty", tty); | ||||||
|  | 		field_to_json(Obj,"developer", developer); | ||||||
|  | 		field_to_json(Obj,"upgrade", upgrade); | ||||||
|  | 		field_to_json(Obj,"commands", commands); | ||||||
|  | 		field_to_json(Obj,"country", country); | ||||||
|  | 		field_to_json(Obj,"key_info", key_info); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj,"dfs", dfs); | ||||||
|  | 			field_from_json(Obj,"ssh", ssh); | ||||||
|  | 			field_from_json(Obj,"rtty", rtty); | ||||||
|  | 			field_from_json(Obj,"tty", tty); | ||||||
|  | 			field_from_json(Obj,"developer", developer); | ||||||
|  | 			field_from_json(Obj,"upgrade", upgrade); | ||||||
|  | 			field_from_json(Obj,"commands", commands); | ||||||
|  | 			field_from_json(Obj,"country", country); | ||||||
|  | 			field_from_json(Obj,"key_info", key_info); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { | ||||||
|  | 		return (T.algo!=algo) || (T.vendor!=vendor); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { | ||||||
|  | 		return (	(T.dfs!=dfs)					|| | ||||||
|  | 					(T.rtty!=rtty)					|| | ||||||
|  | 					(T.upgrade!=upgrade)		|| | ||||||
|  | 					(T.commands != commands)		|| | ||||||
|  | 					(T.developer != developer)		|| | ||||||
|  | 					(T.ssh !=ssh) 					|| | ||||||
|  | 					(T.key_info != key_info)		|| | ||||||
|  | 					(T.country != country) ); | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,6 +47,33 @@ namespace OpenWifi::GWObjects { | |||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	struct DeviceRestrictionsKeyInfo { | ||||||
|  | 		std::string 	vendor; | ||||||
|  | 		std::string 	algo; | ||||||
|  |  | ||||||
|  | 		bool operator !=(const DeviceRestrictionsKeyInfo &b) const; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DeviceRestrictions { | ||||||
|  | 		bool    					dfs = false; | ||||||
|  | 		bool    					ssh = false; | ||||||
|  | 		bool    					rtty = false; | ||||||
|  | 		bool    					tty = false; | ||||||
|  | 		bool    					developer = false; | ||||||
|  | 		bool    					upgrade = false; | ||||||
|  | 		bool    					commands = false; | ||||||
|  | 		std::vector<std::string>   	country; | ||||||
|  | 		DeviceRestrictionsKeyInfo	key_info; | ||||||
|  |  | ||||||
|  | 		bool operator !=(const DeviceRestrictions &D) const; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	struct Device { | 	struct Device { | ||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		std::string DeviceType; | 		std::string DeviceType; | ||||||
| @@ -71,6 +98,9 @@ namespace OpenWifi::GWObjects { | |||||||
| 		uint64_t 	modified=0; | 		uint64_t 	modified=0; | ||||||
| 		std::string locale; | 		std::string locale; | ||||||
| 		bool 		restrictedDevice=false; | 		bool 		restrictedDevice=false; | ||||||
|  | 		std::string pendingConfiguration; | ||||||
|  | 		std::string pendingConfigurationCmd; | ||||||
|  | 		DeviceRestrictions	restrictionDetails; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||||
| @@ -230,6 +260,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		Types::StringVec 	restricted; | 		Types::StringVec 	restricted; | ||||||
| 		bool				deferred=false; | 		bool				deferred=false; | ||||||
| 		std::uint64_t 		timeout=30; | 		std::uint64_t 		timeout=30; | ||||||
|  | 		std::string 		defaultUploadURI; | ||||||
|  |  | ||||||
| 		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); | ||||||
| @@ -265,6 +296,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string secret; | 		std::string secret; | ||||||
| 		std::string certificate; | 		std::string certificate; | ||||||
| 		bool 		radsec=false; | 		bool 		radsec=false; | ||||||
|  | 		bool 		allowSelfSigned=false; | ||||||
| 		uint16_t 	radsecPort=2083; | 		uint16_t 	radsecPort=2083; | ||||||
| 		std::string radsecSecret; | 		std::string radsecSecret; | ||||||
| 		std::string radsecKey; | 		std::string radsecKey; | ||||||
| @@ -306,4 +338,5 @@ namespace OpenWifi::GWObjects { | |||||||
| 		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); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,7 +51,13 @@ namespace OpenWifi { | |||||||
|             poco_information(Logger(),"Starting..."); |             poco_information(Logger(),"Starting..."); | ||||||
| 			Running_=true; | 			Running_=true; | ||||||
| 			Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); | 			Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); | ||||||
| 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_); | 			Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard( | ||||||
|  | 				Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6 | ||||||
|  | 												  : Poco::Net::AddressFamily::IPv4)); | ||||||
|  | 			Poco::Net::SocketAddress SockAddr(Addr, Port_); | ||||||
|  | 			Poco::Net::ServerSocket ClientSocket(SockAddr, 64); | ||||||
|  |  | ||||||
|  | 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_); | ||||||
| 			auto Params = new Poco::Net::HTTPServerParams; | 			auto Params = new Poco::Net::HTTPServerParams; | ||||||
| 			Params->setName("ws:alb"); | 			Params->setName("ws:alb"); | ||||||
| 			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | 			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | ||||||
|   | |||||||
| @@ -19,10 +19,9 @@ | |||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| static const std::string GitUCentralJSONSchemaFile{ | static const std::string GitUCentralJSONSchemaFile{ | ||||||
| 	"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"}; | 	"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json"}; | ||||||
|  |  | ||||||
| static json DefaultUCentralSchema = R"( | static json DefaultUCentralSchema = R"( | ||||||
|  |  | ||||||
| { | { | ||||||
|     "$id": "https://openwrt.org/ucentral.schema.json", |     "$id": "https://openwrt.org/ucentral.schema.json", | ||||||
|     "$schema": "http://json-schema.org/draft-07/schema#", |     "$schema": "http://json-schema.org/draft-07/schema#", | ||||||
| @@ -49,7 +48,7 @@ static json DefaultUCentralSchema = R"( | |||||||
|         "switch": { |         "switch": { | ||||||
|             "$ref": "#/$defs/switch" |             "$ref": "#/$defs/switch" | ||||||
|         }, |         }, | ||||||
| 		"radiosgrep": { |         "radios": { | ||||||
|             "type": "array", |             "type": "array", | ||||||
|             "items": { |             "items": { | ||||||
|                 "$ref": "#/$defs/radio" |                 "$ref": "#/$defs/radio" | ||||||
| @@ -201,7 +200,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                     ] |                     ] | ||||||
|                 }, |                 }, | ||||||
|                 "wireless-multimedia": { |                 "wireless-multimedia": { | ||||||
| 					"anyOf": [{ |                     "anyOf": [ | ||||||
|  |                         { | ||||||
|                             "$ref": "#/$defs/globals.wireless-multimedia.table" |                             "$ref": "#/$defs/globals.wireless-multimedia.table" | ||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
| @@ -395,7 +395,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                     ] |                     ] | ||||||
|                 }, |                 }, | ||||||
|                 "channel": { |                 "channel": { | ||||||
| 					"oneOf": [{ |                     "oneOf": [ | ||||||
|  |                         { | ||||||
|                             "type": "integer", |                             "type": "integer", | ||||||
|                             "maximum": 196, |                             "maximum": 196, | ||||||
|                             "minimum": 1 |                             "minimum": 1 | ||||||
| @@ -1004,7 +1005,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "interface.broad-band": { |         "interface.broad-band": { | ||||||
| 			"oneOf": [{ |             "oneOf": [ | ||||||
|  |                 { | ||||||
|                     "$ref": "#/$defs/interface.broad-band.wwan" |                     "$ref": "#/$defs/interface.broad-band.wwan" | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
| @@ -1261,7 +1263,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                                 "minimum": 1 |                                 "minimum": 1 | ||||||
|                             }, |                             }, | ||||||
|                             "value": { |                             "value": { | ||||||
| 								"anyOf": [{ |                                 "anyOf": [ | ||||||
|  |                                     { | ||||||
|                                         "type": "integer", |                                         "type": "integer", | ||||||
|                                         "maximum": 4294967295, |                                         "maximum": 4294967295, | ||||||
|                                         "minimum": 0 |                                         "minimum": 0 | ||||||
| @@ -1272,7 +1275,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                                 ] |                                 ] | ||||||
|                             } |                             } | ||||||
|                         }, |                         }, | ||||||
| 						"examples": [{ |                         "examples": [ | ||||||
|  |                             { | ||||||
|                                 "id": 27, |                                 "id": 27, | ||||||
|                                 "value": 900 |                                 "value": 900 | ||||||
|                             }, |                             }, | ||||||
| @@ -1336,7 +1340,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|                 "authentication": { |                 "authentication": { | ||||||
| 					"allOf": [{ |                     "allOf": [ | ||||||
|  |                         { | ||||||
|                             "$ref": "#/$defs/interface.ssid.radius.server" |                             "$ref": "#/$defs/interface.ssid.radius.server" | ||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
| @@ -1351,7 +1356,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|                     ] |                     ] | ||||||
|                 }, |                 }, | ||||||
|                 "accounting": { |                 "accounting": { | ||||||
| 					"allOf": [{ |                     "allOf": [ | ||||||
|  |                         { | ||||||
|                             "$ref": "#/$defs/interface.ssid.radius.server" |                             "$ref": "#/$defs/interface.ssid.radius.server" | ||||||
|                         }, |                         }, | ||||||
|                         { |                         { | ||||||
| @@ -1554,13 +1560,15 @@ static json DefaultUCentralSchema = R"( | |||||||
|                                 ] |                                 ] | ||||||
|                             } |                             } | ||||||
|                         }, |                         }, | ||||||
| 						"examples": [{ |                         "examples": [ | ||||||
|  |                             { | ||||||
|                                 "width": 32, |                                 "width": 32, | ||||||
|                                 "height": 32, |                                 "height": 32, | ||||||
|                                 "type": "image/png", |                                 "type": "image/png", | ||||||
|                                 "language": "eng", |                                 "language": "eng", | ||||||
|                                 "icon": "R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" |                                 "icon": "R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" | ||||||
| 						}] |                             } | ||||||
|  |                         ] | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|                 "wan-metrics": { |                 "wan-metrics": { | ||||||
| @@ -1806,7 +1814,8 @@ static json DefaultUCentralSchema = R"( | |||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         "interface.tunnel": { |         "interface.tunnel": { | ||||||
| 			"oneOf": [{ |             "oneOf": [ | ||||||
|  |                 { | ||||||
|                     "$ref": "#/$defs/interface.tunnel.mesh" |                     "$ref": "#/$defs/interface.tunnel.mesh" | ||||||
|                 }, |                 }, | ||||||
|                 { |                 { | ||||||
| @@ -2630,12 +2639,12 @@ static json DefaultUCentralSchema = R"( | |||||||
|             return; |             return; | ||||||
|  |  | ||||||
|         std::string GitSchema; |         std::string GitSchema; | ||||||
| 		if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) { | 		// if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) { | ||||||
| 			RootSchema_ = DefaultUCentralSchema; | 			RootSchema_ = DefaultUCentralSchema; | ||||||
| 			poco_information(Logger(),"Using uCentral validation from built-in default."); | 			poco_information(Logger(),"Using uCentral validation from built-in default."); | ||||||
| 			Initialized_ = Working_ = true; | 			Initialized_ = Working_ = true; | ||||||
| 			return; | 			return; | ||||||
| 		} | 		// } | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
| 			auto GitURI = MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile); | 			auto GitURI = MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile); | ||||||
| @@ -2749,7 +2758,7 @@ static json DefaultUCentralSchema = R"( | |||||||
|             if(std::regex_match(value,host_regex)) |             if(std::regex_match(value,host_regex)) | ||||||
|                 return; |                 return; | ||||||
|             throw std::invalid_argument(value + " is not a proper FQDN."); |             throw std::invalid_argument(value + " is not a proper FQDN."); | ||||||
|         } else if(format == "fqdn") { |         } else if(format == "fqdn" || format=="uc-fqdn") { | ||||||
|             if(std::regex_match(value,host_regex)) |             if(std::regex_match(value,host_regex)) | ||||||
|                 return; |                 return; | ||||||
|             throw std::invalid_argument(value + " is not a proper FQDN."); |             throw std::invalid_argument(value + " is not a proper FQDN."); | ||||||
|   | |||||||
| @@ -102,6 +102,48 @@ namespace OpenWifi { | |||||||
| 													  E.displayText(), | 													  E.displayText(), | ||||||
| 													  E.message(), | 													  E.message(), | ||||||
| 													  E.what())); | 													  E.what())); | ||||||
|  | 			} catch (const Poco::TimeoutException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::NoThreadAvailableException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::OutOfMemoryException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::BadCastException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::DataException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::PoolOverflowException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::SystemException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
| 			} catch (const Poco::RuntimeException &E) { | 			} catch (const Poco::RuntimeException &E) { | ||||||
| 				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", | 				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
| 													  t_name, t_id, E.code(), | 													  t_name, t_id, E.code(), | ||||||
|   | |||||||
| @@ -633,6 +633,18 @@ namespace OpenWifi { | |||||||
| 			ReturnObject(Answer); | 			ReturnObject(Answer); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		template<typename T> void Object(const char *Name, const std::vector<T> & Objects) { | ||||||
|  | 			Poco::JSON::Object  Answer; | ||||||
|  | 			RESTAPI_utils::field_to_json(Answer,Name,Objects); | ||||||
|  | 			ReturnObject(Answer); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		template <typename T> void Object(const T &O) { | ||||||
|  | 			Poco::JSON::Object  Answer; | ||||||
|  | 			O.to_json(Answer); | ||||||
|  | 			ReturnObject(Answer); | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		Poco::Logger & Logger() { return Logger_; } | 		Poco::Logger & Logger() { return Logger_; } | ||||||
|  |  | ||||||
| 		virtual void DoGet() = 0 ; | 		virtual void DoGet() = 0 ; | ||||||
|   | |||||||
| @@ -119,7 +119,7 @@ namespace OpenWifi { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) { | 	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) { | ||||||
| 		std::lock_guard G(Mutex_); | 		std::lock_guard G(LocalMutex_); | ||||||
|  |  | ||||||
| 		for(const auto &Client:Clients_) { | 		for(const auto &Client:Clients_) { | ||||||
| 			if(Client.second->UserName_ == UserName) { | 			if(Client.second->UserName_ == UserName) { | ||||||
| @@ -139,7 +139,7 @@ namespace OpenWifi { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) { | 	void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) { | ||||||
| 		std::lock_guard G(Mutex_); | 		std::lock_guard G(LocalMutex_); | ||||||
|  |  | ||||||
| 		for(const auto &Client:Clients_) { | 		for(const auto &Client:Clients_) { | ||||||
| 			try { | 			try { | ||||||
| @@ -189,7 +189,6 @@ namespace OpenWifi { | |||||||
| 	void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) { | 	void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) { | ||||||
|  |  | ||||||
|         UI_WebSocketClientServer::ClientList::iterator Client; |         UI_WebSocketClientServer::ClientList::iterator Client; | ||||||
|  |  | ||||||
|         std::lock_guard     G(LocalMutex_); |         std::lock_guard     G(LocalMutex_); | ||||||
|  |  | ||||||
| 		try { | 		try { | ||||||
| @@ -295,6 +294,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) { | 	void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) { | ||||||
|         try { |         try { | ||||||
|  | 			std::lock_guard     G(LocalMutex_); | ||||||
| 			auto Client = Clients_.find(pNf->socket().impl()->sockfd()); | 			auto Client = Clients_.find(pNf->socket().impl()->sockfd()); | ||||||
|             if (Client == end(Clients_)) |             if (Client == end(Clients_)) | ||||||
|                 return; |                 return; | ||||||
|   | |||||||
| @@ -231,6 +231,8 @@ namespace OpenWifi::RESTAPI::Errors { | |||||||
| 	static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."}; | 	static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."}; | ||||||
| 	static const struct msg InvalidURI{1152,"Invalid URI."}; | 	static const struct msg InvalidURI{1152,"Invalid URI."}; | ||||||
| 	static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."}; | 	static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."}; | ||||||
|  |  | ||||||
|  | 	static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."}; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -526,6 +528,63 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
| 	}; | 	}; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | namespace OpenWifi::APCommands { | ||||||
|  | 	enum class Commands:uint8_t { | ||||||
|  | 		capabilities, | ||||||
|  | 		logs, | ||||||
|  | 		healthchecks, | ||||||
|  | 		statistics, | ||||||
|  | 		status, | ||||||
|  | 		rtty, | ||||||
|  | 		configure, | ||||||
|  | 		upgrade, | ||||||
|  | 		reboot, | ||||||
|  | 		factory, | ||||||
|  | 		leds, | ||||||
|  | 		trace, | ||||||
|  | 		request, | ||||||
|  | 		wifiscan, | ||||||
|  | 		eventqueue, | ||||||
|  | 		telemetry, | ||||||
|  | 		ping, | ||||||
|  | 		script, | ||||||
|  | 		unknown | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	inline static const std::vector<const char *> uCentralAPCommands { | ||||||
|  | 		RESTAPI::Protocol::CAPABILITIES, | ||||||
|  | 		RESTAPI::Protocol::LOGS, | ||||||
|  | 		RESTAPI::Protocol::HEALTHCHECKS, | ||||||
|  | 		RESTAPI::Protocol::STATISTICS, | ||||||
|  | 		RESTAPI::Protocol::STATUS, | ||||||
|  | 		RESTAPI::Protocol::RTTY, | ||||||
|  | 		RESTAPI::Protocol::CONFIGURE, | ||||||
|  | 		RESTAPI::Protocol::UPGRADE, | ||||||
|  | 		RESTAPI::Protocol::REBOOT, | ||||||
|  | 		RESTAPI::Protocol::FACTORY, | ||||||
|  | 		RESTAPI::Protocol::LEDS, | ||||||
|  | 		RESTAPI::Protocol::TRACE, | ||||||
|  | 		RESTAPI::Protocol::REQUEST, | ||||||
|  | 		RESTAPI::Protocol::WIFISCAN, | ||||||
|  | 		RESTAPI::Protocol::EVENTQUEUE, | ||||||
|  | 		RESTAPI::Protocol::TELEMETRY, | ||||||
|  | 		RESTAPI::Protocol::PING, | ||||||
|  | 		RESTAPI::Protocol::SCRIPT}; | ||||||
|  |  | ||||||
|  | 	inline const char * to_string(Commands Cmd) { | ||||||
|  | 		return uCentralAPCommands[(uint8_t)Cmd]; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	inline Commands to_apcommand(const char *cmd) { | ||||||
|  | 		for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) { | ||||||
|  | 			if(strcmp(uCentralAPCommands[i],cmd)==0) | ||||||
|  | 				return (Commands)i; | ||||||
|  | 		} | ||||||
|  | 		return Commands::unknown; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| namespace OpenWifi::Provisioning::DeviceClass { | namespace OpenWifi::Provisioning::DeviceClass { | ||||||
|  |  | ||||||
|     static const char * ANY = "any"; |     static const char * ANY = "any"; | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     bool ApiKeyDB::RemoveAllApiKeys(const std::string & user_uuid) { |     bool ApiKeyDB::RemoveAllApiKeys(const std::string & user_uuid) { | ||||||
|         SecurityObjects::ApiKeyEntryList    Keys; |         SecurityObjects::ApiKeyEntryList    Keys; | ||||||
|         if(StorageService()->ApiKeyDB().GetRecords(0,500,Keys.apiKeys,fmt::format(" userUuid='{} ", user_uuid))) { |         if(StorageService()->ApiKeyDB().GetRecords(0,500,Keys.apiKeys,fmt::format(" userUuid='{}' ", user_uuid))) { | ||||||
|             for(const auto &key:Keys.apiKeys) { |             for(const auto &key:Keys.apiKeys) { | ||||||
|                 AuthService()->RemoveTokenSystemWide(key.apiKey); |                 AuthService()->RemoveTokenSystemWide(key.apiKey); | ||||||
|             } |             } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user