mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-11-02 19:57:46 +00:00
Fixing MFA saving issue
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_;
|
||||||
|
|||||||
Reference in New Issue
Block a user