TestOAuth2RegistrationTokenSecurity tests security aspects of registration access tokens
(t *testing.T)
| 102 | |
| 103 | // TestOAuth2RegistrationTokenSecurity tests security aspects of registration access tokens |
| 104 | func TestOAuth2RegistrationTokenSecurity(t *testing.T) { |
| 105 | t.Parallel() |
| 106 | |
| 107 | // Single instance shared across all sub-tests. Each registers |
| 108 | // independent OAuth2 apps with unique client names. |
| 109 | client := coderdtest.New(t, nil) |
| 110 | _ = coderdtest.CreateFirstUser(t, client) |
| 111 | |
| 112 | t.Run("InvalidTokenFormats", func(t *testing.T) { |
| 113 | t.Parallel() |
| 114 | |
| 115 | ctx := t.Context() |
| 116 | |
| 117 | // Register a client to use for testing |
| 118 | clientName := fmt.Sprintf("test-client-%s-%d", t.Name(), time.Now().UnixNano()) |
| 119 | regReq := codersdk.OAuth2ClientRegistrationRequest{ |
| 120 | RedirectURIs: []string{"https://example.com/callback"}, |
| 121 | ClientName: clientName, |
| 122 | } |
| 123 | regResp, err := client.PostOAuth2ClientRegistration(ctx, regReq) |
| 124 | require.NoError(t, err) |
| 125 | |
| 126 | invalidTokens := []string{ |
| 127 | "", // Empty token |
| 128 | "invalid", // Too short |
| 129 | "not-base64-!@#$%^&*", // Invalid characters |
| 130 | strings.Repeat("a", 1000), // Too long |
| 131 | "Bearer " + regResp.RegistrationAccessToken, // With Bearer prefix (incorrect) |
| 132 | } |
| 133 | |
| 134 | for i, token := range invalidTokens { |
| 135 | t.Run(fmt.Sprintf("InvalidToken_%d", i), func(t *testing.T) { |
| 136 | t.Parallel() |
| 137 | |
| 138 | _, err := client.GetOAuth2ClientConfiguration(ctx, regResp.ClientID, token) |
| 139 | require.Error(t, err) |
| 140 | |
| 141 | var httpErr *codersdk.Error |
| 142 | require.ErrorAs(t, err, &httpErr) |
| 143 | require.Equal(t, http.StatusUnauthorized, httpErr.StatusCode()) |
| 144 | }) |
| 145 | } |
| 146 | }) |
| 147 | |
| 148 | t.Run("TokenNotReusableAcrossClients", func(t *testing.T) { |
| 149 | t.Parallel() |
| 150 | |
| 151 | ctx := t.Context() |
| 152 | |
| 153 | // Register first client |
| 154 | client1Name := fmt.Sprintf("test-client-1-%s-%d", t.Name(), time.Now().UnixNano()) |
| 155 | regReq1 := codersdk.OAuth2ClientRegistrationRequest{ |
| 156 | RedirectURIs: []string{"https://example.com/callback"}, |
| 157 | ClientName: client1Name, |
| 158 | } |
| 159 | regResp1, err := client.PostOAuth2ClientRegistration(ctx, regReq1) |
| 160 | require.NoError(t, err) |
| 161 |
nothing calls this directly
no test coverage detected