|
1 | 1 | package coderd
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "context" |
5 | 4 | "crypto/sha256"
|
6 | 5 | "database/sql"
|
7 | 6 | "errors"
|
8 | 7 | "fmt"
|
9 | 8 | "net/http"
|
10 |
| - "net/url" |
11 |
| - "strings" |
12 | 9 |
|
13 | 10 | "github.com/google/uuid"
|
14 |
| - "golang.org/x/xerrors" |
15 | 11 |
|
16 |
| - "github.com/coder/coder/v2/coderd/apikey" |
17 | 12 | "github.com/coder/coder/v2/coderd/database"
|
18 | 13 | "github.com/coder/coder/v2/coderd/database/db2sdk"
|
19 |
| - "github.com/coder/coder/v2/coderd/database/dbauthz" |
20 | 14 | "github.com/coder/coder/v2/coderd/database/dbtime"
|
21 | 15 | "github.com/coder/coder/v2/coderd/httpapi"
|
22 | 16 | "github.com/coder/coder/v2/coderd/httpmw"
|
23 |
| - "github.com/coder/coder/v2/coderd/rbac" |
24 | 17 | "github.com/coder/coder/v2/codersdk"
|
25 | 18 | "github.com/coder/coder/v2/cryptorand"
|
26 | 19 | "github.com/coder/coder/v2/enterprise/coderd/identityprovider"
|
@@ -308,123 +301,7 @@ func (api *API) postOAuth2ProviderAppAuthorize() http.HandlerFunc {
|
308 | 301 | // @Success 200 {object} oauth2.Token
|
309 | 302 | // @Router /login/oauth2/tokens [post]
|
310 | 303 | func (api *API) postOAuth2ProviderAppToken() http.HandlerFunc {
|
311 |
| - return identityprovider.Tokens(api.Database, api.AccessURL, api.DeploymentValues.SessionDuration.Value()) |
312 |
| -} |
313 |
| - |
314 |
| -func (api *API) authorizationCodeGrant(ctx context.Context, app database.OAuth2ProviderApp, clientSecret, code string) (string, error) { |
315 |
| - // Validate the client secret. |
316 |
| - secretHash := sha256.Sum256([]byte(clientSecret)) |
317 |
| - secret, err := api.Database.GetOAuth2ProviderAppSecretByAppIDAndSecret( |
318 |
| - //nolint:gocritic // System needs to validate the client secret. |
319 |
| - dbauthz.AsSystemRestricted(ctx), |
320 |
| - database.GetOAuth2ProviderAppSecretByAppIDAndSecretParams{ |
321 |
| - AppID: app.ID, |
322 |
| - HashedSecret: secretHash[:], |
323 |
| - }) |
324 |
| - if err != nil { |
325 |
| - return "", err |
326 |
| - } |
327 |
| - |
328 |
| - // Validate the authorization code. |
329 |
| - codeHash := sha256.Sum256([]byte(code)) |
330 |
| - dbCode, err := api.Database.GetOAuth2ProviderAppCodeByAppIDAndSecret( |
331 |
| - //nolint:gocritic // System needs to validate the code. |
332 |
| - dbauthz.AsSystemRestricted(ctx), |
333 |
| - database.GetOAuth2ProviderAppCodeByAppIDAndSecretParams{ |
334 |
| - AppID: app.ID, |
335 |
| - HashedSecret: codeHash[:], |
336 |
| - }) |
337 |
| - if err != nil { |
338 |
| - return "", err |
339 |
| - } |
340 |
| - |
341 |
| - // Generate a refresh token. |
342 |
| - // The refresh token is not currently used or exposed though as API keys can |
343 |
| - // already be refreshed by just using them. |
344 |
| - // TODO: However, should we implement the refresh grant anyway? |
345 |
| - // 40 characters matches the length of GitHub's client secrets. |
346 |
| - rawRefreshToken, err := cryptorand.String(40) |
347 |
| - if err != nil { |
348 |
| - return "", err |
349 |
| - } |
350 |
| - |
351 |
| - // Generate the API key we will swap for the code. |
352 |
| - // TODO: We are ignoring scopes for now. |
353 |
| - // TODO: Should we add a name and only allow one at a time? |
354 |
| - key, sessionToken, err := apikey.Generate(apikey.CreateParams{ |
355 |
| - UserID: dbCode.UserID, |
356 |
| - LoginType: database.LoginTypeOAuth2ProviderApp, |
357 |
| - DefaultLifetime: api.DeploymentValues.SessionDuration.Value(), |
358 |
| - }) |
359 |
| - if err != nil { |
360 |
| - return "", err |
361 |
| - } |
3
57AE
62 |
| - |
363 |
| - // Grab the user roles so we can perform the exchange as the user. |
364 |
| - //nolint:gocritic // System needs to fetch user roles. |
365 |
| - roles, err := api.Database.GetAuthorizationUserRoles(dbauthz.AsSystemRestricted(ctx), dbCode.UserID) |
366 |
| - if err != nil { |
367 |
| - return "", err |
368 |
| - } |
369 |
| - userSubj := rbac.Subject{ |
370 |
| - ID: dbCode.UserID.String(), |
371 |
| - Roles: rbac.RoleNames(roles.Roles), |
372 |
| - Groups: roles.Groups, |
373 |
| - Scope: rbac.ScopeAll, |
374 |
| - } |
375 |
| - |
376 |
| - // Do the actual token exchange in the database. |
377 |
| - err = api.Database.InTx(func(tx database.Store) error { |
378 |
| - err = tx.DeleteOAuth2ProviderAppCodeByID(dbauthz.As(ctx, userSubj), dbCode.ID) |
379 |
| - if err != nil { |
380 |
| - return xerrors.Errorf("delete oauth2 app code: %w", err) |
381 |
| - } |
382 |
| - |
383 |
| - newKey, err := tx.InsertAPIKey(dbauthz.As(ctx, userSubj), key) |
384 |
| - if err != nil { |
385 |
| - return xerrors.Errorf("insert oauth2 access token: %w", err) |
386 |
| - } |
387 |
| - |
388 |
| - hashed := sha256.Sum256([]byte(rawRefreshToken)) |
389 |
| - _, err = tx.InsertOAuth2ProviderAppToken( |
390 |
| - dbauthz.As(ctx, userSubj), |
391 |
| - database.InsertOAuth2ProviderAppTokenParams{ |
392 |
| - ID: uuid.New(), |
393 |
| - CreatedAt: dbtime.Now(), |
394 |
| - ExpiresAt: key.ExpiresAt, |
395 |
| - HashedSecret: hashed[:], |
396 |
| - AppSecretID: secret.ID, |
397 |
| - APIKeyID: newKey.ID, |
398 |
| - }) |
399 |
| - if err != nil { |
400 |
| - return xerrors.Errorf("insert oauth2 refresh token: %w", err) |
401 |
| - } |
402 |
| - return nil |
403 |
| - }, nil) |
404 |
| - if err != nil { |
405 |
| - return "", err |
406 |
| - } |
407 |
| - |
408 |
| - return sessionToken, nil |
409 |
| -} |
410 |
| - |
411 |
| -// validateRedirectURL validates that the redirectURL is contained in baseURL. |
412 |
| -func validateRedirectURL(baseURL string, redirectURL string) error { |
413 |
| - base, err := url.Parse(baseURL) |
414 |
| - if err != nil { |
415 |
| - return err |
416 |
| - } |
417 |
| - |
418 |
| - redirect, err := url.Parse(redirectURL) |
419 |
| - if err != nil { |
420 |
| - return err |
421 |
| - } |
422 |
| - // It can be a sub-domain or a sub-directory. |
423 |
| - if (redirect.Host != base.Host && !strings.HasSuffix(redirect.Host, "."+base.Host)) || |
424 |
| - !strings.HasPrefix(redirect.Path, base.Path) { |
425 |
| - return xerrors.New("invalid redirect URL") |
426 |
| - } |
427 |
| - return nil |
| 304 | + return identityprovider.Tokens(api.Database, api.DeploymentValues.SessionDuration.Value()) |
428 | 305 | }
|
429 | 306 |
|
430 | 307 | // @Summary Delete OAuth2 application tokens.
|
|
0 commit comments