OCPI create + commands JSON schemas
MODIFY
src/assets/server/rest/v1/docs/e-mobility-oas.json
src/assets/server/rest/v1/docs/e-mobility-oas.json
"$ref": "#/components/parameters/OCPIEndpointID"
}
],
- "requestBody": {
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/OCPIEndpoint"
- }
- }
- }
- },
"responses": {
"200": {
"description": "OCPI Endpoint's local tokens generated",

ADD
src/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-by-id.json
+{
+ "title": "OCPI Endpoint by id Request",
+ "description": "",
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "ocpi-endpoint.json#/definitions/id"
+ }
+ }
+}

ADD
src/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-create.json
+{
+ "title": "OCPI Endpoint creation Request",
+ "description": "",
+ "type": "object",
+ "properties": {
+ "name": {
+ "$ref": "ocpi-endpoint.json#/definitions/name"
+ },
+ "role": {
+ "$ref": "ocpi-endpoint.json#/definitions/role"
+ },
+ "baseUrl": {
+ "$ref": "ocpi-endpoint.json#/definitions/baseUrl"
+ },
+ "countryCode": {
+ "$ref": "ocpi-endpoint.json#/definitions/countryCode"
+ },
+ "partyId": {
+ "$ref": "ocpi-endpoint.json#/definitions/partyId"
+ },
+ "localToken": {
+ "$ref": "ocpi-endpoint.json#/definitions/localToken"
+ },
+ "token": {
+ "$ref": "ocpi-endpoint.json#/definitions/token"
+ },
+ "backgroundPatchJob": {
+ "$ref": "ocpi-endpoint.json#/definitions/name"
+ }
+ },
+ "required": [
+ "name",
+ "role",
+ "baseUrl",
+ "localToken",
+ "token"
+ ]
+}

ADD
src/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-generate-local-token.json
+{
+ "title": "Generate OCPI Endpoint local token Request",
+ "description": "",
+ "type": "object",
+ "properties": {
+ "id": {
+ "$ref": "ocpi-endpoint.json#/definitions/id"
+ },
+ "name": {
+ "$ref": "ocpi-endpoint.json#/definitions/name"
+ }
+ },
+ "required": [
+ "id",
+ "name"
+ ]
+}

ADD
src/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-ping.json
+{
+ "title": "OCPI Endpoint ping Request",
+ "description": "",
+ "type": "object",
+ "properties": {
+ "name": {
+ "$ref": "ocpi-endpoint.json#/definitions/name"
+ },
+ "role": {
+ "$ref": "ocpi-endpoint.json#/definitions/role"
+ },
+ "baseUrl": {
+ "$ref": "ocpi-endpoint.json#/definitions/baseUrl"
+ },
+ "countryCode": {
+ "$ref": "ocpi-endpoint.json#/definitions/countryCode"
+ },
+ "partyId": {
+ "$ref": "ocpi-endpoint.json#/definitions/partyId"
+ },
+ "localToken": {
+ "$ref": "ocpi-endpoint.json#/definitions/localToken"
+ },
+ "token": {
+ "$ref": "ocpi-endpoint.json#/definitions/token"
+ },
+ "backgroundPatchJob": {
+ "$ref": "ocpi-endpoint.json#/definitions/name"
+ }
+ },
+ "required": [
+ "name",
+ "role",
+ "baseUrl",
+ "localToken",
+ "token"
+ ]
+}

ADD
src/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint.json
+{
+ "$id": "ocpi-endpoint.json",
+ "definitions": {
+ "id": {
+ "$ref": "common.json#/definitions/id"
+ },
+ "name": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "role": {
+ "type": "string",
+ "sanitize": "mongo",
+ "enum": [
+ "CPO",
+ "EMSP"
+ ]
+ },
+ "baseUrl": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "countryCode": {
+ "type": "string",
+ "sanitize": "mongo",
+ "format": "country"
+ },
+ "partyId": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "localToken": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "token": {
+ "type": "string",
+ "sanitize": "mongo"
+ },
+ "backgroundPathJob": {
+ "type": "boolean",
+ "sanitize": "mongo"
+ }
+ }
+}

MODIFY
src/server/rest/v1/service/OCPIEndpointService.ts
src/server/rest/v1/service/OCPIEndpointService.ts
@@ -15,6 +15,7 @@ import OCPIClientFactory from '../../../../client/ocpi/OCPIClientFactory';
import OCPIEndpoint from '../../../../types/ocpi/OCPIEndpoint';
import OCPIEndpointSecurity from './security/OCPIEndpointSecurity';
import OCPIEndpointStorage from '../../../../storage/mongodb/OCPIEndpointStorage';
+import OCPIEndpointValidator from '../validator/OCPIEndpointValidator';
import { OCPIRegistrationStatus } from '../../../../types/ocpi/OCPIRegistrationStatus';
import OCPIUtils from '../../../ocpi/OCPIUtils';
import { ServerAction } from '../../../../types/Server';
@@ -143,9 +144,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointCreateRequest(req.body);
- // Check Mandatory fields
- UtilsService.checkIfOCPIEndpointValid(filteredRequest, req);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointCreate(req.body);
const ocpiEndpoint: OCPIEndpoint = {
...filteredRequest,
createdBy: { id: req.user.id },
@@ -216,9 +215,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointPingRequest(req.body);
- // Check Mandatory fields
- UtilsService.checkIfOCPIEndpointValid(filteredRequest, req);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointPing(req.body);
// Build OCPI Client
const ocpiClient = await OCPIClientFactory.getOcpiClient(req.tenant, filteredRequest);
// Try to ping
@@ -259,8 +256,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointTriggerJobRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePullLocationsEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -312,8 +308,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointTriggerJobRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePullSessionsEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -365,8 +360,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointTriggerJobRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePullTokensEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -418,8 +412,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointTriggerJobRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePullCdrsEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -524,8 +517,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiCheckSessionsRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handleCheckSessionsEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -577,8 +569,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiCheckLocationsRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handleCheckSessionsOcpiEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -630,8 +621,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointSendEVSEStatusesRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePushEVSEStatusesOcpiEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -683,8 +673,7 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointSendTokensRequest(req.body);
- UtilsService.assertIdIsProvided(action, filteredRequest.id, MODULE_NAME, 'handlePushTokensOcpiEndpoint', req.user);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
// Get ocpiEndpoint
const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
@@ -849,13 +838,17 @@ export default class OCPIEndpointService {
});
}
// Filter
- const filteredRequest = OCPIEndpointSecurity.filterOcpiEndpointGenerateLocalTokenRequest(req.body);
+ const filteredRequest = OCPIEndpointValidator.getInstance().validateOCPIEndpointById(req.body);
+ // Get OcpiEndpoint
+ const ocpiEndpoint = await OCPIEndpointStorage.getOcpiEndpoint(req.tenant, filteredRequest.id);
+ UtilsService.assertObjectExists(action, ocpiEndpoint, `OCPI Endpoint ID '${filteredRequest.id}' does not exist`,
+ MODULE_NAME, 'handleGenerateLocalTokenOcpiEndpoint', req.user);
const tenant = await TenantStorage.getTenant(req.user.tenantID);
const localToken = OCPIUtils.generateLocalToken(tenant.subdomain);
await Logging.logSecurityInfo({
tenantID: req.user.tenantID,
user: req.user, module: MODULE_NAME, method: 'handleGenerateLocalTokenOcpiEndpoint',
- message: `Local Token for Ocpi Endpoint '${filteredRequest.name}' has been generatd successfully`,
+ message: `Local Token for Ocpi Endpoint '${ocpiEndpoint.name}' has been generated successfully`,
action,
detailedMessages: { token: filteredRequest }
});

MODIFY
src/server/rest/v1/validator/OCPIEndpointValidator.ts
src/server/rest/v1/validator/OCPIEndpointValidator.ts
+import { HttpOCPIEndpointByIdRequest } from '../../../../types/requests/HttpOCPIEndpointRequest';
import OCPIEndpoint from '../../../../types/ocpi/OCPIEndpoint';
import Schema from '../../../../types/validator/Schema';
import SchemaValidator from './SchemaValidator';
@@ -7,11 +8,15 @@ import global from '../../../../types/GlobalType';
export default class OCPIEndpointValidator extends SchemaValidator {
private static instance: OCPIEndpointValidator|null = null;
private ocpiEndpointCreate: Schema;
+ private ocpiEndpointPing: Schema;
+ private ocpiEndpointById: Schema;
private constructor() {
super('OCPIEndpointValidator');
this.ocpiEndpointCreate = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-create.json`, 'utf8'));
+ this.ocpiEndpointPing = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-ping.json`, 'utf8'));
+ this.ocpiEndpointById = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint-by-id.json`, 'utf8'));
}
public static getInstance(): OCPIEndpointValidator {
@@ -21,9 +26,21 @@ export default class OCPIEndpointValidator extends SchemaValidator {
return OCPIEndpointValidator.instance;
}
- public validateCreateOCPIEndpoint(data: any): OCPIEndpoint {
+ public validateOCPIEndpointCreate(data: any): OCPIEndpoint {
// Validate schema
this.validate(this.ocpiEndpointCreate, data);
return data;
}
+
+ public validateOCPIEndpointPing(data: any): OCPIEndpoint {
+ // Validate schema
+ this.validate(this.ocpiEndpointPing, data);
+ return data;
+ }
+
+ public validateOCPIEndpointById(data: any): HttpOCPIEndpointByIdRequest {
+ // Validate schema
+ this.validate(this.ocpiEndpointById, data);
+ return data;
+ }
}

MODIFY
src/server/rest/v1/validator/SchemaValidator.ts
src/server/rest/v1/validator/SchemaValidator.ts
@@ -4,6 +4,7 @@ import Constants from '../../../../utils/Constants';
import { HTTPError } from '../../../../types/HTTPError';
import Schema from '../../../../types/validator/Schema';
import ajvSanitizer from 'ajv-sanitizer';
+import countries from 'i18n-iso-countries';
import fs from 'fs';
import global from '../../../../types/GlobalType';
import sanitize from 'mongo-sanitize';
@@ -24,6 +25,7 @@ export default class SchemaValidator {
private carSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/car/car.json`, 'utf8'));
private assetSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/asset/asset.json`, 'utf8'));
private companySchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/company/company.json`, 'utf8'));
+ private ocpiEndpointSchema: Schema = JSON.parse(fs.readFileSync(`${global.appRoot}/assets/server/rest/v1/schemas/ocpi/ocpi-endpoint.json`, 'utf8'));
constructor(readonly moduleName: string,
config: {
@@ -44,6 +46,10 @@ export default class SchemaValidator {
type: 'number',
validate: (c) => Constants.REGEX_VALIDATION_LONGITUDE.test(c.toString())
});
+ this.ajv.addFormat('country', {
+ type: 'string',
+ validate: (c) => countries.isValid(c)
+ });
this.ajv.addSchema(this.commonSchema);
this.ajv.addSchema(this.tenantSchema);
this.ajv.addSchema(this.tenantComponentSchema);
@@ -54,6 +60,7 @@ export default class SchemaValidator {
this.ajv.addSchema(this.carSchema);
this.ajv.addSchema(this.assetSchema);
this.ajv.addSchema(this.companySchema);
+ this.ajv.addSchema(this.ocpiEndpointSchema);
}
protected validate(schema: Schema, content: any): void {

MODIFY
src/types/requests/HttpOCPIEndpointRequest.ts
src/types/requests/HttpOCPIEndpointRequest.ts
@@ -4,3 +4,7 @@ export interface HttpOCPIEndpointsRequest extends HttpDatabaseRequest{
ID?: string;
Search?: string;
}
+
+export interface HttpOCPIEndpointByIdRequest {
+ id: string;
+}

OCPI create + commands JSON schemas