Fixing MFA saving issue

This commit is contained in:
stephb9959
2021-10-12 13:55:58 -07:00
parent 448b5949d8
commit 0013f47cbf
5 changed files with 79 additions and 38 deletions

2
build
View File

@@ -1 +1 @@
37 38

View File

@@ -50,6 +50,8 @@ namespace OpenWifi::RESTAPI::Errors {
static const std::string InvalidPassword{"Invalid password."}; static const std::string InvalidPassword{"Invalid password."};
static const std::string PasswordRejected{"Password was rejected. This maybe an old password."}; static const std::string PasswordRejected{"Password was rejected. This maybe an old password."};
static const std::string InvalidIPRanges{"Invalid IP range specifications."}; static const std::string InvalidIPRanges{"Invalid IP range specifications."};
static const std::string NeedMobileNumber{"You must provide at least one validated phone number."};
static const std::string BadMFAMethod{"MFA only supports sms or email."};
} }
#endif //OWPROV_RESTAPI_ERRORS_H #endif //OWPROV_RESTAPI_ERRORS_H

View File

@@ -8,6 +8,7 @@
#include "Utils.h" #include "Utils.h"
#include "RESTAPI_utils.h" #include "RESTAPI_utils.h"
#include "RESTAPI_errors.h" #include "RESTAPI_errors.h"
#include "SMSSender.h"
namespace OpenWifi { namespace OpenWifi {
void RESTAPI_user_handler::DoGet() { void RESTAPI_user_handler::DoGet() {
@@ -113,50 +114,43 @@ namespace OpenWifi {
void RESTAPI_user_handler::DoPut() { void RESTAPI_user_handler::DoPut() {
std::string Id = GetBinding("id", ""); std::string Id = GetBinding("id", "");
if(Id.empty()) { if(Id.empty()) {
BadRequest(RESTAPI::Errors::MissingUserID); return BadRequest(RESTAPI::Errors::MissingUserID);
return;
} }
SecurityObjects::UserInfo LocalObject; SecurityObjects::UserInfo Existing;
if(!Storage()->GetUserById(Id,LocalObject)) { if(!Storage()->GetUserById(Id,Existing)) {
NotFound(); return NotFound();
return; }
SecurityObjects::UserInfo NewUser;
auto RawObject = ParseStream();
if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
} }
// some basic validations // some basic validations
auto RawObject = ParseStream();
if(RawObject->has("userRole") && SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN) { if(RawObject->has("userRole") && SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN) {
BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::InvalidUserRole);
return;
} }
// The only valid things to change are: changePassword, name, // The only valid things to change are: changePassword, name,
if(RawObject->has("name")) AssignIfPresent(RawObject,"name", Existing.name);
LocalObject.name = RawObject->get("name").toString(); AssignIfPresent(RawObject,"description", Existing.description);
if(RawObject->has("description")) AssignIfPresent(RawObject,"owner", Existing.owner);
LocalObject.description = RawObject->get("description").toString(); AssignIfPresent(RawObject,"location", Existing.location);
if(RawObject->has("avatar")) AssignIfPresent(RawObject,"locale", Existing.locale);
LocalObject.avatar = RawObject->get("avatar").toString(); AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
if(RawObject->has("changePassword")) AssignIfPresent(RawObject,"suspended", Existing.suspended);
LocalObject.changePassword = RawObject->get("changePassword").toString()=="true"; AssignIfPresent(RawObject,"blackListed", Existing.blackListed);
if(RawObject->has("owner"))
LocalObject.owner = RawObject->get("owner").toString();
if(RawObject->has("location"))
LocalObject.location = RawObject->get("location").toString();
if(RawObject->has("locale"))
LocalObject.locale = RawObject->get("locale").toString();
if(RawObject->has("userRole")) if(RawObject->has("userRole"))
LocalObject.userRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); Existing.userRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
if(RawObject->has("suspended"))
LocalObject.suspended = RawObject->get("suspended").toString()=="true";
if(RawObject->has("blackListed"))
LocalObject.blackListed = RawObject->get("blackListed").toString()=="true";
if(RawObject->has("notes")) { if(RawObject->has("notes")) {
SecurityObjects::NoteInfoVec NIV; SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString()); NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
for(auto const &i:NIV) { for(auto const &i:NIV) {
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note}; SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note};
LocalObject.notes.push_back(ii); Existing.notes.push_back(ii);
} }
} }
if(RawObject->has("currentPassword")) { if(RawObject->has("currentPassword")) {
@@ -164,22 +158,54 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::InvalidPassword); BadRequest(RESTAPI::Errors::InvalidPassword);
return; return;
} }
if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),LocalObject)) { if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),Existing)) {
BadRequest(RESTAPI::Errors::PasswordRejected); BadRequest(RESTAPI::Errors::PasswordRejected);
return; return;
} }
} }
if(GetParameter("email_verification","false")=="true") { if(GetParameter("email_verification","false")=="true") {
if(AuthService::VerifyEmail(LocalObject)) if(AuthService::VerifyEmail(Existing))
Logger_.information(Poco::format("Verification e-mail requested for %s",LocalObject.email)); Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email));
} }
if(Storage()->UpdateUserInfo(UserInfo_.userinfo.email,Id,LocalObject)) { if(NewUser.userTypeProprietaryInfo.mfa.enabled!=Existing.userTypeProprietaryInfo.mfa.enabled) {
std::cout << "Saving MFA" << std::endl;
if(!NewUser.userTypeProprietaryInfo.mfa.enabled) {
Existing.userTypeProprietaryInfo.mfa.enabled=false;
} else {
// Need to make sure the provided number has been validated.
if(NewUser.userTypeProprietaryInfo.mfa.method=="sms") {
std::cout << "Saving in sms" << std::endl;
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
if(!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number)){
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
Existing.userTypeProprietaryInfo.mfa.method = "sms";
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
std::cout << "Saving in mobiles" << std::endl;
} else if(NewUser.userTypeProprietaryInfo.mfa.method=="email") {
} else {
return BadRequest(RESTAPI::Errors::BadMFAMethod);
}
}
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
}
if(Storage()->UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
std::cout << "Saved data." << std::endl;
SecurityObjects::UserInfo NewUserInfo;
Storage()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
Poco::JSON::Object ModifiedObject; Poco::JSON::Object ModifiedObject;
LocalObject.to_json(ModifiedObject); NewUserInfo.to_json(ModifiedObject);
ReturnObject(ModifiedObject);
return; return ReturnObject(ModifiedObject);
} }
BadRequest(RESTAPI::Errors::RecordNotUpdated); BadRequest(RESTAPI::Errors::RecordNotUpdated);
} }

View File

@@ -53,11 +53,22 @@ namespace OpenWifi {
return Send(Number, Message)==0; return Send(Number, Message)==0;
} }
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code) { bool SMSSender::IsNumberValid(const std::string &Number) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
for(const auto &i:Cache_) { for(const auto &i:Cache_) {
if(i.Number==Number)
return i.Validated;
}
return false;
}
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code) {
std::lock_guard G(Mutex_);
for(auto &i:Cache_) {
if(i.Code==Code && i.Number==Number) { if(i.Code==Code && i.Number==Number) {
i.Validated=true;
return true; return true;
} }
} }

View File

@@ -16,6 +16,7 @@ namespace OpenWifi {
std::string Number; std::string Number;
std::string Code; std::string Code;
uint64_t Created; uint64_t Created;
bool Validated=false;
}; };
class SMSSender : public SubSystemServer { class SMSSender : public SubSystemServer {
@@ -33,6 +34,7 @@ namespace OpenWifi {
bool Enabled() const { return Enabled_; } bool Enabled() const { return Enabled_; }
bool StartValidation(const std::string &Number); bool StartValidation(const std::string &Number);
bool CompleteValidation(const std::string &Number, const std::string &Code); bool CompleteValidation(const std::string &Number, const std::string &Code);
bool IsNumberValid(const std::string &Number);
private: private:
static SMSSender * instance_; static SMSSender * instance_;
std::string SecretKey_; std::string SecretKey_;