Change assignAsstesToSiteArea logic
MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -97,7 +97,13 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
resource: Entity.ASSET, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE,
Action.CHECK_CONNECTION, Action.RETRIEVE_CONSUMPTION], attributes: ['*']
},
- { resource: Entity.ASSETS, action: [Action.LIST, Action.IN_ERROR], attributes: ['*'] },
+ {
+ resource: Entity.ASSETS, action: [Action.LIST, Action.IN_ERROR],
+ attributes: [
+ 'id', 'name', 'siteAreaID', 'siteArea.id', 'siteArea.name', 'siteArea.siteID', 'siteID', 'assetType', 'coordinates',
+ 'dynamicAsset', 'connectionID', 'meterID', 'currentInstantWatts', 'currentStateOfCharge'
+ ]
+ },
{ resource: Entity.SETTINGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.SETTING, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE], attributes: ['*'] },
{ resource: Entity.TOKENS, action: Action.LIST, attributes: ['*'] },
@@ -142,7 +148,13 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
condition: { Fn: 'EQUALS', args: { 'user': '$.owner' } }
},
{ resource: Entity.SETTING, action: Action.READ, attributes: ['*'] },
- { resource: Entity.ASSETS, action: Action.LIST, attributes: ['*'] },
+ {
+ resource: Entity.ASSETS, action: Action.LIST,
+ attributes: [
+ 'id', 'name', 'siteAreaID', 'siteArea.id', 'siteArea.name', 'siteArea.siteID', 'siteID', 'assetType', 'coordinates',
+ 'dynamicAsset', 'connectionID', 'meterID', 'currentInstantWatts', 'currentStateOfCharge'
+ ]
+ },
{ resource: Entity.ASSET, action: Action.READ, attributes: ['*'] },
{ resource: Entity.CAR_CATALOGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.CAR_CATALOG, action: Action.READ, attributes: ['*'] },
@@ -290,7 +302,13 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
resource: Entity.USER, action: [Action.READ], attributes: ['*'],
condition: { Fn: 'EQUALS', args: { 'user': '$.owner' } }
},
- { resource: Entity.ASSETS, action: Action.LIST, attributes: ['*'] },
+ {
+ resource: Entity.ASSETS, action: Action.LIST,
+ attributes: [
+ 'id', 'name', 'siteAreaID', 'siteArea.id', 'siteArea.name', 'siteArea.siteID', 'siteID', 'assetType', 'coordinates',
+ 'dynamicAsset', 'connectionID', 'meterID', 'currentInstantWatts', 'currentStateOfCharge'
+ ]
+ },
{ resource: Entity.ASSET, action: Action.READ, attributes: ['*'] },
{ resource: Entity.CAR_CATALOGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.CAR_CATALOG, action: Action.READ, attributes: ['*'] },

MODIFY
src/server/rest/v1/service/AuthorizationService.ts
src/server/rest/v1/service/AuthorizationService.ts
@@ -47,6 +47,10 @@ export default class AuthorizationService {
return entity['can' + Action.ASSIGN_CHARGING_STATIONS];
case Action.UNASSIGN_CHARGING_STATIONS:
return entity['can' + Action.UNASSIGN_CHARGING_STATIONS];
+ case Action.ASSIGN_ASSETS:
+ return entity['can' + Action.ASSIGN_ASSETS];
+ case Action.UNASSIGN_ASSETS:
+ return entity['can' + Action.UNASSIGN_ASSETS];
default:
return false;
}
@@ -357,22 +361,16 @@ export default class AuthorizationService {
}
public static async checkAndGetAssetsAuthorizationFilters(
- tenant: Tenant, userToken: UserToken, filteredRequest: HttpAssetsRequest): Promise<AuthorizationFilter> {
+ tenant: Tenant, userToken: UserToken, filteredRequest: Record<string, any>): Promise<AuthorizationFilter> {
const authorizationFilters: AuthorizationFilter = {
filters: {},
dataSources: new Map(),
- projectFields: [
- 'id', 'name', 'siteAreaID', 'siteArea.id', 'siteArea.name', 'siteArea.siteID', 'siteID', 'assetType', 'coordinates',
- 'dynamicAsset', 'connectionID', 'meterID', 'currentInstantWatts', 'currentStateOfCharge'
- ],
- authorized: userToken.role === UserRole.ADMIN,
+ projectFields: [ ],
+ authorized: false,
};
- // Filter projected fields
- authorizationFilters.projectFields = AuthorizationService.filterProjectFields(
- authorizationFilters.projectFields, filteredRequest.ProjectFields);
- // Handle Sites
- await AuthorizationService.checkAssignedSites(
- tenant, userToken, filteredRequest, authorizationFilters);
+ // Check static & dynamic authorization
+ await this.canPerformAuthorizationAction(
+ tenant, userToken, Entity.ASSETS, Action.LIST, authorizationFilters, filteredRequest);
return authorizationFilters;
}

MODIFY
src/server/rest/v1/service/SiteAreaService.ts
src/server/rest/v1/service/SiteAreaService.ts
@@ -33,20 +33,10 @@ export default class SiteAreaService {
Action.UPDATE, Entity.ASSET, MODULE_NAME, 'handleAssignAssetsToSiteArea');
// Filter request
const filteredRequest = SiteAreaSecurity.filterAssignAssetsToSiteAreaRequest(req.body);
- // Check Mandatory fields
- UtilsService.assertIdIsProvided(action, filteredRequest.siteAreaID, MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
- if (Utils.isEmptyArray(filteredRequest.assetIDs)) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: 'The Asset\'s IDs must be provided',
- module: MODULE_NAME, method: 'handleAssignAssetsToSiteArea',
- user: req.user
- });
- }
// Check and Get Site Area
+ const authAction = action === ServerAction.ADD_ASSET_TO_SITE_AREA ? Action.ASSIGN_ASSETS : Action.UNASSIGN_ASSETS;
const siteArea = await UtilsService.checkAndGetSiteAreaAuthorization(
- req.tenant, req.user, filteredRequest.siteAreaID, Action.UPDATE, action, {});
+ req.tenant, req.user, filteredRequest.siteAreaID, authAction, action, {});
// Check and Get Assets
const assets = await UtilsService.checkSiteAreaAssetsAuthorization(
req.tenant, req.user, siteArea, filteredRequest.assetIDs, action, {});

MODIFY
src/server/rest/v1/service/UtilsService.ts
src/server/rest/v1/service/UtilsService.ts
@@ -103,7 +103,7 @@ export default class UtilsService {
public static async checkAndGetChargingStationsAuthorization(tenant: Tenant, userToken: UserToken, action: ServerAction,
additionalFilters: Record<string, any>, applyProjectFields = false): Promise<ChargingStation[]> {
- // Check dynamic auth for assignment
+ // Check dynamic auth
const authorizationFilter = await AuthorizationService.checkAndGetChargingStationsAuthorizationFilters(tenant, userToken, {});
if (!authorizationFilter.authorized) {
throw new AppAuthError({
@@ -139,6 +139,44 @@ export default class UtilsService {
return chargingStations.result;
}
+ public static async checkAndGetAssetsAuthorization(tenant: Tenant, userToken: UserToken,action: ServerAction,
+ additionalFilters: Record<string, any>, applyProjectFields = false):Promise<Asset[]> {
+ // Check dynamic auth
+ const authorizationFilter = await AuthorizationService.checkAndGetAssetsAuthorizationFilters(tenant, userToken, {});
+ if (!authorizationFilter.authorized) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.FORBIDDEN,
+ user: userToken,
+ action: Action.LIST,
+ entity: Entity.ASSETS,
+ module: MODULE_NAME, method: 'checkAndGetAssetsAuthorization',
+ });
+ }
+ // Get Assets
+ const assets = await AssetStorage.getAssets(tenant.id,
+ {
+ ...additionalFilters,
+ ...authorizationFilter.filters,
+ }, Constants.DB_PARAMS_MAX_LIMIT,
+ applyProjectFields ? authorizationFilter.projectFields : null
+ );
+ // Check
+ for (const asset of assets.result) {
+ // External Asset
+ if (!asset.issuer) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: `Asset ID '${asset.id}' not issued by the organization`,
+ module: MODULE_NAME, method: 'checkSiteAreaAssetsAuthorization',
+ user: userToken,
+ action: action
+ });
+ }
+ }
+ return assets.result;
+ }
+
public static async checkAndGetCompanyAuthorization(tenant: Tenant, userToken: UserToken, companyID: string, authAction: Action,
action: ServerAction, additionalFilters: Record<string, any>, applyProjectFields = false): Promise<Company> {
// Check mandatory fields
@@ -368,29 +406,22 @@ export default class UtilsService {
public static async checkSiteAreaAssetsAuthorization(tenant: Tenant, userToken: UserToken, siteArea: SiteArea, assetIDs: string[],
action: ServerAction, additionalFilters: Record<string, any>, applyProjectFields = false): Promise<Asset[]> {
- // Check dynamic auth for assignment
- const authorizationFilter = await AuthorizationService.checkAssignSiteAreaAssetsAuthorizationFilters(
- tenant, action, userToken, siteArea, { siteAreaID: siteArea.id, assetIDs });
- if (!authorizationFilter.authorized) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.FORBIDDEN,
- user: userToken,
- action: action === ServerAction.ADD_ASSET_TO_SITE_AREA ? Action.ASSIGN : Action.UNASSIGN,
- entity: Entity.ASSET,
+
+ // Check Mandatory fields
+ UtilsService.assertIdIsProvided(action, siteArea.id, MODULE_NAME, 'checkSiteAreaAssetsAuthorization', userToken);
+ if (Utils.isEmptyArray(assetIDs)) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'The Asset\'s IDs must be provided',
module: MODULE_NAME, method: 'checkSiteAreaAssetsAuthorization',
+ user: userToken
});
}
- // Get Assets
- const assets = await AssetStorage.getAssets(tenant.id,
- {
- assetIDs,
- ...additionalFilters,
- ...authorizationFilter.filters,
- }, Constants.DB_PARAMS_MAX_LIMIT,
- applyProjectFields ? authorizationFilter.projectFields : null
- );
+ const assets = await this.checkAndGetAssetsAuthorization(tenant, userToken, action,
+ { assetIDs, ...additionalFilters }, applyProjectFields);
// Must have the same result
- if (assetIDs.length !== assets.result.length) {
+ if (assetIDs.length !== assets.length) {
throw new AppAuthError({
errorCode: HTTPAuthError.FORBIDDEN,
user: userToken,
@@ -399,21 +430,7 @@ export default class UtilsService {
module: MODULE_NAME, method: 'checkSiteAreaAssetsAuthorization',
});
}
- // Check
- for (const asset of assets.result) {
- // External Asset
- if (!asset.issuer) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.GENERAL_ERROR,
- message: `Asset ID '${asset.id}' not issued by the organization`,
- module: MODULE_NAME, method: 'checkSiteAreaAssetsAuthorization',
- user: userToken,
- action: action
- });
- }
- }
- return assets.result;
+ return assets;
}
public static async checkSiteAreaChargingStationsAuthorization(tenant: Tenant, userToken: UserToken, siteArea: SiteArea, chargingStationIDs: string[],
@@ -431,7 +448,10 @@ export default class UtilsService {
});
}
const chargingStations = await this.checkAndGetChargingStationsAuthorization(tenant, userToken, action,
- { chargingStationIDs, ...additionalFilters }, applyProjectFields);
+ {
+ chargingStationIDs,
+ ...additionalFilters
+ }, applyProjectFields);
// Must have the same result
if (chargingStationIDs.length !== chargingStations.length) {
throw new AppAuthError({

Change assignAsstesToSiteArea logic