mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-11-03 20:27:45 +00:00 
			
		
		
		
	Compare commits
	
		
			22 Commits
		
	
	
		
			gh-pages
			...
			release/v2
		
	
	| 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. 
 | 
			
		||||
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
 | 
			
		||||
The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port
 | 
			
		||||
access:
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
 | 
			
		||||
images:
 | 
			
		||||
  owsec:
 | 
			
		||||
    repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
 | 
			
		||||
    tag: main
 | 
			
		||||
    tag: v2.8.0
 | 
			
		||||
    pullPolicy: Always
 | 
			
		||||
#    regcred:
 | 
			
		||||
#      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) {
 | 
			
		||||
 | 
			
		||||
            // rule 0
 | 
			
		||||
            if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE)
 | 
			
		||||
            switch(Op) {
 | 
			
		||||
                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;
 | 
			
		||||
 | 
			
		||||
            //  rule 1
 | 
			
		||||
            if(User.id == Target.id && Op==DELETE)
 | 
			
		||||
                        case SecurityObjects::ADMIN:
 | 
			
		||||
                            return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER;
 | 
			
		||||
                        case SecurityObjects::SUBSCRIBER:
 | 
			
		||||
                            return User.id==Target.id;
 | 
			
		||||
                        case SecurityObjects::CSR:
 | 
			
		||||
                            return false;
 | 
			
		||||
 | 
			
		||||
            //  rule 2
 | 
			
		||||
            if(User.userRole==SecurityObjects::ROOT)
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            //  rule 3
 | 
			
		||||
            if(User.id == Target.id)
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            //  rule 4
 | 
			
		||||
            if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
 | 
			
		||||
                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;
 | 
			
		||||
                        case SecurityObjects::SYSTEM:
 | 
			
		||||
                            return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER;
 | 
			
		||||
                        case SecurityObjects::INSTALLER:
 | 
			
		||||
                            return User.id==Target.id;
 | 
			
		||||
                        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 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;
 | 
			
		||||
                        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:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,9 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		field_to_json(Obj,"modified", modified);
 | 
			
		||||
		field_to_json(Obj,"locale", locale);
 | 
			
		||||
		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 {
 | 
			
		||||
@@ -93,6 +95,9 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
			field_from_json(Obj,"entity", entity);
 | 
			
		||||
			field_from_json(Obj,"locale", locale);
 | 
			
		||||
			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;
 | 
			
		||||
		} catch (const Poco::Exception &E) {
 | 
			
		||||
		}
 | 
			
		||||
@@ -394,6 +399,7 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		field_to_json(Obj,"secret",secret);
 | 
			
		||||
		field_to_json(Obj,"certificate",certificate);
 | 
			
		||||
		field_to_json(Obj,"radsec",radsec);
 | 
			
		||||
		field_to_json(Obj,"allowSelfSigned",allowSelfSigned);
 | 
			
		||||
		field_to_json(Obj,"radsecPort",radsecPort);
 | 
			
		||||
		field_to_json(Obj,"radsecSecret",radsecSecret);
 | 
			
		||||
		field_to_json(Obj,"radsecCacerts",radsecCacerts);
 | 
			
		||||
@@ -412,6 +418,7 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
			field_from_json(Obj,"secret",secret);
 | 
			
		||||
			field_from_json(Obj,"certificate",certificate);
 | 
			
		||||
			field_from_json(Obj,"radsec",radsec);
 | 
			
		||||
			field_from_json(Obj,"allowSelfSigned",allowSelfSigned);
 | 
			
		||||
			field_from_json(Obj,"radsecSecret",radsecSecret);
 | 
			
		||||
			field_from_json(Obj,"radsecPort",radsecPort);
 | 
			
		||||
			field_from_json(Obj,"radsecCacerts",radsecCacerts);
 | 
			
		||||
@@ -439,6 +446,7 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		field_to_json(Obj,"restricted", restricted);
 | 
			
		||||
		field_to_json(Obj,"deferred", deferred);
 | 
			
		||||
		field_to_json(Obj,"timeout", timeout);
 | 
			
		||||
		field_to_json(Obj,"defaultUploadURI", defaultUploadURI);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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,"deferred", deferred);
 | 
			
		||||
			field_from_json(Obj,"timeout", timeout);
 | 
			
		||||
			field_from_json(Obj,"defaultUploadURI", defaultUploadURI);
 | 
			
		||||
			return true;
 | 
			
		||||
		} catch (const Poco::Exception &E) {
 | 
			
		||||
		}
 | 
			
		||||
@@ -475,5 +484,64 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		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;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	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 {
 | 
			
		||||
		std::string SerialNumber;
 | 
			
		||||
		std::string DeviceType;
 | 
			
		||||
@@ -71,6 +98,9 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		uint64_t 	modified=0;
 | 
			
		||||
		std::string locale;
 | 
			
		||||
		bool 		restrictedDevice=false;
 | 
			
		||||
		std::string pendingConfiguration;
 | 
			
		||||
		std::string pendingConfigurationCmd;
 | 
			
		||||
		DeviceRestrictions	restrictionDetails;
 | 
			
		||||
 | 
			
		||||
		void to_json(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;
 | 
			
		||||
		bool				deferred=false;
 | 
			
		||||
		std::uint64_t 		timeout=30;
 | 
			
		||||
		std::string 		defaultUploadURI;
 | 
			
		||||
 | 
			
		||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
			
		||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
			
		||||
@@ -265,6 +296,7 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		std::string secret;
 | 
			
		||||
		std::string certificate;
 | 
			
		||||
		bool 		radsec=false;
 | 
			
		||||
		bool 		allowSelfSigned=false;
 | 
			
		||||
		uint16_t 	radsecPort=2083;
 | 
			
		||||
		std::string radsecSecret;
 | 
			
		||||
		std::string radsecKey;
 | 
			
		||||
@@ -306,4 +338,5 @@ namespace OpenWifi::GWObjects {
 | 
			
		||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
			
		||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,13 @@ namespace OpenWifi {
 | 
			
		||||
            poco_information(Logger(),"Starting...");
 | 
			
		||||
			Running_=true;
 | 
			
		||||
			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;
 | 
			
		||||
			Params->setName("ws:alb");
 | 
			
		||||
			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
 | 
			
		||||
 
 | 
			
		||||
@@ -19,10 +19,9 @@
 | 
			
		||||
namespace OpenWifi {
 | 
			
		||||
 | 
			
		||||
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"(
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    "$id": "https://openwrt.org/ucentral.schema.json",
 | 
			
		||||
    "$schema": "http://json-schema.org/draft-07/schema#",
 | 
			
		||||
@@ -49,7 +48,7 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
        "switch": {
 | 
			
		||||
            "$ref": "#/$defs/switch"
 | 
			
		||||
        },
 | 
			
		||||
		"radiosgrep": {
 | 
			
		||||
        "radios": {
 | 
			
		||||
            "type": "array",
 | 
			
		||||
            "items": {
 | 
			
		||||
                "$ref": "#/$defs/radio"
 | 
			
		||||
@@ -201,7 +200,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                "wireless-multimedia": {
 | 
			
		||||
					"anyOf": [{
 | 
			
		||||
                    "anyOf": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "$ref": "#/$defs/globals.wireless-multimedia.table"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
@@ -395,7 +395,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                "channel": {
 | 
			
		||||
					"oneOf": [{
 | 
			
		||||
                    "oneOf": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "type": "integer",
 | 
			
		||||
                            "maximum": 196,
 | 
			
		||||
                            "minimum": 1
 | 
			
		||||
@@ -1004,7 +1005,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "interface.broad-band": {
 | 
			
		||||
			"oneOf": [{
 | 
			
		||||
            "oneOf": [
 | 
			
		||||
                {
 | 
			
		||||
                    "$ref": "#/$defs/interface.broad-band.wwan"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
@@ -1261,7 +1263,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                                "minimum": 1
 | 
			
		||||
                            },
 | 
			
		||||
                            "value": {
 | 
			
		||||
								"anyOf": [{
 | 
			
		||||
                                "anyOf": [
 | 
			
		||||
                                    {
 | 
			
		||||
                                        "type": "integer",
 | 
			
		||||
                                        "maximum": 4294967295,
 | 
			
		||||
                                        "minimum": 0
 | 
			
		||||
@@ -1272,7 +1275,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                                ]
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
						"examples": [{
 | 
			
		||||
                        "examples": [
 | 
			
		||||
                            {
 | 
			
		||||
                                "id": 27,
 | 
			
		||||
                                "value": 900
 | 
			
		||||
                            },
 | 
			
		||||
@@ -1336,7 +1340,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                "authentication": {
 | 
			
		||||
					"allOf": [{
 | 
			
		||||
                    "allOf": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "$ref": "#/$defs/interface.ssid.radius.server"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
@@ -1351,7 +1356,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                "accounting": {
 | 
			
		||||
					"allOf": [{
 | 
			
		||||
                    "allOf": [
 | 
			
		||||
                        {
 | 
			
		||||
                            "$ref": "#/$defs/interface.ssid.radius.server"
 | 
			
		||||
                        },
 | 
			
		||||
                        {
 | 
			
		||||
@@ -1554,13 +1560,15 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
                                ]
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
						"examples": [{
 | 
			
		||||
                        "examples": [
 | 
			
		||||
                            {
 | 
			
		||||
                                "width": 32,
 | 
			
		||||
                                "height": 32,
 | 
			
		||||
                                "type": "image/png",
 | 
			
		||||
                                "language": "eng",
 | 
			
		||||
                                "icon": "R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
 | 
			
		||||
						}]
 | 
			
		||||
                            }
 | 
			
		||||
                        ]
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                "wan-metrics": {
 | 
			
		||||
@@ -1806,7 +1814,8 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "interface.tunnel": {
 | 
			
		||||
			"oneOf": [{
 | 
			
		||||
            "oneOf": [
 | 
			
		||||
                {
 | 
			
		||||
                    "$ref": "#/$defs/interface.tunnel.mesh"
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
@@ -2630,12 +2639,12 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        std::string GitSchema;
 | 
			
		||||
		if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) {
 | 
			
		||||
		// if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) {
 | 
			
		||||
			RootSchema_ = DefaultUCentralSchema;
 | 
			
		||||
			poco_information(Logger(),"Using uCentral validation from built-in default.");
 | 
			
		||||
			Initialized_ = Working_ = true;
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
			auto GitURI = MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
 | 
			
		||||
@@ -2749,7 +2758,7 @@ static json DefaultUCentralSchema = R"(
 | 
			
		||||
            if(std::regex_match(value,host_regex))
 | 
			
		||||
                return;
 | 
			
		||||
            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))
 | 
			
		||||
                return;
 | 
			
		||||
            throw std::invalid_argument(value + " is not a proper FQDN.");
 | 
			
		||||
 
 | 
			
		||||
@@ -102,6 +102,48 @@ namespace OpenWifi {
 | 
			
		||||
													  E.displayText(),
 | 
			
		||||
													  E.message(),
 | 
			
		||||
													  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) {
 | 
			
		||||
				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
			
		||||
													  t_name, t_id, E.code(),
 | 
			
		||||
 
 | 
			
		||||
@@ -633,6 +633,18 @@ namespace OpenWifi {
 | 
			
		||||
			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_; }
 | 
			
		||||
 | 
			
		||||
		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) {
 | 
			
		||||
		std::lock_guard G(Mutex_);
 | 
			
		||||
		std::lock_guard G(LocalMutex_);
 | 
			
		||||
 | 
			
		||||
		for(const auto &Client:Clients_) {
 | 
			
		||||
			if(Client.second->UserName_ == UserName) {
 | 
			
		||||
@@ -139,7 +139,7 @@ namespace OpenWifi {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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_) {
 | 
			
		||||
			try {
 | 
			
		||||
@@ -189,7 +189,6 @@ namespace OpenWifi {
 | 
			
		||||
	void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
 | 
			
		||||
 | 
			
		||||
        UI_WebSocketClientServer::ClientList::iterator Client;
 | 
			
		||||
 | 
			
		||||
        std::lock_guard     G(LocalMutex_);
 | 
			
		||||
 | 
			
		||||
		try {
 | 
			
		||||
@@ -295,6 +294,7 @@ namespace OpenWifi {
 | 
			
		||||
 | 
			
		||||
	void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
 | 
			
		||||
        try {
 | 
			
		||||
			std::lock_guard     G(LocalMutex_);
 | 
			
		||||
			auto Client = Clients_.find(pNf->socket().impl()->sockfd());
 | 
			
		||||
            if (Client == end(Clients_))
 | 
			
		||||
                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 InvalidURI{1152,"Invalid URI."};
 | 
			
		||||
	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 {
 | 
			
		||||
 | 
			
		||||
    static const char * ANY = "any";
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ namespace OpenWifi {
 | 
			
		||||
 | 
			
		||||
    bool ApiKeyDB::RemoveAllApiKeys(const std::string & user_uuid) {
 | 
			
		||||
        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) {
 | 
			
		||||
                AuthService()->RemoveTokenSystemWide(key.apiKey);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user