From 39a1d597ec3d4af607b13dea64f2638c0301309f Mon Sep 17 00:00:00 2001 From: tab Date: Fri, 28 Feb 2025 19:57:13 +0200 Subject: [PATCH] feat(client): Add nonce [WIP] The WithNonce method allows setting a nonce value in the client configuration --- client.go | 6 ++++++ client_mock.go | 14 ++++++++++++++ client_test.go | 29 +++++++++++++++++++++++++++++ internal/config/config.go | 1 + internal/models/models.go | 1 + internal/requests/requests.go | 1 + internal/requests/requests_test.go | 13 +++++++++++++ 7 files changed, 65 insertions(+) diff --git a/client.go b/client.go index 3ffefb9..860dbd5 100644 --- a/client.go +++ b/client.go @@ -28,6 +28,7 @@ type Client interface { WithRelyingPartyUUID(id string) Client WithCertificateLevel(level string) Client WithHashType(hashType string) Client + WithNonce(nonce string) Client WithInteractionType(interactionType string) Client WithDisplayText60(text string) Client WithDisplayText200(text string) Client @@ -78,6 +79,11 @@ func (c *client) WithHashType(hashType string) Client { return c } +func (c *client) WithNonce(nonce string) Client { + c.config.Nonce = nonce + return c +} + func (c *client) WithInteractionType(interactionType string) Client { c.config.InteractionType = interactionType return c diff --git a/client_mock.go b/client_mock.go index 6fba214..55ac778 100644 --- a/client_mock.go +++ b/client_mock.go @@ -156,6 +156,20 @@ func (mr *MockClientMockRecorder) WithInteractionType(interactionType any) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithInteractionType", reflect.TypeOf((*MockClient)(nil).WithInteractionType), interactionType) } +// WithNonce mocks base method. +func (m *MockClient) WithNonce(nonce string) Client { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "WithNonce", nonce) + ret0, _ := ret[0].(Client) + return ret0 +} + +// WithNonce indicates an expected call of WithNonce. +func (mr *MockClientMockRecorder) WithNonce(nonce any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithNonce", reflect.TypeOf((*MockClient)(nil).WithNonce), nonce) +} + // WithRelyingPartyName mocks base method. func (m *MockClient) WithRelyingPartyName(name string) Client { m.ctrl.T.Helper() diff --git a/client_test.go b/client_test.go index 4ed89c1..7bac64a 100644 --- a/client_test.go +++ b/client_test.go @@ -242,6 +242,35 @@ func Test_WithHashType(t *testing.T) { } } +func Test_WithNonce(t *testing.T) { + c := NewClient() + + tests := []struct { + name string + param string + expected string + }{ + { + name: "Success", + param: "1234567890", + expected: "1234567890", + }, + { + name: "Empty", + param: "", + expected: "", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c = c.WithNonce(tt.param) + clientImpl := c.(*client) + assert.Equal(t, tt.expected, clientImpl.config.Nonce) + }) + } +} + func Test_WithInteractionType(t *testing.T) { c := NewClient() diff --git a/internal/config/config.go b/internal/config/config.go index e5669d6..376310f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,6 +11,7 @@ type Config struct { RelyingPartyUUID string CertificateLevel string HashType string + Nonce string InteractionType string DisplayText60 string DisplayText200 string diff --git a/internal/models/models.go b/internal/models/models.go index 1918dff..3efdef7 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -7,6 +7,7 @@ type AuthenticationRequest struct { CertificateLevel string `json:"certificateLevel"` Hash string `json:"hash"` HashType string `json:"hashType"` + Nonce string `json:"nonce,omitempty"` AllowedInteractionsOrder []AllowedInteraction `json:"allowedInteractionsOrder"` } diff --git a/internal/requests/requests.go b/internal/requests/requests.go index a9f05a4..629819c 100644 --- a/internal/requests/requests.go +++ b/internal/requests/requests.go @@ -68,6 +68,7 @@ func CreateAuthenticationSession( CertificateLevel: cfg.CertificateLevel, Hash: hash, HashType: cfg.HashType, + Nonce: cfg.Nonce, AllowedInteractionsOrder: []models.AllowedInteraction{ interaction, }, diff --git a/internal/requests/requests_test.go b/internal/requests/requests_test.go index 172007c..05299ee 100644 --- a/internal/requests/requests_test.go +++ b/internal/requests/requests_test.go @@ -39,6 +39,8 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { assert.Equal(t, "QUALIFIED", req.CertificateLevel) assert.Equal(t, "displayTextAndPIN", req.AllowedInteractionsOrder[0].Type) assert.Equal(t, "Enter PIN1", req.AllowedInteractionsOrder[0].DisplayText60) + assert.Equal(t, "SHA512", req.HashType) + assert.Equal(t, "random-nonce-123", req.Nonce) assert.Equal(t, identity, req.NationalIdentityNumber) w.Header().Set("Content-Type", "application/json") @@ -52,6 +54,7 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { InteractionType: "displayTextAndPIN", DisplayText60: "Enter PIN1", HashType: "SHA512", + Nonce: "random-nonce-123", Timeout: 10 * time.Second, }, }, @@ -69,6 +72,8 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { assert.Equal(t, "QUALIFIED", req.CertificateLevel) assert.Equal(t, "verificationCodeChoice", req.AllowedInteractionsOrder[0].Type) assert.Equal(t, "Enter PIN1", req.AllowedInteractionsOrder[0].DisplayText60) + assert.Equal(t, "SHA512", req.HashType) + assert.Equal(t, "random-nonce-123", req.Nonce) assert.Equal(t, identity, req.NationalIdentityNumber) w.Header().Set("Content-Type", "application/json") @@ -82,6 +87,7 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { InteractionType: "verificationCodeChoice", DisplayText60: "Enter PIN1", HashType: "SHA512", + Nonce: "random-nonce-123", Timeout: 10 * time.Second, }, }, @@ -99,6 +105,8 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { assert.Equal(t, "QUALIFIED", req.CertificateLevel) assert.Equal(t, "confirmationMessage", req.AllowedInteractionsOrder[0].Type) assert.Equal(t, "Confirm the authentication request and enter PIN1", req.AllowedInteractionsOrder[0].DisplayText200) + assert.Equal(t, "SHA512", req.HashType) + assert.Equal(t, "random-nonce-123", req.Nonce) assert.Equal(t, identity, req.NationalIdentityNumber) w.Header().Set("Content-Type", "application/json") @@ -112,6 +120,7 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { InteractionType: "confirmationMessage", DisplayText200: "Confirm the authentication request and enter PIN1", HashType: "SHA512", + Nonce: "random-nonce-123", Timeout: 10 * time.Second, }, }, @@ -129,6 +138,8 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { assert.Equal(t, "QUALIFIED", req.CertificateLevel) assert.Equal(t, "confirmationMessageAndVerificationCodeChoice", req.AllowedInteractionsOrder[0].Type) assert.Equal(t, "Confirm the authentication request and enter PIN1", req.AllowedInteractionsOrder[0].DisplayText200) + assert.Equal(t, "SHA512", req.HashType) + assert.Equal(t, "random-nonce-123", req.Nonce) assert.Equal(t, identity, req.NationalIdentityNumber) w.Header().Set("Content-Type", "application/json") @@ -142,6 +153,7 @@ func Test_CreateAuthenticationSession_Body(t *testing.T) { InteractionType: "confirmationMessageAndVerificationCodeChoice", DisplayText200: "Confirm the authentication request and enter PIN1", HashType: "SHA512", + Nonce: "random-nonce-123", Timeout: 10 * time.Second, }, }, @@ -170,6 +182,7 @@ func Test_CreateAuthenticationSession(t *testing.T) { DisplayText60: "Enter PIN1", DisplayText200: "Confirm the authentication request and enter PIN1", HashType: "SHA512", + Nonce: "random-nonce-123", Timeout: 10 * time.Second, }