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/RESTAPI/RESTAPI_submfa_handler.cpp src/RESTAPI/RESTAPI_submfa_handler.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)
target_link_libraries(owsec PUBLIC

2
build
View File

@@ -1 +1 @@
164
167

View File

@@ -17,22 +17,62 @@ namespace OpenWifi {
DELETE,
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) {
// rule 1
if(User.Id == Target.Id && Op==DELETE)
return false;
// rule 2
if(User.userRole==SecurityObjects::ROOT)
return true;
// rule 3
if(User.Id == Target.Id)
return true;
if(User.userRole!=SecurityObjects::ADMIN && User.userRole!=SecurityObjects::ROOT && Op!=READ)
return false;
// rule 4
if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
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;
}
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 "Daemon.h"
#include "AuthService.h"
#include "RESTAPI_oauth2_handler.h"
#include "MFAServer.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
#include "StorageService.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_oauth2_handler::DoGet() {
bool Expired = false;
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));
Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
FilterCredentials(ReturnedUser);
Sanitize(UserInfo_, ReturnedUser);
ReturnedUser.to_json(Me);
return ReturnObject(Me);
}

View File

@@ -3,21 +3,15 @@
//
#include "RESTAPI_suboauth2_handler.h"
#include "Daemon.h"
#include "AuthService.h"
#include "MFAServer.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
#include "StorageService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_suboauth2_handler::DoGet() {
bool Expired = false;
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));
Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
FilterCredentials(ReturnedUser);
Sanitize(UserInfo_, ReturnedUser);
ReturnedUser.to_json(Me);
return ReturnObject(Me);
}

View File

@@ -8,15 +8,10 @@
#include "SMSSender.h"
#include "ACLProcessor.h"
#include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_subuser_handler::DoGet() {
std::string Id = GetBinding("id", "");
if(Id.empty()) {
@@ -35,7 +30,7 @@ namespace OpenWifi {
}
Poco::JSON::Object UserInfoObject;
FilterCredentials(UInfo);
Sanitize(UserInfo_, UInfo);
UInfo.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
}
@@ -82,11 +77,16 @@ namespace OpenWifi {
SecurityObjects::UserInfo NewUser;
RESTAPI_utils::from_request(NewUser,*Request);
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)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
}
Poco::toLowerInPlace(NewUser.email);
@@ -120,7 +120,7 @@ namespace OpenWifi {
}
Poco::JSON::Object UserInfoObject;
FilterCredentials(NewUser);
Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
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,
AssignIfPresent(RawObject,"name", Existing.name);
AssignIfPresent(RawObject,"description", Existing.description);
AssignIfPresent(RawObject,"owner", Existing.owner);
// AssignIfPresent(RawObject,"owner", Existing.owner);
AssignIfPresent(RawObject,"location", Existing.location);
AssignIfPresent(RawObject,"locale", Existing.locale);
AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
@@ -233,9 +233,9 @@ namespace OpenWifi {
if(StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
SecurityObjects::UserInfo NewUserInfo;
StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
StorageService()->SubDB().GetUserById(Id,NewUserInfo);
Poco::JSON::Object ModifiedObject;
FilterCredentials(NewUserInfo);
Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject);
}

View File

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

View File

@@ -8,15 +8,10 @@
#include "SMSSender.h"
#include "ACLProcessor.h"
#include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
static void FilterCredentials(SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();
}
void RESTAPI_user_handler::DoGet() {
std::string Id = GetBinding("id", "");
if(Id.empty()) {
@@ -34,8 +29,12 @@ namespace OpenWifi {
return NotFound();
}
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
}
Poco::JSON::Object UserInfoObject;
FilterCredentials(UInfo);
Sanitize(UserInfo_, UInfo);
UInfo.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
}
@@ -80,6 +79,12 @@ namespace OpenWifi {
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)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
}
@@ -115,7 +120,7 @@ namespace OpenWifi {
}
Poco::JSON::Object UserInfoObject;
FilterCredentials(NewUser);
Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
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);
}
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,
AssignIfPresent(RawObject,"name", Existing.name);
AssignIfPresent(RawObject,"description", Existing.description);
AssignIfPresent(RawObject,"owner", Existing.owner);
AssignIfPresent(RawObject,"location", Existing.location);
AssignIfPresent(RawObject,"locale", Existing.locale);
AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
@@ -228,7 +239,7 @@ namespace OpenWifi {
SecurityObjects::UserInfo NewUserInfo;
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
Poco::JSON::Object ModifiedObject;
FilterCredentials(NewUserInfo);
Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject);
}

View File

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