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