Skip to content

Commit 65b1054

Browse files
committed
feat(oauth2): add frontend UI for client credentials applications
- Add ClientCredentialsAppForm and ClientCredentialsAppRow components - Update API schemas to include created_at, grant_types, and user_id fields - Add dedicated pages for creating and managing client credentials apps - Update sidebar navigation and routing for OAuth2 client credentials - Enhance OAuth2AppPageView with user ownership information display Change-Id: I3271c7fb995d7225dd6cc830066fa2c8cb29720a Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent ac0d1f6 commit 65b1054

File tree

31 files changed

+1400
-86
lines changed

31 files changed

+1400
-86
lines changed

coderd/apidoc/docs.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/db2sdk/db2sdk.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,11 +354,19 @@ func TemplateVersionParameterOptionFromPreview(option *previewtypes.ParameterOpt
354354
}
355355

356356
func OAuth2ProviderApp(accessURL *url.URL, dbApp database.OAuth2ProviderApp) codersdk.OAuth2ProviderApp {
357+
var userID uuid.UUID
358+
if dbApp.UserID.Valid {
359+
userID = dbApp.UserID.UUID
360+
}
361+
357362
return codersdk.OAuth2ProviderApp{
358363
ID: dbApp.ID,
359364
Name: dbApp.Name,
360365
RedirectURIs: dbApp.RedirectUris,
361366
Icon: dbApp.Icon,
367+
CreatedAt: dbApp.CreatedAt,
368+
GrantTypes: dbApp.GrantTypes,
369+
UserID: userID,
362370
Endpoints: codersdk.OAuth2AppEndpoints{
363371
Authorization: accessURL.ResolveReference(&url.URL{
364372
Path: "/oauth2/authorize",
@@ -369,6 +377,9 @@ func OAuth2ProviderApp(accessURL *url.URL, dbApp database.OAuth2ProviderApp) cod
369377
DeviceAuth: accessURL.ResolveReference(&url.URL{
370378
Path: "/oauth2/device/authorize",
371379
}).String(),
380+
Revocation: accessURL.ResolveReference(&url.URL{
381+
Path: "/oauth2/revoke",
382+
}).String(),
372383
},
373384
}
374385
}

coderd/database/dbauthz/dbauthz.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,10 @@ func (q *querier) GetOAuth2ProviderApps(ctx context.Context) ([]database.OAuth2P
23042304
return q.db.GetOAuth2ProviderApps(ctx)
23052305
}
23062306

2307+
func (q *querier) GetOAuth2ProviderAppsByOwnerID(ctx context.Context, userID uuid.NullUUID) ([]database.OAuth2ProviderApp, error) {
2308+
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetOAuth2ProviderAppsByOwnerID)(ctx, userID)
2309+
}
2310+
23072311
func (q *querier) GetOAuth2ProviderAppsByUserID(ctx context.Context, userID uuid.UUID) ([]database.GetOAuth2ProviderAppsByUserIDRow, error) {
23082312
// This authz check is to make sure the caller can read all their own tokens.
23092313
if err := q.authorizeContext(ctx, policy.ActionRead,

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5288,6 +5288,28 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
52885288
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
52895289
check.Args(app.ID).Asserts(rbac.ResourceOauth2App, policy.ActionDelete)
52905290
}))
5291+
s.Run("GetOAuth2ProviderAppsByOwnerID", s.Subtest(func(db database.Store, check *expects) {
5292+
owner := dbgen.User(s.T(), db, database.User{})
5293+
// Create multiple apps with the same owner
5294+
app1 := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{
5295+
UserID: uuid.NullUUID{UUID: owner.ID, Valid: true},
5296+
})
5297+
app2 := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{
5298+
UserID: uuid.NullUUID{UUID: owner.ID, Valid: true},
5299+
})
5300+
// Create an app with a different owner to ensure filtering works
5301+
differentOwner := dbgen.User(s.T(), db, database.User{})
5302+
_ = dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{
5303+
UserID: uuid.NullUUID{UUID: differentOwner.ID, Valid: true},
5304+
})
5305+
// fetchWithPostFilter will check each individual app, so we need to assert those checks
5306+
check.Args(uuid.NullUUID{UUID: owner.ID, Valid: true}).
5307+
Asserts(
5308+
app1, policy.ActionRead, // Check for first app (includes owner)
5309+
app2, policy.ActionRead, // Check for second app (includes owner)
5310+
).
5311+
Returns([]database.OAuth2ProviderApp{app1, app2})
5312+
}))
52915313
s.Run("GetOAuth2ProviderAppByClientID", s.Subtest(func(db database.Store, check *expects) {
52925314
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
52935315
check.Args(app.ID).Asserts(rbac.ResourceOauth2App, policy.ActionRead).Returns(app)

coderd/database/dbmetrics/querymetrics.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/modelmethods.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,10 @@ func (OAuth2ProviderAppSecret) RBACObject() rbac.Object {
391391
return rbac.ResourceOauth2AppSecret
392392
}
393393

394-
func (OAuth2ProviderApp) RBACObject() rbac.Object {
394+
func (app OAuth2ProviderApp) RBACObject() rbac.Object {
395+
if app.UserID.Valid {
396+
return rbac.ResourceOauth2App.WithOwner(app.UserID.UUID.String())
397+
}
395398
return rbac.ResourceOauth2App
396399
}
397400

coderd/database/querier.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy