Aligned assignment in Service
MODIFY
src/migration/tasks/UpdateChargingStationTemplatesTask.ts
src/migration/tasks/UpdateChargingStationTemplatesTask.ts
@@ -37,7 +37,7 @@ export default class UpdateChargingStationTemplatesTask extends MigrationTask {
}
getVersion() {
- return '2.5';
+ return '2.6';
}
private async applyTemplateToChargingStations(tenant: Tenant) {

MODIFY
src/server/rest/CentralRestServerService.ts
src/server/rest/CentralRestServerService.ts
@@ -63,8 +63,8 @@ class RequestMapper {
[ServerAction.REGISTRATION_TOKEN_CREATE]: RegistrationTokenService.handleCreateRegistrationToken.bind(this),
[ServerAction.USER_CREATE]: UserService.handleCreateUser.bind(this),
[ServerAction.COMPANY_CREATE]: CompanyService.handleCreateCompany.bind(this),
- [ServerAction.ADD_ASSET_TO_SITE_AREA]: AssetService.handleAssignAssetsToSiteArea.bind(this),
- [ServerAction.REMOVE_ASSET_TO_SITE_AREA]: AssetService.handleAssignAssetsToSiteArea.bind(this),
+ [ServerAction.ADD_ASSET_TO_SITE_AREA]: SiteAreaService.handleAssignAssetsToSiteArea.bind(this),
+ [ServerAction.REMOVE_ASSET_TO_SITE_AREA]: SiteAreaService.handleAssignAssetsToSiteArea.bind(this),
[ServerAction.ASSET_CREATE]: AssetService.handleCreateAsset.bind(this),
[ServerAction.TENANT_CREATE]: TenantService.handleCreateTenant.bind(this),
[ServerAction.SITE_CREATE]: SiteService.handleCreateSite.bind(this),

MODIFY
src/server/rest/service/AssetService.ts
src/server/rest/service/AssetService.ts
import { Action, Entity } from '../../../types/Authorization';
-import { HTTPAuthError, HTTPError } from '../../../types/HTTPError';
import { NextFunction, Request, Response } from 'express';
import AppAuthError from '../../../exception/AppAuthError';
-import AppError from '../../../exception/AppError';
import Asset from '../../../types/Asset';
-import AssetFactory from '../../../integration/asset/AssetFactory';
import { AssetInErrorType } from '../../../types/InError';
import AssetSecurity from './security/AssetSecurity';
import AssetStorage from '../../../storage/mongodb/AssetStorage';
import Authorizations from '../../../authorization/Authorizations';
import Constants from '../../../utils/Constants';
+import { HTTPAuthError } from '../../../types/HTTPError';
import Logging from '../../../utils/Logging';
import { ServerAction } from '../../../types/Server';
import SiteAreaStorage from '../../../storage/mongodb/SiteAreaStorage';
@@ -22,78 +20,6 @@ const MODULE_NAME = 'AssetService';
export default class AssetService {
- public static async handleAssignAssetsToSiteArea(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
- // Check if component is active
- UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ASSET,
- Action.UPDATE, Entity.ASSET, MODULE_NAME, 'handleAssignAssetsToSiteArea');
- const filteredRequest = AssetSecurity.filterAssignAssetsToSiteAreaRequest(req.body);
- // Check Mandatory fields
- UtilsService.assertIdIsProvided(action, filteredRequest.siteAreaID, MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
- if (!filteredRequest.assetIDs || (filteredRequest.assetIDs && filteredRequest.assetIDs.length <= 0)) {
- 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
- });
- }
- // Get the Site Area
- const siteArea = await SiteAreaStorage.getSiteArea(req.user.tenantID, filteredRequest.siteAreaID);
- UtilsService.assertObjectExists(action, siteArea, `Site Area '${filteredRequest.siteAreaID}' does not exist anymore.`,
- MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
- // Check auth
- if (!Authorizations.canUpdateSiteArea(req.user, siteArea.siteID)) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.ERROR,
- user: req.user,
- action: Action.UPDATE,
- entity: Entity.SITE_AREA,
- module: MODULE_NAME,
- method: 'handleAssignAssetsToSiteArea',
- value: filteredRequest.siteAreaID
- });
- }
- // Get Assets
- for (const assetID of filteredRequest.assetIDs) {
- // Check the asset
- const asset = await AssetStorage.getAsset(req.user.tenantID, assetID);
- UtilsService.assertObjectExists(action, asset, `Asset '${assetID}' does not exist anymore.`,
- MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
- // Check auth
- if (!Authorizations.canUpdateAsset(req.user)) {
- throw new AppAuthError({
- errorCode: HTTPAuthError.ERROR,
- user: req.user,
- action: Action.UPDATE,
- entity: Entity.ASSET,
- module: MODULE_NAME,
- method: 'handleAssignAssetsToSiteArea',
- value: assetID
- });
- }
- }
- // Save
- if (action === ServerAction.ADD_ASSET_TO_SITE_AREA) {
- await AssetStorage.addAssetsToSiteArea(req.user.tenantID, filteredRequest.siteAreaID, filteredRequest.assetIDs);
- } else {
- await AssetStorage.removeAssetsFromSiteArea(req.user.tenantID, filteredRequest.siteAreaID, filteredRequest.assetIDs);
- }
- // Log
- Logging.logSecurityInfo({
- tenantID: req.user.tenantID,
- user: req.user,
- module: MODULE_NAME,
- method: 'handleAssignAssetsToSiteArea',
- message: 'Site Area\'s Assets have been assigned successfully',
- action: action
- });
- // Ok
- res.json(Constants.REST_RESPONSE_SUCCESS);
- next();
- }
-
public static async handleGetAssetsInError(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ASSET,

MODIFY
src/server/rest/service/SiteAreaService.ts
src/server/rest/service/SiteAreaService.ts
@@ -5,6 +5,7 @@ import { NextFunction, Request, Response } from 'express';
import { ActionsResponse } from '../../../types/GlobalType';
import AppAuthError from '../../../exception/AppAuthError';
import AppError from '../../../exception/AppError';
+import AssetStorage from '../../../storage/mongodb/AssetStorage';
import Authorizations from '../../../authorization/Authorizations';
import { ChargingProfilePurposeType } from '../../../types/ChargingProfile';
import ChargingStationStorage from '../../../storage/mongodb/ChargingStationStorage';
@@ -28,6 +29,78 @@ import moment from 'moment';
const MODULE_NAME = 'SiteAreaService';
export default class SiteAreaService {
+ public static async handleAssignAssetsToSiteArea(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ // Check if component is active
+ UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ASSET,
+ Action.UPDATE, Entity.ASSET, MODULE_NAME, 'handleAssignAssetsToSiteArea');
+ const filteredRequest = SiteAreaSecurity.filterAssignAssetsToSiteAreaRequest(req.body);
+ // Check Mandatory fields
+ UtilsService.assertIdIsProvided(action, filteredRequest.siteAreaID, MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
+ if (!filteredRequest.assetIDs || (filteredRequest.assetIDs && filteredRequest.assetIDs.length <= 0)) {
+ 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
+ });
+ }
+ // Get the Site Area
+ const siteArea = await SiteAreaStorage.getSiteArea(req.user.tenantID, filteredRequest.siteAreaID);
+ UtilsService.assertObjectExists(action, siteArea, `Site Area '${filteredRequest.siteAreaID}' does not exist anymore.`,
+ MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
+ // Check auth
+ if (!Authorizations.canUpdateSiteArea(req.user, siteArea.siteID)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.ERROR,
+ user: req.user,
+ action: Action.UPDATE,
+ entity: Entity.SITE_AREA,
+ module: MODULE_NAME,
+ method: 'handleAssignAssetsToSiteArea',
+ value: filteredRequest.siteAreaID
+ });
+ }
+ // Get Assets
+ for (const assetID of filteredRequest.assetIDs) {
+ // Check the asset
+ const asset = await AssetStorage.getAsset(req.user.tenantID, assetID);
+ UtilsService.assertObjectExists(action, asset, `Asset '${assetID}' does not exist anymore.`,
+ MODULE_NAME, 'handleAssignAssetsToSiteArea', req.user);
+ // Check auth
+ if (!Authorizations.canReadAsset(req.user)) {
+ throw new AppAuthError({
+ errorCode: HTTPAuthError.ERROR,
+ user: req.user,
+ action: Action.READ,
+ entity: Entity.ASSET,
+ module: MODULE_NAME,
+ method: 'handleAssignAssetsToSiteArea',
+ value: assetID
+ });
+ }
+ }
+ // Save
+ if (action === ServerAction.ADD_ASSET_TO_SITE_AREA) {
+ await AssetStorage.addAssetsToSiteArea(req.user.tenantID, filteredRequest.siteAreaID, filteredRequest.assetIDs);
+ } else {
+ await AssetStorage.removeAssetsFromSiteArea(req.user.tenantID, filteredRequest.siteAreaID, filteredRequest.assetIDs);
+ }
+ // Log
+ Logging.logSecurityInfo({
+ tenantID: req.user.tenantID,
+ user: req.user,
+ module: MODULE_NAME,
+ method: 'handleAssignAssetsToSiteArea',
+ message: 'Site Area\'s Assets have been assigned successfully',
+ action: action
+ });
+ // Ok
+ res.json(Constants.REST_RESPONSE_SUCCESS);
+ next();
+ }
+
public static async handleAssignChargingStationsToSiteArea(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
// Check if component is active
UtilsService.assertComponentIsActiveFromToken(
@@ -70,11 +143,11 @@ export default class SiteAreaService {
UtilsService.assertObjectExists(action, chargingStation, `ChargingStation '${chargingStationID}' does not exist anymore.`,
MODULE_NAME, 'handleAssignChargingStationsToSiteArea', req.user);
// Check auth
- if (!Authorizations.canUpdateChargingStation(req.user, siteArea.siteID)) {
+ if (!Authorizations.canReadChargingStation(req.user)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
- action: Action.UPDATE,
+ action: Action.READ,
entity: Entity.CHARGING_STATION,
module: MODULE_NAME,
method: 'handleAssignChargingStationsToSiteArea',

MODIFY
src/server/rest/service/UserService.ts
src/server/rest/service/UserService.ts
@@ -10,7 +10,6 @@ import Authorizations from '../../../authorization/Authorizations';
import BillingFactory from '../../../integration/billing/BillingFactory';
import ConnectionStorage from '../../../storage/mongodb/ConnectionStorage';
import Constants from '../../../utils/Constants';
-// pragma import ConvergentChargingPricingIntegration from '../../../integration/pricing/export-convergent-charging';
import EmspOCPIClient from '../../../client/ocpi/EmspOCPIClient';
import Logging from '../../../utils/Logging';
import NotificationHandler from '../../../notification/NotificationHandler';
@@ -40,7 +39,6 @@ export default class UserService {
Action.UPDATE, Entity.SITES, 'SiteService', 'handleAssignSitesToUser');
// Filter
const filteredRequest = UserSecurity.filterAssignSitesToUserRequest(req.body);
- // Check Mandatory fields
if (!filteredRequest.userID) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -64,7 +62,7 @@ export default class UserService {
});
}
// Check auth
- if (!Authorizations.canUpdateUser(req.user, filteredRequest.userID)) {
+ if (!Authorizations.canReadUser(req.user, filteredRequest.userID)) {
throw new AppAuthError({
errorCode: HTTPAuthError.ERROR,
user: req.user,
@@ -81,17 +79,9 @@ export default class UserService {
MODULE_NAME, 'handleAssignSitesToUser', req.user);
// Get Sites
for (const siteID of filteredRequest.siteIDs) {
- if (!await SiteStorage.siteExists(req.user.tenantID, siteID)) {
- throw new AppError({
- source: Constants.CENTRAL_SERVER,
- errorCode: HTTPError.OBJECT_DOES_NOT_EXIST_ERROR,
- message: `Site with ID '${siteID}' does not exist anymore`,
- module: MODULE_NAME,
- method: 'handleAssignSitesToUser',
- user: req.user,
- action: action
- });
- }
+ 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({

MODIFY
src/server/rest/service/security/AssetSecurity.ts
src/server/rest/service/security/AssetSecurity.ts
-import { HttpAssetRequest, HttpAssetsRequest, HttpAssignAssetsToSiteAreaRequest } from '../../../../types/requests/HttpAssetRequest';
+import { HttpAssetRequest, HttpAssetsRequest } from '../../../../types/requests/HttpAssetRequest';
import Asset from '../../../../types/Asset';
import Authorizations from '../../../../authorization/Authorizations';
@@ -21,13 +21,6 @@ export default class AssetSecurity {
} as HttpAssetRequest;
}
- public static filterAssignAssetsToSiteAreaRequest(request: any): HttpAssignAssetsToSiteAreaRequest {
- return {
- siteAreaID: sanitize(request.siteAreaID),
- assetIDs: request.assetIDs.map(sanitize)
- };
- }
-
public static filterAssetsRequest(request: any): HttpAssetsRequest {
const filteredRequest: HttpAssetsRequest = {
Search: sanitize(request.Search),

MODIFY
src/server/rest/service/security/SiteAreaSecurity.ts
src/server/rest/service/security/SiteAreaSecurity.ts
-import { HttpAssignChargingStationToSiteAreaRequest, HttpSiteAreaConsumptionsRequest, HttpSiteAreaRequest, HttpSiteAreasRequest } from '../../../../types/requests/HttpSiteAreaRequest';
+import { HttpAssignAssetsToSiteAreaRequest, HttpAssignChargingStationToSiteAreaRequest, HttpSiteAreaConsumptionsRequest, HttpSiteAreaRequest, HttpSiteAreasRequest } from '../../../../types/requests/HttpSiteAreaRequest';
import Authorizations from '../../../../authorization/Authorizations';
import ChargingStationSecurity from './ChargingStationSecurity';
@@ -17,6 +17,13 @@ export default class SiteAreaSecurity {
return sanitize(request.ID);
}
+ public static filterAssignAssetsToSiteAreaRequest(request: any): HttpAssignAssetsToSiteAreaRequest {
+ return {
+ siteAreaID: sanitize(request.siteAreaID),
+ assetIDs: request.assetIDs.map(sanitize)
+ };
+ }
+
public static filterAssignChargingStationsToSiteAreaRequest(request: any): HttpAssignChargingStationToSiteAreaRequest {
return {
siteAreaID: sanitize(request.siteAreaID),

MODIFY
src/storage/mongodb/SiteStorage.ts
src/storage/mongodb/SiteStorage.ts
@@ -503,22 +503,6 @@ export default class SiteStorage {
Logging.traceEnd(MODULE_NAME, 'deleteCompanySites', uniqueTimerID, { companyID });
}
- public static async siteExists(tenantID: string, siteID: string): Promise<boolean> {
- // Debug
- const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'deleteCompanySites');
- // Check Tenant
- await Utils.checkTenant(tenantID);
- // Exec
- const result = await global.database.getCollection<any>(tenantID, 'sites').findOne({ _id: Utils.convertToObjectID(siteID) });
- // Debug
- Logging.traceEnd(MODULE_NAME, 'deleteCompanySites', uniqueTimerID, { siteID });
- // Check
- if (!result) {
- return false;
- }
- return true;
- }
-
public static async siteHasUser(tenantID: string, siteID: string, userID: string): Promise<boolean> {
// Debug
const uniqueTimerID = Logging.traceStart(MODULE_NAME, 'siteHasUser');

MODIFY
src/types/requests/HttpAssetRequest.ts
src/types/requests/HttpAssetRequest.ts
@@ -12,8 +12,3 @@ export interface HttpAssetsRequest extends HttpDatabaseRequest {
WithNoSiteArea?: boolean;
ErrorType?: string;
}
-
-export interface HttpAssignAssetsToSiteAreaRequest {
- siteAreaID: string;
- assetIDs: string[];
-}

MODIFY
src/types/requests/HttpSiteAreaRequest.ts
src/types/requests/HttpSiteAreaRequest.ts
@@ -25,3 +25,8 @@ export interface HttpAssignChargingStationToSiteAreaRequest {
siteAreaID: string;
chargingStationIDs: string[];
}
+
+export interface HttpAssignAssetsToSiteAreaRequest {
+ siteAreaID: string;
+ assetIDs: string[];
+}

Aligned assignment in Service