feat: get issuer from context for device auth (#363)

* feat: get issuer from context for device auth

* use distinct UserFormURL and UserFormPath

- Properly deprecate UserFormURL and default to old behaviour,
to prevent breaking change.

- Refactor unit tests to test both cases.

* update example
This commit is contained in:
Tim Möhlmann 2023-04-11 21:29:17 +03:00 committed by GitHub
parent 97bc09583d
commit 44f8403574
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 90 additions and 32 deletions

View file

@ -8,6 +8,7 @@ import (
"fmt"
"math/big"
"net/http"
"net/url"
"strings"
"time"
@ -18,7 +19,14 @@ import (
type DeviceAuthorizationConfig struct {
Lifetime time.Duration
PollInterval time.Duration
UserFormURL string // the URL where the user must go to authorize the device
// UserFormURL is the complete URL where the user must go to authorize the device.
// Deprecated: use UserFormPath instead.
UserFormURL string
// UserFormPath is the path where the user must go to authorize the device.
// The hostname for the URL is taken from the request by IssuerFromContext.
UserFormPath string
UserCode UserCodeConfig
}
@ -82,15 +90,28 @@ func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvide
return err
}
var verification *url.URL
if config.UserFormURL != "" {
if verification, err = url.Parse(config.UserFormURL); err != nil {
return oidc.ErrServerError().WithParent(err).WithDescription("invalid URL for device user form")
}
} else {
if verification, err = url.Parse(IssuerFromContext(r.Context())); err != nil {
return oidc.ErrServerError().WithParent(err).WithDescription("invalid URL for issuer")
}
verification.Path = config.UserFormPath
}
response := &oidc.DeviceAuthorizationResponse{
DeviceCode: deviceCode,
UserCode: userCode,
VerificationURI: config.UserFormURL,
VerificationURI: verification.String(),
ExpiresIn: int(config.Lifetime / time.Second),
Interval: int(config.PollInterval / time.Second),
}
response.VerificationURIComplete = fmt.Sprintf("%s?user_code=%s", config.UserFormURL, userCode)
verification.RawQuery = "user_code=" + userCode
response.VerificationURIComplete = verification.String()
httphelper.MarshalJSON(w, response)
return nil