diff --git a/build b/build index ca7bf83..da2d398 100644 --- a/build +++ b/build @@ -1 +1 @@ -13 \ No newline at end of file +14 \ No newline at end of file diff --git a/openpapi/owsec.yaml b/openpapi/owsec.yaml index 7f5883d..7c23a8c 100644 --- a/openpapi/owsec.yaml +++ b/openpapi/owsec.yaml @@ -1498,9 +1498,10 @@ paths: format: email required: true - in: query - name: serialNumber + name: signupUUID schema: type: string + format: uuid required: true responses: 200: @@ -1543,6 +1544,7 @@ paths: - inprogress - failed - poll + - emailVerified required: true requestBody: content: diff --git a/src/RESTAPI/RESTAPI_action_links.cpp b/src/RESTAPI/RESTAPI_action_links.cpp index 50ff337..a13cf0e 100644 --- a/src/RESTAPI/RESTAPI_action_links.cpp +++ b/src/RESTAPI/RESTAPI_action_links.cpp @@ -188,6 +188,7 @@ namespace OpenWifi { UInfo.changePassword = false; UInfo.lastEmailCheck = std::time(nullptr); UInfo.waitingForEmailCheck = false; + UInfo.validated = OpenWifi::Now(); StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); @@ -195,6 +196,20 @@ namespace OpenWifi { Types::StringPairVec FormVars{ {"UUID", Id}, {"USERNAME", UInfo.email} }; StorageService()->ActionLinksDB().CompleteAction(Id); + + // Send the update to the provisioning service + Poco::JSON::Object Body; + + OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup", + { + {"signupUUID", UInfo.signingUp} , + {"operation", "emailVerified"} + }, + Body,30000); + + Poco::JSON::Object::Ptr Response; + ProvRequest.Do(Response); + SendHTMLFileBack(FormFile,FormVars); } else { DoReturnA404(); diff --git a/src/RESTAPI/RESTAPI_signup_handler.cpp b/src/RESTAPI/RESTAPI_signup_handler.cpp index 4786e3a..96ce58c 100644 --- a/src/RESTAPI/RESTAPI_signup_handler.cpp +++ b/src/RESTAPI/RESTAPI_signup_handler.cpp @@ -11,9 +11,9 @@ namespace OpenWifi { void RESTAPI_signup_handler::DoPost() { auto UserName = GetParameter("email",""); - auto SerialNumber = GetParameter("serialNumber",""); + auto signupUUID = GetParameter("signupUUID",""); - if(UserName.empty() || SerialNumber.empty()) { + if(UserName.empty() || signupUUID.empty()) { return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); } @@ -21,10 +21,6 @@ namespace OpenWifi { return BadRequest(RESTAPI::Errors::InvalidEmailAddress); } - if(!Utils::ValidSerialNumber(SerialNumber)) { - return BadRequest(RESTAPI::Errors::InvalidSerialNumber); - } - // Do we already exist? Can only signup once... SecurityObjects::UserInfo Existing; if(StorageService()->SubDB().GetUserByEmail(UserName,Existing)) { @@ -41,7 +37,7 @@ namespace OpenWifi { } SecurityObjects::UserInfo NewSub; - NewSub.signingUp = SerialNumber; + NewSub.signingUp = signupUUID; NewSub.waitingForEmailCheck = true; NewSub.modified = std::time(nullptr); NewSub.creationDate = std::time(nullptr); diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp index 1f338c2..8eaa7de 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.cpp +++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp @@ -297,19 +297,20 @@ namespace OpenWifi::ProvObjects { 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, "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); field_to_json( Obj,"state",state); + field_to_json( Obj,"devClass",devClass); } bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -320,7 +321,7 @@ namespace OpenWifi::ProvObjects { 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, "qrCode", qrCode); field_from_json( Obj,"geoCode",geoCode); field_from_json( Obj,"location",location); field_from_json( Obj,"contact",contact); @@ -328,6 +329,7 @@ namespace OpenWifi::ProvObjects { field_from_json( Obj,"rrm",rrm); field_from_json( Obj,"managementPolicy",managementPolicy); field_from_json( Obj,"state",state); + field_from_json( Obj,"devClass",devClass); return true; } catch(...) { @@ -601,6 +603,30 @@ namespace OpenWifi::ProvObjects { return false; } + void SignupEntry::to_json(Poco::JSON::Object &Obj) const { + info.to_json(Obj); + RESTAPI_utils::field_to_json( Obj,"email", email); + RESTAPI_utils::field_to_json( Obj,"userId", userId); + RESTAPI_utils::field_to_json( Obj,"serialNumber", serialNumber); + RESTAPI_utils::field_to_json( Obj,"created", created); + RESTAPI_utils::field_to_json( Obj,"completed", completed); + } + + bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + info.from_json(Obj); + RESTAPI_utils::field_from_json( Obj,"email", email); + RESTAPI_utils::field_from_json( Obj,"userId", userId); + RESTAPI_utils::field_from_json( Obj,"serialNumber", serialNumber); + RESTAPI_utils::field_from_json( Obj,"created", created); + RESTAPI_utils::field_from_json( Obj,"completed", completed); + 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")) diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h index 991b8bf..b144e11 100644 --- a/src/RESTObjects/RESTAPI_ProvObjects.h +++ b/src/RESTObjects/RESTAPI_ProvObjects.h @@ -285,6 +285,7 @@ namespace OpenWifi::ProvObjects { std::string rrm; Types::UUID_t managementPolicy; std::string state; + std::string devClass; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); @@ -385,6 +386,18 @@ namespace OpenWifi::ProvObjects { bool from_json(const Poco::JSON::Object::Ptr &Obj); }; + struct SignupEntry { + ObjectInfo info; + std::string email; + std::string userId; + std::string serialNumber; + uint64_t created = 0 ; + uint64_t completed = 0 ; + + 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/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index a7f1d7e..0b9dba3 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -2414,7 +2414,7 @@ namespace OpenWifi { } else if(format == "uc-mac") { if(std::regex_match(value,mac_regex)) return; - throw std::invalid_argument(value + " is not a valid MAC: should be something like 2e60:3500::/64."); + throw std::invalid_argument(value + " is not a valid MAC: should be something like 11:22:33:44:55:66"); } else if(format == "uc-timeout") { if(std::regex_match(value,uc_timeout_regex)) return; diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index 7998f04..4c24a73 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -86,6 +86,8 @@ using namespace std::chrono_literals; namespace OpenWifi { + inline uint64_t Now() { return std::time(nullptr); }; + enum UNAUTHORIZED_REASON { SUCCESS=0, PASSWORD_CHANGE_REQUIRED, diff --git a/src/framework/orm.h b/src/framework/orm.h index 6b56371..ae4d1de 100644 --- a/src/framework/orm.h +++ b/src/framework/orm.h @@ -430,7 +430,6 @@ namespace ORM { Cache_->UpdateCache(R); return true; } - return false; } catch (const Poco::Exception &E) { Logger_.log(E); } @@ -467,9 +466,10 @@ namespace ORM { return false; } - typedef std::vector RecordList; + typedef std::vector RecordList; + typedef std::vector RecordVec; - bool GetRecords( uint64_t Offset, uint64_t HowMany, std::vector & Records, const std::string & Where = "", const std::string & OrderBy = "") { + bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") { try { Poco::Data::Session Session = Pool_.get(); Poco::Data::Statement Select(Session); diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 905b730..7250fbc 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -67,6 +67,8 @@ namespace OpenWifi::RESTAPI::Errors { static const std::string SMSCouldNotBeSentRetry{"SMS could not be sent to validate device, try later or change the phone number."}; static const std::string SMSCouldNotValidate{"Code and number could not be validated"}; static const std::string InvalidDeviceClass{"Invalid device class. Must be: any, venue, entity, or subscriber"}; + static const std::string SerialNumberAlreadyProvisioned{"This device has already been provisioned to a subscriber."}; + static const std::string SerialNumberNotTheProperClass{"Device is not available to subscribers. It ahs been assigned to another class of devices."}; } namespace OpenWifi::RESTAPI::Protocol { @@ -214,6 +216,9 @@ namespace OpenWifi::uCentralProtocol { static const char * FIRMWARE = "firmware"; static const char * CONNECT = "connect"; static const char * STATE = "state"; + static const char * STATUS = "status"; + static const char * ERROR = "error"; + static const char * TEXT = "text"; static const char * HEALTHCHECK = "healthcheck"; static const char * LOG = "log"; static const char * CRASHLOG = "crashlog";