Skip to content

Commit ae9bd18

Browse files
committed
Add OAuth2 provider codes and tokens to database
1 parent 4587ef0 commit ae9bd18

20 files changed

+1373
-82
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,13 +812,40 @@ func (q *querier) DeleteOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID)
812812
return q.db.DeleteOAuth2ProviderAppByID(ctx, id)
813813
}
814814

815+
func (q *querier) DeleteOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.UUID) error {
816+
code, err := q.db.GetOAuth2ProviderAppCodeByID(ctx, id)
817+
if err != nil {
818+
return err
819+
}
820+
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(code.UserID.String())); err != nil {
821+
return err
822+
}
823+
return q.db.DeleteOAuth2ProviderAppCodeByID(ctx, id)
824+
}
825+
826+
func (q *querier) DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams) error {
827+
if err := q.authorizeContext(ctx, rbac.ActionDelete,
828+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
829+
return err
830+
}
831+
return q.db.DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx, arg)
832+
}
833+
815834
func (q *querier) DeleteOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) error {
816835
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
817836
return err
818837
}
819838
return q.db.DeleteOAuth2ProviderAppSecretByID(ctx, id)
820839
}
821840

841+
func (q *querier) DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams) error {
842+
if err := q.authorizeContext(ctx, rbac.ActionDelete,
843+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
844+
return err
845+
}
846+
return q.db.DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx, arg)
847+
}
848+
822849
func (q *querier) DeleteOldProvisionerDaemons(ctx context.Context) error {
823850
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceSystem); err != nil {
824851
return err
@@ -1152,6 +1179,27 @@ func (q *querier) GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (d
11521179
return q.db.GetOAuth2ProviderAppByID(ctx, id)
11531180
}
11541181

1182+
func (q *querier) GetOAuth2ProviderAppCodeByAppIDAndSecret(ctx context.Context, arg database.GetOAuth2ProviderAppCodeByAppIDAndSecretParams) (database.OAuth2ProviderAppCode, error) {
1183+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppCodeToken); err != nil {
1184+
return database.OAuth2ProviderAppCode{}, err
1185+
}
1186+
return q.db.GetOAuth2ProviderAppCodeByAppIDAndSecret(ctx, arg)
1187+
}
1188+
1189+
func (q *querier) GetOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderAppCode, error) {
1190+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppCodeToken); err != nil {
1191+
return database.OAuth2ProviderAppCode{}, err
1192+
}
1193+
return q.db.GetOAuth2ProviderAppCodeByID(ctx, id)
1194+
}
1195+
1196+
func (q *querier) GetOAuth2ProviderAppSecretByAppIDAndSecret(ctx context.Context, arg database.GetOAuth2ProviderAppSecretByAppIDAndSecretParams) (database.OAuth2ProviderAppSecret, error) {
1197+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
1198+
return database.OAuth2ProviderAppSecret{}, err
1199+
}
1200+
return q.db.GetOAuth2ProviderAppSecretByAppIDAndSecret(ctx, arg)
1201+
}
1202+
11551203
func (q *querier) GetOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderAppSecret, error) {
11561204
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
11571205
return database.OAuth2ProviderAppSecret{}, err
@@ -1166,13 +1214,28 @@ func (q *querier) GetOAuth2ProviderAppSecretsByAppID(ctx context.Context, appID
11661214
return q.db.GetOAuth2ProviderAppSecretsByAppID(ctx, appID)
11671215
}
11681216

1217+
func (q *querier) GetOAuth2ProviderAppTokenByAppSecretIDAndSecret(ctx context.Context, arg database.GetOAuth2ProviderAppTokenByAppSecretIDAndSecretParams) (database.OAuth2ProviderAppToken, error) {
1218+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderAppCodeToken); err != nil {
1219+
return database.OAuth2ProviderAppToken{}, err
1220+
}
1221+
return q.db.GetOAuth2ProviderAppTokenByAppSecretIDAndSecret(ctx, arg)
1222+
}
1223+
11691224
func (q *querier) GetOAuth2ProviderApps(ctx context.Context) ([]database.OAuth2ProviderApp, error) {
11701225
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceOAuth2ProviderApp); err != nil {
11711226
return []database.OAuth2ProviderApp{}, err
11721227
}
11731228
return q.db.GetOAuth2ProviderApps(ctx)
11741229
}
11751230

1231+
func (q *querier) GetOAuth2ProviderAppsByUserID(ctx context.Context, userID uuid.UUID) ([]database.GetOAuth2ProviderAppsByUserIDRow, error) {
1232+
if err := q.authorizeContext(ctx, rbac.ActionRead,
1233+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(userID.String())); err != nil {
1234+
return []database.GetOAuth2ProviderAppsByUserIDRow{}, err
1235+
}
1236+
return q.db.GetOAuth2ProviderAppsByUserID(ctx, userID)
1237+
}
1238+
11761239
func (q *querier) GetOAuthSigningKey(ctx context.Context) (string, error) {
11771240
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
11781241
return "", err
@@ -2194,13 +2257,32 @@ func (q *querier) InsertOAuth2ProviderApp(ctx context.Context, arg database.Inse
21942257
return q.db.InsertOAuth2ProviderApp(ctx, arg)
21952258
}
21962259

2260+
func (q *querier) InsertOAuth2ProviderAppCode(ctx context.Context, arg database.InsertOAuth2ProviderAppCodeParams) (database.OAuth2ProviderAppCode, error) {
2261+
if err := q.authorizeContext(ctx, rbac.ActionCreate,
2262+
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
2263+
return database.OAuth2ProviderAppCode{}, err
2264+
}
2265+
return q.db.InsertOAuth2ProviderAppCode(ctx, arg)
2266+
}
2267+
21972268
func (q *querier) InsertOAuth2ProviderAppSecret(ctx context.Context, arg database.InsertOAuth2ProviderAppSecretParams) (database.OAuth2ProviderAppSecret, error) {
21982269
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
21992270
return database.OAuth2ProviderAppSecret{}, err
22002271
}
22012272
return q.db.InsertOAuth2ProviderAppSecret(ctx, arg)
22022273
}
22032274

2275+
func (q *querier) InsertOAuth2ProviderAppToken(ctx context.Context, arg database.InsertOAuth2ProviderAppTokenParams) (database.OAuth2ProviderAppToken, error) {
2276+
key, err := q.db.GetAPIKeyByID(ctx, arg.APIKeyID)
2277+
if err != nil {
2278+
return database.OAuth2ProviderAppToken{}, err
2279+
}
2280+
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(key.UserID.String())); err != nil {
2281+
return database.OAuth2ProviderAppToken{}, err
2282+
}
2283+
return q.db.InsertOAuth2ProviderAppToken(ctx, arg)
2284+
}
2285+
22042286
func (q *querier) InsertOrganization(ctx context.Context, arg database.InsertOrganizationParams) (database.Organization, error) {
22052287
return insert(q.log, q.auth, rbac.ResourceOrganization, q.db.InsertOrganization)(ctx, arg)
22062288
}

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,6 +2258,16 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
22582258
})
22592259
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionRead).Returns(secret)
22602260
}))
2261+
s.Run("GetOAuth2ProviderAppSecretByAppIDAndSecret", s.Subtest(func(db database.Store, check *expects) {
2262+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2263+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2264+
AppID: app.ID,
2265+
})
2266+
check.Args(database.GetOAuth2ProviderAppSecretByAppIDAndSecretParams{
2267+
AppID: app.ID,
2268+
HashedSecret: secret.HashedSecret,
2269+
}).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionRead).Returns(secret)
2270+
}))
22612271
s.Run("InsertOAuth2ProviderAppSecret", s.Subtest(func(db database.Store, check *expects) {
22622272
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
22632273
check.Args(database.InsertOAuth2ProviderAppSecretParams{
@@ -2283,3 +2293,139 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
22832293
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, rbac.ActionDelete)
22842294
}))
22852295
}
2296+
2297+
func (s *MethodTestSuite) TestOAuth2ProviderAppCodes() {
2298+
s.Run("GetOAuth2ProviderAppCodeByID", s.Subtest(func(db database.Store, check *expects) {
2299+
user := dbgen.User(s.T(), db, database.User{})
2300+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2301+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2302+
AppID: app.ID,
2303+
UserID: user.ID,
2304+
})
2305+
check.Args(code.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken, rbac.ActionRead).Returns(code)
2306+
}))
2307+
s.Run("GetOAuth2ProviderAppCodeByAppIDAndSecret", s.Subtest(func(db database.Store, check *expects) {
2308+
user := dbgen.User(s.T(), db, database.User{})
2309+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2310+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2311+
AppID: app.ID,
2312+
UserID: user.ID,
2313+
})
2314+
check.Args(database.GetOAuth2ProviderAppCodeByAppIDAndSecretParams{
2315+
AppID: app.ID,
2316+
HashedSecret: code.HashedSecret,
2317+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken, rbac.ActionRead).Returns(code)
2318+
}))
2319+
s.Run("InsertOAuth2ProviderAppCode", s.Subtest(func(db database.Store, check *expects) {
2320+
user := dbgen.User(s.T(), db, database.User{})
2321+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2322+
check.Args(database.InsertOAuth2ProviderAppCodeParams{
2323+
AppID: app.ID,
2324+
UserID: user.ID,
2325+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionCreate)
2326+
}))
2327+
s.Run("DeleteOAuth2ProviderAppCodeByID", s.Subtest(func(db database.Store, check *expects) {
2328+
user := dbgen.User(s.T(), db, database.User{})
2329+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2330+
code := dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2331+
AppID: app.ID,
2332+
UserID: user.ID,
2333+
})
2334+
check.Args(code.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2335+
}))
2336+
s.Run("DeleteOAuth2ProviderAppCodesByAppAndUserID", s.Subtest(func(db database.Store, check *expects) {
2337+
user := dbgen.User(s.T(), db, database.User{})
2338+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2339+
for i := 0; i < 5; i++ {
2340+
_ = dbgen.OAuth2ProviderAppCode(s.T(), db, database.OAuth2ProviderAppCode{
2341+
AppID: app.ID,
2342+
UserID: user.ID,
2343+
})
2344+
}
2345+
check.Args(database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams{
2346+
AppID: app.ID,
2347+
UserID: user.ID,
2348+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2349+
}))
2350+
}
2351+
2352+
func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
2353+
s.Run("GetOAuth2ProviderAppTokenByAppSecretIDAndSecret", s.Subtest(func(db database.Store, check *expects) {
2354+
user := dbgen.User(s.T(), db, database.User{})
2355+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2356+
UserID: user.ID,
2357+
})
2358+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2359+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2360+
AppID: app.ID,
2361+
})
2362+
token := dbgen.OAuth2ProviderAppToken(s.T(), db, database.OAuth2ProviderAppToken{
2363+
AppSecretID: secret.ID,
2364+
APIKeyID: key.ID,
2365+
})
2366+
check.Args(database.GetOAuth2ProviderAppTokenByAppSecretIDAndSecretParams{
2367+
AppSecretID: secret.ID,
2368+
HashedSecret: token.HashedSecret,
2369+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken, rbac.ActionRead).Returns(token)
2370+
}))
2371+
s.Run("GetOAuth2ProviderAppsByUserID", s.Subtest(func(db database.Store, check *expects) {
2372+
user := dbgen.User(s.T(), db, database.User{})
2373+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2374+
UserID: user.ID,
2375+
})
2376+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2377+
_ = dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2378+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2379+
AppID: app.ID,
2380+
})
2381+
for i := 0; i < 5; i++ {
2382+
_ = dbgen.OAuth2ProviderAppToken(s.T(), db, database.OAuth2ProviderAppToken{
2383+
AppSecretID: secret.ID,
2384+
APIKeyID: key.ID,
2385+
})
2386+
}
2387+
check.Args(user.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionRead).Returns([]database.GetOAuth2ProviderAppsByUserIDRow{
2388+
{
2389+
ID: app.ID,
2390+
CallbackURL: app.CallbackURL,
2391+
Icon: app.Icon,
2392+
Name: app.Name,
2393+
TokenCount: 5,
2394+
},
2395+
})
2396+
}))
2397+
s.Run("InsertOAuth2ProviderAppToken", s.Subtest(func(db database.Store, check *expects) {
2398+
user := dbgen.User(s.T(), db, database.User{})
2399+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2400+
UserID: user.ID,
2401+
})
2402+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2403+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2404+
AppID: app.ID,
2405+
})
2406+
check.Args(database.InsertOAuth2ProviderAppTokenParams{
2407+
AppSecretID: secret.ID,
2408+
APIKeyID: key.ID,
2409+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionCreate)
2410+
}))
2411+
s.Run("DeleteOAuth2ProviderAppTokensByAppAndUserID", s.Subtest(func(db database.Store, check *expects) {
2412+
user := dbgen.User(s.T(), db, database.User{})
2413+
key, _ := dbgen.APIKey(s.T(), db, database.APIKey{
2414+
UserID: user.ID,
2415+
})
2416+
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
2417+
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
2418+
AppID: app.ID,
2419+
})
2420+
for i := 0; i < 5; i++ {
2421+
_ = dbgen.OAuth2ProviderAppToken(s.T(), db, database.OAuth2ProviderAppToken{
2422+
AppSecretID: secret.ID,
2423+
APIKeyID: key.ID,
2424+
})
2425+
}
2426+
check.Args(database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams{
2427+
AppID: app.ID,
2428+
UserID: user.ID,
2429+
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), rbac.ActionDelete)
2430+
}))
2431+
}

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)