mirror of
https://github.com/Telecominfraproject/wlan-cloud-owprov.git
synced 2025-11-01 02:58:00 +00:00
261 lines
11 KiB
C++
261 lines
11 KiB
C++
//
|
|
// Created by stephane bourque on 2022-02-20.
|
|
//
|
|
|
|
#include "RESTAPI_signup_handler.h"
|
|
#include "StorageService.h"
|
|
#include "Signup.h"
|
|
#include "framework/OpenAPIRequests.h"
|
|
#include "framework/MicroServiceNames.h"
|
|
#include "framework/MicroServiceFuncs.h"
|
|
#include "framework/utils.h"
|
|
|
|
namespace OpenWifi {
|
|
|
|
void RESTAPI_signup_handler::DoPost() {
|
|
auto UserName = GetParameter("email");
|
|
Poco::toLowerInPlace(UserName);
|
|
Poco::trimInPlace(UserName);
|
|
|
|
auto macAddress = GetParameter("macAddress");
|
|
Poco::toLowerInPlace(macAddress);
|
|
Poco::trimInPlace(macAddress);
|
|
|
|
auto deviceID = GetParameter("deviceID");
|
|
Poco::toLowerInPlace(deviceID);
|
|
Poco::trimInPlace(deviceID);
|
|
|
|
auto registrationId = GetParameter("registrationId");
|
|
Poco::toLowerInPlace(registrationId);
|
|
Poco::trimInPlace(registrationId);
|
|
|
|
if(UserName.empty() || macAddress.empty() || registrationId.empty()) {
|
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
}
|
|
|
|
if(!Utils::ValidEMailAddress(UserName)) {
|
|
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
|
}
|
|
|
|
if(!Utils::ValidSerialNumber(macAddress)) {
|
|
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
|
|
}
|
|
|
|
if(registrationId.empty()) {
|
|
return BadRequest(RESTAPI::Errors::InvalidRegistrationOperatorName);
|
|
}
|
|
|
|
// find the operator id
|
|
ProvObjects::Operator SignupOperator;
|
|
if(!StorageService()->OperatorDB().GetRecord("registrationId", registrationId, SignupOperator)) {
|
|
return BadRequest(RESTAPI::Errors::InvalidRegistrationOperatorName);
|
|
}
|
|
|
|
// if a signup already exists for this user, we should just return its value completion
|
|
SignupDB::RecordVec SEs;
|
|
if(StorageService()->SignupDB().GetRecords(0,100, SEs, " email='" + UserName + "' and serialNumber='"+macAddress+"' ")) {
|
|
for(const auto &i:SEs) {
|
|
|
|
if(!i.deviceID.empty() && i.deviceID!=deviceID) {
|
|
return BadRequest(RESTAPI::Errors::InvalidDeviceID);
|
|
}
|
|
|
|
if (i.statusCode == ProvObjects::SignupStatusCodes::SignupWaitingForEmail ||
|
|
i.statusCode == ProvObjects::SignupStatusCodes::SignupWaitingForDevice ||
|
|
i.statusCode == ProvObjects::SignupStatusCodes::SignupSuccess ) {
|
|
poco_debug(Logger(),fmt::format("SIGNUP: Returning existing signup record for '{}'",i.email));
|
|
Poco::JSON::Object Answer;
|
|
i.to_json(Answer);
|
|
return ReturnObject(Answer);
|
|
}
|
|
}
|
|
}
|
|
|
|
// So we do not have an outstanding signup...
|
|
// Can we actually claim this serial number??? if not, we need to return an error
|
|
ProvObjects::InventoryTag IT;
|
|
std::string SerialNumber;
|
|
bool FoundIT=false;
|
|
for(int Index=0;Index<4;Index++) {
|
|
auto TrySerialNumber = Utils::SerialNumberToInt(macAddress);
|
|
for (uint i = 0; i < 4; ++i) {
|
|
SerialNumber = Utils::IntToSerialNumber(TrySerialNumber + i);
|
|
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber, IT)) {
|
|
if (!IT.subscriber.empty()) {
|
|
return BadRequest(RESTAPI::Errors::SerialNumberAlreadyProvisioned);
|
|
}
|
|
|
|
if (!(IT.devClass.empty() || IT.devClass == "subscriber" || IT.devClass == "any")) {
|
|
return BadRequest(RESTAPI::Errors::SerialNumberNotTheProperClass);
|
|
}
|
|
FoundIT = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// OK, we can claim this device, can we create a userid?
|
|
// Let's create one
|
|
// If sec.signup("email",uuid);
|
|
auto SignupUUID = MicroServiceCreateUUID();
|
|
poco_debug(Logger(),fmt::format("SIGNUP: Creating signup entry for '{}', uuid='{}'",UserName, SignupUUID));
|
|
|
|
Poco::JSON::Object Body;
|
|
OpenAPIRequestPost CreateUser( uSERVICE_SECURITY, "/api/v1/signup", {
|
|
{ "email", UserName },
|
|
{ "signupUUID" , SignupUUID },
|
|
{ "owner" , SignupOperator.info.id },
|
|
{ "operatorName", SignupOperator.registrationId }
|
|
}, Body, 30000);
|
|
|
|
Poco::JSON::Object::Ptr Answer;
|
|
if(CreateUser.Do(Answer) == Poco::Net::HTTPServerResponse::HTTP_OK) {
|
|
SecurityObjects::UserInfo UI;
|
|
|
|
UI.from_json(Answer);
|
|
std::ostringstream os;
|
|
Answer->stringify(os);
|
|
poco_debug(Logger(),fmt::format("SIGNUP: email: '{}' signupID: '{}' userId: '{}'", UserName, SignupUUID, UI.id));
|
|
|
|
// so create the Signup entry and modify the inventory
|
|
ProvObjects::SignupEntry SE;
|
|
SE.info.id = SignupUUID;
|
|
SE.info.created = SE.info.modified = SE.submitted = Utils::Now();
|
|
SE.completed = 0 ;
|
|
SE.macAddress = macAddress;
|
|
SE.error = 0 ;
|
|
SE.userId = UI.id;
|
|
SE.email = UserName;
|
|
SE.deviceID = deviceID;
|
|
SE.registrationId = registrationId;
|
|
SE.status = "waiting-for-email-verification";
|
|
SE.operatorId = SignupOperator.info.id;
|
|
SE.statusCode = ProvObjects::SignupStatusCodes::SignupWaitingForEmail;
|
|
StorageService()->SignupDB().CreateRecord(SE);
|
|
Signup()->AddOutstandingSignup(SE);
|
|
|
|
if(FoundIT) {
|
|
Poco::JSON::Object StateDoc;
|
|
StateDoc.set("method", "signup");
|
|
StateDoc.set("claimer", UserName);
|
|
StateDoc.set("claimerId", UI.id);
|
|
StateDoc.set("signupUUID", SignupUUID);
|
|
StateDoc.set("errorCode",0);
|
|
StateDoc.set("date", Utils::Now());
|
|
StateDoc.set("status", "waiting for email-verification");
|
|
std::ostringstream os2;
|
|
StateDoc.stringify(os2);
|
|
IT.realMacAddress = macAddress;
|
|
IT.state = os2.str();
|
|
IT.info.modified = Utils::Now();
|
|
std::cout << "Updating inventory entry: " << SE.macAddress << std::endl;
|
|
StorageService()->InventoryDB().UpdateRecord("id",IT.info.id,IT);
|
|
}
|
|
|
|
Poco::JSON::Object SEAnswer;
|
|
SE.to_json(SEAnswer);
|
|
return ReturnObject(SEAnswer);
|
|
}
|
|
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
|
|
}
|
|
|
|
// this will be called by the SEC backend once the password has been verified.
|
|
void RESTAPI_signup_handler::DoPut() {
|
|
auto SignupUUID = GetParameter("signupUUID");
|
|
auto Operation = GetParameter("operation");
|
|
|
|
poco_information(Logger(),fmt::format("signup-progress: {} - {} ", SignupUUID, Operation));
|
|
if(SignupUUID.empty() || Operation.empty()) {
|
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
}
|
|
|
|
ProvObjects::SignupEntry SE;
|
|
poco_information(Logger(),fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
|
|
if(!StorageService()->SignupDB().GetRecord("id",SignupUUID,SE)) {
|
|
return NotFound();
|
|
}
|
|
|
|
poco_debug(Logger(),fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
|
|
if(Operation == "emailVerified" && SE.statusCode==ProvObjects::SignupStatusCodes::SignupWaitingForEmail) {
|
|
poco_information(Logger(),fmt::format("{}: email {} verified.",SE.info.id, SE.email));
|
|
std::cout << "Verified email for : " << SE.email << std::endl;
|
|
SE.info.modified = Utils::Now();
|
|
SE.status = "emailVerified";
|
|
SE.statusCode = ProvObjects::SignupStatusCodes::SignupWaitingForDevice;
|
|
StorageService()->SignupDB().UpdateRecord("id", SE.info.id, SE);
|
|
Signup()->AddOutstandingSignup(SE);
|
|
Poco::JSON::Object Answer;
|
|
SE.to_json(Answer);
|
|
return ReturnObject(Answer);
|
|
}
|
|
poco_information(Logger(),fmt::format("signup-progress: {} - {} something is bad", SignupUUID, Operation));
|
|
|
|
return BadRequest(RESTAPI::Errors::UnknownId);
|
|
}
|
|
|
|
void RESTAPI_signup_handler::DoGet() {
|
|
auto EMail = GetParameter("email");
|
|
auto SignupUUID = GetParameter("signupUUID");
|
|
auto macAddress = GetParameter("macAddress");
|
|
auto List = GetBoolParameter("listOnly",false);
|
|
|
|
poco_information(Logger(),fmt::format("Looking for signup for {}",EMail));
|
|
Poco::JSON::Object Answer;
|
|
ProvObjects::SignupEntry SE;
|
|
if(!SignupUUID.empty()) {
|
|
poco_information(Logger(),fmt::format("Looking for signup for {}: Signup {}",EMail, SignupUUID));
|
|
if(StorageService()->SignupDB().GetRecord("id", SignupUUID, SE)) {
|
|
SE.to_json(Answer);
|
|
return ReturnObject(Answer);
|
|
}
|
|
return NotFound();
|
|
} else if(!EMail.empty()) {
|
|
SignupDB::RecordVec SEs;
|
|
poco_information(Logger(),fmt::format("Looking for signup for {}: Signup {}",EMail, SignupUUID));
|
|
if(StorageService()->SignupDB().GetRecords(0,100,SEs, " email='"+EMail+"' ")) {
|
|
return ReturnObject("signups",SEs);
|
|
}
|
|
return NotFound();
|
|
} else if(!macAddress.empty()) {
|
|
SignupDB::RecordVec SEs;
|
|
poco_information(Logger(),fmt::format("Looking for signup for {}: Mac {}",EMail, macAddress));
|
|
if(StorageService()->SignupDB().GetRecords(0,100,SEs, " serialNumber='"+macAddress+"' ")) {
|
|
return ReturnObject("signups",SEs);
|
|
}
|
|
return NotFound();
|
|
} else if(List) {
|
|
poco_information(Logger(),fmt::format("Returning list of signups...",EMail, macAddress));
|
|
SignupDB::RecordVec SEs;
|
|
StorageService()->SignupDB().GetRecords(0,100,SEs);
|
|
return ReturnObject("signups",SEs);
|
|
}
|
|
poco_information(Logger(),fmt::format("Bad signup get",EMail, macAddress));
|
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
}
|
|
|
|
void RESTAPI_signup_handler::DoDelete() {
|
|
auto EMail = GetParameter("email", "");
|
|
auto SignupUUID = GetParameter("signupUUID", "");
|
|
auto macAddress = GetParameter("macAddress", "");
|
|
auto deviceID = GetParameter("deviceID","");
|
|
|
|
if(!SignupUUID.empty()) {
|
|
if(StorageService()->SignupDB().DeleteRecord("id", SignupUUID)) {
|
|
return OK();
|
|
}
|
|
return NotFound();
|
|
} else if(!EMail.empty()) {
|
|
if(StorageService()->SignupDB().DeleteRecord("email",EMail)) {
|
|
return OK();
|
|
}
|
|
return NotFound();
|
|
} else if(!macAddress.empty()) {
|
|
if(StorageService()->SignupDB().DeleteRecord("serialNumber", macAddress)) {
|
|
return OK();
|
|
}
|
|
return NotFound();
|
|
}
|
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
}
|
|
|
|
} |