8000 Add OAuth2 provider codes and tokens to database · coder/coder@171dc79 · GitHub
[go: up one dir, main page]

Skip to content

Commit 171dc79

Browse files
committed
Add OAuth2 provider codes and tokens to database
1 parent c0e169e commit 171dc79

21 files changed

+1288
-84
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,13 +821,40 @@ func (q *querier) DeleteOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID)
821821
return q.db.DeleteOAuth2ProviderAppByID(ctx, id)
822822
}
823823

824+
func (q *querier) DeleteOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.UUID) error {
825+
code, err := q.db.GetOAuth2ProviderAppCodeByID(ctx, id)
826+
if err != nil {
827+
return err
828+
}
829+
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(code.UserID.String())); err != nil {
830+
return err
831+
}
832+
return q.db.DeleteOAuth2ProviderAppCodeByID(ctx, id)
833+
}
834+
835+
func (q *querier) DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams) error {
836+
if err := q.authorizeContext(ctx, rbac.ActionDelete,
837+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
838+
return err
839+
}
840+
return q.db.DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx, arg)
841+
}
842+
824843
func (q *querier) DeleteOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) error {
825844
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
826845
return err
827846
}
828847
return q.db.DeleteOAuth2ProviderAppSecretByID(ctx, id)
829848
}
830849

850+
func (q *querier) DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams) error {
851+
if err := q.authorizeContext(ctx, rbac.ActionDelete,
852+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
853+
return err
854+
}
855+
return q.db.DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx, arg)
856+
}
857+
831858
func (q *querier) DeleteOldProvisionerDaemons(ctx context.Context) error {
832859
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceSystem); err != nil {
833860
return err
@@ -1175,6 +1202,18 @@ func (q *querier) GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (d
11751202
return q.db.GetOAuth2ProviderAppByID(ctx, id)
11761203
}
11771204

1205+
func (q *querier) GetOAuth2ProviderAppCodeByAppIDAndSecret(ctx context.Context, arg database.GetOAuth2ProviderAppCodeByAppIDAndSecretParams) (database.OAuth2ProviderAppCode, error) {
1206+
return fetch(q.log, q.auth, q.db.GetOAuth2ProviderAppCodeByAppIDAndSecret)(ctx, arg)
1207+
}
1208+
1209+
func (q *querier) GetOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderAppCode, error) {
1210+
return fetch(q.log, q.auth, q.db.GetOAuth2ProviderAppCodeByID)(ctx, id)
1211+
}
1212+
1213+
func (q *querier) GetOAuth2ProviderAppSecretByAppIDAndSecret(ctx context.Context, arg database.GetOAuth2ProviderAppSecretByAppIDAndSecretParams) (database.OAuth2ProviderAppSecret, error) {
1214+
return fetch(q.log, q.auth, q.db.GetOAuth2ProviderAppSecretByAppIDAndSecret)(ctx, arg)
1215+
}
1216+
11781217
func (q *querier) GetOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderAppSecret, error) {
11791218
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
11801219
return database.OAuth2ProviderAppSecret{}, err
@@ -1196,6 +1235,15 @@ func (q *querier) GetOAuth2ProviderApps(ctx context.Context) ([]database.OAuth2P
11961235
return q.db.GetOAuth2ProviderApps(ctx)
11971236
}
11981237

1238+
func (q *querier) GetOAuth2ProviderAppsByUserID(ctx context.Context, userID uuid.UUID) ([]database.GetOAuth2ProviderAppsByUserIDRow, error) {
1239+
// These two authz checks make sure the caller can read all their own tokens.
1240+
if err := q.authorizeContext(ctx, rbac.ActionRead,
1241+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(userID.String())); err != nil {
1242+
return []database.GetOAuth2ProviderAppsByUserIDRow{}, err
1243+
}
1244+
return q.db.GetOAuth2ProviderAppsByUserID(ctx, userID)
1245+
}
1246+
11991247
func (q *querier) GetOAuthSigningKey(ctx context.Context) (string, error) {
12001248
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
12011249
return "", err
@@ -2228,13 +2276,32 @@ func (q *querier) InsertOAuth2ProviderApp(ctx context.Context, arg database.Inse
22282276
return q.db.InsertOAuth2ProviderApp(ctx, arg)
22292277
}
22302278

2279+
func (q *querier) InsertOAuth2ProviderAppCode(ctx context.Context, arg database.InsertOAuth2ProviderAppCodeParams) (database.OAuth2ProviderAppCode, error) {
2280+
if err := q.authorizeContext(ctx, rbac.ActionCreate,
2281+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
2282+
return database.OAuth2ProviderAppCode{}, err
2283+
}
2284+
return q.db.InsertOAuth2ProviderAppCode(ctx, arg)
2285+
}
2286+
22312287
func (q *querier) InsertOAuth2ProviderAppSecret(ctx context.Context, arg database.InsertOAuth2ProviderAppSecretParams) (database.OAuth2ProviderAppSecret, error) {
22322288
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
22332289
return database.OAuth2ProviderAppSecret{}, err
22342290
}
22352291
return q.db.InsertOAuth2ProviderAppSecret(ctx, arg)
22362292
}
22372293

2294+
func (q *querier) InsertOAuth2ProviderAppToken(ctx context.Context, arg database.InsertOAuth2ProviderAppTokenParams) (database.OAuth2ProviderAppToken, error) {
2295+
key, err := q.db.GetAPIKeyByID(ctx, arg.APIKeyID)
2296+
if err != nil {
2297+
return database.OAuth2ProviderAppToken{}, err
2298+
}
2299+
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(key.UserID.String())); err != nil {
2300+
return database.OAuth2ProviderAppToken{}, err
2301+
}
2302+
return q.db.InsertOAuth2ProviderAppToken(ctx, arg)
2303+
}
2304+
22382305
func (q *querier) InsertOrganization(ctx context.Context, arg database.InsertOrganizationParams) (database.Organization, error) {
22392306
return insert(q.log, q.auth, rbac.ResourceOrganization, q.db.InsertOrganization)(ctx, arg)
22402307
}

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,34 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
22792279
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
22802280
check.Args(app.ID).Asserts(rbac.ResourceOAuth2ProviderApp, rbac.ActionRead).Returns(app)
22812281
}))
2282+
s.Run("GetOAuth2ProviderAppsByUserID", s.Subtest(func(db database.Store, check *expects) {
2283+
user := dbgen.User(s.T(), db, database.User{})
2284+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2285+
UserID: user.ID,
2286+
})
2287+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2288+
_ = dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2289+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2290+
AppID: app.ID,
2291+
})
2292+
for i := 0; i < 5; i++ {
2293+
_ = dbgen.OAuth2ProviderAppToken(s.T(), db, database.OAuth2ProviderAppToken{
2294+
AppSecretID: secret.ID,
2295+
APIKeyID: key.ID,
2296+
})
2297+
}
2298+
check.Args(user.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionRead).Returns([]database.GetOAuth2ProviderAppsByUserIDRow{
2299+
{
2300+
OAuth2ProviderApp: database.OAuth2ProviderApp{
2301+
ID: app.ID,
2302+
CallbackURL: app.CallbackURL,
2303+
Icon: app.Icon,
2304+
Name: app.Name,
2305+
},
2306+
TokenCount: 5,
2307+
},
2308+
})
2309+
}))
22822310
s.Run("InsertOAuth2ProviderApp", s.Subtest(func(db database.Store, check *expects) {
22832311
check.Args(database.InsertOAuth2ProviderAppParams{}).Asserts(rbac.ResourceOAuth2ProviderApp, rbac.ActionCreate)
22842312
}))
@@ -2324,6 +2352,16 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
23242352
})
23252353
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionRead).Returns(secret)
23262354
}))
2355+
s.Run("GetOAuth2ProviderAppSecretByAppIDAndSecret", s.Subtest(func(db database.Store, check *expects) {
2356+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2357+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2358+
AppID: app.ID,
2359+
})
2360+
check.Args(database.GetOAuth2ProviderAppSecretByAppIDAndSecretParams{
2361+
AppID: app.ID,
2362+
HashedSecret: secret.HashedSecret,
2363+
}).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionRead).Returns(secret)
2364+
}))
23272365
s.Run("InsertOAuth2ProviderAppSecret", s.Subtest(func(db database.Store, check *expects) {
23282366
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
23292367
check.Args(database.InsertOAuth2ProviderAppSecretParams{
@@ -2349,3 +2387,95 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
23492387
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionDelete)
23502388
}))
23512389
}
2390+
2391+
func (s *MethodTestSuite) TestOAuth2ProviderAppCodes() {
2392+
s.Run("GetOAuth2ProviderAppCodeByID", s.Subtest(func(db database.Store, check *expects) {
2393+
user := dbgen.User(s.T(), db, database.User{})
2394+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderAp 10000 p{})
2395+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2396+
AppID: app.ID,
2397+
UserID: user.ID,
2398+
})
2399+
check.Args(code.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionRead).Returns(code)
2400+
}))
2401+
s.Run("GetOAuth2ProviderAppCodeByAppIDAndSecret", s.Subtest(func(db database.Store, check *expects) {
2402+
user := dbgen.User(s.T(), db, database.User{})
2403+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2404+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2405+
AppID: app.ID,
2406+
UserID: user.ID,
2407+
})
2408+
check.Args(database.GetOAuth2ProviderAppCodeByAppIDAndSecretParams{
2409+
AppID: app.ID,
2410+
HashedSecret: code.HashedSecret,
2411+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionRead).Returns(code)
2412+
}))
2413+
s.Run("InsertOAuth2ProviderAppCode", s.Subtest(func(db database.Store, check *expects) {
2414+
user := dbgen.User(s.T(), db, database.User{})
2415+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2416+
check.Args(database.InsertOAuth2ProviderAppCodeParams{
2417+
AppID: app.ID,
2418+
UserID: user.ID,
2419+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionCreate)
2420+
}))
2421+
s.Run("DeleteOAuth2ProviderAppCodeByID", s.Subtest(func(db database.Store, check *expects) {
2422+
user := dbgen.User(s.T(), db, database.User{})
2423+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2424+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2425+
AppID: app.ID,
2426+
UserID: user.ID,
2427+
})
2428+
check.Args(code.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2429+
}))
2430+
s.Run("DeleteOAuth2ProviderAppCodesByAppAndUserID", s.Subtest(func(db database.Store, check *expects) {
2431+
user := dbgen.User(s.T(), db, database.User{})
2432+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2433+
for i := 0; i < 5; i++ {
2434+
_ = dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2435+
AppID: app.ID,
2436+
UserID: user.ID,
2437+
})
2438+
}
2439+
check.Args(database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams{
2440+
AppID: app.ID,
2441+
UserID: user.ID,
2442+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2443+
}))
2444+
}
2445+
2446+
func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
2447+
s.Run("InsertOAuth2ProviderAppToken", s.Subtest(func(db database.Store, check *expects) {
2448+
user := dbgen.User(s.T(), db, database.User{})
2449+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2450+
UserID: user.ID,
2451+
})
2452+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2453+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2454+
AppID: app.ID,
2455+
})
2456+
check.Args(database.InsertOAuth2ProviderAppTokenParams{
2457+
AppSecretID: secret.ID,
2458+
APIKeyID: key.ID,
2459+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionCreate)
2460+
}))
2461+
s.Run("DeleteOAuth2ProviderAppTokensByAppAndUserID", s.Subtest(func(db database.Store, check *expects) {
2462+
user := dbgen.User(s.T(), db, database.User{})
2463+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2464+
UserID: user.ID,
2465+
})
2466+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2467+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2468+
AppID: app.ID,
2469+
})
2470+
for i := 0; i < 5; i++ {
2471+
_ = dbgen.OAuth2ProviderAppToken(s.T(), db, database.OAuth2ProviderAppToken{
2472+
AppSecretID: secret.ID,
2473+
APIKeyID: key.ID,
2474+
})
2475+
}
2476+
check.Args(database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams{
2477+
AppID: app.ID,
2478+
UserID: user.ID,
2479+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2480+
}))
2481+
}

coderd/database/dbgen/dbgen.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,32 @@ func OAuth2ProviderAppSecret(t testing.TB, db database.Store, seed database.OAut
704704
return app
705705
}
706706

707+
func OAuth2ProviderAppCode(t testing.TB, db database.Store, seed database.OAuth2ProviderAppCode) database.OAuth2ProviderAppCode {
708+
code, err := db.InsertOAuth2ProviderAppCode(genCtx, database.InsertOAuth2ProviderAppCodeParams{
709+
ID: takeFirst(seed.ID, uuid.New()),
710+
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
711+
ExpiresAt: takeFirst(seed.CreatedAt, dbtime.Now()),
712+
HashedSecret: takeFirstSlice(seed.HashedSecret, []byte("hashed-secret")),
713+
AppID: takeFirst(seed.AppID, uuid.New()),
714+
UserID: takeFirst(seed.UserID, uuid.New()),
715+
})
716+
require.NoError(t, err, "insert oauth2 app code")
717+
return code
718+
}
719+
720+
func OAuth2ProviderAppToken(t testing.TB, db database.Store, seed database.OAuth2ProviderAppToken) database.OAuth2ProviderAppToken {
721+
token, err := db.InsertOAuth2ProviderAppToken(genCtx, database.InsertOAuth2ProviderAppTokenParams{
722+
ID: takeFirst(seed.ID, uuid.New()),
723+
CreatedAt: takeFirst(seed.CreatedAt, dbtime.Now()),
724+
ExpiresAt: takeFirst(seed.CreatedAt, dbtime.Now()),
725+
HashedSecret: takeFirstSlice(seed.HashedSecret, []byte("hashed-secret")),
726+
AppSecretID: takeFirst(seed.AppSecretID, uuid.New()),
727+
APIKeyID: takeFirst(seed.APIKeyID, uuid.New().String()),
728+
})
729+
require.NoError(t, err, "insert oauth2 app token")
730+
return token
731+
}
732+
707733
func must[V any](v V, err error) V {
708734
if err != nil {
709735
panic(err)

0 commit comments

Comments
 (0)
0