Skip to content

Commit 6a10587

Browse files
authored
Add endpoint oidc email to enroll response (#29)
* Add endpoint oidc email to enroll response * Add endpoint oidc email to doUpdate response * Make existing tests pass * Assert happy-path values * Check what happens when email is nil * Fix nil location * Remove omitempty * Little more test cleanup * Assert nil on standard host
1 parent 7df0fd4 commit 6a10587

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

client.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ var ErrInvalidCredentials = fmt.Errorf("invalid credentials")
8383
var ErrInvalidCode = fmt.Errorf("invalid enrollment code")
8484

8585
type ConfigMeta struct {
86-
Org ConfigOrg
87-
Network ConfigNetwork
88-
Host ConfigHost
86+
Org ConfigOrg
87+
Network ConfigNetwork
88+
Host ConfigHost
89+
EndpointOIDC *ConfigEndpointOIDC
8990
}
9091

9192
type ConfigOrg struct {
@@ -104,6 +105,10 @@ type ConfigHost struct {
104105
IPAddress string
105106
}
106107

108+
type ConfigEndpointOIDC struct {
109+
Email string
110+
}
111+
107112
// Enroll issues an enrollment request against the REST API using the given enrollment code, passing along a locally
108113
// generated DH X25519 public key to be signed by the CA, and an Ed 25519 public key for future API call authentication.
109114
// On success it returns the Nebula config generated by the server, a Nebula private key PEM to be inserted into the
@@ -204,6 +209,12 @@ func (c *Client) Enroll(ctx context.Context, logger logrus.FieldLogger, code str
204209
},
205210
}
206211

212+
if r.Data.EndpointOIDCMeta != nil {
213+
meta.EndpointOIDC = &ConfigEndpointOIDC{
214+
Email: r.Data.EndpointOIDCMeta.Email,
215+
}
216+
}
217+
207218
// Determine the private keys to save based on the network curve type
208219
var privkeyPEM []byte
209220
var privkey keys.PrivateKey
@@ -382,6 +393,12 @@ func (c *Client) DoUpdate(ctx context.Context, creds keys.Credentials) ([]byte,
382393
},
383394
}
384395

396+
if result.EndpointOIDCMeta != nil {
397+
meta.EndpointOIDC = &ConfigEndpointOIDC{
398+
Email: result.EndpointOIDCMeta.Email,
399+
}
400+
}
401+
385402
return result.Config, nebulaPrivkeyPEM, newCreds, meta, nil
386403
}
387404

client_test.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func TestEnroll(t *testing.T) {
5050
hostID := "foobar"
5151
hostName := "foo host"
5252
hostIP := "192.168.100.1"
53+
oidcEmail := "[email protected]"
5354
counter := uint(5)
5455
ca, _ := dnapitest.NebulaCACert()
5556
caPEM, err := ca.MarshalToPEM()
@@ -92,6 +93,9 @@ func TestEnroll(t *testing.T) {
9293
Name: hostName,
9394
IPAddress: hostIP,
9495
},
96+
EndpointOIDCMeta: &message.HostEndpointOIDCMetadata{
97+
Email: oidcEmail,
98+
},
9599
},
96100
})
97101
})
@@ -139,6 +143,7 @@ func TestEnroll(t *testing.T) {
139143
assert.Equal(t, hostID, meta.Host.ID)
140144
assert.Equal(t, hostName, meta.Host.Name)
141145
assert.Equal(t, hostIP, meta.Host.IPAddress)
146+
assert.Equal(t, oidcEmail, meta.EndpointOIDC.Email)
142147

143148
// Test error handling
144149
errorMsg := "invalid enrollment code"
@@ -377,6 +382,7 @@ func TestDoUpdate(t *testing.T) {
377382
hostID := "foobar"
378383
hostName := "foo host"
379384
hostIP := "192.168.100.1"
385+
oidcEmail := "[email protected]"
380386

381387
// This time sign the response with the correct CA key.
382388
ts.ExpectDNClientRequest(message.DoUpdate, http.StatusOK, func(r message.RequestWrapper) []byte {
@@ -400,6 +406,9 @@ func TestDoUpdate(t *testing.T) {
400406
Name: hostName,
401407
IPAddress: hostIP,
402408
},
409+
EndpointOIDCMeta: &message.HostEndpointOIDCMetadata{
410+
Email: oidcEmail,
411+
},
403412
}
404413
rawRes := jsonMarshal(newConfigResponse)
405414

@@ -427,6 +436,7 @@ func TestDoUpdate(t *testing.T) {
427436
assert.Equal(t, hostID, meta.Host.ID)
428437
assert.Equal(t, hostName, meta.Host.Name)
429438
assert.Equal(t, hostIP, meta.Host.IPAddress)
439+
assert.Equal(t, oidcEmail, meta.EndpointOIDC.Email)
430440

431441
}
432442

@@ -727,7 +737,7 @@ func TestCommandResponse(t *testing.T) {
727737

728738
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
729739
defer cancel()
730-
config, pkey, creds, _, err := c.Enroll(ctx, testutil.NewTestLogger(), "foobar")
740+
config, pkey, creds, meta, err := c.Enroll(ctx, testutil.NewTestLogger(), "foobar")
731741
require.NoError(t, err)
732742

733743
// make sure all credential values were set
@@ -740,6 +750,9 @@ func TestCommandResponse(t *testing.T) {
740750
assert.NotEmpty(t, config)
741751
assert.NotEmpty(t, pkey)
742752

753+
// no EndpointOIDC for standard host enrollments
754+
assert.Nil(t, meta.EndpointOIDC)
755+
743756
// This time sign the response with the correct CA key.
744757
responseToken := "abc123"
745758
res := map[string]any{"msg": "Hello, world!"}

message/message.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,14 @@ type DoUpdateRequest struct {
7373

7474
// DoUpdateResponse is the response generated for a DoUpdate request.
7575
type DoUpdateResponse struct {
76-
Config []byte `json:"config"`
77-
Counter uint `json:"counter"`
78-
Nonce []byte `json:"nonce"`
79-
TrustedKeys []byte `json:"trustedKeys"`
80-
Organization HostOrgMetadata `json:"organization"`
81-
Network HostNetworkMetadata `json:"network"`
82-
Host HostHostMetadata `json:"host"`
76+
Config []byte `json:"config"`
77+
Counter uint `json:"counter"`
78+
Nonce []byte `json:"nonce"`
79+
TrustedKeys []byte `json:"trustedKeys"`
80+
Organization HostOrgMetadata `json:"organization"`
81+
Network HostNetworkMetadata `json:"network"`
82+
Host HostHostMetadata `json:"host"`
83+
EndpointOIDCMeta *HostEndpointOIDCMetadata `json:"endpointOIDC"`
8384
}
8485

8586
// LongPollWaitResponseWrapper contains a response to LongPollWait inside "data."
@@ -152,13 +153,14 @@ type EnrollResponse struct {
152153

153154
// EnrollResponseData is included in the EnrollResponse.
154155
type EnrollResponseData struct {
155-
Config []byte `json:"config"`
156-
HostID string `json:"hostID"`
157-
Counter uint `json:"counter"`
158-
TrustedKeys []byte `json:"trustedKeys"`
159-
Organization HostOrgMetadata `json:"organization"`
160-
Network HostNetworkMetadata `json:"network"`
161-
Host HostHostMetadata `json:"host"`
156+
Config []byte `json:"config"`
157+
HostID string `json:"hostID"`
158+
Counter uint `json:"counter"`
159+
TrustedKeys []byte `json:"trustedKeys"`
160+
Organization HostOrgMetadata `json:"organization"`
161+
Network HostNetworkMetadata `json:"network"`
162+
Host HostHostMetadata `json:"host"`
163+
EndpointOIDCMeta *HostEndpointOIDCMetadata `json:"endpointOIDC"`
162164
}
163165

164166
// HostOrgMetadata is included in EnrollResponseData.
@@ -182,6 +184,11 @@ type HostHostMetadata struct {
182184
IPAddress string `json:"ipAddress"`
183185
}
184186

187+
// HostEndpointOIDCMetadata is included in EnrollResponseData.
188+
type HostEndpointOIDCMetadata struct {
189+
Email string `json:"email"`
190+
}
191+
185192
// APIError represents a single error returned in an API error response.
186193
type APIError struct {
187194
Code string `json:"code"`

0 commit comments

Comments
 (0)