@@ -23,6 +23,7 @@ import (
2323 "github.com/coder/coder/v2/coderd/database/dbauthz"
2424 "github.com/coder/coder/v2/coderd/database/dbtestutil"
2525 "github.com/coder/coder/v2/coderd/database/dbtime"
26+ "github.com/coder/coder/v2/coderd/httpmw"
2627 "github.com/coder/coder/v2/coderd/oauth2provider"
2728 "github.com/coder/coder/v2/coderd/userpassword"
2829 "github.com/coder/coder/v2/coderd/util/ptr"
@@ -1607,18 +1608,22 @@ func TestOAuth2RegistrationAccessToken(t *testing.T) {
16071608func TestOAuth2CoderClient (t * testing.T ) {
16081609 t .Parallel ()
16091610
1610- owner := coderdtest .New (t , nil )
1611+ db , pubsub := dbtestutil .NewDB (t )
1612+ owner := coderdtest .New (t , & coderdtest.Options {
1613+ Database : db ,
1614+ Pubsub : pubsub ,
1615+ })
16111616 first := coderdtest .CreateFirstUser (t , owner )
16121617
16131618 // Setup an oauth app
1614- ctx := testutil .Context (t , testutil .WaitLong )
1615- app , err := owner .PostOAuth2ProviderApp (ctx , codersdk.PostOAuth2ProviderAppRequest {
1619+ setupCtx := testutil .Context (t , testutil .WaitLong )
1620+ app , err := owner .PostOAuth2ProviderApp (setupCtx , codersdk.PostOAuth2ProviderAppRequest {
16161621 Name : "new-app" ,
16171622 CallbackURL : "http://localhost" ,
16181623 })
16191624 require .NoError (t , err )
16201625
1621- appsecret , err := owner .PostOAuth2ProviderAppSecret (ctx , app .ID )
1626+ appsecret , err := owner .PostOAuth2ProviderAppSecret (setupCtx , app .ID )
16221627 require .NoError (t , err )
16231628
16241629 cfg := & oauth2.Config {
@@ -1635,47 +1640,76 @@ func TestOAuth2CoderClient(t *testing.T) {
16351640 }
16361641
16371642 // Make a new user
1638- client , user := coderdtest .CreateAnotherUser (t , owner , first .OrganizationID )
1643+ userClient , user := coderdtest .CreateAnotherUser (t , owner , first .OrganizationID )
1644+
1645+ // userOAuthFlow is a helper function that runs the oauth flow and returns
1646+ // the codersdk userClient using oauth as the means of authentication.
1647+ userOAuthFlow := func (t * testing.T ) (* codersdk.Client , * oauth2.Token ) {
1648+ // Do an OAuth2 token exchange and get a new userClient with an oauth token
1649+ state := uuid .NewString ()
1650+
1651+ // Get an OAuth2 code for a token exchange
1652+ code , err := oidctest .OAuth2GetCode (
1653+ cfg .AuthCodeURL (state ),
1654+ func (req * http.Request ) (* http.Response , error ) {
1655+ // Change to POST to simulate the form submission
1656+ req .Method = http .MethodPost
1657+
1658+ // Prevent automatic redirect following
1659+ userClient .HTTPClient .CheckRedirect = func (req * http.Request , via []* http.Request ) error {
1660+ return http .ErrUseLastResponse
1661+ }
1662+ return userClient .Request (setupCtx , req .Method , req .URL .String (), nil )
1663+ },
1664+ )
1665+ require .NoError (t , err )
16391666
1640- // Do an OAuth2 token exchange and get a new client with an oauth token
1641- state := uuid . NewString ( )
1667+ token , err := cfg . Exchange ( setupCtx , code )
1668+ require . NoError ( t , err )
16421669
1643- // Get an OAuth2 code for a token exchange
1644- code , err := oidctest .OAuth2GetCode (
1645- cfg .AuthCodeURL (state ),
1646- func (req * http.Request ) (* http.Response , error ) {
1647- // Change to POST to simulate the form submission
1648- req .Method = http .MethodPost
1670+ // Use the oauth userClient's authentication
1671+ // TODO: The SDK could probably support this with a better syntax/api.
1672+ oauthClient := oauth2 .NewClient (setupCtx , oauth2 .StaticTokenSource (token ))
1673+ usingOauth := codersdk .New (owner .URL )
1674+ usingOauth .HTTPClient = oauthClient
16491675
1650- // Prevent automatic redirect following
1651- client .HTTPClient .CheckRedirect = func (req * http.Request , via []* http.Request ) error {
1652- return http .ErrUseLastResponse
1653- }
1654- return client .Request (ctx , req .Method , req .URL .String (), nil )
1655- },
1656- )
1657- require .NoError (t , err )
1676+ me , err := usingOauth .User (setupCtx , codersdk .Me )
1677+ require .NoError (t , err )
1678+ require .Equal (t , user .ID , me .ID )
1679+ return usingOauth , token
1680+ }
16581681
1659- token , err := cfg .Exchange (ctx , code )
1660- require .NoError (t , err )
1682+ //nolint:tparallel,paralleltest
1683+ t .Run ("OauthRevoke" , func (t * testing.T ) {
1684+ // OauthRevoke uses the proper oauth revocation endpoint to revoke the token.
1685+ ctx := testutil .Context (t , testutil .WaitShort )
1686+ client , token := userOAuthFlow (t )
1687+ // Revoking the refresh token should prevent further access
1688+ // Revoking the refresh also invalidates the associated access token.
1689+ err = client .RevokeOAuth2Token (ctx , app .ID , token .RefreshToken )
1690+ require .NoError (t , err )
16611691
1662- // Use the oauth client's authentication
1663- // TODO: The SDK could probably support this with a better syntax/api.
1664- oauthClient := oauth2 .NewClient (ctx , oauth2 .StaticTokenSource (token ))
1665- usingOauth := codersdk .New (owner .URL )
1666- usingOauth .HTTPClient = oauthClient
1692+ _ , err = client .User (ctx , codersdk .Me )
1693+ require .Error (t , err )
1694+ })
16671695
1668- me , err := usingOauth .User (ctx , codersdk .Me )
1669- require .NoError (t , err )
1670- require .Equal (t , user .ID , me .ID )
1696+ //nolint:tparallel,paralleltest
1697+ t .Run ("DeleteAPIKey" , func (t * testing.T ) {
1698+ // DeleteAPIKey uses the coder api to delete the underlying api key used by the
1699+ // oauth token. This is not the recommended way to revoke oauth tokens, but is
1700+ // supported and should work.
1701+ ctx := testutil .Context (t , testutil .WaitShort )
1702+ client , token := userOAuthFlow (t )
16711703
1672- // Revoking the refresh token should prevent further access
1673- // Revoking the refresh also invalidates the associated access token.
1674- err = usingOauth .RevokeOAuth2Token (ctx , app .ID , token .RefreshToken )
1675- require .NoError (t , err )
1704+ id , _ , err := httpmw .SplitAPIToken (token .AccessToken )
1705+ require .NoError (t , err )
16761706
1677- _ , err = usingOauth .User (ctx , codersdk .Me )
1678- require .Error (t , err )
1707+ err = db .DeleteAPIKeyByID (ctx , id )
1708+ require .NoError (t , err )
1709+
1710+ _ , err = client .User (ctx , codersdk .Me )
1711+ require .Error (t , err )
1712+ })
16791713}
16801714
16811715// NOTE: OAuth2 client registration validation tests have been migrated to
0 commit comments