Created asset test connection service + filter the request
MODIFY
src/authorization/Authorizations.ts
src/authorization/Authorizations.ts
@@ -570,6 +570,10 @@ export default class Authorizations {
return Authorizations.canPerformAction(loggedUser, Entity.INVOICES, Action.SYNCHRONIZE_INVOICES);
}
+ public static canCheckConnectionAsset(loggedUser: UserToken): boolean {
+ return Authorizations.canPerformAction(loggedUser, Entity.ASSET, Action.CHECK_CONNECTION);
+ }
+
public static isSuperAdmin(user: UserToken | User): boolean {
return user.role === UserRole.SUPER_ADMIN;
}

MODIFY
src/authorization/AuthorizationsDefinition.ts
src/authorization/AuthorizationsDefinition.ts
@@ -63,7 +63,7 @@ const AUTHORIZATION_DEFINITION: AuthorizationDefinition = {
},
{ resource: Entity.TAXES, action: [Action.LIST], attributes: ['*'] },
{ resource: Entity.INVOICES, action: [Action.LIST, Action.SYNCHRONIZE_INVOICES], attributes: ['*'] },
- { resource: Entity.ASSET, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE], attributes: ['*'] },
+ { resource: Entity.ASSET, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE, Action.CHECK_CONNECTION], attributes: ['*'] },
{ resource: Entity.ASSETS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.SETTINGS, action: Action.LIST, attributes: ['*'] },
{ resource: Entity.SETTING, action: [Action.CREATE, Action.READ, Action.UPDATE, Action.DELETE], attributes: ['*'] },

MODIFY
src/integration/pricing/export/convergent-charging/index.ts
src/integration/pricing/export/convergent-charging/index.ts
-export { default } from '../../convergent-charging';
+export { default } from '../../dummy/DummyPricingIntegration';

MODIFY
src/integration/refund/export/concur/index.ts
src/integration/refund/export/concur/index.ts
-export { default } from '../../concur';
+export { default } from '../../dummy/DummyRefundIntegration';

MODIFY
src/integration/smart-charging/export/sap-smart-charging/index.ts
src/integration/smart-charging/export/sap-smart-charging/index.ts
-export { default } from '../../sap-smart-charging';
+export { default } from '../../dummy/DummySmartChargingIntegration';

MODIFY
src/server/rest/CentralRestServerService.ts
src/server/rest/CentralRestServerService.ts
@@ -64,6 +64,7 @@ class RequestMapper {
[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.ASSET_TEST_CONNECTION]: AssetService.handleCheckAssetConnection.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
@@ -22,6 +22,56 @@ const MODULE_NAME = 'AssetService';
export default class AssetService {
+ public static async handleCheckAssetConnection(action: ServerAction, req: Request, res: Response, next: NextFunction): Promise<void> {
+ // Check if component is active
+ UtilsService.assertComponentIsActiveFromToken(req.user, TenantComponents.ASSET,
+ Action.CHECK_CONNECTION, Entity.ASSET, MODULE_NAME, 'handleCheckAssetConnection');
+ // Filter request
+ const filteredRequest = AssetSecurity.filterAssetTestConnection(req.body);
+ // Get asset connection type
+ const assetImpl = await AssetFactory.getAssetImpl(req.user.tenantID, filteredRequest.id);
+ // Asset has unknown connection type
+ if (!assetImpl) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Asset service is not configured',
+ module: MODULE_NAME, method: 'handleCheckAssetConnection',
+ action: action,
+ user: req.user
+ });
+ }
+ // Is authorized to check connection ?
+ if (!Authorizations.canCheckConnectionAsset(req.user)) {
+ throw new AppError({
+ source: Constants.CENTRAL_SERVER,
+ errorCode: HTTPError.GENERAL_ERROR,
+ message: 'Not authorized to check asset connections',
+ module: MODULE_NAME, method: 'handleCheckAssetConnection',
+ action: action,
+ user: req.user
+ });
+ }
+ try {
+ // Check connection
+ await assetImpl.checkConnection();
+ // Success
+ res.json(Object.assign({ connectionIsValid: true }, Constants.REST_RESPONSE_SUCCESS))
+ } catch (error) {
+ // KO
+ Logging.logError({
+ tenantID: req.user.tenantID,
+ user: req.user,
+ module: MODULE_NAME, method: 'handleCheckAssetConnection',
+ message: 'Asset connection failed',
+ action: action,
+ detailedMessages: { error: error.message, stack: error.stack }
+ });
+ res.json(Object.assign({ connectionIsValid: false }, Constants.REST_RESPONSE_SUCCESS));
+ }
+ next();
+ }
+
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,

MODIFY
src/server/rest/service/security/AssetSecurity.ts
src/server/rest/service/security/AssetSecurity.ts
-import { HttpAssetRequest, HttpAssetsRequest, HttpAssignAssetsToSiteAreaRequest } from '../../../../types/requests/HttpAssetRequest';
-
-import Asset from '../../../../types/Asset';
+import sanitize from 'mongo-sanitize';
import Authorizations from '../../../../authorization/Authorizations';
+import Asset from '../../../../types/Asset';
import { DataResult } from '../../../../types/DataResult';
-import SiteAreaSecurity from './SiteAreaSecurity';
+import { HttpAssetRequest, HttpAssetsRequest, HttpAssignAssetsToSiteAreaRequest } from '../../../../types/requests/HttpAssetRequest';
+import { AssetConnectionSetting } from '../../../../types/Setting';
import UserToken from '../../../../types/UserToken';
+import SiteAreaSecurity from './SiteAreaSecurity';
import UtilsSecurity from './UtilsSecurity';
-import sanitize from 'mongo-sanitize';
export default class AssetSecurity {
@@ -53,6 +53,20 @@ export default class AssetSecurity {
return AssetSecurity._filterAssetRequest(request);
}
+ public static filterAssetTestConnection(request: any): Partial<AssetConnectionSetting> {
+ return {
+ id: sanitize(request.id),
+ name: sanitize(request.name),
+ description: sanitize(request.description),
+ url: sanitize(request.url),
+ type: sanitize(request.type),
+ connection: {
+ user: sanitize(request.connection.user),
+ password: sanitize(request.connection.password)
+ }
+ }
+ }
+
public static _filterAssetRequest(request: any): Partial<Asset> {
const filteredRequest: Partial<Asset> = {};
filteredRequest.name = sanitize(request.name),

MODIFY
src/types/Server.ts
src/types/Server.ts
@@ -260,6 +260,7 @@ export enum ServerAction {
ASSET_IN_ERROR = 'AssetsInError',
ASSET_UPDATE = 'AssetUpdate',
ASSET_DELETE = 'AssetDelete',
+ ASSET_TEST_CONNECTION = 'AssetTestConnection',
TENANT_CREATE = 'TenantCreate',
TENANTS = 'Tenants',

Created asset test connection service + filter the request