@@ -720,7 +720,7 @@ func TestOAuth2ProviderRevoke(t *testing.T) {
720720},
721721},
722722{
723- name :"DeleteToken " ,
723+ name :"DeleteApp " ,
724724fn :func (ctx context.Context ,client * codersdk.Client ,s exchangeSetup ) {
725725err := client .RevokeOAuth2ProviderApp (ctx ,s .app .ID )
726726require .NoError (t ,err )
@@ -1603,5 +1603,81 @@ func TestOAuth2RegistrationAccessToken(t *testing.T) {
16031603})
16041604}
16051605
1606+ // TestOAuth2CoderClient verfies a codersdk client can be used with an oauth client.
1607+ func TestOAuth2CoderClient (t * testing.T ) {
1608+ t .Parallel ()
1609+
1610+ owner := coderdtest .New (t ,nil )
1611+ first := coderdtest .CreateFirstUser (t ,owner )
1612+
1613+ // Setup an oauth app
1614+ ctx := testutil .Context (t ,testutil .WaitLong )
1615+ app ,err := owner .PostOAuth2ProviderApp (ctx , codersdk.PostOAuth2ProviderAppRequest {
1616+ Name :"new-app" ,
1617+ CallbackURL :"http://localhost" ,
1618+ })
1619+ require .NoError (t ,err )
1620+
1621+ appsecret ,err := owner .PostOAuth2ProviderAppSecret (ctx ,app .ID )
1622+ require .NoError (t ,err )
1623+
1624+ cfg := & oauth2.Config {
1625+ ClientID :app .ID .String (),
1626+ ClientSecret :appsecret .ClientSecretFull ,
1627+ Endpoint : oauth2.Endpoint {
1628+ AuthURL :app .Endpoints .Authorization ,
1629+ DeviceAuthURL :app .Endpoints .DeviceAuth ,
1630+ TokenURL :app .Endpoints .Token ,
1631+ AuthStyle :oauth2 .AuthStyleInParams ,
1632+ },
1633+ RedirectURL :app .CallbackURL ,
1634+ Scopes : []string {},
1635+ }
1636+
1637+ // Make a new user
1638+ client ,user := coderdtest .CreateAnotherUser (t ,owner ,first .OrganizationID )
1639+
1640+ // Do an OAuth2 token exchange and get a new client with an oauth token
1641+ state := uuid .NewString ()
1642+
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
1649+
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 )
1658+
1659+ token ,err := cfg .Exchange (ctx ,code )
1660+ require .NoError (t ,err )
1661+
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
1667+
1668+ me ,err := usingOauth .User (ctx ,codersdk .Me )
1669+ require .NoError (t ,err )
1670+ require .Equal (t ,user .ID ,me .ID )
1671+
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 )
1676+
1677+ _ ,err = usingOauth .User (ctx ,codersdk .Me )
1678+ require .Error (t ,err )
1679+
1680+ }
1681+
16061682// NOTE: OAuth2 client registration validation tests have been migrated to
16071683// oauth2provider/validation_test.go for better separation of concerns