Enhance the auth on Site and User
MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
import { Action, AuthorizationFilter, Entity } from '../../../../types/Authorization';
import { HttpSiteAssignUsersRequest, HttpSiteRequest, HttpSiteUsersRequest } from '../../../../types/requests/HttpSiteRequest';
-import { HttpUserRequest, HttpUserSitesRequest, HttpUsersRequest } from '../../../../types/requests/HttpUserRequest';
+import { HttpUserAssignSitesRequest, HttpUserRequest, HttpUserSitesRequest, HttpUsersRequest } from '../../../../types/requests/HttpUserRequest';
import User, { UserRole } from '../../../../types/User';
import AppAuthError from '../../../../exception/AppAuthError';
@@ -37,7 +37,18 @@ export default class AuthorizationService {
if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
// Get Site IDs from Site Admin flag
const siteIDs = await AuthorizationService.getAssignedSiteIDs(tenant.id, userToken, filteredRequest.ID);
- if (Utils.isEmptyArray(siteIDs)) {
+ if (!Utils.isEmptyArray(siteIDs)) {
+ if (!siteIDs.includes(filteredRequest.ID)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: userToken,
+ action: Action.READ, entity: Entity.SITE,
+ module: MODULE_NAME, method: 'checkAndGetSiteAuthorizationFilters',
+ });
+ } else {
+ authorizationFilters.authorized = true;
+ }
+ } else {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: userToken,
@@ -85,9 +96,25 @@ export default class AuthorizationService {
if (!Utils.isEmptyArray(filteredRequest.ProjectFields)) {
authorizationFilters.projectFields = authorizationFilters.projectFields.filter((projectField) => filteredRequest.ProjectFields.includes(projectField));
}
- // Handle Sites
- await AuthorizationService.checkAssignedSites(
- tenant, userToken, filteredRequest, authorizationFilters);
+ // Not an Admin?
+ if (userToken.role !== UserRole.ADMIN) {
+ // Get Site IDs from Site Admin flag
+ const siteIDs = await AuthorizationService.getAssignedSiteIDs(tenant.id, userToken);
+ if (!Utils.isEmptyArray(siteIDs)) {
+ // Force the filter
+ authorizationFilters.filters.siteIDs = siteIDs;
+ // Check if filter is provided
+ if (filteredRequest.SiteID) {
+ const filteredSiteIDs = filteredRequest.SiteID.split('|');
+ // Override
+ authorizationFilters.filters.siteIDs = filteredSiteIDs.filter(
+ (siteID) => authorizationFilters.filters.siteIDs.includes(siteID));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.siteIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ }
return authorizationFilters;
}
@@ -133,15 +160,9 @@ export default class AuthorizationService {
tenant: Tenant, action: ServerAction, userToken: UserToken, filteredRequest: HttpSiteAssignUsersRequest): Promise<AuthorizationFilter> {
const authorizationFilters: AuthorizationFilter = {
filters: {},
- projectFields: [
- 'user.id', 'user.name', 'user.firstName', 'user.email', 'user.role', 'siteAdmin', 'siteOwner', 'siteID'
- ],
+ projectFields: [],
authorized: userToken.role === UserRole.ADMIN,
};
- // Check projection
- if (!Utils.isEmptyArray(filteredRequest.ProjectFields)) {
- authorizationFilters.projectFields = authorizationFilters.projectFields.filter((projectField) => filteredRequest.ProjectFields.includes(projectField));
- }
// Not an Admin?
if (userToken.role !== UserRole.ADMIN) {
if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
@@ -185,6 +206,51 @@ export default class AuthorizationService {
return authorizationFilters;
}
+ public static async checkAndAssignUserSitesAuthorizationFilters(
+ tenant: Tenant, action: ServerAction, userToken: UserToken, filteredRequest: HttpUserAssignSitesRequest): Promise<AuthorizationFilter> {
+ const authorizationFilters: AuthorizationFilter = {
+ filters: {},
+ projectFields: [],
+ authorized: userToken.role === UserRole.ADMIN,
+ };
+ // Not an Admin?
+ if (userToken.role !== UserRole.ADMIN) {
+ if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
+ // Get Site IDs from Site Admin flag
+ const siteAdminSiteIDs = await AuthorizationService.getSiteAdminSiteIDs(tenant.id, userToken);
+ // Get User IDs from Site Admin flag
+ if (!Utils.isEmptyArray(siteAdminSiteIDs)) {
+ // Check Sites
+ if (!Utils.isEmptyArray(filteredRequest.siteIDs)) {
+ let foundInvalidUserID = false;
+ // Check
+ for (const siteID of filteredRequest.siteIDs) {
+ if (!siteAdminSiteIDs.includes(siteID)) {
+ foundInvalidUserID = true;
+ break;
+ }
+ }
+ if (!foundInvalidUserID) {
+ authorizationFilters.authorized = true;
+ }
+ }
+ }
+ if (!authorizationFilters.authorized) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: userToken,
+ action: action === ServerAction.ADD_SITES_TO_USER ? Action.ASSIGN : Action.UNASSIGN,
+ entity: Entity.USERS_SITES,
+ module: MODULE_NAME, method: 'checkAndAssignUserSitesAuthorizationFilters'
+ });
+ }
+ } else {
+ authorizationFilters.authorized = true;
+ }
+ }
+ return authorizationFilters;
+ }
+
public static async checkAndGetUsersInErrorAuthorizationFilters(
tenant: Tenant, userToken: UserToken, filteredRequest: HttpUsersRequest): Promise<AuthorizationFilter> {
const authorizationFilters: AuthorizationFilter = {
@@ -313,7 +379,7 @@ export default class AuthorizationService {
}
private static async checkAssignedSites(tenant: Tenant, userToken: UserToken,
- filteredRequest: HttpSiteUsersRequest|HttpUserSitesRequest|HttpUserRequest, authorizationFilters: AuthorizationFilter): Promise<void> {
+ filteredRequest: HttpSiteUsersRequest|HttpUserSitesRequest|HttpUserRequest|HttpUserAssignSitesRequest, authorizationFilters: AuthorizationFilter): Promise<void> {
if (userToken.role !== UserRole.ADMIN) {
if (Utils.isTenantComponentActive(tenant, TenantComponents.ORGANIZATION)) {
// Get Site IDs from Site Admin flag

MODIFY
src/server/rest/v1/service/SiteService.ts
src/server/rest/v1/service/SiteService.ts
@@ -75,12 +75,20 @@ export default class SiteService {
value: filteredRequest.siteID
});
}
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.siteID });
// Get the Site
- const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.siteID);
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.siteID, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.siteID}' does not exist`,
MODULE_NAME, 'handleUpdateSiteUserAdmin', req.user);
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.userID });
// Get the User
- const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.userID);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.userID, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User with ID '${filteredRequest.userID}' does not exist`,
MODULE_NAME, 'handleUpdateSiteUserAdmin', req.user);
// Check user
@@ -151,12 +159,20 @@ export default class SiteService {
user: req.user
});
}
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.siteID });
// Get the Site
- const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.siteID);
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.siteID, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.siteID}' does not exist`,
MODULE_NAME, 'handleUpdateSiteUserOwner', req.user);
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.userID });
// Get the User
- const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.userID);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.userID, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User with ID '${filteredRequest.userID}' does not exist`,
MODULE_NAME, 'handleUpdateSiteUserOwner', req.user);
// Update
@@ -200,7 +216,7 @@ export default class SiteService {
const filteredRequest = SiteSecurity.filterAssignSiteUsers(req.body);
// Check
UtilsService.assertIdIsProvided(action, filteredRequest.siteID, MODULE_NAME, 'handleAssignUsersToSite', req.user);
- if (!filteredRequest.userIDs || (filteredRequest.userIDs && filteredRequest.userIDs.length <= 0)) {
+ if (!filteredRequest.userIDs || Utils.isEmptyArray(filteredRequest.userIDs)) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
errorCode: HTTPError.GENERAL_ERROR,
@@ -210,10 +226,21 @@ export default class SiteService {
});
}
// Check auth
- await AuthorizationService.checkAndAssignSiteUsersAuthorizationFilters(
- req.tenant, action, req.user, filteredRequest);
+ if (!Authorizations.canReadSite(req.user)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: req.user,
+ action: Action.UPDATE, entity: Entity.USER,
+ module: MODULE_NAME, method: 'handleAssignUsersToSite',
+ value: filteredRequest.siteID
+ });
+ }
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.siteID });
// Get the Site
- const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.siteID);
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.siteID, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site '${filteredRequest.siteID}' does not exist`,
MODULE_NAME, 'handleAssignUsersToSite', req.user);
// OCPI Site
@@ -227,6 +254,9 @@ export default class SiteService {
action: action
});
}
+ // Check auth
+ await AuthorizationService.checkAndAssignSiteUsersAuthorizationFilters(
+ req.tenant, action, req.user, filteredRequest);
// Save
if (action === ServerAction.ADD_USERS_TO_SITE) {
await SiteStorage.addUsersToSite(req.user.tenantID, filteredRequest.siteID, filteredRequest.userIDs);
@@ -259,33 +289,44 @@ export default class SiteService {
}
// Filter
const filteredRequest = SiteSecurity.filterSiteUsersRequest(req.query);
- // Check Mandatory fields
- if (!filteredRequest.SiteID) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'The Site\'s ID must be provided',
- module: MODULE_NAME, method: 'handleGetUsersFromSite',
- user: req.user
+ UtilsService.assertIdIsProvided(action, filteredRequest.SiteID, MODULE_NAME, 'handleGetUsersFromSite', req.user);
+ // Check auth
+ if (!Authorizations.canReadSite(req.user)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: req.user,
+ action: Action.UPDATE, entity: Entity.USER,
+ module: MODULE_NAME, method: 'handleGetUsers',
+ value: filteredRequest.SiteID
});
}
// Check auth
- const authorizationFilters = await AuthorizationService.checkAndGetSiteUsersAuthorizationFilters(
- req.tenant, req.user, filteredRequest);
- if (!authorizationFilters.authorized) {
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.SiteID });
+ if (!authorizationSiteFilters.authorized) {
UtilsService.sendEmptyDataResult(res, next);
return;
}
// Get the Site
- const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.SiteID);
- UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.SiteID}' does not exist`,
- MODULE_NAME, 'handleGetUsersFromSite', req.user);
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.SiteID, authorizationSiteFilters.filters);
+ if (!site) {
+ UtilsService.sendEmptyDataResult(res, next);
+ return;
+ }
+ // Check auth
+ const authorizationSiteUsersFilters = await AuthorizationService.checkAndGetSiteUsersAuthorizationFilters(
+ req.tenant, req.user, filteredRequest);
+ if (!authorizationSiteUsersFilters.authorized) {
+ UtilsService.sendEmptyDataResult(res, next);
+ return;
+ }
// Get users
const users = await SiteStorage.getSiteUsers(req.user.tenantID,
{
search: filteredRequest.Search,
siteIDs: [ filteredRequest.SiteID ],
- ...authorizationFilters.filters
+ ...authorizationSiteUsersFilters.filters
},
{
limit: filteredRequest.Limit,
@@ -293,7 +334,7 @@ export default class SiteService {
sort: filteredRequest.SortFields,
onlyRecordCount: filteredRequest.OnlyRecordCount
},
- authorizationFilters.projectFields
+ authorizationSiteUsersFilters.projectFields
);
res.json(users);
next();
@@ -317,8 +358,12 @@ export default class SiteService {
value: siteID
});
}
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: siteID });
// Get
- const site = await SiteStorage.getSite(req.user.tenantID, siteID);
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, siteID, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site with ID '${siteID}' does not exist`,
MODULE_NAME, 'handleDeleteSite', req.user);
// OCPI Site
@@ -364,16 +409,16 @@ export default class SiteService {
const filteredRequest = SiteSecurity.filterSiteRequest(req.query);
UtilsService.assertIdIsProvided(action, filteredRequest.ID, MODULE_NAME, 'handleGetSite', req.user);
// Check auth
- const authorizationFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
req.tenant, req.user, filteredRequest);
// Get it
const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.ID,
{
withCompany: filteredRequest.WithCompany,
withImage: true,
- ...authorizationFilters.filters
+ ...authorizationSiteFilters.filters
},
- authorizationFilters.projectFields
+ authorizationSiteFilters.projectFields
);
UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.ID}' does not exist`,
MODULE_NAME, 'handleGetSite', req.user);
@@ -398,9 +443,9 @@ export default class SiteService {
// Filter
const filteredRequest = SiteSecurity.filterSitesRequest(req.query);
// Check auth
- const authorizationFilters = await AuthorizationService.checkAndGetSitesAuthorizationFilters(
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSitesAuthorizationFilters(
req.tenant, req.user, filteredRequest);
- if (!authorizationFilters.authorized) {
+ if (!authorizationSiteFilters.authorized) {
UtilsService.sendEmptyDataResult(res, next);
return;
}
@@ -417,7 +462,7 @@ export default class SiteService {
withAvailableChargingStations: filteredRequest.WithAvailableChargers,
locCoordinates: filteredRequest.LocCoordinates,
locMaxDistanceMeters: filteredRequest.LocMaxDistanceMeters,
- ...authorizationFilters.filters
+ ...authorizationSiteFilters.filters
},
{
limit: filteredRequest.Limit,
@@ -425,7 +470,7 @@ export default class SiteService {
sort: filteredRequest.SortFields,
onlyRecordCount: filteredRequest.OnlyRecordCount
},
- authorizationFilters.projectFields
+ authorizationSiteFilters.projectFields
);
// Add Auth flags
await AuthorizationService.addSitesAuthorizations(req.tenant, req.user, sites.result);
@@ -438,9 +483,16 @@ export default class SiteService {
// Filter
const filteredRequest = SiteSecurity.filterSiteImageRequest(req.query);
UtilsService.assertIdIsProvided(action, filteredRequest.ID, MODULE_NAME, 'handleGetSiteImage', req.user);
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, filteredRequest);
+ // Get
+ const site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.ID, authorizationSiteFilters.filters);
+ UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.ID}' does not exist`,
+ MODULE_NAME, 'handleDeleteSite', req.user);
// Get the image
const siteImage = await SiteStorage.getSiteImage(filteredRequest.TenantID, filteredRequest.ID);
- // Return
if (siteImage?.image) {
let header = 'image';
let encoding: BufferEncoding = 'base64';
@@ -545,8 +597,12 @@ export default class SiteService {
action: action
});
}
+ // Check auth
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.id });
// Get Site
- const site: Site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.id);
+ const site: Site = await SiteStorage.getSite(
+ req.user.tenantID, filteredRequest.id, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site with ID '${filteredRequest.id}' does not exist`,
MODULE_NAME, 'handleUpdateSite', req.user);
// OCPI Site

MODIFY
src/server/rest/v1/service/UserService.ts
src/server/rest/v1/service/UserService.ts
@@ -47,7 +47,6 @@ const MODULE_NAME = 'UserService';
export default class UserService {
public static async handleGetUserDefaultTagCar(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- const userID = UserSecurity.filterDefaultTagCarRequestByUserID(req.query);
// Check auth
if (!Authorizations.canReadTag(req.user)) {
throw new AppAuthError({
@@ -66,6 +65,7 @@ export default class UserService {
module: MODULE_NAME, method: 'handleGetUserDefaultTagCar'
});
}
+ const userID = UserSecurity.filterDefaultTagCarRequestByUserID(req.query);
UtilsService.assertIdIsProvided(action, userID, MODULE_NAME, 'handleGetUserDefaultTagCar', req.user);
// Check auth
if (!Authorizations.canReadUser(req.user, userID)) {
@@ -76,6 +76,13 @@ export default class UserService {
module: MODULE_NAME, method: 'handleGetUserDefaultTagCar'
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: userID });
+ // Check user
+ const user = await UserStorage.getUser(
+ req.user.tenantID, userID, authorizationUserFilters.filters);
+ UtilsService.assertObjectExists(action, user, `User '${userID}' does not exist`, MODULE_NAME, 'handleDeleteUser', req.user);
// Handle Tag
// Get the default Tag
let tag = await TagStorage.getDefaultUserTag(req.user.tenantID, userID, {
@@ -130,16 +137,8 @@ export default class UserService {
}
// Filter
const filteredRequest = UserSecurity.filterAssignSitesToUserRequest(req.body);
- if (!filteredRequest.userID) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'User\'s ID must be provided',
- module: MODULE_NAME, method: 'handleAssignSitesToUser',
- user: req.user,
- action: action
- });
- }
+ // Check
+ UtilsService.assertIdIsProvided(action, filteredRequest.userID, MODULE_NAME, 'handleAssignSitesToUser', req.user);
if (!filteredRequest.siteIDs || Utils.isEmptyArray(filteredRequest.siteIDs)) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -160,8 +159,12 @@ export default class UserService {
value: filteredRequest.userID
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.userID });
// Get the User
- const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.userID);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.userID, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${filteredRequest.userID}' does not exist`,
MODULE_NAME, 'handleAssignSitesToUser', req.user);
// Deleted
@@ -186,35 +189,12 @@ export default class UserService {
action: action
});
}
- // Get Sites
- for (const siteID of filteredRequest.siteIDs) {
- const site = await SiteStorage.getSite(req.user.tenantID, siteID);
- UtilsService.assertObjectExists(action, site, `Site with ID '${siteID}' does not exist`,
- MODULE_NAME, 'handleUpdateSiteUserOwner', req.user);
// Check auth
- if (!Authorizations.canUpdateSite(req.user, siteID)) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: req.user,
- action: Action.UPDATE, entity: Entity.SITE,
- module: MODULE_NAME, method: 'handleAssignSitesToUser',
- value: siteID
- });
- }
- // OCPI Site
- if (!site.issuer) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: `Site '${site.name}' with ID '${site.id}' not issued by the organization`,
- module: MODULE_NAME, method: 'handleAssignSitesToUser',
- user: req.user,
- action: action
- });
- }
- }
+ await AuthorizationService.checkAndAssignUserSitesAuthorizationFilters(
+ req.tenant, action, req.user, filteredRequest);
+ // Get Sites
// Save
- if (action.toLowerCase().includes('add')) {
+ if (action === ServerAction.ADD_SITES_TO_USER) {
await UserStorage.addSitesToUser(req.user.tenantID, filteredRequest.userID, filteredRequest.siteIDs);
} else {
await UserStorage.removeSitesFromUser(req.user.tenantID, filteredRequest.userID, filteredRequest.siteIDs);
@@ -265,8 +245,12 @@ export default class UserService {
action: action
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: userID });
// Check user
- const user = await UserStorage.getUser(req.user.tenantID, userID);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, userID, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${userID}' does not exist`, MODULE_NAME, 'handleDeleteUser', req.user);
// Get tags
const tags = (await TagStorage.getTags(req.user.tenantID,
@@ -468,8 +452,12 @@ export default class UserService {
value: filteredRequest.id
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.id });
// Get User
- let user = await UserStorage.getUser(req.user.tenantID, filteredRequest.id);
+ let user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.id, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${filteredRequest.id}' does not exist`,
MODULE_NAME, 'handleUpdateUser', req.user);
// Deleted?
@@ -629,8 +617,12 @@ export default class UserService {
value: filteredRequest.id
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.id });
// Get User
- const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.id);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.id, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${filteredRequest.id}' does not exist`,
MODULE_NAME, 'handleUpdateUserMobileToken', req.user);
// Deleted?
@@ -682,14 +674,15 @@ export default class UserService {
});
}
// Get authorization filters
- const authorizationFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(req.tenant, req.user, filteredRequest);
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, filteredRequest);
// Get the user
const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.ID,
{
withImage: true,
- ...authorizationFilters.filters
+ ...authorizationUserFilters.filters
},
- authorizationFilters.projectFields
+ authorizationUserFilters.projectFields
);
UtilsService.assertObjectExists(action, user, `User '${filteredRequest.ID}' does not exist`,
MODULE_NAME, 'handleGetUser', req.user);
@@ -722,8 +715,12 @@ export default class UserService {
value: userID
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: userID });
// Get the logged user
- const user = await UserStorage.getUser(req.user.tenantID, userID);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, userID, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${userID}' does not exist`,
MODULE_NAME, 'handleGetUserImage', req.user);
// Deleted?
@@ -777,14 +774,24 @@ export default class UserService {
value: filteredRequest.UserID
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.UserID });
+ if (!authorizationUserFilters.authorized) {
+ UtilsService.sendEmptyDataResult(res, next);
+ return;
+ }
// Get User
- const user = await UserStorage.getUser(req.user.tenantID, filteredRequest.UserID);
- UtilsService.assertObjectExists(action, user, `User with ID '${filteredRequest.UserID}' does not exist`,
- MODULE_NAME, 'handleGetSites', req.user);
+ const user = await UserStorage.getUser(
+ req.user.tenantID, filteredRequest.UserID, authorizationUserFilters.filters);
+ if (!user) {
+ UtilsService.sendEmptyDataResult(res, next);
+ return;
+ }
// Check auth
- const authorizationFilters = await AuthorizationService.checkAndGetUserSitesAuthorizationFilters(
+ const authorizationUserSitesFilters = await AuthorizationService.checkAndGetUserSitesAuthorizationFilters(
req.tenant, req.user, filteredRequest);
- if (!authorizationFilters.authorized) {
+ if (!authorizationUserSitesFilters.authorized) {
UtilsService.sendEmptyDataResult(res, next);
return;
}
@@ -793,7 +800,7 @@ export default class UserService {
{
search: filteredRequest.Search,
userID: filteredRequest.UserID,
- ...authorizationFilters.filters
+ ...authorizationUserSitesFilters.filters
},
{
limit: filteredRequest.Limit,
@@ -801,7 +808,7 @@ export default class UserService {
sort: filteredRequest.SortFields,
onlyRecordCount: filteredRequest.OnlyRecordCount
},
- authorizationFilters.projectFields
+ authorizationUserSitesFilters.projectFields
);
// Filter
userSites.result = userSites.result.map((userSite) => ({
@@ -816,7 +823,7 @@ export default class UserService {
public static async handleGetUsers(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Return
- res.json(await UserService.getUsers(req));
+ res.json(await UserService.getUsers(req, res, next));
next();
}
@@ -838,7 +845,7 @@ export default class UserService {
Action.READ, Entity.USER, MODULE_NAME, 'handleGetUsersInError');
}
// Get authorization filters
- const authorizationFilters = await AuthorizationService.checkAndGetUsersInErrorAuthorizationFilters(
+ const authorizationUserInErrorFilters = await AuthorizationService.checkAndGetUsersInErrorAuthorizationFilters(
req.tenant, req.user, filteredRequest);
// Get users
const users = await UserStorage.getUsersInError(req.user.tenantID,
@@ -846,7 +853,7 @@ export default class UserService {
search: filteredRequest.Search,
roles: (filteredRequest.Role ? filteredRequest.Role.split('|') : null),
errorTypes: (filteredRequest.ErrorType ? filteredRequest.ErrorType.split('|') : Object.values(UserInErrorType)),
- ...authorizationFilters.filters
+ ...authorizationUserInErrorFilters.filters
},
{
limit: filteredRequest.Limit,
@@ -854,7 +861,7 @@ export default class UserService {
skip: filteredRequest.Skip,
sort: filteredRequest.SortFields
},
- authorizationFilters.projectFields
+ authorizationUserInErrorFilters.projectFields
);
// Add Auth flags
AuthorizationService.addUsersAuthorizations(req.tenant, req.user, users.result);
@@ -1092,8 +1099,11 @@ export default class UserService {
value: id
});
}
+ // Get authorization filters
+ const authorizationUserFilters = await AuthorizationService.checkAndGetUserAuthorizationFilters(
+ req.tenant, req.user, { ID: id });
// Get the user
- const user = await UserStorage.getUser(req.user.tenantID, id);
+ const user = await UserStorage.getUser(req.user.tenantID, id, authorizationUserFilters.filters);
UtilsService.assertObjectExists(action, user, `User '${id}' does not exist`,
MODULE_NAME, 'handleGetUserInvoice', req.user);
// Deleted?
@@ -1230,7 +1240,7 @@ export default class UserService {
return csv;
}
- private static async getUsers(req: Request): Promise<DataResult<User>> {
+ private static async getUsers(req: Request, res: Response, next: NextFunction): Promise<DataResult<User>> {
// Check auth
if (!Authorizations.canListUsers(req.user)) {
throw new AppAuthError({
@@ -1252,8 +1262,11 @@ export default class UserService {
Action.READ, Entity.USER, MODULE_NAME, 'getUsers');
}
// Get authorization filters
- const authorizationFilters = await AuthorizationService.checkAndGetUsersAuthorizationFilters(
+ const authorizationUsersFilters = await AuthorizationService.checkAndGetUsersAuthorizationFilters(
req.tenant, req.user, filteredRequest);
+ if (!authorizationUsersFilters.authorized) {
+ return Constants.DB_EMPTY_DATA_RESULT;
+ }
// Get users
const users = await UserStorage.getUsers(req.user.tenantID,
{
@@ -1266,7 +1279,7 @@ export default class UserService {
excludeUserIDs: (filteredRequest.ExcludeUserIDs ? filteredRequest.ExcludeUserIDs.split('|') : null),
includeCarUserIDs: (filteredRequest.IncludeCarUserIDs ? filteredRequest.IncludeCarUserIDs.split('|') : null),
notAssignedToCarID: filteredRequest.NotAssignedToCarID,
- ...authorizationFilters.filters
+ ...authorizationUsersFilters.filters
},
{
limit: filteredRequest.Limit,
@@ -1274,7 +1287,7 @@ export default class UserService {
sort: filteredRequest.SortFields,
onlyRecordCount: filteredRequest.OnlyRecordCount
},
- authorizationFilters.projectFields
+ authorizationUsersFilters.projectFields
);
// Add Auth flags
AuthorizationService.addUsersAuthorizations(req.tenant, req.user, users.result);

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -220,13 +220,13 @@ export default class UtilsService {
}
}
- public static async exportToCSV(req: Request, res: Response, attachementName: string,
+ public static async exportToCSV(req: Request, res: Response, attachmentName: string,
handleGetData: (req: Request) => Promise<DataResult<any>>,
handleConvertToCSV: (req: Request, data: any[], writeHeader: boolean) => string): Promise<void> {
// Override
req.query.Limit = Constants.EXPORT_PAGE_SIZE.toString();
// Set the attachment name
- res.attachment(attachementName);
+ res.attachment(attachmentName);
// Get the total number of Logs
req.query.OnlyRecordCount = 'true';
let data = await handleGetData(req);

MODIFY
src/server/rest/v1/service/security/UserSecurity.ts
src/server/rest/v1/service/security/UserSecurity.ts
-import { HttpSitesAssignUserRequest, HttpUserMobileTokenRequest, HttpUserRequest, HttpUserSitesRequest, HttpUsersRequest } from '../../../../../types/requests/HttpUserRequest';
+import { HttpUserAssignSitesRequest, HttpUserMobileTokenRequest, HttpUserRequest, HttpUserSitesRequest, HttpUsersRequest } from '../../../../../types/requests/HttpUserRequest';
import User, { UserRole } from '../../../../../types/User';
import Authorizations from '../../../../../authorization/Authorizations';
@@ -10,7 +10,7 @@ import sanitize from 'mongo-sanitize';
export default class UserSecurity {
- public static filterAssignSitesToUserRequest(request: any): HttpSitesAssignUserRequest {
+ public static filterAssignSitesToUserRequest(request: any): HttpUserAssignSitesRequest {
return {
userID: sanitize(request.userID),
siteIDs: request.siteIDs ? request.siteIDs.map(sanitize) : []

MODIFY
src/storage/mongodb/SiteStorage.ts
src/storage/mongodb/SiteStorage.ts
@@ -20,8 +20,7 @@ export default class SiteStorage {
params: { withCompany?: boolean, withImage?: boolean; } = {}, projectFields?: string[]): Promise<Site> {
const sitesMDB = await SiteStorage.getSites(tenantID, {
siteIDs: [id],
- withCompany: params.withCompany,
- withImage: params.withImage,
+ ...params,
}, Constants.DB_PARAMS_SINGLE_RECORD, projectFields);
return sitesMDB.count === 1 ? sitesMDB.result[0] : null;
}

MODIFY
src/types/requests/HttpUserRequest.ts
src/types/requests/HttpUserRequest.ts
+import HttpDatabaseRequest, { HttpDatabaseProjectRequest } from './HttpDatabaseRequest';
+
import HttpByIDRequest from './HttpByIDRequest';
-import HttpDatabaseRequest from './HttpDatabaseRequest';
export type HttpUserRequest = HttpByIDRequest;
@@ -22,7 +23,7 @@ export interface HttpUserMobileTokenRequest {
mobileOS: string;
}
-export interface HttpSitesAssignUserRequest {
+export interface HttpUserAssignSitesRequest extends HttpDatabaseProjectRequest {
userID: string;
siteIDs: string[];
}

Enhance the auth on Site and User