mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-30 18:27:49 +00:00 
			
		
		
		
	Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
This commit is contained in:
		| @@ -1983,9 +1983,19 @@ paths: | |||||||
|           schema: |           schema: | ||||||
|             type: string |             type: string | ||||||
|           required: true |           required: true | ||||||
|  |         - in: query | ||||||
|  |           name: all | ||||||
|  |           schema: | ||||||
|  |             type: boolean | ||||||
|  |           required: false | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           $ref: '#/components/schemas/SystemSecretEntry' |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 oneOf: | ||||||
|  |                   - $ref: '#/components/schemas/SystemSecretEntry' | ||||||
|  |                   - $ref: '#/components/schemas/SystemSecretEntryList' | ||||||
|         403: |         403: | ||||||
|           $ref: '#/components/responses/Unauthorized' |           $ref: '#/components/responses/Unauthorized' | ||||||
|         404: |         404: | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ | |||||||
| #include "TotpCache.h" | #include "TotpCache.h" | ||||||
| #include "framework/RESTAPI_RateLimiter.h" | #include "framework/RESTAPI_RateLimiter.h" | ||||||
| #include "framework/UI_WebSocketClientServer.h" | #include "framework/UI_WebSocketClientServer.h" | ||||||
|  | #include <SecretStore.h> | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class Daemon *Daemon::instance_ = nullptr; |     class Daemon *Daemon::instance_ = nullptr; | ||||||
| @@ -47,7 +48,8 @@ namespace OpenWifi { | |||||||
|                                            RESTAPI_RateLimiter(), |                                            RESTAPI_RateLimiter(), | ||||||
|                                            TotpCache(), |                                            TotpCache(), | ||||||
|                                            AuthService(), |                                            AuthService(), | ||||||
|                                            UI_WebSocketClientServer() |                                            UI_WebSocketClientServer(), | ||||||
|  |                                            SecretStore() | ||||||
|                                    }); |                                    }); | ||||||
|         } |         } | ||||||
|         return instance_; |         return instance_; | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_systemSecret_handler.h" | #include "RESTAPI_systemSecret_handler.h" | ||||||
|  | #include <SecretStore.h> | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -10,6 +11,35 @@ namespace OpenWifi { | |||||||
|         if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { |         if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if(GetBoolParameter("all")) { | ||||||
|  |             auto Store = SecretStore()->Store(); | ||||||
|  |             Poco::JSON::Array   Entries; | ||||||
|  |             Poco::JSON::Object  List; | ||||||
|  |  | ||||||
|  |             for(const auto &[Key,Value]:Store) { | ||||||
|  |                 Poco::JSON::Object  E; | ||||||
|  |                 E.set("key",Key); | ||||||
|  |                 E.set("value",Value); | ||||||
|  |                 Entries.add(E); | ||||||
|  |             } | ||||||
|  |             List.set("secrets",Entries); | ||||||
|  |             return ReturnObject(List); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         auto Key = GetBinding("secret"); | ||||||
|  |         if(Key.empty()) { | ||||||
|  |             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         std::string Value; | ||||||
|  |         if(SecretStore()->Get(Key,Value,"")) { | ||||||
|  |             Poco::JSON::Object  Answer; | ||||||
|  |             Answer.set("key", Key); | ||||||
|  |             Answer.set("value", Value); | ||||||
|  |             return ReturnObject(Answer); | ||||||
|  |         } | ||||||
|  |         return NotFound(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_systemSecret_handler::DoDelete() { |     void RESTAPI_systemSecret_handler::DoDelete() { | ||||||
| @@ -17,6 +47,14 @@ namespace OpenWifi { | |||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         auto Key = GetBinding("secret"); | ||||||
|  |         if(Key.empty()) { | ||||||
|  |             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         SecretStore()->Remove(Key); | ||||||
|  |         return OK(); | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_systemSecret_handler::DoPut() { |     void RESTAPI_systemSecret_handler::DoPut() { | ||||||
| @@ -24,6 +62,17 @@ namespace OpenWifi { | |||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         auto Key = GetBinding("secret"); | ||||||
|  |         auto Value = GetParameter("value","_______no_value_____"); | ||||||
|  |         if(Key.empty() || Value == "_______no_value_____") { | ||||||
|  |             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         SecretStore()->Set(Key,Value); | ||||||
|  |         Poco::JSON::Object  Answer; | ||||||
|  |         Answer.set("key", Key); | ||||||
|  |         Answer.set("value", Value); | ||||||
|  |         return ReturnObject(Answer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // OpenWifi | } // OpenWifi | ||||||
| @@ -2,15 +2,91 @@ | |||||||
| // Created by stephane bourque on 2023-01-25. | // Created by stephane bourque on 2023-01-25. | ||||||
| // | // | ||||||
|  |  | ||||||
|  | #include <fstream> | ||||||
| #include "SecretStore.h" | #include "SecretStore.h" | ||||||
|  | #include <framework/MicroServiceFuncs.h> | ||||||
|  | #include <Poco/File.h> | ||||||
|  | #include <Poco/JSON/Parser.h> | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     int SecretStore::Start() { |     int SecretStore::Start() { | ||||||
|  |         std::lock_guard G(Mutex_); | ||||||
|  |         ReadStore(); | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void SecretStore::Stop() { |     void SecretStore::Stop() { | ||||||
|  |         std::lock_guard G(Mutex_); | ||||||
|  |         SaveStore(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SecretStore::ReadStore() { | ||||||
|  |         Poco::File  StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); | ||||||
|  |         if(StoreFileName.exists() && StoreFileName.isFile()) { | ||||||
|  |             try { | ||||||
|  |                 std::ostringstream  OS; | ||||||
|  |                 std::ifstream       IF(StoreFileName.path().c_str()); | ||||||
|  |                 Poco::StreamCopier::copyStream(IF, OS); | ||||||
|  |                 Poco::JSON::Parser  P; | ||||||
|  |                 auto Doc = P.parse(OS.str()).extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |                 if(Doc->isArray("secrets")) { | ||||||
|  |                     auto Secrets = Doc->getArray("secrets"); | ||||||
|  |                     for(const auto &secret:*Secrets) { | ||||||
|  |                         const auto &entry = secret.extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |                         if(entry->has("key") && entry->has("value")) { | ||||||
|  |                             Store_[entry->get("key")] = entry->get("value").toString(); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } catch (const Poco::Exception &E) { | ||||||
|  |                 Logger().log(E); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SecretStore::SaveStore() { | ||||||
|  |         Poco::JSON::Object  StoreJSON; | ||||||
|  |         Poco::JSON::Array   Secrets; | ||||||
|  |  | ||||||
|  |         for(const auto &[key,value]:Store_) { | ||||||
|  |             Poco::JSON::Object  Entry; | ||||||
|  |             Entry.set("key", key); | ||||||
|  |             Entry.set("value", value); | ||||||
|  |             Secrets.add(Entry); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         StoreJSON.set("secrets",Secrets); | ||||||
|  |         Poco::File  StoreFileName(MicroServiceDataDirectory() + "/secrets.json"); | ||||||
|  |         std::ofstream   OF(StoreFileName.path(),std::ios_base::trunc); | ||||||
|  |         StoreJSON.stringify(OF); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool SecretStore::Get(const std::string & key, std::string & value, const std::string & default_value) { | ||||||
|  |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|  |         auto It = Store_.find(key); | ||||||
|  |         if(It!=end(Store_)) { | ||||||
|  |             value = It->second; | ||||||
|  |             return true; | ||||||
|  |         } else { | ||||||
|  |             value = default_value; | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SecretStore::Set(const std::string & key, const std::string & value ) { | ||||||
|  |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|  |         Store_[key] = value; | ||||||
|  |         SaveStore(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void SecretStore::Remove(const std::string & key) { | ||||||
|  |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|  |         Store_.erase(key); | ||||||
|  |         SaveStore(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // OpenWifi | } // OpenWifi | ||||||
| @@ -10,6 +10,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class SecretStore : public SubSystemServer { |     class SecretStore : public SubSystemServer { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|  |         using SecretStoreType = std::map<std::string,std::string>; | ||||||
|         static SecretStore *instance() { |         static SecretStore *instance() { | ||||||
|             static auto *instance_ = new SecretStore; |             static auto *instance_ = new SecretStore; | ||||||
|             return instance_; |             return instance_; | ||||||
| @@ -17,9 +19,18 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         int  Start() final; |         int  Start() final; | ||||||
|         void Stop() final; |         void Stop() final; | ||||||
|  |         void ReadStore(); | ||||||
|  |         void SaveStore(); | ||||||
|  |         bool Get(const std::string & key, std::string & value, const std::string & default_value); | ||||||
|  |         void Set(const std::string & key, const std::string & value ); | ||||||
|  |         void Remove(const std::string &key); | ||||||
|  |         inline SecretStoreType Store() { | ||||||
|  |             std::lock_guard G(Mutex_); | ||||||
|  |             return Store_; | ||||||
|  |         } | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |         SecretStoreType   Store_; | ||||||
|         SecretStore() noexcept: |         SecretStore() noexcept: | ||||||
|                 SubSystemServer("SecretStore", "SECRET-SVR", "secret.store") |                 SubSystemServer("SecretStore", "SECRET-SVR", "secret.store") | ||||||
|         { |         { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 stephb9959
					stephb9959