// // 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_entity_handler.h" #include "RESTAPI_db_helpers.h" #include "RESTObjects/RESTAPI_ProvObjects.h" #include "RESTObjects/RESTAPI_SecurityObjects.h" #include "StorageService.h" #include "framework/CIDR.h" namespace OpenWifi { void RESTAPI_entity_handler::DoGet() { std::string UUID = GetBinding("uuid", ""); ProvObjects::Entity Existing; if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) { return NotFound(); } Poco::JSON::Object Answer; Existing.to_json(Answer); if (NeedAdditionalInfo()) AddExtendedInfo(Existing, Answer); ReturnObject(Answer); } void RESTAPI_entity_handler::DoDelete() { std::string UUID = GetBinding("uuid", ""); ProvObjects::Entity Existing; if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) { return NotFound(); } if (UUID == EntityDB::RootUUID()) { return BadRequest(RESTAPI::Errors::CannotDeleteRoot); } if (!Existing.children.empty() || !Existing.devices.empty() || !Existing.venues.empty() || !Existing.locations.empty() || !Existing.contacts.empty() || !Existing.configurations.empty()) { return BadRequest(RESTAPI::Errors::StillInUse); } MoveUsage(StorageService()->PolicyDB(), DB_, Existing.managementPolicy, "", Existing.info.id); DB_.DeleteRecord("id", UUID); DB_.DeleteChild("id", Existing.parent, UUID); return OK(); } void RESTAPI_entity_handler::DoPost() { std::string UUID = GetBinding("uuid", ""); if (UUID.empty()) { return BadRequest(RESTAPI::Errors::MissingUUID); } if (UUID == EntityDB::RootUUID()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } const auto &RawObject = ParsedBody_; ProvObjects::Entity NewEntity; if (!NewEntity.from_json(RawObject)) { return BadRequest(RESTAPI::Errors::InvalidJSONDocument); } if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules, *this))) { return; } if (!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewEntity.info)) { return BadRequest(RESTAPI::Errors::NameMustBeSet); } // When creating an entity, it cannot have any relations other that parent, notes, name, // description. Everything else must be conveyed through PUT. NewEntity.info.id = (UUID == EntityDB::RootUUID()) ? UUID : MicroServiceCreateUUID(); if (UUID == EntityDB::RootUUID()) { NewEntity.parent = ""; } else if (NewEntity.parent.empty() || !DB_.Exists("id", NewEntity.parent)) { return BadRequest(RESTAPI::Errors::ParentUUIDMustExist); } if (!NewEntity.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id", NewEntity.managementPolicy)) { return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID); } if (!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) { return BadRequest(RESTAPI::Errors::InvalidIPRanges); } NewEntity.venues.clear(); NewEntity.children.clear(); NewEntity.contacts.clear(); NewEntity.locations.clear(); NewEntity.deviceConfiguration.clear(); NewEntity.managementRoles.clear(); if (DB_.CreateRecord(NewEntity)) { MoveUsage(StorageService()->PolicyDB(), DB_, "", NewEntity.managementPolicy, NewEntity.info.id); DB_.AddChild("id", NewEntity.parent, NewEntity.info.id); Poco::JSON::Object Answer; NewEntity.to_json(Answer); return ReturnObject(Answer); } InternalError(RESTAPI::Errors::RecordNotCreated); } /* * Put is a complex operation, it contains commands only. * addContact=UUID, delContact=UUID, * addLocation=UUID, delLocation=UUID, * addVenue=UUID, delVenue=UUID, * addEntity=UUID, delEntity=UUID * addDevice=UUID, delDevice=UUID */ void RESTAPI_entity_handler::DoPut() { std::string UUID = GetBinding("uuid", ""); ProvObjects::Entity Existing; if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) { return NotFound(); } const auto &RawObject = ParsedBody_; ProvObjects::Entity NewEntity; if (!NewEntity.from_json(RawObject)) { return BadRequest(RESTAPI::Errors::InvalidJSONDocument); } if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules, *this))) { return; } if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) { return BadRequest(RESTAPI::Errors::NameMustBeSet); } std::string FromPolicy, ToPolicy; if (!CreateMove(RawObject, "managementPolicy", &EntityDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB())) return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID); if (RawObject->has("sourceIP")) { if (!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) { return BadRequest(RESTAPI::Errors::InvalidIPRanges); } Existing.sourceIP = NewEntity.sourceIP; } RESTAPI::Errors::msg Error; if (!StorageService()->Validate(Parameters_, Error)) { return BadRequest(Error); } if (RawObject->has("deviceRules")) Existing.deviceRules = NewEntity.deviceRules; if (DB_.UpdateRecord("id", UUID, Existing)) { MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id); Poco::JSON::Object Answer; ProvObjects::Entity NewRecord; StorageService()->EntityDB().GetRecord("id", UUID, NewRecord); NewRecord.to_json(Answer); return ReturnObject(Answer); } InternalError(RESTAPI::Errors::RecordNotUpdated); } } // namespace OpenWifi