diff --git a/CMakeLists.txt b/CMakeLists.txt index ec1cc74..983d7d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,7 +209,7 @@ add_executable(owprov src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h - src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h) + src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h src/OpenRoamin_GlobalReach.cpp src/OpenRoamin_GlobalReach.h src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h src/storage/storage_orion_accounts.cpp src/storage/storage_orion_accounts.h) target_link_libraries(owprov PUBLIC ${Poco_LIBRARIES} diff --git a/build b/build index cabf43b..d99e90e 100644 --- a/build +++ b/build @@ -1 +1 @@ -24 \ No newline at end of file +29 \ No newline at end of file diff --git a/openapi/openroaming_orion.yaml b/openapi/openroaming_orion.yaml index 847bf7e..d2cb132 100644 --- a/openapi/openroaming_orion.yaml +++ b/openapi/openroaming_orion.yaml @@ -94,7 +94,7 @@ paths: 404: $ref: '#/components/responses/NotFound' - /openroaming/globalreach/account/{name}: + /openroaming/globalreach/account/{id}: get: tags: - OpenRoaming-Google Orion diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp index 7150e06..b985f1a 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp @@ -3,6 +3,98 @@ // #include "RESTAPI_openroaming_orion_acct_handler.h" +#include "OpenRoamin_GlobalReach.h" namespace OpenWifi { + + void RESTAPI_openroaming_orion_acct_handler::DoGet() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GooglOrionAccountInfo Record; + if(DB_.GetRecord("id",Account,Record)) { + return ReturnObject(Record); + } + return NotFound(); + } + + void RESTAPI_openroaming_orion_acct_handler::DoDelete() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + ProvObjects::GooglOrionAccountInfo Record; + if(!DB_.GetRecord("id",Account,Record)) { + return NotFound(); + } + DB_.DeleteRecord("id", Account); + return OK(); + } + + void RESTAPI_openroaming_orion_acct_handler::DoPost() { + auto Account = GetBinding("id",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GooglOrionAccountInfo NewObject; + if( !NewObject.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if( NewObject.privateKey.empty() || + NewObject.certificate.empty() || + NewObject.cacerts.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + if( !Utils::VerifyRSAKey(NewObject.privateKey) || + !Utils::ValidX509Certificate(NewObject.certificate) || + !Utils::ValidX509Certificate(NewObject.cacerts)) { + return BadRequest(RESTAPI::Errors::NotAValidECKey); + } + + ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info); + + if(DB_.CreateRecord(NewObject)) { + ProvObjects::GooglOrionAccountInfo StoredObject; + DB_.GetRecord("id",NewObject.info.id,StoredObject); + return ReturnObject(StoredObject); + } + return BadRequest(RESTAPI::Errors::RecordNotCreated); + } + + void RESTAPI_openroaming_orion_acct_handler::DoPut() { + auto Account = GetBinding("account",""); + if(Account.empty()) { + return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); + } + + const auto &RawObject = ParsedBody_; + ProvObjects::GLBLRAccountInfo Modify; + if(!Modify.from_json(RawObject)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + ProvObjects::GooglOrionAccountInfo Existing; + if(!DB_.GetRecord("id",Account,Existing)) { + return NotFound(); + } + + if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) { + return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument); + } + + if(DB_.UpdateRecord("id",Existing.info.id,Existing)) { + ProvObjects::GooglOrionAccountInfo StoredObject; + DB_.GetRecord("id",Existing.info.id,StoredObject); + return ReturnObject(StoredObject); + } + return BadRequest(RESTAPI::Errors::RecordNotUpdated); + } + } // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h index ebdb31d..a896b2b 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h @@ -2,15 +2,29 @@ // Created by stephane bourque on 2023-09-15. // -#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H -#define OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { + class RESTAPI_openroaming_orion_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_orion_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_DELETE, + Poco::Net::HTTPRequest::HTTP_POST, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/orion/account/{id}"}; }; - class RESTAPI_openroaming_orion_acct_handler { - + private: + OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB(); + void DoGet() final; + void DoPost() final; + void DoPut() final; + void DoDelete() final; }; - -} // OpenWifi - -#endif //OWPROV_RESTAPI_OPENROAMING_ORION_ACCT_HANDLER_H +} // namespace OpenWifi diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp index e15682d..3041d33 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp @@ -4,5 +4,18 @@ #include "RESTAPI_openroaming_orion_list_acct_handler.h" + namespace OpenWifi { + + void RESTAPI_openroaming_orion_list_acct_handler::DoGet() { + + if(GetBoolParameter("countOnly")) { + return ReturnCountOnly(DB_.Count()); + } + + std::vector Accounts; + DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts); + return ReturnObject(Accounts); + } + } // OpenWifi \ No newline at end of file diff --git a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h index 99b7f5c..864a69b 100644 --- a/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h +++ b/src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h @@ -2,15 +2,28 @@ // Created by stephane bourque on 2023-09-15. // -#ifndef OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H -#define OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H +#pragma once +#include "StorageService.h" +#include "framework/RESTAPI_Handler.h" namespace OpenWifi { + class RESTAPI_openroaming_orion_list_acct_handler : public RESTAPIHandler { + public: + RESTAPI_openroaming_orion_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, + RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, + bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, TransactionId, Internal) {} + static auto PathName() { return std::list{"/api/v1/openroaming/orion/accounts"}; }; - class RESTAPI_openroaming_orion_list_acct_handler { - + private: + OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB(); + void DoGet() final; + void DoPost() final{}; + void DoPut() final{}; + void DoDelete() final{}; }; +} // namespace OpenWifi -} // OpenWifi - -#endif //OWPROV_RESTAPI_OPENROAMING_ORION_LIST_ACCT_HANDLER_H diff --git a/src/StorageService.cpp b/src/StorageService.cpp index 1a1e193..cfd1b23 100644 --- a/src/StorageService.cpp +++ b/src/StorageService.cpp @@ -41,6 +41,7 @@ namespace OpenWifi { OverridesDB_ = std::make_unique(dbType_, *Pool_, Logger()); GLBLRAccountInfoDB_ = std::make_unique(dbType_, *Pool_, Logger()); GLBLRCertsDB_ = std::make_unique(dbType_, *Pool_, Logger()); + OrionAccountsDB_ = std::make_unique(dbType_, *Pool_, Logger()); EntityDB_->Create(); PolicyDB_->Create(); @@ -63,6 +64,7 @@ namespace OpenWifi { OverridesDB_->Create(); GLBLRAccountInfoDB_->Create(); GLBLRCertsDB_->Create(); + OrionAccountsDB_->Create(); ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return EntityDB_->Exists(F, V); @@ -127,10 +129,13 @@ namespace OpenWifi { ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { return GLBLRCertsDB_->Exists(F, V); }; + ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool { + return OrionAccountsDB_->Exists(F, V); + }; - ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, + ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name, std::string &Description) -> bool { return EntityDB_->GetNameAndDescription(F, V, Name, Description); }; @@ -218,7 +223,6 @@ namespace OpenWifi { [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; - ExpandFunc_[GLBLRAccountInfoDB_->Prefix()] = [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, @@ -227,14 +231,16 @@ namespace OpenWifi { [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; - ExpandFunc_[GLBLRCertsDB_->Prefix()] = [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, [[maybe_unused]] std::string &Name, [[maybe_unused]] std::string &Description) -> bool { return false; }; + ExpandFunc_[OrionAccountsDB_->Prefix()] = + [=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V, + [[maybe_unused]] std::string &Name, + [[maybe_unused]] std::string &Description) -> bool { return false; }; - InventoryDB_->InitializeSerialCache(); - + InventoryDB_->InitializeSerialCache(); ConsistencyCheck(); InitializeSystemDBs(); diff --git a/src/StorageService.h b/src/StorageService.h index adafaa8..0de189f 100644 --- a/src/StorageService.h +++ b/src/StorageService.h @@ -30,6 +30,7 @@ #include "storage/storage_venue.h" #include "storage/storage_glblraccounts.h" #include "storage/storage_glblrcerts.h" +#include "storage/storage_orion_accounts.h" #include "Poco/URI.h" #include "framework/ow_constants.h" @@ -70,6 +71,7 @@ namespace OpenWifi { inline OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; }; inline OpenWifi::GLBLRAccountInfoDB &GLBLRAccountInfoDB() { return *GLBLRAccountInfoDB_; } inline OpenWifi::GLBLRCertsDB &GLBLRCertsDB() { return *GLBLRCertsDB_; } + inline OpenWifi::OrionAccountsDB &OrionAccountsDB() { return *OrionAccountsDB_; } bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error); bool Validate(const Types::StringVec &P, std::string &Error); @@ -131,6 +133,7 @@ namespace OpenWifi { std::unique_ptr OverridesDB_; std::unique_ptr GLBLRAccountInfoDB_; std::unique_ptr GLBLRCertsDB_; + std::unique_ptr OrionAccountsDB_; std::string DefaultOperator_; typedef std::function exist_func; diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 65ed7a3..370ab40 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -417,6 +417,8 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg NotAValidECKey { 1176, "Not a valid Signing Key." }; + static const struct msg NotAValidRadiusPoolType { 1177, "Not a valid RADIUS pool type." }; + static const struct msg SimulationDoesNotExist { 7000, "Simulation Instance ID does not exist." }; diff --git a/src/framework/utils.cpp b/src/framework/utils.cpp index b4486ba..6c34cdb 100644 --- a/src/framework/utils.cpp +++ b/src/framework/utils.cpp @@ -8,6 +8,12 @@ #include "framework/AppServiceRegistry.h" #include "framework/utils.h" +#include +#include +#include +#include +#include + namespace OpenWifi::Utils { bool NormalizeMac(std::string &Mac) { @@ -759,4 +765,101 @@ namespace OpenWifi::Utils { return false; } + bool VerifyRSAKey([[ + maybe_unused]] const std::string &key) { + try { + Poco::TemporaryFile F; + + std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + of << key; + of.close(); + + auto Key = Poco::SharedPtr( + new Poco::Crypto::RSAKey("", F.path(),"")); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + bool ValidX509Certificate([[ + maybe_unused]] const std::string &Cert) { + try { + Poco::TemporaryFile F; + std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary); + of << Cert; + of.close(); + + auto Key = Poco::SharedPtr( + new Poco::Crypto::X509Certificate(F.path())); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + } + + bool ValidX509Certificate([[ + maybe_unused]] const std::vector &Certs) { + auto F = [](const std::string &C) -> bool { return ValidX509Certificate(C); }; + return std::all_of(Certs.begin(),Certs.end(), F); + } + + std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase) { + // Define character sets for each category + const std::string lowercaseChars = "abcdefghijklmnopqrstuvwxyz"; + const std::string uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const std::string digitChars = "0123456789"; + const std::string specialChars = "!@#$%^&*()_+[]{}|;:,.<>?"; + + // Check if parameters are valid + if (minLength < 1 || minLength > maxLength || minLowercase + minUppercase + numDigits + minSpecial > maxLength) { + return "Invalid parameters"; + } + + // Initialize random seed + std::random_device rd; + std::mt19937 g(rd()); + + // Initialize the password string + std::string password; + + // Generate the required number of each character type + for (int i = 0; i < minLowercase; ++i) { + password += lowercaseChars[g() % lowercaseChars.length()]; + } + for (int i = 0; i < minUppercase; ++i) { + password += uppercaseChars[g() % uppercaseChars.length()]; + } + for (int i = 0; i < numDigits; ++i) { + password += digitChars[g() % digitChars.length()]; + } + for (int i = 0; i < minSpecial; ++i) { + password += specialChars[g() % specialChars.length()]; + } + + // Calculate how many more characters are needed + int remainingLength = maxLength - (int)password.length(); + + // Generate random characters to fill the remaining length + for (int i = 0; i < remainingLength; ++i) { + int category = g() % 4; // Randomly select a category + if (category == 0) { + password += lowercaseChars[g() % lowercaseChars.length()]; + } else if (category == 1) { + password += uppercaseChars[g() % uppercaseChars.length()]; + } else if (category == 2) { + password += digitChars[g() % digitChars.length()]; + } else { + password += specialChars[g() % specialChars.length()]; + } + } + + // Shuffle the password to randomize the character order + std::shuffle(password.begin(), password.end(),g); + + return password; + } + } // namespace OpenWifi::Utils diff --git a/src/framework/utils.h b/src/framework/utils.h index 9a9c939..cf708bd 100644 --- a/src/framework/utils.h +++ b/src/framework/utils.h @@ -258,6 +258,10 @@ namespace OpenWifi::Utils { }; bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results); - + std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase); bool VerifyECKey(const std::string &key); + bool VerifyRSAKey(const std::string &key); + bool ValidX509Certificate(const std::string &Cert); + bool ValidX509Certificate(const std::vector &Certs); + } // namespace OpenWifi::Utils diff --git a/src/storage/storage_orion_accounts.cpp b/src/storage/storage_orion_accounts.cpp new file mode 100644 index 0000000..1f548fb --- /dev/null +++ b/src/storage/storage_orion_accounts.cpp @@ -0,0 +1,76 @@ +// +// Created by stephane bourque on 2023-09-17. +// + +#include "storage_orion_accounts.h" +#include +#include "framework/OpenWifiTypes.h" +#include "framework/RESTAPI_utils.h" + +#include "RESTObjects/RESTAPI_SecurityObjects.h" + +namespace OpenWifi { + + static ORM::FieldVec OrionAccountsDB_Fields{ + ORM::Field{"id", 64, true}, + ORM::Field{"name", ORM::FieldType::FT_TEXT}, + ORM::Field{"description", ORM::FieldType::FT_TEXT}, + ORM::Field{"notes", ORM::FieldType::FT_TEXT}, + ORM::Field{"created", ORM::FieldType::FT_BIGINT}, + ORM::Field{"modified", ORM::FieldType::FT_BIGINT}, + ORM::Field{"privateKey", ORM::FieldType::FT_TEXT}, + ORM::Field{"certificate", ORM::FieldType::FT_TEXT}, + ORM::Field{"cacerts", ORM::FieldType::FT_TEXT} + }; + + static ORM::IndexVec OrionAccountsDB_Indexes{ + {std::string("orion_name_index"), + ORM::IndexEntryVec{{std::string("name"), ORM::Indextype::ASC}}}}; + + OrionAccountsDB::OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L) + : DB(T, "orion_accts", OrionAccountsDB_Fields, OrionAccountsDB_Indexes, P, L, "oat") {} + + bool OrionAccountsDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { + to = Version(); + std::vector Script{}; + + for (const auto &i : Script) { + try { + auto Session = Pool_.get(); + Session << i, Poco::Data::Keywords::now; + } catch (...) { + } + } + return true; + } + +} // namespace OpenWifi + +template <> +void ORM::DB::Convert( + const OpenWifi::OrionAccountsDBRecordType &In, OpenWifi::ProvObjects::GooglOrionAccountInfo &Out) { + Out.info.id = In.get<0>(); + Out.info.name = In.get<1>(); + Out.info.description = In.get<2>(); + Out.info.notes = + OpenWifi::RESTAPI_utils::to_object_array(In.get<3>()); + Out.info.created = In.get<4>(); + Out.info.modified = In.get<5>(); + Out.privateKey =In.get<6>(); + Out.certificate = In.get<7>(); + Out.cacerts = OpenWifi::RESTAPI_utils::to_object_array(In.get<8>()); +} + +template <> +void ORM::DB::Convert( + const OpenWifi::ProvObjects::GooglOrionAccountInfo &In, OpenWifi::OrionAccountsDBRecordType &Out) { + Out.set<0>(In.info.id); + Out.set<1>(In.info.name); + Out.set<2>(In.info.description); + Out.set<3>(OpenWifi::RESTAPI_utils::to_string(In.info.notes)); + Out.set<4>(In.info.created); + Out.set<5>(In.info.modified); + Out.set<6>(In.privateKey); + Out.set<7>(In.certificate); + Out.set<8>(OpenWifi::RESTAPI_utils::to_string(In.cacerts)); +} diff --git a/src/storage/storage_orion_accounts.h b/src/storage/storage_orion_accounts.h new file mode 100644 index 0000000..937d15c --- /dev/null +++ b/src/storage/storage_orion_accounts.h @@ -0,0 +1,32 @@ +// +// Created by stephane bourque on 2023-09-17. +// + +#pragma once + +#include "RESTObjects/RESTAPI_ProvObjects.h" +#include "framework/orm.h" + +namespace OpenWifi { + + typedef Poco::Tuple + OrionAccountsDBRecordType; + + class OrionAccountsDB : public ORM::DB { + public: + OrionAccountsDB(OpenWifi::DBType T, Poco::Data::SessionPool &P, Poco::Logger &L); + virtual ~OrionAccountsDB(){}; + bool Upgrade(uint32_t from, uint32_t &to) override; + private: + + }; + +} // namespace OpenWifi