mirror of
				https://github.com/Telecominfraproject/wlan-cloud-owprov.git
				synced 2025-10-31 10:37:57 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			202 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //
 | |
| // Created by stephane bourque on 2023-09-27.
 | |
| //
 | |
| 
 | |
| #include "RESTAPI_radius_endpoint_handler.h"
 | |
| #include <storage/storage_orion_accounts.h>
 | |
| #include <RESTObjects/RESTAPI_GWobjects.h>
 | |
| 
 | |
| namespace OpenWifi {
 | |
| 
 | |
|     void RESTAPI_radius_endpoint_handler::DoGet() {
 | |
|         auto id = GetBinding("id");
 | |
|         if(id.empty()) {
 | |
|             return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
 | |
|         }
 | |
| 
 | |
|         RecordType Record;
 | |
|         if(DB_.GetRecord("id",id,Record)) {
 | |
|             return ReturnObject(Record);
 | |
|         }
 | |
| 
 | |
|         return NotFound();
 | |
|     }
 | |
| 
 | |
|     void RESTAPI_radius_endpoint_handler::DoDelete() {
 | |
|         auto id = GetBinding("id");
 | |
|         if(id.empty()) {
 | |
|             return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
 | |
|         }
 | |
|         RecordType Record;
 | |
|         if(DB_.GetRecord("id",id,Record)) {
 | |
|             DB_.DeleteRecord("id",id);
 | |
|             ProvObjects::RADIUSEndpointUpdateStatus Status;
 | |
|             Status.ChangeConfiguration();
 | |
|             return OK();
 | |
|         }
 | |
|         return NotFound();
 | |
|     }
 | |
| 
 | |
|     static bool ValidPort(std::uint32_t P) {
 | |
|         return P>0 && P<65535;
 | |
|     }
 | |
| 
 | |
|     static bool ValidRadiusServer(const ProvObjects::RADIUSServer &S) {
 | |
|         if(S.Hostname.empty() || !ValidPort(S.Port) || !Utils::ValidIP(S.IP) || S.Secret.empty()) {
 | |
|             return false;
 | |
|         }
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     static bool ValidRadiusServer(const std::vector<ProvObjects::RADIUSServer> &ServerList) {
 | |
|         return std::all_of(ServerList.begin(),ServerList.end(),[](const ProvObjects::RADIUSServer &Server)->bool { return ValidRadiusServer(Server); });
 | |
|     }
 | |
| 
 | |
|     void RESTAPI_radius_endpoint_handler::DoPost() {
 | |
|         auto id = GetBinding("id");
 | |
|         if(id.empty()) {
 | |
|             return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
 | |
|         }
 | |
| 
 | |
|         const auto &RawObject = ParsedBody_;
 | |
|         RecordType     NewRecord;
 | |
|         if(!NewRecord.from_json(RawObject)) {
 | |
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | |
|         }
 | |
| 
 | |
|         if(GWObjects::RadiusEndpointType(NewRecord.Type)==GWObjects::RadiusEndpointType::unknown) {
 | |
|             return BadRequest(RESTAPI::Errors::InvalidRadiusTypeEndpoint);
 | |
|         }
 | |
|         if(GWObjects::RadiusPoolStrategy(NewRecord.PoolStrategy)==GWObjects::RadiusPoolStrategy::unknown) {
 | |
|             return BadRequest(RESTAPI::Errors::InvalidRadiusEndpointPoolStrategy);
 | |
|         }
 | |
|         if(!NewRecord.RadiusServers.empty() && !NewRecord.RadsecServers.empty()) {
 | |
|             return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
 | |
|         }
 | |
| 
 | |
|         auto EndPointType = GWObjects::RadiusEndpointType(NewRecord.Type);
 | |
|         switch(EndPointType) {
 | |
|             case GWObjects::RadiusEndpointType::radsec:
 | |
|             case GWObjects::RadiusEndpointType::orion:
 | |
|             case GWObjects::RadiusEndpointType::globalreach:
 | |
|             {
 | |
|                 if(NewRecord.RadsecServers.empty()) {
 | |
|                     return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
 | |
|                 }
 | |
|             } break;
 | |
|             case GWObjects::RadiusEndpointType::generic: {
 | |
|                 if(NewRecord.RadiusServers.empty()) {
 | |
|                     return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
 | |
|                 }
 | |
|             } break;
 | |
|             default:
 | |
|                 return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
 | |
|         }
 | |
| 
 | |
|         if(NewRecord.Index.empty() || !RadiusEndpointDB::ValidIndex(NewRecord.Index)) {
 | |
|             return BadRequest(RESTAPI::Errors::RadiusEndpointIndexInvalid);
 | |
|         }
 | |
| 
 | |
|         //  Make sure that nobody is using that index
 | |
|         auto where = fmt::format(" index='{}' ", NewRecord.Index);
 | |
|         if(DB_.Count(where)!=0) {
 | |
|             return BadRequest(RESTAPI::Errors::RadiusEndpointIndexInvalid);
 | |
|         }
 | |
| 
 | |
|         if(EndPointType==GWObjects::RadiusEndpointType::generic) {
 | |
|             for(const auto &Server:NewRecord.RadiusServers) {
 | |
|                 if(!ValidRadiusServer(Server.Authentication) ||
 | |
|                 !ValidRadiusServer(Server.Accounting) ||
 | |
|                 !ValidRadiusServer(Server.CoA)) {
 | |
|                     return BadRequest(RESTAPI::Errors::InvalidRadiusServer);
 | |
|                 }
 | |
|             }
 | |
|         } else {
 | |
|             switch(EndPointType) {
 | |
|                 case GWObjects::RadiusEndpointType::orion: {
 | |
|                     for(const auto &Server:NewRecord.RadsecServers) {
 | |
|                         if(!StorageService()->OrionAccountsDB().Exists("id",Server.UseOpenRoamingAccount)) {
 | |
|                             return BadRequest(RESTAPI::Errors::OrionAccountMustExist);
 | |
|                         }
 | |
|                     }
 | |
|                 } break;
 | |
|                 case GWObjects::RadiusEndpointType::globalreach: {
 | |
|                     for(const auto &Server:NewRecord.RadsecServers) {
 | |
|                         if(!StorageService()->GLBLRCertsDB().Exists("id",Server.UseOpenRoamingAccount)) {
 | |
|                             return BadRequest(RESTAPI::Errors::GlobalReachCertMustExist);
 | |
|                         }
 | |
|                     }
 | |
|                 } break;
 | |
|                 case GWObjects::RadiusEndpointType::radsec: {
 | |
|                     for(const auto &Server:NewRecord.RadsecServers) {
 | |
|                         if(Server.Certificate.empty() || !Utils::ValidX509Certificate(Server.Certificate)) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecMainCertificate);
 | |
|                         }
 | |
|                         if(Server.CaCerts.empty() || !Utils::ValidX509Certificate(Server.CaCerts)) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecCaCertificate);
 | |
|                         }
 | |
|                         if(Server.PrivateKey.empty() || !Utils::VerifyPrivateKey(Server.PrivateKey)) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecPrivteKey);
 | |
|                         }
 | |
|                         if(!Utils::ValidIP(Server.IP)) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecIPAddress);
 | |
|                         }
 | |
|                         if(!(Server.Port>0 && Server.Port<65535)) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecPort);
 | |
|                         }
 | |
|                         if(Server.Secret.empty()) {
 | |
|                             return BadRequest(RESTAPI::Errors::InvalidRadsecSecret);
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                 } break;
 | |
|                 default: {
 | |
| 
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewRecord.info);
 | |
|         if(DB_.CreateRecord(NewRecord)) {
 | |
|             RecordType  AddedRecord;
 | |
|             DB_.GetRecord("id", NewRecord.info.id, AddedRecord);
 | |
|             ProvObjects::RADIUSEndpointUpdateStatus Status;
 | |
|             Status.ChangeConfiguration();
 | |
|             return ReturnObject(AddedRecord);
 | |
|         }
 | |
|         return BadRequest(RESTAPI::Errors::RecordNotCreated);
 | |
|     }
 | |
| 
 | |
|     void RESTAPI_radius_endpoint_handler::DoPut() {
 | |
|         auto id = GetBinding("id");
 | |
|         if(id.empty()) {
 | |
|             return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
 | |
|         }
 | |
| 
 | |
|         const auto &RawObject = ParsedBody_;
 | |
|         RecordType     ModifiedRecord;
 | |
|         if(!ModifiedRecord.from_json(RawObject)) {
 | |
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | |
|         }
 | |
| 
 | |
|         RecordType     Existing;
 | |
|         if(!DB_.GetRecord("id",id,Existing)) {
 | |
|             return NotFound();
 | |
|         }
 | |
| 
 | |
|         AssignIfPresent(RawObject,"NasIdentifier", Existing.NasIdentifier);
 | |
|         AssignIfPresent(RawObject,"AccountingInterval", Existing.AccountingInterval);
 | |
| 
 | |
|         ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
 | |
|         if(DB_.UpdateRecord("id", Existing.info.id, Existing)) {
 | |
|             RecordType  AddedRecord;
 | |
|             DB_.GetRecord("id", Existing.info.id, AddedRecord);
 | |
|             ProvObjects::RADIUSEndpointUpdateStatus Status;
 | |
|             Status.ChangeConfiguration();
 | |
|             return ReturnObject(AddedRecord);
 | |
|         }
 | |
| 
 | |
|         return BadRequest(RESTAPI::Errors::NotImplemented);
 | |
|     }
 | |
| 
 | |
| } // OpenWifi
 | 
