Use dinamic filters on createSiteArea.
MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -326,7 +326,11 @@ 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: ['*'] },
+ { resource: Entity.SITE_AREA, action: [Action.CREATE, Action.UPDATE, Action.DELETE], attributes: ['*'],
+ condition: {
+ Fn: 'custom:dynamicAuthorizationFilters',
+ args: { filters: ['SitesAdmin'] }
+ }, },
{
resource: Entity.CHARGING_STATION,
action: [Action.UPDATE, Action.DELETE, Action.RESET, Action.CLEAR_CACHE, Action.GET_CONFIGURATION,

ADD
src/authorization/dynamic-data-source/SitesAdminDynamicAuthorizationDataSource.ts
+import { DynamicAuthorizationDataSourceName, SitesAdminDynamicAuthorizationDataSourceData } from '../../types/Authorization';
+
+import Constants from '../../utils/Constants';
+import DynamicAuthorizationDataSource from '../DynamicAuthorizationDataSource';
+import SiteStorage from '../../storage/mongodb/SiteStorage';
+import UserStorage from '../../storage/mongodb/UserStorage';
+import _ from 'lodash';
+
+export default class SitesAdminDynamicAuthorizationDataSource
+ extends DynamicAuthorizationDataSource<SitesAdminDynamicAuthorizationDataSourceData> {
+
+ public getName(): DynamicAuthorizationDataSourceName {
+ return DynamicAuthorizationDataSourceName.SITES_ADMIN;
+ }
+
+ public async loadData(): Promise<void> {
+ const assignedSitesCompaniesData: SitesAdminDynamicAuthorizationDataSourceData = {};
+ // Get Site IDs from Site Admin flag
+ assignedSitesCompaniesData.siteIDs = await this.getSitesAdminSiteIDs();
+ // Set
+ this.setData(assignedSitesCompaniesData);
+ }
+
+ private async getSitesAdminSiteIDs(): Promise<string[]> {
+ // Get the Site IDs of the Sites for which the user is SiteAdmin
+ const sites = await UserStorage.getUserSites(this.tenant.id,
+ {
+ userID: this.userToken.id,
+ siteAdmin: true
+ }, Constants.DB_PARAMS_MAX_LIMIT,
+ ['siteID']
+ );
+ return sites.result.map((userSite) => userSite.siteID);
+ }
+}

ADD
src/authorization/dynamic-filters/SitesAdminDynamicAuthorizationFilter.ts
+import { AuthorizationFilter, DynamicAuthorizationDataSourceName, Entity } from '../../types/Authorization';
+
+import DynamicAuthorizationFilter from '../DynamicAuthorizationFilter';
+import SitesAdminDynamicAuthorizationDataSource from '../dynamic-data-source/SitesAdminDynamicAuthorizationDataSource';
+import Utils from '../../utils/Utils';
+
+export default class SitesAdminDynamicAuthorizationFilter extends DynamicAuthorizationFilter {
+ public processFilter(authorizationFilters: AuthorizationFilter, extraFilters: Record<string, any>): void {
+ // Get Site IDs
+ const sitesAdminDataSource = this.getDataSource(
+ DynamicAuthorizationDataSourceName.SITES_ADMIN) as SitesAdminDynamicAuthorizationDataSource;
+ const { siteIDs } = sitesAdminDataSource.getData();
+ // Check
+ if (!Utils.isEmptyArray(siteIDs)) {
+ // Force the filter
+ authorizationFilters.filters.siteIDs = siteIDs;
+ // Check if filter is provided
+ if (Utils.objectHasProperty(extraFilters, 'SiteID') && !Utils.isNullOrUndefined(extraFilters['SiteID'])) {
+ const filteredSiteIDs: string[] = extraFilters['SiteID'].split('|');
+ // Override
+ authorizationFilters.filters.siteIDs = filteredSiteIDs.filter(
+ (siteID) => authorizationFilters.filters.siteIDs.includes(siteID));
+ } else if (Utils.objectHasProperty(extraFilters, 'siteID') && !Utils.isNullOrUndefined(extraFilters['siteID'])) {
+ const filteredSiteIDs: string[] = extraFilters['siteID'].split('|');
+ // Override
+ authorizationFilters.filters.siteIDs = filteredSiteIDs.filter(
+ (siteID) => authorizationFilters.filters.siteIDs.includes(siteID));
+ }
+ }
+ if (!Utils.isEmptyArray(authorizationFilters.filters.siteIDs)) {
+ authorizationFilters.authorized = true;
+ }
+ }
+
+ public getApplicableEntities(): Entity[] {
+ return [
+ Entity.SITE
+ ];
+ }
+
+ public getApplicableDataSources(): DynamicAuthorizationDataSourceName[] {
+ return [
+ DynamicAuthorizationDataSourceName.SITES_ADMIN
+ ];
+ }
+}

MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
@@ -544,7 +544,8 @@ export default class AuthorizationService {
return authorizationFilters;
}
- public static async checkAndGetSiteAreaAuthorizationFilters(tenant: Tenant, userToken: UserToken, filteredRequest: HttpSiteAreaRequest): Promise<AuthorizationFilter> {
+ public static async checkAndGetSiteAreaAuthorizationFilters(tenant: Tenant, userToken: UserToken, filteredRequest: Record<string, any>,
+ action: Action): Promise<AuthorizationFilter> {
const authorizationFilters: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
@@ -552,26 +553,7 @@ export default class AuthorizationService {
authorized: false,
};
- // Check static auth
- const authorizationContext: AuthorizationContext = {};
- const authResult = await Authorizations.canReadSiteArea(userToken, authorizationContext);
- authorizationFilters.authorized = authResult.authorized;
- // Check
- if (!authorizationFilters.authorized) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: userToken,
- action: Action.READ, entity: Entity.SITE_AREA,
- module: MODULE_NAME, method: 'checkAndGetSiteAreaAuthorizationFilters',
- });
- }
-
- // Process dynamic filters
- await AuthorizationService.processDynamicFilters(tenant, userToken, Action.READ, Entity.SITE,
- authorizationFilters, authorizationContext, { SiteAreaID: filteredRequest.ID });
- // Filter projected fields
- authorizationFilters.projectFields = AuthorizationService.filterProjectFields(
- authResult.fields, filteredRequest.ProjectFields);
+ await this.canPerformAuthorizationAction(tenant, userToken, Entity.SITE_AREA, action, authorizationFilters, filteredRequest);
return authorizationFilters;
}

MODIFY
src/server/rest/v1/service/SiteAreaService.ts
src/server/rest/v1/service/SiteAreaService.ts
@@ -291,8 +291,14 @@ export default class SiteAreaService {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ORGANIZATION,
Action.CREATE, Entity.SITE_AREAS, MODULE_NAME, 'handleCreateSiteArea');
- // Check static auth
- if (!await Authorizations.canCreateSiteArea(req.user)) {
+ // Filter request
+ const filteredRequest = SiteAreaSecurity.filterSiteAreaCreateRequest(req.body);
+ // Check request data is valid
+ UtilsService.checkIfSiteAreaValid(filteredRequest, req);
+ // Check auth
+ const authorizationFilters = await AuthorizationService.checkAndGetSiteAreaAuthorizationFilters(
+ req.tenant, req.user, filteredRequest, Action.CREATE);
+ if (!authorizationFilters.authorized) {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: req.user,
@@ -300,13 +306,9 @@ export default class SiteAreaService {
module: MODULE_NAME, method: 'handleCreateSiteArea'
});
}
- // Filter request
- const filteredRequest = SiteAreaSecurity.filterSiteAreaCreateRequest(req.body);
- // Check request data is valid
- UtilsService.checkIfSiteAreaValid(filteredRequest, req);
- // Check Site
+ // Check Site auth
await UtilsService.checkAndGetSiteAuthorization(
- req.tenant, req.user, filteredRequest.siteID, Action.UPDATE, action, {});
+ req.tenant, req.user, filteredRequest.siteID, Action.READ, action, {});
// Create Site Area
const newSiteArea: SiteArea = {
...filteredRequest,

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -434,7 +434,7 @@ export default class UtilsService {
UtilsService.assertIdIsProvided(action, siteAreaID, MODULE_NAME, 'checkAndGetSiteAreaAuthorization', userToken);
// Get dynamic auth
const authorizationFilter = await AuthorizationService.checkAndGetSiteAreaAuthorizationFilters(
- tenant, userToken, { ID: siteAreaID });
+ tenant, userToken, { ID: siteAreaID }, Action.READ);
if (!authorizationFilter.authorized) {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,

Use dinamic filters on createSiteArea.