X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Fui-server%2FAbstractUIServer.ts;h=596ddb598d78bfb10dca5c076b395e059289ba87;hb=27782dbc3512349e7ff5e9fab9180dd31bf68ffa;hp=65847d85d4f313a92880c99fc6bfcb2f98a3cfbf;hpb=db2336d96424096d5570606680824af180e33c3a;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ui-server/AbstractUIServer.ts b/src/charging-station/ui-server/AbstractUIServer.ts index 65847d85..596ddb59 100644 --- a/src/charging-station/ui-server/AbstractUIServer.ts +++ b/src/charging-station/ui-server/AbstractUIServer.ts @@ -1,24 +1,98 @@ -import { Server as HttpServer } from 'http'; +import { type IncomingMessage, Server, type ServerResponse } from 'http'; -import WebSocket from 'ws'; +import type { WebSocket } from 'ws'; -import { ChargingStationData } from '../../types/ChargingStationWorker'; -import { ProtocolVersion } from '../../types/UIProtocol'; +import type { ChargingStationData } from '../../types/ChargingStationWorker'; +import type { UIServerConfiguration } from '../../types/ConfigurationData'; +import { + AuthenticationType, + ProcedureName, + ProtocolRequest, + ProtocolResponse, + ProtocolVersion, + RequestPayload, + ResponsePayload, +} from '../../types/UIProtocol'; import type AbstractUIService from './ui-services/AbstractUIService'; +import UIServiceFactory from './ui-services/UIServiceFactory'; export abstract class AbstractUIServer { public readonly chargingStations: Map; + protected readonly httpServer: Server; + protected readonly responseHandlers: Map; protected readonly uiServices: Map; - protected server: WebSocket.Server | HttpServer; - public constructor() { + public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { this.chargingStations = new Map(); + this.httpServer = new Server(); + this.responseHandlers = new Map(); this.uiServices = new Map(); } + public buildProtocolRequest( + id: string, + procedureName: ProcedureName, + requestPayload: RequestPayload + ): ProtocolRequest { + return [id, procedureName, requestPayload]; + } + + public buildProtocolResponse(id: string, responsePayload: ResponsePayload): ProtocolResponse { + return [id, responsePayload]; + } + + public stop(): void { + this.chargingStations.clear(); + } + + protected startHttpServer(): void { + if (this.httpServer.listening === false) { + this.httpServer.listen(this.uiServerConfiguration.options); + } + } + + protected registerProtocolVersionUIService(version: ProtocolVersion): void { + if (this.uiServices.has(version) === false) { + this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this)); + } + } + + protected authenticate(req: IncomingMessage, next: (err?: Error) => void): void { + if (this.isBasicAuthEnabled() === true) { + if (this.isValidBasicAuth(req) === false) { + next(new Error('Unauthorized')); + } + next(); + } + next(); + } + + private isBasicAuthEnabled(): boolean { + return ( + this.uiServerConfiguration.authentication?.enabled === true && + this.uiServerConfiguration.authentication?.type === AuthenticationType.BASIC_AUTH + ); + } + + private isValidBasicAuth(req: IncomingMessage): boolean { + const authorizationHeader = req.headers.authorization ?? ''; + const authorizationToken = authorizationHeader.split(/\s+/).pop() ?? ''; + const authentication = Buffer.from(authorizationToken, 'base64').toString(); + const authenticationParts = authentication.split(/:/); + const username = authenticationParts.shift(); + const password = authenticationParts.join(':'); + return ( + this.uiServerConfiguration.authentication?.username === username && + this.uiServerConfiguration.authentication?.password === password + ); + } + public abstract start(): void; - public abstract stop(): void; - public abstract sendRequest(request: string): void; - public abstract sendResponse(response: string): void; - public abstract logPrefix(modName?: string, methodName?: string): string; + public abstract sendRequest(request: ProtocolRequest): void; + public abstract sendResponse(response: ProtocolResponse): void; + public abstract logPrefix( + moduleName?: string, + methodName?: string, + prefixSuffix?: string + ): string; }