Module: Ocpp::Rails::StationAuthenticator

Defined in:
app/services/ocpp/rails/station_authenticator.rb

Overview

OCPP-J Security Profile 1: HTTP Basic Auth on the WebSocket upgrade. The username must equal the charge point identity and the password must match the per-station credential stored (hashed) on the ChargePoint. Profile 2 additionally requires TLS, terminated in front of the app.

Defined Under Namespace

Classes: Result

Class Method Summary collapse

Class Method Details

.authenticate(identifier:, authorization_header:) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'app/services/ocpp/rails/station_authenticator.rb', line 14

def self.authenticate(identifier:, authorization_header:)
  charge_point = ChargePoint.find_by(identifier: identifier)
  return failure(:unknown_charge_point) unless charge_point

  return Result.new(charge_point, nil) if Ocpp::Rails.configuration.authentication_mode == :none

  username, password = decode_basic(authorization_header)
  return failure(:missing_credentials) if username.nil?

  # OCPP-J requires the Basic Auth username to equal the station identity
  return failure(:identity_mismatch) unless username == identifier
  return failure(:no_credential_configured) if charge_point.auth_password_digest.blank?
  return failure(:invalid_credentials) unless charge_point.authenticate_password?(password)

  Result.new(charge_point, nil)
end

.decode_basic(header) ⇒ Object



31
32
33
34
35
36
37
38
# File 'app/services/ocpp/rails/station_authenticator.rb', line 31

def self.decode_basic(header)
  return nil unless header.is_a?(String) && header.start_with?("Basic ")

  decoded = Base64.strict_decode64(header.delete_prefix("Basic "))
  decoded.split(":", 2)
rescue ArgumentError
  nil
end