Remove conditions from auth def, update CreateSiteArea logic.
MODIFY
src/authorization/Authorizations.ts
src/authorization/Authorizations.ts
@@ -529,9 +529,8 @@ export default class Authorizations {
{ site: siteID, sites: loggedUser.sites });
}
- public static canCreateSiteArea(loggedUser: UserToken, siteID: string): boolean {
- return Authorizations.canPerformAction(loggedUser, Entity.SITE_AREA, Action.CREATE,
- { site: siteID, sites: loggedUser.sitesAdmin });
+ public static canCreateSiteArea(loggedUser: UserToken): boolean {
+ return Authorizations.canPerformAction(loggedUser, Entity.SITE_AREA, Action.CREATE);
}
public static canUpdateSiteArea(loggedUser: UserToken, siteID: string): boolean {

MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -141,10 +141,7 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.SITES, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.SITE, action: Action.READ, attributes: ['*'] },
{ resource: Entity.SITE_AREAS, action: Action.LIST, attributes: ['*'] },
- {
- resource: Entity.SITE_AREA, action: Action.READ, attributes: ['*'],
- condition: { Fn: 'LIST_CONTAINS', args: { 'sites': '$.site' } }
- },
+ { resource: Entity.SITE_AREA, action: Action.READ, attributes: ['*'] },
{ resource: Entity.CHARGING_STATIONS, action: Action.LIST, attributes: ['*'] },
{
resource: Entity.CHARGING_STATION, action: [Action.READ], attributes: ['*']
@@ -272,10 +269,7 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
{ resource: Entity.USERS_SITES, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.USERS_SITES, action: [Action.UNASSIGN], attributes: ['*'] },
{ resource: Entity.SITE, action: [Action.UPDATE], attributes: ['*'] },
- {
- resource: Entity.SITE_AREA, action: [Action.CREATE, Action.UPDATE, Action.DELETE], attributes: ['*'],
- condition: { Fn: 'LIST_CONTAINS', args: { 'sites': '$.site' } }
- },
+ { resource: Entity.SITE_AREA, action: [Action.CREATE, Action.UPDATE, Action.DELETE], attributes: ['*'] },
{
resource: Entity.CHARGING_STATION,
action: [Action.UPDATE, Action.DELETE, Action.RESET, Action.CLEAR_CACHE, Action.GET_CONFIGURATION,

MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
@@ -75,7 +75,7 @@ export default class AuthorizationService {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: userToken,
- action: Action.READ, entity: Entity.SITE,
+ action: Action.UPDATE, entity: Entity.SITE,
module: MODULE_NAME, method: 'checkAndGetSiteAuthorizationFilters',
});
} else {
@@ -485,7 +485,15 @@ export default class AuthorizationService {
return authorizationFilters;
}
- public static async getAssignedSitesCompanyIDs(tenantID: string, userToken: UserToken, siteID?: string): Promise<string[]> {
+ public static async checkCreateSiteAreaAuthorization(tenant: Tenant, userToken: UserToken, siteID: string): Promise<boolean> {
+ const { siteAdminIDs, siteOwnerIDs } = await AuthorizationService.getSiteAdminOwnerIDs(tenant, userToken);
+ if (Utils.isEmptyArray(siteAdminIDs) || !siteAdminIDs.includes(siteID)) {
+ return false;
+ }
+ return true;
+ }
+
+ private static async getAssignedSitesCompanyIDs(tenantID: string, userToken: UserToken, siteID?: string): Promise<string[]> {
// Get the Company IDs of the assigned Sites
const sites = await SiteStorage.getSites(tenantID,
{
@@ -595,3 +603,4 @@ export default class AuthorizationService {
}
}
}
+

MODIFY
src/server/rest/v1/service/SiteAreaService.ts
src/server/rest/v1/service/SiteAreaService.ts
@@ -6,6 +6,7 @@ import { ActionsResponse } from '../../../../types/GlobalType';
import AppAuthError from '../../../../exception/AppAuthError';
import AppError from '../../../../exception/AppError';
import AssetStorage from '../../../../storage/mongodb/AssetStorage';
+import AuthorizationService from './AuthorizationService';
import Authorizations from '../../../../authorization/Authorizations';
import { ChargingProfilePurposeType } from '../../../../types/ChargingProfile';
import ChargingStationStorage from '../../../../storage/mongodb/ChargingStationStorage';
@@ -216,16 +217,12 @@ export default class SiteAreaService {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ORGANIZATION,
Action.DELETE, Entity.SITE_AREA, MODULE_NAME, 'handleDeleteSiteArea');
- // Filter
+ // Filter request
const siteAreaID = SiteAreaSecurity.filterSiteAreaRequestByID(req.query);
// Check Mandatory fields
UtilsService.assertIdIsProvided(action, siteAreaID, MODULE_NAME, 'handleDeleteSiteArea', req.user);
- // Get
- const siteArea = await SiteAreaStorage.getSiteArea(req.user.tenantID, siteAreaID);
- UtilsService.assertObjectExists(action, siteArea, `Site Area with ID '${siteAreaID}' does not exist`,
- MODULE_NAME, 'handleDeleteSiteArea', req.user);
- // Check auth
- if (!Authorizations.canDeleteSiteArea(req.user, siteArea.siteID)) {
+ // Check statuc auth
+ if (!Authorizations.canDeleteSiteArea(req.user, siteAreaID)) {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: req.user,
@@ -234,6 +231,11 @@ export default class SiteAreaService {
value: siteAreaID
});
}
+ // Get
+ // todo: check and get... (can read); check it exists
+ const siteArea = await SiteAreaStorage.getSiteArea(req.user.tenantID, siteAreaID);
+ UtilsService.assertObjectExists(action, siteArea, `Site Area with ID '${siteAreaID}' does not exist`,
+ MODULE_NAME, 'handleDeleteSiteArea', req.user);
// OCPI Site Area
if (!siteArea.issuer) {
throw new AppError({
@@ -423,12 +425,13 @@ export default class SiteAreaService {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ORGANIZATION,
Action.CREATE, Entity.SITE_AREAS, MODULE_NAME, 'handleCreateSiteArea');
- // Filter
+ // Filter request
const filteredRequest = SiteAreaSecurity.filterSiteAreaCreateRequest(req.body);
- // Check
+ // Check request data is valid
UtilsService.checkIfSiteAreaValid(filteredRequest, req);
// Check auth
- if (!Authorizations.canCreateSiteArea(req.user, filteredRequest.siteID)) {
+ const createSiteAreaAuthorization = await AuthorizationService.checkCreateSiteAreaAuthorization(req.tenant,req.user, filteredRequest.siteID);
+ if (!Authorizations.canCreateSiteArea(req.user) || !createSiteAreaAuthorization) {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: req.user,
@@ -436,8 +439,20 @@ export default class SiteAreaService {
module: MODULE_NAME, method: 'handleCreateSiteArea'
});
}
- // Check Site
- const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.siteID);
+ // Check static auth for reading site
+ if (!Authorizations.canReadSite(req.user)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: req.user,
+ action: Action.READ, entity: Entity.SITE,
+ module: MODULE_NAME, method: 'handleCreateSiteArea',
+ });
+ }
+ // Check dynamic auth for reading site
+ const authorizationSiteFilters = await AuthorizationService.checkAndGetSiteAuthorizationFilters(
+ req.tenant, req.user, { ID: filteredRequest.siteID });
+ // Get Site & check it exists
+ const site = await SiteStorage.getSite(req.user.tenantID, filteredRequest.siteID, authorizationSiteFilters.filters);
UtilsService.assertObjectExists(action, site, `Site ID '${filteredRequest.siteID}' does not exist`,
MODULE_NAME, 'handleCreateSiteArea', req.user);
// OCPI Site

Remove conditions from auth def, update CreateSiteArea logic.