mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-29 18:02:29 +00:00
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
This commit is contained in:
@@ -1983,9 +1983,19 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: all
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/SystemSecretEntry'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemSecretEntry'
|
||||
- $ref: '#/components/schemas/SystemSecretEntryList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "TotpCache.h"
|
||||
#include "framework/RESTAPI_RateLimiter.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include <SecretStore.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
@@ -47,7 +48,8 @@ namespace OpenWifi {
|
||||
RESTAPI_RateLimiter(),
|
||||
TotpCache(),
|
||||
AuthService(),
|
||||
UI_WebSocketClientServer()
|
||||
UI_WebSocketClientServer(),
|
||||
SecretStore()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_systemSecret_handler.h"
|
||||
#include <SecretStore.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -10,6 +11,35 @@ namespace OpenWifi {
|
||||
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
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() {
|
||||
@@ -17,6 +47,14 @@ namespace OpenWifi {
|
||||
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() {
|
||||
@@ -24,6 +62,17 @@ namespace OpenWifi {
|
||||
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
|
||||
@@ -2,15 +2,91 @@
|
||||
// Created by stephane bourque on 2023-01-25.
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
#include "SecretStore.h"
|
||||
#include <framework/MicroServiceFuncs.h>
|
||||
#include <Poco/File.h>
|
||||
#include <Poco/JSON/Parser.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int SecretStore::Start() {
|
||||
std::lock_guard G(Mutex_);
|
||||
ReadStore();
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -10,6 +10,8 @@ namespace OpenWifi {
|
||||
|
||||
class SecretStore : public SubSystemServer {
|
||||
public:
|
||||
|
||||
using SecretStoreType = std::map<std::string,std::string>;
|
||||
static SecretStore *instance() {
|
||||
static auto *instance_ = new SecretStore;
|
||||
return instance_;
|
||||
@@ -17,9 +19,18 @@ namespace OpenWifi {
|
||||
|
||||
int Start() 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:
|
||||
|
||||
SecretStoreType Store_;
|
||||
SecretStore() noexcept:
|
||||
SubSystemServer("SecretStore", "SECRET-SVR", "secret.store")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user