mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
# Refactor OAuth2 Provider Code into Dedicated Package This PR refactors the OAuth2 provider functionality by moving it from the main `coderd` package into a dedicated `oauth2provider` package. The change improves code organization and maintainability without changing functionality. Key changes: - Created a new `oauth2provider` package to house all OAuth2 provider-related code - Moved existing OAuth2 provider functionality from `coderd/identityprovider` to the new package - Refactored handler functions to follow a consistent pattern of returning `http.HandlerFunc` instead of being handlers directly - Split large files into smaller, more focused files organized by functionality: - `app_secrets.go` - Manages OAuth2 application secrets - `apps.go` - Handles OAuth2 application CRUD operations - `authorize.go` - Implements the authorization flow - `metadata.go` - Provides OAuth2 metadata endpoints - `registration.go` - Handles dynamic client registration - `revoke.go` - Implements token revocation - `secrets.go` - Manages secret generation and validation - `tokens.go` - Handles token issuance and validation This refactoring improves code organization and makes the OAuth2 provider functionality more maintainable while preserving all existing behavior.
84 lines
2.7 KiB
Go
84 lines
2.7 KiB
Go
package oauth2provider
|
|
|
|
import (
|
|
"net/http"
|
|
"net/url"
|
|
|
|
"github.com/coder/coder/v2/coderd/httpmw"
|
|
"github.com/coder/coder/v2/site"
|
|
)
|
|
|
|
// authorizeMW serves to remove some code from the primary authorize handler.
|
|
// It decides when to show the html allow page, and when to just continue.
|
|
func authorizeMW(accessURL *url.URL) func(next http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
|
app := httpmw.OAuth2ProviderApp(r)
|
|
ua := httpmw.UserAuthorization(r.Context())
|
|
|
|
// If this is a POST request, it means the user clicked the "Allow" button
|
|
// on the consent form. Process the authorization.
|
|
if r.Method == http.MethodPost {
|
|
next.ServeHTTP(rw, r)
|
|
return
|
|
}
|
|
|
|
// For GET requests, show the authorization consent page
|
|
// TODO: For now only browser-based auth flow is officially supported but
|
|
// in a future PR we should support a cURL-based flow where we output text
|
|
// instead of HTML.
|
|
|
|
callbackURL, err := url.Parse(app.CallbackURL)
|
|
if err != nil {
|
|
site.RenderStaticErrorPage(rw, r, site.ErrorPageData{
|
|
Status: http.StatusInternalServerError,
|
|
HideStatus: false,
|
|
Title: "Internal Server Error",
|
|
Description: err.Error(),
|
|
RetryEnabled: false,
|
|
DashboardURL: accessURL.String(),
|
|
Warnings: nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
// Extract the form parameters for two reasons:
|
|
// 1. We need the redirect URI to build the cancel URI.
|
|
// 2. Since validation will run once the user clicks "allow", it is
|
|
// better to validate now to avoid wasting the user's time clicking a
|
|
// button that will just error anyway.
|
|
params, validationErrs, err := extractAuthorizeParams(r, callbackURL)
|
|
if err != nil {
|
|
errStr := make([]string, len(validationErrs))
|
|
for i, err := range validationErrs {
|
|
errStr[i] = err.Detail
|
|
}
|
|
site.RenderStaticErrorPage(rw, r, site.ErrorPageData{
|
|
Status: http.StatusBadRequest,
|
|
HideStatus: false,
|
|
Title: "Invalid Query Parameters",
|
|
Description: "One or more query parameters are missing or invalid.",
|
|
RetryEnabled: false,
|
|
DashboardURL: accessURL.String(),
|
|
Warnings: errStr,
|
|
})
|
|
return
|
|
}
|
|
|
|
cancel := params.redirectURL
|
|
cancelQuery := params.redirectURL.Query()
|
|
cancelQuery.Add("error", "access_denied")
|
|
cancel.RawQuery = cancelQuery.Encode()
|
|
|
|
// Render the consent page with the current URL (no need to add redirected parameter)
|
|
site.RenderOAuthAllowPage(rw, r, site.RenderOAuthAllowData{
|
|
AppIcon: app.Icon,
|
|
AppName: app.Name,
|
|
CancelURI: cancel.String(),
|
|
RedirectURI: r.URL.String(),
|
|
Username: ua.FriendlyName,
|
|
})
|
|
})
|
|
}
|
|
}
|