diff --git a/microservice_sample/set_env.sh b/microservice_sample/set_env.sh new file mode 100755 index 0000000..87497be --- /dev/null +++ b/microservice_sample/set_env.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +export OWHELLOW_CONFIG=`pwd` +export OWHELLOW_ROOT=`pwd` diff --git a/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.cpp b/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.cpp new file mode 100644 index 0000000..ba6996e --- /dev/null +++ b/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.cpp @@ -0,0 +1,19 @@ +// +// Created by stephane bourque on 2021-11-29. +// + +#include "RESTAPI_helloWorld_handler.h" + +namespace OpenWifi { + + void RESTAPI_helloWorld_handler::DoGet() { + Poco::JSON::Object Answer; + + Answer.set("response","World!"); + Answer.set("From", UserInfo_.userinfo.email); + Answer.set("time", std::time(nullptr)); + + return ReturnObject(Answer); + } + +} \ No newline at end of file diff --git a/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.h b/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.h new file mode 100644 index 0000000..8ade9de --- /dev/null +++ b/microservice_sample/src/RESTAPI/RESTAPI_helloWorld_handler.h @@ -0,0 +1,26 @@ +// +// Created by stephane bourque on 2021-11-29. +// + +#pragma once + +#include "framework/MicroService.h" + +namespace OpenWifi { + class RESTAPI_helloWorld_handler : public RESTAPIHandler { + public: + RESTAPI_helloWorld_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, bool Internal) + : RESTAPIHandler(bindings, L, + std::vector{ + Poco::Net::HTTPRequest::HTTP_GET, + Poco::Net::HTTPRequest::HTTP_OPTIONS}, + Server, + Internal) {} + static const std::list PathName() { return std::list{"/api/v1/hello"}; }; + + void DoGet() final; + void DoPost() final {}; + void DoPut() final {}; + void DoDelete() final {}; + }; +} diff --git a/microservice_sample/src/RESTObjects/RESTAPI_GWobjects.h b/microservice_sample/src/RESTObjects/RESTAPI_GWobjects.h new file mode 100644 index 0000000..5485357 --- /dev/null +++ b/microservice_sample/src/RESTObjects/RESTAPI_GWobjects.h @@ -0,0 +1,192 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#pragma once + +#include "Poco/JSON/Object.h" +#include "RESTAPI_SecurityObjects.h" + +namespace OpenWifi::GWObjects { + + enum CertificateValidation { + NO_CERTIFICATE, + VALID_CERTIFICATE, + MISMATCH_SERIAL, + VERIFIED + }; + + struct ConnectionState { + uint64_t MessageCount = 0 ; + std::string SerialNumber; + std::string Address; + uint64_t UUID = 0 ; + uint64_t PendingUUID = 0 ; + uint64_t TX = 0, RX = 0; + uint64_t Associations_2G=0; + uint64_t Associations_5G=0; + bool Connected = false; + uint64_t LastContact=0; + std::string Firmware; + CertificateValidation VerifiedCertificate = NO_CERTIFICATE; + std::string Compatible; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct Device { + std::string SerialNumber; + std::string DeviceType; + std::string MACAddress; + std::string Manufacturer; + std::string Configuration; + SecurityObjects::NoteInfoVec Notes; + std::string Owner; + std::string Location; + std::string Firmware; + std::string Compatible; + std::string FWUpdatePolicy; + uint64_t UUID; + uint64_t CreationTimestamp; + uint64_t LastConfigurationChange; + uint64_t LastConfigurationDownload; + uint64_t LastFWUpdate; + std::string Venue; + std::string DevicePassword; + void to_json(Poco::JSON::Object &Obj) const; + void to_json_with_status(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + void Print() const; + }; + + struct Statistics { + std::string SerialNumber; + uint64_t UUID; + std::string Data; + uint64_t Recorded; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct HealthCheck { + std::string SerialNumber; + uint64_t UUID; + std::string Data; + uint64_t Recorded; + uint64_t Sanity; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct Capabilities { + std::string Capabilities; + uint64_t FirstUpdate; + uint64_t LastUpdate; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct DeviceLog { + enum Level { + LOG_EMERG = 0, /* system is unusable */ + LOG_ALERT = 1, /* action must be taken immediately */ + LOG_CRIT = 2, /* critical conditions */ + LOG_ERR = 3, /* error conditions */ + LOG_WARNING = 4, /* warning conditions */ + LOG_NOTICE = 5, /* normal but significant condition */ + LOG_INFO = 6, /* informational */ + LOG_DEBUG = 7 /* debug-level messages */ + }; + std::string SerialNumber; + std::string Log; + std::string Data; + uint64_t Severity; + uint64_t Recorded; + uint64_t LogType; + uint64_t UUID; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct DefaultConfiguration { + std::string Name; + std::string Configuration; + Types::StringVec Models; + std::string Description; + uint64_t Created; + uint64_t LastModified; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct CommandDetails { + std::string UUID; + std::string SerialNumber; + std::string Command; + std::string Status; + std::string SubmittedBy; + std::string Results; + std::string Details; + std::string ErrorText; + uint64_t Submitted = time(nullptr); + uint64_t Executed = 0; + uint64_t Completed = 0 ; + uint64_t RunAt = 0 ; + uint64_t ErrorCode = 0 ; + uint64_t Custom = 0 ; + uint64_t WaitingForFile = 0 ; + uint64_t AttachDate = 0 ; + uint64_t AttachSize = 0 ; + std::string AttachType; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct BlackListedDevice { + std::string serialNumber; + std::string reason; + std::string author; + uint64_t created; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct RttySessionDetails { + std::string SerialNumber; + std::string Server; + uint64_t Port; + std::string Token; + uint64_t TimeOut; + std::string ConnectionId; + uint64_t Started; + std::string CommandUUID; + uint64_t ViewPort; + std::string DevicePassword; + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct Dashboard { + uint64_t snapshot; + uint64_t numberOfDevices; + Types::CountedMap commands; + Types::CountedMap upTimes; + Types::CountedMap memoryUsed; + Types::CountedMap load1; + Types::CountedMap load5; + Types::CountedMap load15; + Types::CountedMap vendors; + Types::CountedMap status; + Types::CountedMap deviceType; + Types::CountedMap healths; + Types::CountedMap certificates; + Types::CountedMap lastContact; + Types::CountedMap associations; + void to_json(Poco::JSON::Object &Obj) const; + void reset(); + }; + + struct CapabilitiesModel { + std::string deviceType; + std::string capabilities; + + void to_json(Poco::JSON::Object &Obj) const; + }; +} diff --git a/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.cpp b/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.cpp new file mode 100644 index 0000000..3f76c8f --- /dev/null +++ b/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -0,0 +1,633 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + + +#include "RESTAPI_ProvObjects.h" +#include "framework/MicroService.h" + +using OpenWifi::RESTAPI_utils::field_to_json; +using OpenWifi::RESTAPI_utils::field_from_json; + +namespace OpenWifi::ProvObjects { + + void ObjectInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"id",id); + field_to_json(Obj,"name",name); + field_to_json(Obj,"description",description); + field_to_json(Obj,"created",created); + field_to_json(Obj,"modified",modified); + field_to_json(Obj,"notes",notes); + field_to_json(Obj,"tags",tags); + } + + bool ObjectInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"id",id); + field_from_json(Obj,"name",name); + field_from_json(Obj,"description",description); + field_from_json(Obj,"created",created); + field_from_json(Obj,"modified",modified); + field_from_json(Obj,"notes",notes); + field_from_json(Obj,"tags",tags); + return true; + } catch(...) { + + } + return false; + } + + void ManagementPolicyEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json( Obj,"users",users); + field_to_json( Obj,"resources",resources); + field_to_json( Obj,"access",access); + field_to_json( Obj,"policy",policy); + } + + bool ManagementPolicyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"users",users); + field_from_json( Obj,"resources",resources); + field_from_json( Obj,"access",access); + field_from_json( Obj,"policy",policy); + return true; + } catch(...) { + + } + return false; + } + + void ManagementPolicy::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "entries", entries); + field_to_json(Obj, "inUse", inUse); + field_to_json(Obj, "entity", entity); + } + + bool ManagementPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json(Obj, "entries", entries); + field_from_json(Obj, "inUse", inUse); + field_from_json(Obj, "entity", entity); + return true; + } catch(...) { + + } + return false; + } + + void Entity::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"parent",parent); + field_to_json( Obj,"venues",venues); + field_to_json( Obj,"children",children); + field_to_json( Obj,"contacts",contacts); + field_to_json( Obj,"locations",locations); + field_to_json( Obj,"managementPolicy",managementPolicy); + field_to_json( Obj,"deviceConfiguration",deviceConfiguration); + field_to_json( Obj,"devices",devices); + field_to_json( Obj,"rrm",rrm); + field_to_json( Obj,"sourceIP",sourceIP); + } + + bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json( Obj,"parent",parent); + field_from_json( Obj,"venues",venues); + field_from_json( Obj,"children",children); + field_from_json( Obj,"contacts",contacts); + field_from_json( Obj,"locations",locations); + field_from_json( Obj,"managementPolicy",managementPolicy); + field_from_json( Obj,"deviceConfiguration",deviceConfiguration); + field_from_json( Obj,"devices",devices); + field_from_json( Obj,"rrm",rrm); + field_from_json( Obj,"sourceIP",sourceIP); + return true; + } catch(...) { + + } + return false; + } + + void DiGraphEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json( Obj,"parent",parent); + field_to_json( Obj,"child",child); + } + + bool DiGraphEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"parent",parent); + field_from_json( Obj,"child",child); + return true; + } catch (...) { + + } + return false; + } + + void Venue::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"parent",parent); + field_to_json( Obj,"entity",entity); + field_to_json( Obj,"children",children); + field_to_json( Obj,"devices",devices); + field_to_json( Obj,"topology",topology); + field_to_json( Obj,"parent",parent); + field_to_json( Obj,"design",design); + field_to_json( Obj,"managementPolicy",managementPolicy); + field_to_json( Obj,"deviceConfiguration",deviceConfiguration); + field_to_json( Obj,"contact",contact); + field_to_json( Obj,"location",location); + field_to_json( Obj,"rrm",rrm); + field_to_json( Obj,"sourceIP",sourceIP); + } + + bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json( Obj,"parent",parent); + field_from_json( Obj,"entity",entity); + field_from_json( Obj,"children",children); + field_from_json( Obj,"devices",devices); + field_from_json( Obj,"topology",topology); + field_from_json( Obj,"parent",parent); + field_from_json( Obj,"design",design); + field_from_json( Obj,"managementPolicy",managementPolicy); + field_from_json( Obj,"deviceConfiguration",deviceConfiguration); + field_from_json( Obj,"contact",contact); + field_from_json( Obj,"location",location); + field_from_json( Obj,"rrm",rrm); + field_from_json( Obj,"sourceIP",sourceIP); + return true; + } catch (...) { + + } + return false; + } + + void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const { + field_to_json( Obj,"id",id); + field_to_json( Obj,"entity",loginId); + field_to_json( Obj,"children",userType); + } + + bool UserInfoDigest::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"id",id); + field_from_json( Obj,"entity",loginId); + field_from_json( Obj,"children",userType); + return true; + } catch(...) { + } + return false; + } + + void ManagementRole::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"managementPolicy",managementPolicy); + field_to_json( Obj,"users",users); + field_to_json( Obj,"entity",entity); + } + + bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json( Obj,"managementPolicy",managementPolicy); + field_from_json( Obj,"users",users); + field_from_json( Obj,"entity",entity); + return true; + } catch(...) { + } + return false; + } + + void Location::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"type",OpenWifi::ProvObjects::to_string(type)); + field_to_json( Obj,"buildingName",buildingName); + field_to_json( Obj,"addressLines",addressLines); + field_to_json( Obj,"city",city); + field_to_json( Obj,"state",state); + field_to_json( Obj,"postal",postal); + field_to_json( Obj,"country",country); + field_to_json( Obj,"phones",phones); + field_to_json( Obj,"mobiles",mobiles); + field_to_json( Obj,"geoCode",geoCode); + field_to_json( Obj,"inUse",inUse); + field_to_json( Obj,"entity",entity); + field_to_json( Obj,"managementPolicy",managementPolicy); + } + + bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + std::string tmp_type; + field_from_json( Obj,"type", tmp_type); + type = location_from_string(tmp_type); + field_from_json( Obj,"buildingName",buildingName); + field_from_json( Obj,"addressLines",addressLines); + field_from_json( Obj,"city",city); + field_from_json( Obj,"state",state); + field_from_json( Obj,"postal",postal); + field_from_json( Obj,"country",country); + field_from_json( Obj,"phones",phones); + field_from_json( Obj,"mobiles",mobiles); + field_from_json( Obj,"geoCode",geoCode); + field_from_json( Obj,"inUse",inUse); + field_from_json( Obj,"entity",entity); + field_from_json( Obj,"managementPolicy",managementPolicy); + return true; + } catch (...) { + + } + return false; + } + + void Contact::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"type", to_string(type)); + field_to_json( Obj,"title",title); + field_to_json( Obj,"salutation",salutation); + field_to_json( Obj,"firstname",firstname); + field_to_json( Obj,"lastname",lastname); + field_to_json( Obj,"initials",initials); + field_to_json( Obj,"visual",visual); + field_to_json( Obj,"mobiles",mobiles); + field_to_json( Obj,"phones",phones); + field_to_json( Obj,"primaryEmail",primaryEmail); + field_to_json( Obj,"secondaryEmail",secondaryEmail); + field_to_json( Obj,"accessPIN",accessPIN); + field_to_json( Obj,"inUse",inUse); + field_to_json( Obj,"entity",entity); + field_to_json( Obj,"managementPolicy",managementPolicy); + } + + bool Contact::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + std::string tmp_type; + field_from_json( Obj,"type", tmp_type); + type = contact_from_string(tmp_type); + field_from_json( Obj,"title",title); + field_from_json( Obj,"salutation",salutation); + field_from_json( Obj,"firstname",firstname); + field_from_json( Obj,"lastname",lastname); + field_from_json( Obj,"initials",initials); + field_from_json( Obj,"visual",visual); + field_from_json( Obj,"mobiles",mobiles); + field_from_json( Obj,"phones",phones); + field_from_json( Obj,"primaryEmail",primaryEmail); + field_from_json( Obj,"secondaryEmail",secondaryEmail); + field_from_json( Obj,"accessPIN",accessPIN); + field_from_json( Obj,"inUse",inUse); + field_from_json( Obj,"entity",entity); + field_from_json( Obj,"managementPolicy",managementPolicy); + return true; + } catch (...) { + + } + return false; + } + + void InventoryTag::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json(Obj, "serialNumber", serialNumber); + field_to_json(Obj, "venue", venue); + field_to_json(Obj, "entity", entity); + field_to_json(Obj, "subscriber", subscriber); + field_to_json(Obj, "deviceType", deviceType); + field_to_json(Obj, "qrCode", qrCode); + field_to_json(Obj, "geoCode", geoCode); + field_to_json(Obj, "location", location); + field_to_json(Obj, "contact", contact); + field_to_json( Obj,"deviceConfiguration",deviceConfiguration); + field_to_json( Obj,"rrm",rrm); + field_to_json( Obj,"managementPolicy",managementPolicy); + } + + bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json( Obj,"serialNumber",serialNumber); + field_from_json( Obj,"venue",venue); + field_from_json( Obj,"entity",entity); + field_from_json( Obj,"subscriber",subscriber); + field_from_json( Obj,"deviceType",deviceType); + field_from_json(Obj, "qrCode", qrCode); + field_from_json( Obj,"geoCode",geoCode); + field_from_json( Obj,"location",location); + field_from_json( Obj,"contact",contact); + field_from_json( Obj,"deviceConfiguration",deviceConfiguration); + field_from_json( Obj,"rrm",rrm); + field_from_json( Obj,"managementPolicy",managementPolicy); + return true; + } catch(...) { + + } + return false; + } + + void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const { + field_to_json( Obj,"name", name); + field_to_json( Obj,"description", description); + field_to_json( Obj,"weight", weight); + field_to_json( Obj,"configuration", configuration); + } + + bool DeviceConfigurationElement::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"name",name); + field_from_json( Obj,"description",description); + field_from_json( Obj,"weight",weight); + field_from_json( Obj,"configuration",configuration); + return true; + } catch(...) { + + } + return false; + } + + void DeviceConfiguration::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + field_to_json( Obj,"managementPolicy",managementPolicy); + field_to_json( Obj,"deviceTypes",deviceTypes); + field_to_json( Obj,"configuration",configuration); + field_to_json( Obj,"inUse",inUse); + field_to_json( Obj,"variables",variables); + field_to_json( Obj,"rrm",rrm); + field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade); + field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly); + } + + bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + field_from_json( Obj,"managementPolicy",managementPolicy); + field_from_json( Obj,"deviceTypes",deviceTypes); + field_from_json( Obj,"configuration",configuration); + field_from_json( Obj,"inUse",inUse); + field_from_json( Obj,"variables",variables); + field_from_json( Obj,"rrm",rrm); + field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade); + field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly); + return true; + } catch(...) { + + } + return false; + } + + void Report::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "snapshot", snapShot); + field_to_json(Obj, "devices", tenants); + }; + + void Report::reset() { + tenants.clear(); + } + + void ExpandedUseEntry::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "name", name); + field_to_json(Obj, "description", description); + } + + bool ExpandedUseEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"uuid",uuid); + field_from_json( Obj,"name",name); + field_from_json( Obj,"description",description); + return true; + } catch(...) { + + } + return false; + } + + void ExpandedUseEntryList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "type", type); + field_to_json(Obj, "entries", entries); + } + + bool ExpandedUseEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"type",type); + field_from_json( Obj,"entries",entries); + return true; + } catch(...) { + + } + return false; + } + + void ExpandedUseEntryMapList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "entries", entries); + } + + bool ExpandedUseEntryMapList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json( Obj,"entries",entries); + return true; + } catch(...) { + + } + return false; + } + + void UuidList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "list", list); + } + + bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "list", list); + return true; + } catch(...) { + + } + return false; + } + + void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) { + switch(A) { + case READ: Obj.set(FieldName,"read"); break; + case MODIFY: Obj.set(FieldName,"modify"); break; + case CREATE: Obj.set(FieldName,"create"); break; + case DELETE: Obj.set(FieldName,"delete"); break; + case NONE: + default: + Obj.set(FieldName,"none"); + } + } + + void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) { + if(Obj->has(FieldName)) { + auto V = Obj->getValue(FieldName); + if(V=="read") + A = READ; + else if(V=="modify") + A = MODIFY; + else if(V=="create") + A = CREATE; + else if(V=="delete") + A = DELETE; + else if(V=="none") + A = NONE; + else + throw Poco::Exception("invalid JSON"); + } + } + + void ObjectACL::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj, "users", users); + RESTAPI_utils::field_to_json(Obj, "roles", roles); + field_to_json(Obj, "access", access); + } + + bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj, "users", users); + RESTAPI_utils::field_from_json(Obj, "roles", roles); + field_from_json(Obj, "access", access); + return true; + } catch(...) { + + } + return false; + } + + void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj, "list", list); + } + + bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj, "list", list); + return true; + } catch(...) { + + } + return false; + } + + std::string to_string(VISIBILITY A) { + switch(A) { + case PUBLIC: return "public"; + case SELECT: return "select"; + case PRIVATE: + default: + return "private"; + } + } + + void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) { + Obj.set(FieldName,to_string(A)); + } + + VISIBILITY visibility_from_string(const std::string &V) { + if(V=="public") + return PUBLIC; + else if(V=="select") + return SELECT; + else if(V=="private") + return PRIVATE; + throw Poco::Exception("invalid json"); + } + + void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) { + if(Obj->has(FieldName)) { + auto V = Obj->getValue(FieldName); + A = visibility_from_string(V); + } + } + + void Map::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + RESTAPI_utils::field_to_json( Obj,"data",data); + RESTAPI_utils::field_to_json( Obj,"entity",entity); + RESTAPI_utils::field_to_json( Obj,"creator",creator); + field_to_json( Obj,"visibility",visibility); + RESTAPI_utils::field_to_json( Obj,"access",access); + } + + bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + RESTAPI_utils::field_from_json( Obj,"data",data); + RESTAPI_utils::field_from_json( Obj,"entity",entity); + RESTAPI_utils::field_from_json( Obj,"creator",creator); + field_from_json( Obj,"visibility",visibility); + RESTAPI_utils::field_from_json( Obj,"access",access); + return true; + } catch(...) { + + } + return false; + } + + void MapList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json( Obj,"list",list); + } + + bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json( Obj,"list",list); + return true; + } catch(...) { + + } + return false; + } + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { + uint64_t Now = std::time(nullptr); + if(O->has("name")) + I.name = O->get("name").toString(); + + if(I.name.empty()) + return false; + + if(O->has("description")) + I.description = O->get("description").toString(); + SecurityObjects::MergeNotes(O,U,I.notes); + SecurityObjects::NoteInfoVec N; + for(auto &i:I.notes) { + if(i.note.empty()) + continue; + N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note}); + } + I.modified = Now; + return true; + } + + bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { + uint64_t Now = std::time(nullptr); + if(O->has("name")) + I.name = O->get("name").toString(); + + if(I.name.empty()) + return false; + + if(O->has("description")) + I.description = O->get("description").toString(); + + SecurityObjects::NoteInfoVec N; + for(auto &i:I.notes) { + if(i.note.empty()) + continue; + N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note}); + } + I.notes = N; + I.modified = I.created = Now; + I.id = MicroService::CreateUUID(); + + return true; + } +} + diff --git a/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.h b/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.h new file mode 100644 index 0000000..6ac9b4f --- /dev/null +++ b/microservice_sample/src/RESTObjects/RESTAPI_ProvObjects.h @@ -0,0 +1,380 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#pragma once + +#include +#include "RESTAPI_SecurityObjects.h" + +namespace OpenWifi::ProvObjects { + + enum FIRMWARE_UPGRADE_RULES { + dont_upgrade, + upgrade_inherit, + upgrade_release_only, + upgrade_latest + }; + + struct ObjectInfo { + Types::UUID_t id; + std::string name; + std::string description; + SecurityObjects::NoteInfoVec notes; + uint64_t created=0; + uint64_t modified=0; + Types::TagList tags; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementPolicyEntry { + Types::UUIDvec_t users; + Types::UUIDvec_t resources; + Types::StringVec access; + std::string policy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementPolicy { + ObjectInfo info; + std::vector entries; + Types::StringVec inUse; + Types::UUID_t entity; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ManagementPolicyVec; + + struct Entity { + ObjectInfo info; + Types::UUID_t parent; + Types::UUIDvec_t children; + Types::UUIDvec_t venues; + Types::UUIDvec_t contacts; // all contacts associated in this entity + Types::UUIDvec_t locations; // all locations associated in this entity + Types::UUID_t managementPolicy; + Types::UUIDvec_t deviceConfiguration; + Types::UUIDvec_t devices; + std::string rrm; + Types::StringVec sourceIP; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector EntityVec; + + struct DiGraphEntry { + Types::UUID_t parent; + Types::UUID_t child; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + typedef std::vector DiGraph; + + struct Venue { + ObjectInfo info; + Types::UUID_t entity; + Types::UUID_t parent; + Types::UUIDvec_t children; + Types::UUID_t managementPolicy; + Types::UUIDvec_t devices; + DiGraph topology; + std::string design; + Types::UUIDvec_t deviceConfiguration; + std::string contact; + std::string location; + std::string rrm; + Types::StringVec sourceIP; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector VenueVec; + + struct UserInfoDigest { + std::string id; + std::string loginId; + std::string userType; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ManagementRole { + ObjectInfo info; + Types::UUID_t managementPolicy; + Types::UUIDvec_t users; + Types::StringVec inUse; + Types::UUID_t entity; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ManagementRoleVec; + + enum LocationType { + LT_SERVICE, LT_EQUIPMENT, LT_AUTO, LT_MANUAL, + LT_SPECIAL, LT_UNKNOWN, LT_CORPORATE + }; + + inline std::string to_string(LocationType L) { + switch(L) { + case LT_SERVICE: return "SERVICE"; + case LT_EQUIPMENT: return "EQUIPMENT"; + case LT_AUTO: return "AUTO"; + case LT_MANUAL: return "MANUAL"; + case LT_SPECIAL: return "SPECIAL"; + case LT_UNKNOWN: return "UNKNOWN"; + case LT_CORPORATE: return "CORPORATE"; + default: return "UNKNOWN"; + } + } + + inline LocationType location_from_string(const std::string &S) { + if(!Poco::icompare(S,"SERVICE")) + return LT_SERVICE; + else if(!Poco::icompare(S,"EQUIPMENT")) + return LT_EQUIPMENT; + else if(!Poco::icompare(S,"AUTO")) + return LT_AUTO; + else if(!Poco::icompare(S,"MANUAL")) + return LT_MANUAL; + else if(!Poco::icompare(S,"SPECIAL")) + return LT_SPECIAL; + else if(!Poco::icompare(S,"UNKNOWN")) + return LT_UNKNOWN; + else if(!Poco::icompare(S,"CORPORATE")) + return LT_CORPORATE; + return LT_UNKNOWN; + } + + struct Location { + ObjectInfo info; + LocationType type; + std::string buildingName; + Types::StringVec addressLines; + std::string city; + std::string state; + std::string postal; + std::string country; + Types::StringVec phones; + Types::StringVec mobiles; + std::string geoCode; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector LocationVec; + + enum ContactType { + CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER, + CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN + }; + + inline std::string to_string(ContactType L) { + switch(L) { + case CT_SUBSCRIBER: return "SUBSCRIBER"; + case CT_USER: return "USER"; + case CT_INSTALLER: return "INSTALLER"; + case CT_CSR: return "CSR"; + case CT_MANAGER: return "MANAGER"; + case CT_BUSINESSOWNER: return "BUSINESSOWNER"; + case CT_TECHNICIAN: return "TECHNICIAN"; + case CT_CORPORATE: return "CORPORATE"; + case CT_UNKNOWN: return "UNKNOWN"; + default: return "UNKNOWN"; + } + } + + inline ContactType contact_from_string(const std::string &S) { + if(!Poco::icompare(S,"SUBSCRIBER")) + return CT_SUBSCRIBER; + else if(!Poco::icompare(S,"USER")) + return CT_USER; + else if(!Poco::icompare(S,"INSTALLER")) + return CT_INSTALLER; + else if(!Poco::icompare(S,"CSR")) + return CT_CSR; + else if(!Poco::icompare(S,"BUSINESSOWNER")) + return CT_BUSINESSOWNER; + else if(!Poco::icompare(S,"TECHNICIAN")) + return CT_TECHNICIAN; + else if(!Poco::icompare(S,"CORPORATE")) + return CT_CORPORATE; + else if(!Poco::icompare(S,"UNKNOWN")) + return CT_UNKNOWN; + return CT_UNKNOWN; + } + + struct Contact { + ObjectInfo info; + ContactType type=CT_USER; + std::string title; + std::string salutation; + std::string firstname; + std::string lastname; + std::string initials; + std::string visual; + Types::StringVec mobiles; + Types::StringVec phones; + std::string primaryEmail; + std::string secondaryEmail; + std::string accessPIN; + Types::StringVec inUse; + Types::UUID_t entity; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ContactVec; + + struct DeviceConfigurationElement { + std::string name; + std::string description; + uint64_t weight; + std::string configuration; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector DeviceConfigurationElementVec; + + struct DeviceConfiguration { + ObjectInfo info; + Types::UUID_t managementPolicy; + Types::StringVec deviceTypes; + DeviceConfigurationElementVec configuration; + Types::StringVec inUse; + Types::StringPairVec variables; + std::string rrm; + std::string firmwareUpgrade; + bool firmwareRCOnly=false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector DeviceConfigurationVec; + + struct InventoryTag { + ObjectInfo info; + std::string serialNumber; + std::string venue; + std::string entity; + std::string subscriber; + std::string deviceType; + std::string qrCode; + std::string geoCode; + std::string location; + std::string contact; + std::string deviceConfiguration; + std::string rrm; + Types::UUID_t managementPolicy; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector InventoryTagVec; + + struct Report { + uint64_t snapShot=0; + Types::CountedMap tenants; + + void reset(); + void to_json(Poco::JSON::Object &Obj) const; + }; + + struct ExpandedUseEntry { + std::string uuid; + std::string name; + std::string description; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ExpandedUseEntryList { + std::string type; + std::vector entries; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ExpandedUseEntryMapList { + std::vector entries; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct UuidList { + std::vector list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum ACLACCESS { + NONE, READ, MODIFY, CREATE, DELETE + }; + + struct ObjectACL { + UuidList users; + UuidList roles; + ACLACCESS access = NONE; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct ObjectACLList { + std::vector list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum VISIBILITY { + PUBLIC, PRIVATE, SELECT + }; + + std::string to_string(VISIBILITY A); + VISIBILITY visibility_from_string(const std::string &V); + + struct Map { + ObjectInfo info; + std::string data; + std::string entity; + std::string creator; + VISIBILITY visibility = PRIVATE; + ObjectACLList access; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct MapList { + std::vector list; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); + bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); +}; diff --git a/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.cpp b/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.cpp new file mode 100644 index 0000000..3d0c270 --- /dev/null +++ b/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.cpp @@ -0,0 +1,535 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#include "Poco/JSON/Parser.h" +#include "Poco/JSON/Stringifier.h" + +#include "framework/MicroService.h" +#include "RESTAPI_SecurityObjects.h" + +using OpenWifi::RESTAPI_utils::field_to_json; +using OpenWifi::RESTAPI_utils::field_from_json; + +namespace OpenWifi::SecurityObjects { + + void AclTemplate::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"Read",Read_); + field_to_json(Obj,"ReadWrite",ReadWrite_); + field_to_json(Obj,"ReadWriteCreate",ReadWriteCreate_); + field_to_json(Obj,"Delete",Delete_); + field_to_json(Obj,"PortalLogin",PortalLogin_); + } + + ResourceAccessType ResourceAccessTypeFromString(const std::string &s) { + if(!Poco::icompare(s,"READ")) return READ; + if(!Poco::icompare(s,"MODIFY")) return MODIFY; + if(!Poco::icompare(s,"DELETE")) return DELETE; + if(!Poco::icompare(s,"CREATE")) return CREATE; + if(!Poco::icompare(s,"TEST")) return TEST; + if(!Poco::icompare(s,"MOVE")) return MOVE; + return NONE; + } + + std::string ResourceAccessTypeToString(const ResourceAccessType & T) { + switch(T) { + case READ: return "READ"; + case MODIFY: return "MODIFY"; + case DELETE: return "DELETE"; + case CREATE: return "CREATE"; + case TEST: return "TEST"; + case MOVE: return "MOVE"; + default: return "NONE"; + } + } + + USER_ROLE UserTypeFromString(const std::string &U) { + if (!Poco::icompare(U,"root")) + return ROOT; + else if (!Poco::icompare(U,"admin")) + return ADMIN; + else if (!Poco::icompare(U,"subscriber")) + return SUBSCRIBER; + else if (!Poco::icompare(U,"csr")) + return CSR; + else if (!Poco::icompare(U, "system")) + return SYSTEM; + else if (!Poco::icompare(U, "installer")) + return INSTALLER; + else if (!Poco::icompare(U, "noc")) + return NOC; + else if (!Poco::icompare(U, "accounting")) + return ACCOUNTING; + return UNKNOWN; + } + + std::string UserTypeToString(USER_ROLE U) { + switch(U) { + case ROOT: return "root"; + case ADMIN: return "admin"; + case SUBSCRIBER: return "subscriber"; + case CSR: return "csr"; + case SYSTEM: return "system"; + case INSTALLER: return "installer"; + case NOC: return "noc"; + case ACCOUNTING: return "accounting"; + case UNKNOWN: + default: + return "unknown"; + } + } + + bool AclTemplate::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "Read", Read_); + field_from_json(Obj, "ReadWrite", ReadWrite_); + field_from_json(Obj, "ReadWriteCreate", ReadWriteCreate_); + field_from_json(Obj, "Delete", Delete_); + field_from_json(Obj, "PortalLogin", PortalLogin_); + return true; + } catch(...) { + } + return false; + } + + void WebToken::to_json(Poco::JSON::Object & Obj) const { + Poco::JSON::Object AclTemplateObj; + acl_template_.to_json(AclTemplateObj); + field_to_json(Obj,"access_token",access_token_); + field_to_json(Obj,"refresh_token",refresh_token_); + field_to_json(Obj,"token_type",token_type_); + field_to_json(Obj,"expires_in",expires_in_); + field_to_json(Obj,"idle_timeout",idle_timeout_); + field_to_json(Obj,"created",created_); + field_to_json(Obj,"username",username_); + field_to_json(Obj,"userMustChangePassword",userMustChangePassword); + field_to_json(Obj,"errorCode", errorCode); + Obj.set("aclTemplate",AclTemplateObj); + } + + bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + if (Obj->isObject("aclTemplate")) { + Poco::JSON::Object::Ptr AclTemplate = Obj->getObject("aclTemplate"); + acl_template_.from_json(AclTemplate); + } + field_from_json(Obj, "access_token", access_token_); + field_from_json(Obj, "refresh_token", refresh_token_); + field_from_json(Obj, "token_type", token_type_); + field_from_json(Obj, "expires_in", expires_in_); + field_from_json(Obj, "idle_timeout", idle_timeout_); + field_from_json(Obj, "created", created_); + field_from_json(Obj, "username", username_); + field_from_json(Obj, "userMustChangePassword",userMustChangePassword); + return true; + } catch (...) { + + } + return false; + } + + void MobilePhoneNumber::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"number", number); + field_to_json(Obj,"verified", verified); + field_to_json(Obj,"primary", primary); + } + + bool MobilePhoneNumber::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"number",number); + field_from_json(Obj,"verified",verified); + field_from_json(Obj,"primary",primary); + return true; + } catch (...) { + + } + return false; + }; + + void MfaAuthInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"enabled", enabled); + field_to_json(Obj,"method", method); + } + + bool MfaAuthInfo::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"enabled",enabled); + field_from_json(Obj,"method",method); + return true; + } catch (...) { + + } + return false; + } + + void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "mobiles", mobiles); + field_to_json(Obj, "mfa", mfa); + } + + bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"mobiles",mobiles); + field_from_json(Obj,"mfa",mfa); + return true; + } catch (...) { + + } + return false; + } + + void MFAChallengeRequest::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "question", question); + field_to_json(Obj, "created", created); + field_to_json(Obj, "method", method); + } + + bool MFAChallengeRequest::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"uuid",uuid); + field_from_json(Obj,"question",question); + field_from_json(Obj,"created",created); + field_from_json(Obj,"method",method); + return true; + } catch (...) { + + } + return false; + }; + + void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "uuid", uuid); + field_to_json(Obj, "answer", answer); + + } + + bool MFAChallengeResponse::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"uuid",uuid); + field_from_json(Obj,"answer",answer); + return true; + } catch (...) { + + } + return false; + + } + + void UserInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"Id",Id); + field_to_json(Obj,"name",name); + field_to_json(Obj,"description", description); + field_to_json(Obj,"avatar", avatar); + field_to_json(Obj,"email", email); + field_to_json(Obj,"validated", validated); + field_to_json(Obj,"validationEmail", validationEmail); + field_to_json(Obj,"validationDate", validationDate); + field_to_json(Obj,"creationDate", creationDate); + field_to_json(Obj,"validationURI", validationURI); + field_to_json(Obj,"changePassword", changePassword); + field_to_json(Obj,"lastLogin", lastLogin); + field_to_json(Obj,"currentLoginURI", currentLoginURI); + field_to_json(Obj,"lastPasswordChange", lastPasswordChange); + field_to_json(Obj,"lastEmailCheck", lastEmailCheck); + field_to_json(Obj,"waitingForEmailCheck", waitingForEmailCheck); + field_to_json(Obj,"locale", locale); + field_to_json(Obj,"notes", notes); + field_to_json(Obj,"location", location); + field_to_json(Obj,"owner", owner); + field_to_json(Obj,"suspended", suspended); + field_to_json(Obj,"blackListed", blackListed); + field_to_json(Obj,"userRole", userRole, UserTypeToString); + field_to_json(Obj,"userTypeProprietaryInfo", userTypeProprietaryInfo); + field_to_json(Obj,"securityPolicy", securityPolicy); + field_to_json(Obj,"securityPolicyChange", securityPolicyChange); + field_to_json(Obj,"currentPassword",currentPassword); + field_to_json(Obj,"lastPasswords",lastPasswords); + field_to_json(Obj,"oauthType",oauthType); + field_to_json(Obj,"oauthUserInfo",oauthUserInfo); + }; + + bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"Id",Id); + field_from_json(Obj,"name",name); + field_from_json(Obj,"description",description); + field_from_json(Obj,"avatar",avatar); + field_from_json(Obj,"email",email); + field_from_json(Obj,"validationEmail",validationEmail); + field_from_json(Obj,"validationURI",validationURI); + field_from_json(Obj,"currentLoginURI",currentLoginURI); + field_from_json(Obj,"locale",locale); + field_from_json(Obj,"notes",notes); + field_from_json(Obj,"userRole",userRole, UserTypeFromString); + field_from_json(Obj,"securityPolicy",securityPolicy); + field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo); + field_from_json(Obj,"validationDate",validationDate); + field_from_json(Obj,"creationDate",creationDate); + field_from_json(Obj,"lastLogin",lastLogin); + field_from_json(Obj,"lastPasswordChange",lastPasswordChange); + field_from_json(Obj,"lastEmailCheck",lastEmailCheck); + field_from_json(Obj,"securityPolicyChange",securityPolicyChange); + field_from_json(Obj,"validated",validated); + field_from_json(Obj,"changePassword",changePassword); + field_from_json(Obj,"waitingForEmailCheck",waitingForEmailCheck); + field_from_json(Obj,"suspended",suspended); + field_from_json(Obj,"blackListed",blackListed); + field_from_json(Obj,"currentPassword",currentPassword); + field_from_json(Obj,"lastPasswords",lastPasswords); + field_from_json(Obj,"oauthType",oauthType); + field_from_json(Obj,"oauthUserInfo",oauthUserInfo); + return true; + } catch (const Poco::Exception &E) { + + } + return false; + }; + + void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"privateURI",privateURI); + field_to_json(Obj,"publicURI",publicURI); + field_to_json(Obj,"token",token); + }; + + bool InternalServiceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"privateURI",privateURI); + field_from_json(Obj,"publicURI",publicURI); + field_from_json(Obj,"token",token); + return true; + } catch (...) { + + } + return false; + }; + + void InternalSystemServices::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"key",key); + field_to_json(Obj,"version",version); + field_to_json(Obj,"services",services); + }; + + bool InternalSystemServices::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "key", key); + field_from_json(Obj, "version", version); + field_from_json(Obj, "services", services); + return true; + } catch(...) { + + } + return false; + }; + + void SystemEndpoint::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"type",type); + field_to_json(Obj,"id",id); + field_to_json(Obj,"vendor",vendor); + field_to_json(Obj,"uri",uri); + field_to_json(Obj,"authenticationType",authenticationType); + }; + + bool SystemEndpoint::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "type", type); + field_from_json(Obj, "id", id); + field_from_json(Obj, "vendor", vendor); + field_from_json(Obj, "uri", uri); + field_from_json(Obj, "authenticationType", authenticationType); + return true; + } catch (...) { + + } + return false; + }; + + void SystemEndpointList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"endpoints",endpoints); + } + + bool SystemEndpointList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "endpoints", endpoints); + return true; + } catch (...) { + + } + return false; + } + + void UserInfoAndPolicy::to_json(Poco::JSON::Object &Obj) const { + Poco::JSON::Object UI, TI; + userinfo.to_json(UI); + webtoken.to_json(TI); + Obj.set("tokenInfo",TI); + Obj.set("userInfo",UI); + } + + bool UserInfoAndPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj, "tokenInfo", webtoken); + field_from_json(Obj, "userInfo", userinfo); + return true; + } catch(...) { + + } + return false; + } + + void NoteInfo::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"created", created); + field_to_json(Obj,"createdBy", createdBy); + field_to_json(Obj,"note", note); + } + + bool NoteInfo::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"created",created); + field_from_json(Obj,"createdBy",createdBy); + field_from_json(Obj,"note",note); + return true; + } catch(...) { + + } + return false; + } + + bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes) { + try { + if(Obj->has("notes") && Obj->isArray("notes")) { + SecurityObjects::NoteInfoVec NIV; + NIV = RESTAPI_utils::to_object_array(Obj->get("notes").toString()); + for(auto const &i:NIV) { + SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note}; + Notes.push_back(ii); + } + } + return true; + } catch(...) { + + } + return false; + } + + bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) { + for(auto const &i:NewNotes) { + SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note}; + ExistingNotes.push_back(ii); + } + return true; + } + + void ProfileAction::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"resource", resource); + field_to_json(Obj,"access", access, ResourceAccessTypeToString); + } + + bool ProfileAction::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"resource",resource); + field_from_json(Obj,"access",access,ResourceAccessTypeFromString ); + return true; + } catch(...) { + + } + return false; + } + + void SecurityProfile::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"id", id); + field_to_json(Obj,"name", name); + field_to_json(Obj,"description", description); + field_to_json(Obj,"policy", policy); + field_to_json(Obj,"role", role); + field_to_json(Obj,"notes", notes); + } + + bool SecurityProfile::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"id",id); + field_from_json(Obj,"name",name); + field_from_json(Obj,"description",description); + field_from_json(Obj,"policy",policy); + field_from_json(Obj,"role",role); + field_from_json(Obj,"notes",notes); + return true; + } catch(...) { + + } + return false; + } + + void SecurityProfileList::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj, "profiles", profiles); + } + + bool SecurityProfileList::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"profiles",profiles); + return true; + } catch(...) { + + } + return false; + } + + void ActionLink::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"id",id); + field_to_json(Obj,"action",action); + field_to_json(Obj,"userId",userId); + field_to_json(Obj,"actionTemplate",actionTemplate); + field_to_json(Obj,"variables",variables); + field_to_json(Obj,"locale",locale); + field_to_json(Obj,"message",message); + field_to_json(Obj,"sent",sent); + field_to_json(Obj,"created",created); + field_to_json(Obj,"expires",expires); + field_to_json(Obj,"completed",completed); + field_to_json(Obj,"canceled",canceled); + } + + bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"id",id); + field_from_json(Obj,"action",action); + field_from_json(Obj,"userId",userId); + field_from_json(Obj,"actionTemplate",actionTemplate); + field_from_json(Obj,"variables",variables); + field_from_json(Obj,"locale",locale); + field_from_json(Obj,"message",message); + field_from_json(Obj,"sent",sent); + field_from_json(Obj,"created",created); + field_from_json(Obj,"expires",expires); + field_from_json(Obj,"completed",completed); + field_from_json(Obj,"canceled",canceled); + return true; + } catch(...) { + + } + return false; + } + + void Preferences::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"id",id); + field_to_json(Obj,"modified",modified); + field_to_json(Obj,"data",data); + } + + bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"id",id); + field_from_json(Obj,"modified",modified); + field_from_json(Obj,"data",data); + return true; + } catch(...) { + + } + return false; + } +} + diff --git a/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.h b/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.h new file mode 100644 index 0000000..647eb77 --- /dev/null +++ b/microservice_sample/src/RESTObjects/RESTAPI_SecurityObjects.h @@ -0,0 +1,257 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#ifndef UCENTRAL_RESTAPI_SECURITYOBJECTS_H +#define UCENTRAL_RESTAPI_SECURITYOBJECTS_H + +#include "framework/OpenWifiTypes.h" +#include "Poco/JSON/Object.h" + +namespace OpenWifi::SecurityObjects { + + struct AclTemplate { + bool Read_ = true; + bool ReadWrite_ = true; + bool ReadWriteCreate_ = true; + bool Delete_ = true; + bool PortalLogin_ = true; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); }; + + struct WebToken { + std::string access_token_; + std::string refresh_token_; + std::string id_token_; + std::string token_type_; + std::string username_; + bool userMustChangePassword=false; + uint64_t errorCode=0; + uint64_t expires_in_=0; + uint64_t idle_timeout_=0; + AclTemplate acl_template_; + uint64_t created_=0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + enum USER_ROLE { + UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING + }; + + USER_ROLE UserTypeFromString(const std::string &U); + std::string UserTypeToString(USER_ROLE U); + + struct NoteInfo { + uint64_t created = std::time(nullptr); + std::string createdBy; + std::string note; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector NoteInfoVec; + + struct MobilePhoneNumber { + std::string number; + bool verified = false; + bool primary = false; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct MfaAuthInfo { + bool enabled = false; + std::string method; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct UserLoginLoginExtensions { + std::vector mobiles; + struct MfaAuthInfo mfa; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct MFAChallengeRequest { + std::string uuid; + std::string question; + std::string method; + uint64_t created = std::time(nullptr); + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct MFAChallengeResponse { + std::string uuid; + std::string answer; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct UserInfo { + std::string Id; + std::string name; + std::string description; + std::string avatar; + std::string email; + bool validated = false; + std::string validationEmail; + uint64_t validationDate = 0; + uint64_t creationDate = 0; + std::string validationURI; + bool changePassword = false; + uint64_t lastLogin = 0; + std::string currentLoginURI; + uint64_t lastPasswordChange = 0; + uint64_t lastEmailCheck = 0; + bool waitingForEmailCheck = false; + std::string locale; + NoteInfoVec notes; + std::string location; + std::string owner; + bool suspended = false; + bool blackListed = false; + USER_ROLE userRole; + UserLoginLoginExtensions userTypeProprietaryInfo; + std::string securityPolicy; + uint64_t securityPolicyChange = 0 ; + std::string currentPassword; + Types::StringVec lastPasswords; + std::string oauthType; + std::string oauthUserInfo; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector UserInfoVec; + + // bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); + bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes); + bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes); + + struct InternalServiceInfo { + std::string privateURI; + std::string publicURI; + std::string token; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector InternalServiceInfoVec; + + struct InternalSystemServices { + std::string key; + std::string version; + InternalServiceInfoVec services; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct SystemEndpoint { + std::string type; + uint64_t id = 0; + std::string vendor{"OpenWiFi"}; + std::string uri; + std::string authenticationType{"internal_v1"}; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector SystemEndpointVec; + + struct SystemEndpointList { + SystemEndpointVec endpoints; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + struct UserInfoAndPolicy { + WebToken webtoken; + UserInfo userinfo; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + typedef std::map UserInfoCache; + + enum ResourceAccessType { + NONE, + READ, + MODIFY, + DELETE, + CREATE, + TEST, + MOVE + }; + + ResourceAccessType ResourceAccessTypeFromString(const std::string &s); + std::string ResourceAccessTypeToString(const ResourceAccessType & T); + + struct ProfileAction { + std::string resource; + ResourceAccessType access; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector ProfileActionVec; + + struct SecurityProfile { + uint64_t id=0; + std::string name; + std::string description; + ProfileActionVec policy; + std::string role; + NoteInfoVec notes; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + typedef std::vector SecurityProfileVec; + + struct SecurityProfileList { + SecurityProfileVec profiles; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + enum LinkActions { + FORGOT_PASSWORD=1, + VERIFY_EMAIL + }; + + struct ActionLink { + std::string id; + uint64_t action; + std::string userId; + std::string actionTemplate; + Types::StringPairVec variables; + std::string locale; + std::string message; + uint64_t sent=0; + uint64_t created=std::time(nullptr); + uint64_t expires=0; + uint64_t completed=0; + uint64_t canceled=0; + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; + + struct Preferences { + std::string id; + uint64_t modified; + Types::StringPairVec data; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(Poco::JSON::Object::Ptr &Obj); + }; +} + +#endif //UCENTRAL_RESTAPI_SECURITYOBJECTS_H \ No newline at end of file diff --git a/microservice_sample/src/StorageService.cpp b/microservice_sample/src/StorageService.cpp new file mode 100644 index 0000000..ab7fc50 --- /dev/null +++ b/microservice_sample/src/StorageService.cpp @@ -0,0 +1,26 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#include "StorageService.h" + +namespace OpenWifi { + + int Storage::Start() { + std::lock_guard Guard(Mutex_); + StorageClass::Start(); + + return 0; + } + + void Storage::Stop() { + std::lock_guard Guard(Mutex_); + Logger_.notice("Stopping."); + StorageClass::Stop(); + } +} +// namespace \ No newline at end of file diff --git a/microservice_sample/src/StorageService.h b/microservice_sample/src/StorageService.h new file mode 100644 index 0000000..78e1f31 --- /dev/null +++ b/microservice_sample/src/StorageService.h @@ -0,0 +1,37 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#pragma once + +#include "framework/MicroService.h" +#include "framework/StorageClass.h" +#include "RESTObjects//RESTAPI_GWobjects.h" +#include "Poco/Net/IPAddress.h" + +namespace OpenWifi { + + class Storage : public StorageClass { + + public: + + static Storage *instance() { + static Storage * instance_ = new Storage; + return instance_; + } + + int Start() override; + void Stop() override; + + private: + + }; + + inline Storage * StorageService() { return Storage::instance(); } + +} // namespace + diff --git a/microservice_sample/src/framework/RESTAPI_protocol.h b/microservice_sample/src/framework/RESTAPI_protocol.h new file mode 100644 index 0000000..fdfe4b5 --- /dev/null +++ b/microservice_sample/src/framework/RESTAPI_protocol.h @@ -0,0 +1,137 @@ +// +// License type: BSD 3-Clause License +// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE +// +// Created by Stephane Bourque on 2021-03-04. +// Arilia Wireless Inc. +// + +#pragma once + +namespace OpenWifi::RESTAPI::Protocol { + static const char * CAPABILITIES = "capabilities"; + static const char * LOGS = "logs"; + static const char * HEALTHCHECKS = "healthchecks"; + static const char * STATISTICS = "statistics"; + static const char * STATUS = "status"; + static const char * SERIALNUMBER = "serialNumber"; + static const char * PERFORM = "perform"; + static const char * CONFIGURE = "configure"; + static const char * UPGRADE = "upgrade"; + static const char * REBOOT = "reboot"; + static const char * FACTORY = "factory"; + static const char * LEDS = "leds"; + static const char * TRACE = "trace"; + static const char * REQUEST = "request"; + static const char * WIFISCAN = "wifiscan"; + static const char * EVENTQUEUE = "eventqueue"; + static const char * RTTY = "rtty"; + static const char * COMMAND = "command"; + static const char * STARTDATE = "startDate"; + static const char * ENDDATE = "endDate"; + static const char * OFFSET = "offset"; + static const char * LIMIT = "limit"; + static const char * LIFETIME = "lifetime"; + static const char * UUID = "UUID"; + static const char * DATA = "data"; + static const char * CONFIGURATION = "configuration"; + static const char * WHEN = "when"; + static const char * URI = "uri"; + static const char * LOGTYPE = "logType"; + static const char * VALUES = "values"; + static const char * TYPES = "types"; + static const char * PAYLOAD = "payload"; + static const char * KEEPREDIRECTOR = "keepRedirector"; + static const char * NETWORK = "network"; + static const char * INTERFACE = "interface"; + static const char * BANDS = "bands"; + static const char * CHANNELS = "channels"; + static const char * VERBOSE = "verbose"; + static const char * MESSAGE = "message"; + static const char * STATE = "state"; + static const char * HEALTHCHECK = "healthcheck"; + static const char * PCAP_FILE_TYPE = "pcap"; + static const char * DURATION = "duration"; + static const char * NUMBEROFPACKETS = "numberOfPackets"; + static const char * FILTER = "filter"; + static const char * SELECT = "select"; + static const char * SERIALONLY = "serialOnly"; + static const char * COUNTONLY = "countOnly"; + static const char * DEVICEWITHSTATUS = "deviceWithStatus"; + static const char * DEVICESWITHSTATUS = "devicesWithStatus"; + static const char * DEVICES = "devices"; + static const char * COUNT = "count"; + static const char * SERIALNUMBERS = "serialNumbers"; + static const char * CONFIGURATIONS = "configurations"; + static const char * NAME = "name"; + static const char * COMMANDS = "commands"; + static const char * COMMANDUUID = "commandUUID"; + static const char * FIRMWARES = "firmwares"; + static const char * TOPIC = "topic"; + static const char * HOST = "host"; + static const char * OS = "os"; + static const char * HOSTNAME = "hostname"; + static const char * PROCESSORS = "processors"; + static const char * REASON = "reason"; + static const char * RELOAD = "reload"; + static const char * SUBSYSTEMS = "subsystems"; + static const char * FILEUUID = "uuid"; + static const char * USERID = "userId"; + static const char * PASSWORD = "password"; + static const char * TOKEN = "token"; + static const char * SETLOGLEVEL = "setloglevel"; + static const char * GETLOGLEVELS = "getloglevels"; + static const char * GETSUBSYSTEMNAMES = "getsubsystemnames"; + static const char * GETLOGLEVELNAMES = "getloglevelnames"; + static const char * STATS = "stats"; + static const char * PARAMETERS = "parameters"; + static const char * VALUE = "value"; + static const char * LASTONLY = "lastOnly"; + static const char * NEWEST = "newest"; + static const char * ACTIVESCAN = "activeScan"; + static const char * LIST = "list"; + static const char * TAG = "tag"; + static const char * TAGLIST = "tagList"; + static const char * DESCRIPTION = "description"; + static const char * NOTES = "notes"; + static const char * DEVICETYPE = "deviceType"; + static const char * REVISION = "revision"; + static const char * AGES = "ages"; + static const char * REVISIONS = "revisions"; + static const char * DEVICETYPES = "deviceTypes"; + static const char * LATESTONLY = "latestOnly"; + static const char * IDONLY = "idOnly"; + static const char * REVISIONSET = "revisionSet"; + static const char * DEVICESET = "deviceSet"; + static const char * HISTORY = "history"; + static const char * ID = "id"; + static const char * VERSION = "version"; + static const char * TIMES = "times"; + static const char * UPTIME = "uptime"; + static const char * START = "start"; + + static const char * NEWPASSWORD = "newPassword"; + static const char * USERS = "users"; + static const char * WITHEXTENDEDINFO = "withExtendedInfo"; + + static const char * ERRORTEXT = "errorText"; + static const char * ERRORCODE = "errorCode"; + static const char * AVATARID = "avatarId"; + static const char * UNNAMED = "(unnamed)"; + static const char * UNSPECIFIED = "(unspecified)"; + static const char * CONTENTDISPOSITION = "Content-Disposition"; + static const char * CONTENTTYPE = "Content-Type"; + + static const char * REQUIREMENTS = "requirements"; + static const char * PASSWORDPATTERN = "passwordPattern"; + static const char * ACCESSPOLICY = "accessPolicy"; + static const char * PASSWORDPOLICY = "passwordPolicy"; + static const char * FORGOTPASSWORD = "forgotPassword"; + static const char * RESENDMFACODE = "resendMFACode"; + static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge"; + static const char * ME = "me"; + static const char * TELEMETRY = "telemetry"; + static const char * INTERVAL = "interval"; + static const char * UI = "UI"; + +} diff --git a/microservice_sample/src/framework/StorageClass.h b/microservice_sample/src/framework/StorageClass.h new file mode 100644 index 0000000..95dba62 --- /dev/null +++ b/microservice_sample/src/framework/StorageClass.h @@ -0,0 +1,166 @@ +// +// Created by stephane bourque on 2021-10-06. +// + +#pragma once + +#include "Poco/Data/Session.h" +#include "Poco/Data/SessionPool.h" +#include "Poco/Data/SQLite/Connector.h" +#include "Poco/JSON/Object.h" + +#ifndef SMALL_BUILD +#include "Poco/Data/PostgreSQL/Connector.h" +#include "Poco/Data/MySQL/Connector.h" +#endif + +#include "framework/MicroService.h" + +namespace OpenWifi { + enum DBType { + sqlite, + pgsql, + mysql + }; + + class StorageClass : public SubSystemServer { + public: + StorageClass() noexcept: + SubSystemServer("StorageClass", "STORAGE-SVR", "storage") + { + } + + int Start() override { + std::lock_guard Guard(Mutex_); + + Logger_.setLevel(Poco::Message::PRIO_NOTICE); + Logger_.notice("Starting."); + std::string DBType = MicroService::instance().ConfigGetString("storage.type"); + + if (DBType == "sqlite") { + Setup_SQLite(); + } else if (DBType == "postgresql") { + Setup_PostgreSQL(); + } else if (DBType == "mysql") { + Setup_MySQL(); + } + return 0; + } + + void Stop() override { + Pool_->shutdown(); + } + + [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { + if(dbType_==sqlite) { + return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " "; + } else if(dbType_==pgsql) { + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; + } else if(dbType_==mysql) { + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; + } + return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " "; + } + + inline std::string ConvertParams(const std::string & S) const { + std::string R; + R.reserve(S.size()*2+1); + if(dbType_==pgsql) { + auto Idx=1; + for(auto const & i:S) + { + if(i=='?') { + R += '$'; + R.append(std::to_string(Idx++)); + } else { + R += i; + } + } + } else { + R = S; + } + return R; + } + + private: + inline int Setup_SQLite(); + inline int Setup_MySQL(); + inline int Setup_PostgreSQL(); + + protected: + Poco::SharedPtr Pool_; + Poco::Data::SQLite::Connector SQLiteConn_; + Poco::Data::PostgreSQL::Connector PostgresConn_; + Poco::Data::MySQL::Connector MySQLConn_; + DBType dbType_ = sqlite; + }; + +#ifdef SMALL_BUILD + int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; } + int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; } +#else + + inline int StorageClass::Setup_SQLite() { + Logger_.notice("SQLite StorageClass enabled."); + dbType_ = sqlite; + auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db"); + auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64); + auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60); + SQLiteConn_.registerConnector(); + Pool_ = Poco::SharedPtr(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime)); + return 0; + } + + inline int StorageClass::Setup_MySQL() { + Logger_.notice("MySQL StorageClass enabled."); + dbType_ = mysql; + auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64); + auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60); + auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host"); + auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username"); + auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password"); + auto Database = MicroService::instance().ConfigGetString("storage.type.mysql.database"); + auto Port = MicroService::instance().ConfigGetString("storage.type.mysql.port"); + + std::string ConnectionStr = + "host=" + Host + + ";user=" + Username + + ";password=" + Password + + ";db=" + Database + + ";port=" + Port + + ";compress=true;auto-reconnect=true"; + + MySQLConn_.registerConnector(); + Pool_ = Poco::SharedPtr(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); + + return 0; + } + + inline int StorageClass::Setup_PostgreSQL() { + Logger_.notice("PostgreSQL StorageClass enabled."); + dbType_ = pgsql; + auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64); + auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60); + auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host"); + auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username"); + auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password"); + auto Database = MicroService::instance().ConfigGetString("storage.type.postgresql.database"); + auto Port = MicroService::instance().ConfigGetString("storage.type.postgresql.port"); + auto ConnectionTimeout = MicroService::instance().ConfigGetString("storage.type.postgresql.connectiontimeout"); + + std::string ConnectionStr = + "host=" + Host + + " user=" + Username + + " password=" + Password + + " dbname=" + Database + + " port=" + Port + + " connect_timeout=" + ConnectionTimeout; + + PostgresConn_.registerConnector(); + Pool_ = Poco::SharedPtr(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); + + return 0; + } +#endif + +}