MCPcopy Index your code
hub / github.com/coder/coder / Tokens

Function Tokens

coderd/oauth2provider/tokens.go:123–212  ·  view source on GitHub ↗

Tokens Uses Sessions.DefaultDuration for access token (API key) TTL and Sessions.RefreshDefaultDuration for refresh token TTL.

(db database.Store, lifetimes codersdk.SessionLifetime)

Source from the content-addressed store, hash-verified

121// Uses Sessions.DefaultDuration for access token (API key) TTL and
122// Sessions.RefreshDefaultDuration for refresh token TTL.
123func Tokens(db database.Store, lifetimes codersdk.SessionLifetime) http.HandlerFunc {
124 return func(rw http.ResponseWriter, r *http.Request) {
125 ctx := r.Context()
126 app := httpmw.OAuth2ProviderApp(r)
127
128 callbackURL, err := url.Parse(app.CallbackURL)
129 if err != nil {
130 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
131 Message: "Failed to validate form values.",
132 Detail: err.Error(),
133 })
134 return
135 }
136
137 req, validationErrs, err := extractTokenRequest(r, callbackURL)
138 if err != nil {
139 if errors.Is(err, errConflictingClientAuth) {
140 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeInvalidRequest, "Conflicting client credentials between Authorization header and request body")
141 return
142 }
143
144 // Check for specific validation errors in priority order
145 if slices.ContainsFunc(validationErrs, func(validationError codersdk.ValidationError) bool {
146 return validationError.Field == "grant_type"
147 }) {
148 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeUnsupportedGrantType, "The grant type is missing or unsupported")
149 return
150 }
151
152 // Check for missing required parameters for authorization_code grant
153 for _, field := range []string{"code", "client_id", "client_secret"} {
154 if slices.ContainsFunc(validationErrs, func(validationError codersdk.ValidationError) bool {
155 return validationError.Field == field
156 }) {
157 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeInvalidRequest, fmt.Sprintf("Missing required parameter: %s", field))
158 return
159 }
160 }
161 // Generic invalid request for other validation errors
162 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeInvalidRequest, "The request is missing required parameters or is otherwise malformed")
163 return
164 }
165
166 var token codersdk.OAuth2TokenResponse
167 //nolint:gocritic,revive // More cases will be added later.
168 switch req.GrantType {
169 // TODO: Client creds, device code.
170 case codersdk.OAuth2ProviderGrantTypeRefreshToken:
171 token, err = refreshTokenGrant(ctx, db, app, lifetimes, req)
172 case codersdk.OAuth2ProviderGrantTypeAuthorizationCode:
173 token, err = authorizationCodeGrant(ctx, db, app, lifetimes, req)
174 default:
175 // This should handle truly invalid grant types
176 httpapi.WriteOAuth2Error(ctx, rw, http.StatusBadRequest, codersdk.OAuth2ErrorCodeUnsupportedGrantType, fmt.Sprintf("The grant type %q is not supported", req.GrantType))
177 return
178 }
179
180 if errors.Is(err, errBadSecret) {

Callers 1

Calls 10

OAuth2ProviderAppFunction · 0.92
WriteFunction · 0.92
WriteOAuth2ErrorFunction · 0.92
extractTokenRequestFunction · 0.85
refreshTokenGrantFunction · 0.85
authorizationCodeGrantFunction · 0.85
ContextMethod · 0.65
ParseMethod · 0.65
ErrorMethod · 0.45
IsMethod · 0.45

Tested by

no test coverage detected