Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/components/gitpod-db/go/oidc_client_config_test.go
2498 views
1
// Copyright (c) 2022 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package db_test
6
7
import (
8
"context"
9
"testing"
10
11
db "github.com/gitpod-io/gitpod/components/gitpod-db/go"
12
"github.com/gitpod-io/gitpod/components/gitpod-db/go/dbtest"
13
"github.com/google/uuid"
14
"github.com/stretchr/testify/require"
15
)
16
17
func TestCreateOIDCClientConfig_Create(t *testing.T) {
18
conn := dbtest.ConnectForTests(t)
19
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{})[0]
20
21
retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID)
22
require.NoError(t, err)
23
require.Equal(t, created, retrieved)
24
}
25
26
func TestListOIDCClientConfigsForOrganization(t *testing.T) {
27
ctx := context.Background()
28
conn := dbtest.ConnectForTests(t)
29
30
orgA, orgB := uuid.New(), uuid.New()
31
32
dbtest.CreateOIDCClientConfigs(t, conn,
33
dbtest.NewOIDCClientConfig(t, db.OIDCClientConfig{
34
OrganizationID: orgA,
35
}),
36
dbtest.NewOIDCClientConfig(t, db.OIDCClientConfig{
37
OrganizationID: orgA,
38
}),
39
dbtest.NewOIDCClientConfig(t, db.OIDCClientConfig{
40
OrganizationID: orgB,
41
}),
42
)
43
44
configsForOrgA, err := db.ListOIDCClientConfigsForOrganization(ctx, conn, orgA)
45
require.NoError(t, err)
46
require.Len(t, configsForOrgA, 2)
47
48
configsForOrgB, err := db.ListOIDCClientConfigsForOrganization(ctx, conn, orgB)
49
require.NoError(t, err)
50
require.Len(t, configsForOrgB, 1)
51
52
configsForRandomOrg, err := db.ListOIDCClientConfigsForOrganization(ctx, conn, uuid.New())
53
require.NoError(t, err)
54
require.Len(t, configsForRandomOrg, 0)
55
}
56
57
func TestDeleteOIDCClientConfig(t *testing.T) {
58
59
t.Run("returns not found, when record does not exist", func(t *testing.T) {
60
conn := dbtest.ConnectForTests(t)
61
orgID := uuid.New()
62
63
err := db.DeleteOIDCClientConfig(context.Background(), conn, uuid.New(), orgID)
64
require.Error(t, err)
65
require.ErrorIs(t, err, db.ErrorNotFound)
66
})
67
68
t.Run("marks record deleted", func(t *testing.T) {
69
conn := dbtest.ConnectForTests(t)
70
orgID := uuid.New()
71
72
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
73
OrganizationID: orgID,
74
})[0]
75
76
err := db.DeleteOIDCClientConfig(context.Background(), conn, created.ID, created.OrganizationID)
77
require.NoError(t, err)
78
79
// Delete only sets the `deleted` field, verify that's true
80
var retrieved db.OIDCClientConfig
81
tx := conn.Where("id = ?", created.ID).Where("deleted = 1").First(&retrieved)
82
require.NoError(t, tx.Error)
83
})
84
85
}
86
87
func TestGetOIDCClientConfigForOrganization(t *testing.T) {
88
89
t.Run("not found when config does not exist", func(t *testing.T) {
90
conn := dbtest.ConnectForTests(t)
91
92
_, err := db.GetOIDCClientConfigForOrganization(context.Background(), conn, uuid.New(), uuid.New())
93
require.Error(t, err)
94
require.ErrorIs(t, err, db.ErrorNotFound)
95
})
96
97
t.Run("retrieves config which exists", func(t *testing.T) {
98
conn := dbtest.ConnectForTests(t)
99
100
orgID := uuid.New()
101
102
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
103
OrganizationID: orgID,
104
})[0]
105
106
retrieved, err := db.GetOIDCClientConfigForOrganization(context.Background(), conn, created.ID, created.OrganizationID)
107
require.NoError(t, err)
108
109
require.Equal(t, created, retrieved)
110
})
111
112
}
113
114
func TestGetActiveOIDCClientConfigByOrgSlug(t *testing.T) {
115
116
t.Run("not found when config does not exist", func(t *testing.T) {
117
conn := dbtest.ConnectForTests(t)
118
119
_, err := db.GetActiveOIDCClientConfigByOrgSlug(context.Background(), conn, "non-existing-org")
120
require.Error(t, err)
121
require.ErrorIs(t, err, db.ErrorNotFound)
122
})
123
124
t.Run("retrieves config which exists", func(t *testing.T) {
125
conn := dbtest.ConnectForTests(t)
126
127
// create a single team
128
team := dbtest.CreateOrganizations(t, conn, db.Organization{})[0]
129
130
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
131
OrganizationID: team.ID,
132
Active: true,
133
})[0]
134
135
retrieved, err := db.GetActiveOIDCClientConfigByOrgSlug(context.Background(), conn, team.Slug)
136
require.NoError(t, err)
137
138
require.Equal(t, created, retrieved)
139
})
140
141
t.Run("retrieves single active config", func(t *testing.T) {
142
conn := dbtest.ConnectForTests(t)
143
144
// create a single team
145
team := dbtest.CreateOrganizations(t, conn, db.Organization{})[0]
146
147
// create multiple
148
activeConfigID := uuid.New()
149
configs := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
150
ID: uuid.New(),
151
OrganizationID: team.ID,
152
Active: false,
153
}, db.OIDCClientConfig{
154
ID: activeConfigID,
155
OrganizationID: team.ID,
156
Active: true,
157
}, db.OIDCClientConfig{
158
ID: uuid.New(),
159
OrganizationID: team.ID,
160
Active: false,
161
})
162
require.Len(t, configs, 3)
163
164
retrieved, err := db.GetActiveOIDCClientConfigByOrgSlug(context.Background(), conn, team.Slug)
165
require.NoError(t, err)
166
167
require.Equal(t, activeConfigID, retrieved.ID)
168
169
})
170
171
}
172
173
func TestActivateClientConfig(t *testing.T) {
174
175
t.Run("not found when config does not exist", func(t *testing.T) {
176
conn := dbtest.ConnectForTests(t)
177
178
err := db.SetClientConfigActiviation(context.Background(), conn, uuid.New(), true)
179
require.Error(t, err)
180
require.ErrorIs(t, err, db.ErrorNotFound)
181
})
182
183
t.Run("config which exists is marked as active", func(t *testing.T) {
184
conn := dbtest.ConnectForTests(t)
185
186
config := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
187
OrganizationID: uuid.New(),
188
Active: false,
189
})[0]
190
configID := config.ID
191
192
config, err := db.GetOIDCClientConfig(context.Background(), conn, configID)
193
require.NoError(t, err)
194
require.Equal(t, false, config.Active)
195
196
err = db.SetClientConfigActiviation(context.Background(), conn, configID, true)
197
require.NoError(t, err)
198
199
config2, err := db.GetOIDCClientConfig(context.Background(), conn, configID)
200
require.NoError(t, err)
201
require.Equal(t, true, config2.Active)
202
203
err = db.SetClientConfigActiviation(context.Background(), conn, configID, true)
204
require.NoError(t, err)
205
})
206
207
t.Run("config activation of config de-activates previous active one", func(t *testing.T) {
208
conn := dbtest.ConnectForTests(t)
209
210
organizationId := uuid.New()
211
configs := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
212
OrganizationID: organizationId,
213
Active: false,
214
}, db.OIDCClientConfig{
215
OrganizationID: organizationId,
216
Active: false,
217
})
218
config1 := configs[0]
219
config2 := configs[1]
220
221
// activate first
222
err := db.SetClientConfigActiviation(context.Background(), conn, config1.ID, true)
223
require.NoError(t, err)
224
225
config1, err = db.GetOIDCClientConfig(context.Background(), conn, config1.ID)
226
require.NoError(t, err)
227
require.Equal(t, true, config1.Active, "failed to activate config1")
228
229
// activate second
230
err = db.SetClientConfigActiviation(context.Background(), conn, config2.ID, true)
231
require.NoError(t, err)
232
233
config2, err = db.GetOIDCClientConfig(context.Background(), conn, config2.ID)
234
require.NoError(t, err)
235
require.Equal(t, true, config2.Active, "failed to activate config2")
236
237
config1, err = db.GetOIDCClientConfig(context.Background(), conn, config1.ID)
238
require.NoError(t, err)
239
require.Equal(t, false, config1.Active, "failed to de-activate config1")
240
})
241
242
}
243
244
func TestUpdateOIDCSpec(t *testing.T) {
245
246
t.Run("no existing client config exists", func(t *testing.T) {
247
conn := dbtest.ConnectForTests(t)
248
cipher, _ := dbtest.GetTestCipher(t)
249
250
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
251
ID: uuid.New(),
252
}, nil)
253
require.Error(t, err)
254
require.ErrorIs(t, err, db.ErrorNotFound)
255
})
256
257
t.Run("no existing client config exists with spec update", func(t *testing.T) {
258
conn := dbtest.ConnectForTests(t)
259
cipher, _ := dbtest.GetTestCipher(t)
260
261
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
262
ID: uuid.New(),
263
}, &db.OIDCSpec{})
264
require.Error(t, err)
265
require.ErrorIs(t, err, db.ErrorNotFound)
266
})
267
268
t.Run("partially updates issuer, active, client id and client secret", func(t *testing.T) {
269
conn := dbtest.ConnectForTests(t)
270
cipher, _ := dbtest.GetTestCipher(t)
271
272
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{})[0]
273
274
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
275
ID: created.ID,
276
Active: true,
277
Issuer: "some-new-issuer",
278
}, &db.OIDCSpec{
279
ClientID: "my-new-client-id",
280
ClientSecret: "new-client-secret",
281
})
282
require.NoError(t, err)
283
284
retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID)
285
require.NoError(t, err)
286
287
decrypted, err := retrieved.Data.Decrypt(cipher)
288
require.NoError(t, err)
289
require.Equal(t, "my-new-client-id", decrypted.ClientID)
290
require.Equal(t, "new-client-secret", decrypted.ClientSecret)
291
require.True(t, retrieved.Active)
292
require.Equal(t, "some-new-issuer", retrieved.Issuer)
293
})
294
295
t.Run("partially updates redirect url and scopes", func(t *testing.T) {
296
conn := dbtest.ConnectForTests(t)
297
cipher, _ := dbtest.GetTestCipher(t)
298
299
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{})[0]
300
301
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
302
ID: created.ID,
303
}, &db.OIDCSpec{
304
RedirectURL: "new-url",
305
Scopes: []string{"hello"},
306
})
307
require.NoError(t, err)
308
309
retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID)
310
require.NoError(t, err)
311
312
decrypted, err := retrieved.Data.Decrypt(cipher)
313
require.NoError(t, err)
314
require.Equal(t, "new-url", decrypted.RedirectURL)
315
require.Equal(t, []string{"hello"}, decrypted.Scopes)
316
})
317
318
t.Run("partially updates all spec fields", func(t *testing.T) {
319
conn := dbtest.ConnectForTests(t)
320
cipher, _ := dbtest.GetTestCipher(t)
321
322
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{})[0]
323
324
updateSpec := db.OIDCSpec{
325
RedirectURL: "new-url",
326
ClientID: "my-new-client-id",
327
ClientSecret: "new-client-secret",
328
Scopes: []string{"hello"},
329
}
330
331
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
332
ID: created.ID,
333
}, &updateSpec)
334
require.NoError(t, err)
335
336
retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID)
337
require.NoError(t, err)
338
339
decrypted, err := retrieved.Data.Decrypt(cipher)
340
require.NoError(t, err)
341
require.Equal(t, updateSpec, decrypted)
342
})
343
344
t.Run("updates should unverify entries", func(t *testing.T) {
345
conn := dbtest.ConnectForTests(t)
346
cipher, _ := dbtest.GetTestCipher(t)
347
348
created := dbtest.CreateOIDCClientConfigs(t, conn, db.OIDCClientConfig{
349
Verified: db.BoolPointer(true),
350
})[0]
351
352
updateSpec := db.OIDCSpec{
353
ClientSecret: "new-client-secret",
354
}
355
356
err := db.UpdateOIDCClientConfig(context.Background(), conn, cipher, db.OIDCClientConfig{
357
ID: created.ID,
358
}, &updateSpec)
359
require.NoError(t, err)
360
361
retrieved, err := db.GetOIDCClientConfig(context.Background(), conn, created.ID)
362
require.NoError(t, err)
363
require.NotEqual(t, created.Verified, retrieved.Verified)
364
})
365
366
}
367
368