Skip to content

Commit

Permalink
feat: add support for invalid tokens and group ids
Browse files Browse the repository at this point in the history
  • Loading branch information
subnova committed Mar 21, 2024
1 parent b990d0e commit 9514335
Show file tree
Hide file tree
Showing 9 changed files with 626 additions and 76 deletions.
14 changes: 10 additions & 4 deletions manager/handlers/has2be/authorize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func setupTokenStore(tokenStore store.TokenStore) error {
ContractId: "GBTWK012345678V",
Issuer: "Thoughtworks",
Valid: true,
CacheMode: "NEVER",
CacheMode: "ALWAYS",
LastUpdated: time.Now().Format(time.RFC3339),
})
if err != nil {
Expand All @@ -76,7 +76,7 @@ func setupTokenStore(tokenStore store.TokenStore) error {
ContractId: "GBTWK123456789B",
Issuer: "Thoughtworks",
Valid: true,
CacheMode: "NEVER",
CacheMode: "ALWAYS",
LastUpdated: time.Now().Format(time.RFC3339),
})
if err != nil {
Expand All @@ -92,7 +92,10 @@ func TestAuthorizeWithEmaidAndCertificateHashes(t *testing.T) {

ah := handlersHasToBe.AuthorizeHandler{
Handler201: handlers201.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: &services.OcppTokenAuthService{
Clock: clock.RealClock{},
TokenStore: engine,
},
CertificateValidationService: mockCertValidationService{},
},
}
Expand Down Expand Up @@ -130,7 +133,10 @@ func TestAuthorizeWithEmaidAndInvalidCertificateHashes(t *testing.T) {

ah := handlersHasToBe.AuthorizeHandler{
Handler201: handlers201.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: &services.OcppTokenAuthService{
Clock: clock.RealClock{},
TokenStore: engine,
},
CertificateValidationService: mockCertValidationService{},
},
}
Expand Down
10 changes: 8 additions & 2 deletions manager/handlers/ocpp16/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,10 @@ func NewRouter(emitter transport.Emitter,
RequestSchema: "ocpp201/AuthorizeRequest.json",
ResponseSchema: "ocpp201/AuthorizeResponse.json",
Handler: handlers201.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: &services.OcppTokenAuthService{
Clock: clk,
TokenStore: engine,
},
CertificateValidationService: certValidationService,
},
},
Expand Down Expand Up @@ -156,7 +159,10 @@ func NewRouter(emitter transport.Emitter,
ResponseSchema: "has2be/AuthorizeResponse.json",
Handler: handlersHasToBe.AuthorizeHandler{
Handler201: handlers201.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: &services.OcppTokenAuthService{
Clock: clk,
TokenStore: engine,
},
CertificateValidationService: certValidationService,
},
},
Expand Down
33 changes: 10 additions & 23 deletions manager/handlers/ocpp201/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,18 @@ import (
"github.com/thoughtworks/maeve-csms/manager/ocpp"
types "github.com/thoughtworks/maeve-csms/manager/ocpp/ocpp201"
"github.com/thoughtworks/maeve-csms/manager/services"
"github.com/thoughtworks/maeve-csms/manager/store"
)

type AuthorizeHandler struct {
TokenStore store.TokenStore
TokenAuthService services.TokenAuthService
CertificateValidationService services.CertificateValidationService
}

func (a AuthorizeHandler) HandleCall(ctx context.Context, chargeStationId string, request ocpp.Request) (ocpp.Response, error) {
func (a AuthorizeHandler) HandleCall(ctx context.Context, _ string, request ocpp.Request) (ocpp.Response, error) {
span := trace.SpanFromContext(ctx)

req := request.(*types.AuthorizeRequestJson)

span.SetAttributes(
attribute.String("authorize.token", req.IdToken.IdToken),
attribute.String("authorize.token_type", string(req.IdToken.Type)))
if req.Certificate != nil {
span.SetAttributes(attribute.String("authorize.certificate", "chain"))
} else if req.Iso15118CertificateHashData != nil {
Expand All @@ -35,35 +31,28 @@ func (a AuthorizeHandler) HandleCall(ctx context.Context, chargeStationId string
span.SetAttributes(attribute.String("authorize.certificate", "none"))
}

status := types.AuthorizationStatusEnumTypeUnknown
tok, err := a.TokenStore.LookupToken(ctx, req.IdToken.IdToken)
if err != nil {
return nil, err
}
if tok != nil {
status = types.AuthorizationStatusEnumTypeAccepted
}
idTokenInfo := a.TokenAuthService.Authorize(ctx, req.IdToken)

var certificateStatus *types.AuthorizeCertificateStatusEnumType
if status == types.AuthorizationStatusEnumTypeAccepted {
if idTokenInfo.Status == types.AuthorizationStatusEnumTypeAccepted {
if req.Certificate != nil {
_, err = a.CertificateValidationService.ValidatePEMCertificateChain(ctx, []byte(*req.Certificate), req.IdToken.IdToken)
status, certificateStatus = handleCertificateValidationError(err)
_, err := a.CertificateValidationService.ValidatePEMCertificateChain(ctx, []byte(*req.Certificate), req.IdToken.IdToken)
idTokenInfo.Status, certificateStatus = handleCertificateValidationError(err)
if err != nil {
span.SetAttributes(attribute.String("authorize.cert_error", err.Error()))
}
}

if req.Iso15118CertificateHashData != nil {
_, err := a.CertificateValidationService.ValidateHashedCertificateChain(ctx, *req.Iso15118CertificateHashData)
status, certificateStatus = handleCertificateValidationError(err)
idTokenInfo.Status, certificateStatus = handleCertificateValidationError(err)
if err != nil {
span.SetAttributes(attribute.String("authorize.cert_error", err.Error()))
}
}
}

if status != types.AuthorizationStatusEnumTypeAccepted {
if idTokenInfo.Status != types.AuthorizationStatusEnumTypeAccepted {
var certStatus types.AuthorizeCertificateStatusEnumType
if certificateStatus != nil {
certStatus = *certificateStatus
Expand All @@ -74,12 +63,10 @@ func (a AuthorizeHandler) HandleCall(ctx context.Context, chargeStationId string
span.SetAttributes(attribute.String("authorize.cert_status", string(certStatus)))
}

span.SetAttributes(attribute.String("request.status", string(status)))
span.SetAttributes(attribute.String("request.status", string(idTokenInfo.Status)))

return &types.AuthorizeResponseJson{
IdTokenInfo: types.IdTokenInfoType{
Status: status,
},
IdTokenInfo: idTokenInfo,
CertificateStatus: certificateStatus,
}, nil
}
Expand Down
75 changes: 56 additions & 19 deletions manager/handlers/ocpp201/authorize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import (
"github.com/thoughtworks/maeve-csms/manager/services"
"github.com/thoughtworks/maeve-csms/manager/store"
"github.com/thoughtworks/maeve-csms/manager/store/inmemory"
"k8s.io/utils/clock"
clockutil "k8s.io/utils/clock"
"testing"
"time"
)

type mockCertValidationService struct {
}

func (m mockCertValidationService) ValidatePEMCertificateChain(ctx context.Context, certificate []byte, eMAID string) (*string, error) {
func (m mockCertValidationService) ValidatePEMCertificateChain(_ context.Context, certificate []byte, _ string) (*string, error) {
switch string(certificate) {
case "invalidCertChain":
return nil, services.ValidationErrorCertChain
Expand All @@ -34,7 +34,7 @@ func (m mockCertValidationService) ValidatePEMCertificateChain(ctx context.Conte
return nil, nil
}

func (m mockCertValidationService) ValidateHashedCertificateChain(ctx context.Context, ocspRequestData []types.OCSPRequestDataType) (*string, error) {
func (m mockCertValidationService) ValidateHashedCertificateChain(_ context.Context, ocspRequestData []types.OCSPRequestDataType) (*string, error) {
if len(ocspRequestData) > 0 {
switch ocspRequestData[0].SerialNumber {
case "invalidCertChain":
Expand All @@ -60,7 +60,7 @@ func setupTokenStore(tokenStore store.TokenStore) error {
ContractId: "GBTWK012345678V",
Issuer: "Thoughtworks",
Valid: true,
CacheMode: "NEVER",
CacheMode: "ALWAYS",
LastUpdated: time.Now().Format(time.RFC3339),
})
if err != nil {
Expand All @@ -74,7 +74,7 @@ func setupTokenStore(tokenStore store.TokenStore) error {
ContractId: "GBTWK123456789B",
Issuer: "Thoughtworks",
Valid: true,
CacheMode: "NEVER",
CacheMode: "ALWAYS",
LastUpdated: time.Now().Format(time.RFC3339),
})
if err != nil {
Expand All @@ -84,12 +84,18 @@ func setupTokenStore(tokenStore store.TokenStore) error {
}

func TestAuthorizeKnownRfidCard(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

req := &types.AuthorizeRequestJson{
Expand All @@ -112,12 +118,18 @@ func TestAuthorizeKnownRfidCard(t *testing.T) {
}

func TestAuthorizeWithUnknownRfidCard(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

req := &types.AuthorizeRequestJson{
Expand All @@ -140,12 +152,17 @@ func TestAuthorizeWithUnknownRfidCard(t *testing.T) {
}

func TestAuthorizeWithEmaidAndCertificateChain(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

Expand Down Expand Up @@ -173,12 +190,17 @@ func TestAuthorizeWithEmaidAndCertificateChain(t *testing.T) {
}

func TestAuthorizeWithEmaidAndInvalidCertificateChain(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

Expand Down Expand Up @@ -217,12 +239,17 @@ func TestAuthorizeWithEmaidAndInvalidCertificateChain(t *testing.T) {
}

func TestAuthorizeWithEmaidAndCertificateHashes(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

Expand Down Expand Up @@ -253,12 +280,17 @@ func TestAuthorizeWithEmaidAndCertificateHashes(t *testing.T) {
}

func TestAuthorizeWithEmaidAndInvalidCertificateHashes(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

Expand Down Expand Up @@ -301,12 +333,17 @@ func TestAuthorizeWithEmaidAndInvalidCertificateHashes(t *testing.T) {
}

func TestAuthorizeWithEmaidAndNoCertificateData(t *testing.T) {
engine := inmemory.NewStore(clock.RealClock{})
clock := clockutil.RealClock{}
engine := inmemory.NewStore(clock)
err := setupTokenStore(engine)
require.NoError(t, err)
tokenAuthService := &services.OcppTokenAuthService{
Clock: clock,
TokenStore: engine,
}

ah := handlers.AuthorizeHandler{
TokenStore: engine,
TokenAuthService: tokenAuthService,
CertificateValidationService: mockCertValidationService{},
}

Expand Down
12 changes: 10 additions & 2 deletions manager/handlers/ocpp201/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ func NewRouter(emitter transport.Emitter,
RequestSchema: "ocpp201/AuthorizeRequest.json",
ResponseSchema: "ocpp201/AuthorizeResponse.json",
Handler: AuthorizeHandler{
TokenStore: engine,
// PENDING: inject token auth service
TokenAuthService: &services.OcppTokenAuthService{
Clock: clk,
TokenStore: engine,
},
CertificateValidationService: certValidationService,
},
},
Expand Down Expand Up @@ -123,7 +127,11 @@ func NewRouter(emitter transport.Emitter,
RequestSchema: "ocpp201/TransactionEventRequest.json",
ResponseSchema: "ocpp201/TransactionEventResponse.json",
Handler: TransactionEventHandler{
Store: engine,
Store: engine,
TokenAuthService: &services.OcppTokenAuthService{
Clock: clk,
TokenStore: engine,
},
TariffService: tariffService,
},
},
Expand Down
Loading

0 comments on commit 9514335

Please sign in to comment.