Adding creation right ans support for owner field in user.

This commit is contained in:
stephb9959
2022-01-01 22:47:06 -08:00
parent 2eccf1ef06
commit 51dd7bdfa7
10 changed files with 106 additions and 56 deletions

View File

@@ -110,7 +110,7 @@ add_executable( owsec
src/framework/OpenWifiTypes.h src/framework/OpenWifiTypes.h
src/RESTAPI/RESTAPI_submfa_handler.cpp src/RESTAPI/RESTAPI_submfa_handler.h src/RESTAPI/RESTAPI_submfa_handler.cpp src/RESTAPI/RESTAPI_submfa_handler.h
src/storage/orm_users.cpp src/storage/orm_users.h src/storage/orm_users.cpp src/storage/orm_users.h
src/storage/orm_tokens.cpp src/storage/orm_tokens.h src/storage/orm_preferences.cpp src/storage/orm_preferences.h src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h src/storage/orm_avatar.cpp src/storage/orm_avatar.h src/SpecialUserHelpers.h) src/storage/orm_tokens.cpp src/storage/orm_tokens.h src/storage/orm_preferences.cpp src/storage/orm_preferences.h src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h src/storage/orm_avatar.cpp src/storage/orm_avatar.h src/SpecialUserHelpers.h src/RESTAPI/RESTAPI_db_helpers.h)
if(NOT SMALL_BUILD) if(NOT SMALL_BUILD)
target_link_libraries(owsec PUBLIC target_link_libraries(owsec PUBLIC

2
build
View File

@@ -1 +1 @@
164 167

View File

@@ -17,22 +17,62 @@ namespace OpenWifi {
DELETE, DELETE,
CREATE CREATE
}; };
/*
1) You cannot delete yourself
2) If you are root, you can do anything.
3) You can do anything to yourself
4) Nobody can touch a root, unless they are a root, unless it is to get information on a ROOT
5) Creation rules:
ROOT -> create anything
PARTNER -> (multi-tenant owner) admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning
ADMIN -> admin-subs-csr-installer-noc-accounting
ACCOUNTING -> subs-installer-csr
*/
static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
// rule 1
if(User.Id == Target.Id && Op==DELETE) if(User.Id == Target.Id && Op==DELETE)
return false; return false;
// rule 2
if(User.userRole==SecurityObjects::ROOT) if(User.userRole==SecurityObjects::ROOT)
return true; return true;
// rule 3
if(User.Id == Target.Id) if(User.Id == Target.Id)
return true; return true;
if(User.userRole!=SecurityObjects::ADMIN && User.userRole!=SecurityObjects::ROOT && Op!=READ) // rule 4
return false;
if(Target.userRole==SecurityObjects::ROOT && Op!=READ) if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
return false; return false;
if(Op==CREATE) {
if(User.userRole==SecurityObjects::ROOT)
return true;
if(User.userRole==SecurityObjects::PARTNER && (Target.userRole==SecurityObjects::ADMIN ||
Target.userRole==SecurityObjects::SUBSCRIBER ||
Target.userRole==SecurityObjects::CSR ||
Target.userRole==SecurityObjects::INSTALLER ||
Target.userRole==SecurityObjects::NOC ||
Target.userRole==SecurityObjects::ACCOUNTING))
return true;
if(User.userRole==SecurityObjects::ADMIN &&
(Target.userRole==SecurityObjects::ADMIN ||
Target.userRole==SecurityObjects::SUBSCRIBER ||
Target.userRole==SecurityObjects::CSR ||
Target.userRole==SecurityObjects::INSTALLER ||
Target.userRole==SecurityObjects::NOC ||
Target.userRole==SecurityObjects::ACCOUNTING))
return true;
if(User.userRole==SecurityObjects::ACCOUNTING &&
(Target.userRole==SecurityObjects::SUBSCRIBER ||
Target.userRole==SecurityObjects::INSTALLER ||
Target.userRole==SecurityObjects::CSR))
return true;
return false;
}
return true; return true;
} }
private: private:

View File

@@ -0,0 +1,17 @@
//
// Created by stephane bourque on 2022-01-01.
//
#pragma once
#include "framework/orm.h"
namespace OpenWifi {
inline void Sanitize(const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
}

View File

@@ -8,22 +8,16 @@
#include "Poco/JSON/Parser.h" #include "Poco/JSON/Parser.h"
#include "Daemon.h"
#include "AuthService.h" #include "AuthService.h"
#include "RESTAPI_oauth2_handler.h" #include "RESTAPI_oauth2_handler.h"
#include "MFAServer.h" #include "MFAServer.h"
#include "framework/RESTAPI_protocol.h" #include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include "StorageService.h" #include "StorageService.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_oauth2_handler::DoGet() { void RESTAPI_oauth2_handler::DoGet() {
bool Expired = false; bool Expired = false;
if (!IsAuthorized(Expired)) { if (!IsAuthorized(Expired)) {
@@ -36,7 +30,7 @@ namespace OpenWifi {
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email)); Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
Poco::JSON::Object Me; Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
FilterCredentials(ReturnedUser); Sanitize(UserInfo_, ReturnedUser);
ReturnedUser.to_json(Me); ReturnedUser.to_json(Me);
return ReturnObject(Me); return ReturnObject(Me);
} }

View File

@@ -3,21 +3,15 @@
// //
#include "RESTAPI_suboauth2_handler.h" #include "RESTAPI_suboauth2_handler.h"
#include "Daemon.h"
#include "AuthService.h" #include "AuthService.h"
#include "MFAServer.h" #include "MFAServer.h"
#include "framework/RESTAPI_protocol.h" #include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include "StorageService.h" #include "StorageService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_suboauth2_handler::DoGet() { void RESTAPI_suboauth2_handler::DoGet() {
bool Expired = false; bool Expired = false;
if (!IsAuthorized(Expired, true)) { if (!IsAuthorized(Expired, true)) {
@@ -30,7 +24,7 @@ namespace OpenWifi {
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email)); Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
Poco::JSON::Object Me; Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
FilterCredentials(ReturnedUser); Sanitize(UserInfo_, ReturnedUser);
ReturnedUser.to_json(Me); ReturnedUser.to_json(Me);
return ReturnObject(Me); return ReturnObject(Me);
} }

View File

@@ -8,15 +8,10 @@
#include "SMSSender.h" #include "SMSSender.h"
#include "ACLProcessor.h" #include "ACLProcessor.h"
#include "AuthService.h" #include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_subuser_handler::DoGet() { void RESTAPI_subuser_handler::DoGet() {
std::string Id = GetBinding("id", ""); std::string Id = GetBinding("id", "");
if(Id.empty()) { if(Id.empty()) {
@@ -35,7 +30,7 @@ namespace OpenWifi {
} }
Poco::JSON::Object UserInfoObject; Poco::JSON::Object UserInfoObject;
FilterCredentials(UInfo); Sanitize(UserInfo_, UInfo);
UInfo.to_json(UserInfoObject); UInfo.to_json(UserInfoObject);
ReturnObject(UserInfoObject); ReturnObject(UserInfoObject);
} }
@@ -82,11 +77,16 @@ namespace OpenWifi {
SecurityObjects::UserInfo NewUser; SecurityObjects::UserInfo NewUser;
RESTAPI_utils::from_request(NewUser,*Request); RESTAPI_utils::from_request(NewUser,*Request);
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
return BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::EntityMustExist);
}
NewUser.owner = UserInfo_.userinfo.owner;
if(NewUser.owner.empty()) {
return BadRequest("Owner must be set for a subscriber.");
} }
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED); return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
} }
Poco::toLowerInPlace(NewUser.email); Poco::toLowerInPlace(NewUser.email);
@@ -120,7 +120,7 @@ namespace OpenWifi {
} }
Poco::JSON::Object UserInfoObject; Poco::JSON::Object UserInfoObject;
FilterCredentials(NewUser); Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject); NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject); ReturnObject(UserInfoObject);
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email)); Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
@@ -157,7 +157,7 @@ namespace OpenWifi {
// The only valid things to change are: changePassword, name, // The only valid things to change are: changePassword, name,
AssignIfPresent(RawObject,"name", Existing.name); AssignIfPresent(RawObject,"name", Existing.name);
AssignIfPresent(RawObject,"description", Existing.description); AssignIfPresent(RawObject,"description", Existing.description);
AssignIfPresent(RawObject,"owner", Existing.owner); // AssignIfPresent(RawObject,"owner", Existing.owner);
AssignIfPresent(RawObject,"location", Existing.location); AssignIfPresent(RawObject,"location", Existing.location);
AssignIfPresent(RawObject,"locale", Existing.locale); AssignIfPresent(RawObject,"locale", Existing.locale);
AssignIfPresent(RawObject,"changePassword", Existing.changePassword); AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
@@ -233,9 +233,9 @@ namespace OpenWifi {
if(StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) { if(StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
SecurityObjects::UserInfo NewUserInfo; SecurityObjects::UserInfo NewUserInfo;
StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); StorageService()->SubDB().GetUserById(Id,NewUserInfo);
Poco::JSON::Object ModifiedObject; Poco::JSON::Object ModifiedObject;
FilterCredentials(NewUserInfo); Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject); NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject); return ReturnObject(ModifiedObject);
} }

View File

@@ -6,6 +6,7 @@
#include "StorageService.h" #include "StorageService.h"
#include "framework/RESTAPI_protocol.h" #include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
@@ -22,9 +23,7 @@ namespace OpenWifi {
if (IdOnly) { if (IdOnly) {
ArrayObj.add(i.Id); ArrayObj.add(i.Id);
} else { } else {
i.currentPassword.clear(); Sanitize(UserInfo_, i);
i.lastPasswords.clear();
i.oauthType.clear();
i.to_json(Obj); i.to_json(Obj);
ArrayObj.add(Obj); ArrayObj.add(Obj);
} }
@@ -42,9 +41,7 @@ namespace OpenWifi {
if (IdOnly) { if (IdOnly) {
ArrayObj.add(UInfo.Id); ArrayObj.add(UInfo.Id);
} else { } else {
UInfo.currentPassword.clear(); Sanitize(UserInfo_, UInfo);
UInfo.lastPasswords.clear();
UInfo.oauthType.clear();
UInfo.to_json(Obj); UInfo.to_json(Obj);
ArrayObj.add(Obj); ArrayObj.add(Obj);
} }

View File

@@ -8,15 +8,10 @@
#include "SMSSender.h" #include "SMSSender.h"
#include "ACLProcessor.h" #include "ACLProcessor.h"
#include "AuthService.h" #include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_user_handler::DoGet() { void RESTAPI_user_handler::DoGet() {
std::string Id = GetBinding("id", ""); std::string Id = GetBinding("id", "");
if(Id.empty()) { if(Id.empty()) {
@@ -34,8 +29,12 @@ namespace OpenWifi {
return NotFound(); return NotFound();
} }
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
}
Poco::JSON::Object UserInfoObject; Poco::JSON::Object UserInfoObject;
FilterCredentials(UInfo); Sanitize(UserInfo_, UInfo);
UInfo.to_json(UserInfoObject); UInfo.to_json(UserInfoObject);
ReturnObject(UserInfoObject); ReturnObject(UserInfoObject);
} }
@@ -80,6 +79,12 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::InvalidUserRole);
} }
if(UserInfo_.userinfo.userRole==SecurityObjects::ROOT) {
NewUser.owner = GetParameter("entity","");
} else {
NewUser.owner = UserInfo_.userinfo.owner;
}
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED); return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
} }
@@ -115,7 +120,7 @@ namespace OpenWifi {
} }
Poco::JSON::Object UserInfoObject; Poco::JSON::Object UserInfoObject;
FilterCredentials(NewUser); Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject); NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject); ReturnObject(UserInfoObject);
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email)); Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
@@ -147,10 +152,16 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::InvalidUserRole);
} }
if(RawObject->has("owner")) {
if (UserInfo_.userinfo.userRole == SecurityObjects::ROOT && Existing.owner.empty()) {
AssignIfPresent(RawObject, "owner", Existing.owner);
}
}
// The only valid things to change are: changePassword, name, // The only valid things to change are: changePassword, name,
AssignIfPresent(RawObject,"name", Existing.name); AssignIfPresent(RawObject,"name", Existing.name);
AssignIfPresent(RawObject,"description", Existing.description); AssignIfPresent(RawObject,"description", Existing.description);
AssignIfPresent(RawObject,"owner", Existing.owner);
AssignIfPresent(RawObject,"location", Existing.location); AssignIfPresent(RawObject,"location", Existing.location);
AssignIfPresent(RawObject,"locale", Existing.locale); AssignIfPresent(RawObject,"locale", Existing.locale);
AssignIfPresent(RawObject,"changePassword", Existing.changePassword); AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
@@ -228,7 +239,7 @@ namespace OpenWifi {
SecurityObjects::UserInfo NewUserInfo; SecurityObjects::UserInfo NewUserInfo;
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
Poco::JSON::Object ModifiedObject; Poco::JSON::Object ModifiedObject;
FilterCredentials(NewUserInfo); Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject); NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject); return ReturnObject(ModifiedObject);
} }

View File

@@ -6,6 +6,7 @@
#include "StorageService.h" #include "StorageService.h"
#include "framework/RESTAPI_protocol.h" #include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h" #include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi { namespace OpenWifi {
void RESTAPI_users_handler::DoGet() { void RESTAPI_users_handler::DoGet() {
@@ -21,9 +22,7 @@ namespace OpenWifi {
if (IdOnly) { if (IdOnly) {
ArrayObj.add(i.Id); ArrayObj.add(i.Id);
} else { } else {
i.currentPassword.clear(); Sanitize(UserInfo_, i);
i.lastPasswords.clear();
i.oauthType.clear();
i.to_json(Obj); i.to_json(Obj);
ArrayObj.add(Obj); ArrayObj.add(Obj);
} }
@@ -41,9 +40,7 @@ namespace OpenWifi {
if (IdOnly) { if (IdOnly) {
ArrayObj.add(UInfo.Id); ArrayObj.add(UInfo.Id);
} else { } else {
UInfo.currentPassword.clear(); Sanitize(UserInfo_, UInfo);
UInfo.lastPasswords.clear();
UInfo.oauthType.clear();
UInfo.to_json(Obj); UInfo.to_json(Obj);
ArrayObj.add(Obj); ArrayObj.add(Obj);
} }