op: remove user code endpoint

This commit is contained in:
Tim Möhlmann 2023-02-28 12:16:38 +02:00
parent a80ad6df8a
commit c9ab349d63
3 changed files with 5 additions and 83 deletions

View file

@ -28,7 +28,6 @@ type Configuration interface {
EndSessionEndpoint() Endpoint EndSessionEndpoint() Endpoint
KeysEndpoint() Endpoint KeysEndpoint() Endpoint
DeviceAuthorizationEndpoint() Endpoint DeviceAuthorizationEndpoint() Endpoint
UserCodeFormEndpoint() Endpoint
AuthMethodPostSupported() bool AuthMethodPostSupported() bool
CodeMethodS256Supported() bool CodeMethodS256Supported() bool

View file

@ -18,7 +18,7 @@ import (
type DeviceAuthorizationConfig struct { type DeviceAuthorizationConfig struct {
Lifetime int Lifetime int
PollInterval int PollInterval int
UserFormURL string UserFormURL string // the URL where the user must go to authorize the device
UserCode UserCodeConfig UserCode UserCodeConfig
} }
@ -88,8 +88,7 @@ func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvide
VerificationURI: config.UserFormURL, VerificationURI: config.UserFormURL,
} }
endpoint := o.UserCodeFormEndpoint().Absolute(IssuerFromContext(r.Context())) response.VerificationURIComplete = fmt.Sprintf("%s?user_code=%s", config.UserFormURL, userCode)
response.VerificationURIComplete = fmt.Sprintf("%s?user_code=%s", endpoint, userCode)
httphelper.MarshalJSON(w, response) httphelper.MarshalJSON(w, response)
return nil return nil
@ -179,7 +178,7 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang
defer cancel() defer cancel()
r = r.WithContext(ctx) r = r.WithContext(ctx)
clientID, authenticated, err := ClientIDFromRequest(r, exchanger) clientID, clientAuthenticated, err := ClientIDFromRequest(r, exchanger)
if err != nil { if err != nil {
return err return err
} }
@ -197,7 +196,7 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang
if err != nil { if err != nil {
return err return err
} }
if !authenticated { if !clientAuthenticated {
if m := client.AuthMethod(); m != oidc.AuthMethodNone { // Livio: Does this mean "public" client? if m := client.AuthMethod(); m != oidc.AuthMethodNone { // Livio: Does this mean "public" client?
return oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials). return oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials).
WithDescription(fmt.Sprintf("required client auth method: %s", m)) WithDescription(fmt.Sprintf("required client auth method: %s", m))
@ -252,9 +251,7 @@ func CheckDeviceAuthorizationState(ctx context.Context, clientID, deviceCode str
} }
func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator, client AccessTokenClient) (*oidc.AccessTokenResponse, error) { func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, creator TokenCreator, client AccessTokenClient) (*oidc.AccessTokenResponse, error) {
tokenType := AccessTokenTypeBearer // not sure if this is the correct type? accessToken, refreshToken, validity, err := CreateAccessToken(ctx, tokenRequest, AccessTokenTypeBearer, creator, client, "")
accessToken, refreshToken, validity, err := CreateAccessToken(ctx, tokenRequest, tokenType, creator, client, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -266,69 +263,3 @@ func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, c
ExpiresIn: uint64(validity.Seconds()), ExpiresIn: uint64(validity.Seconds()),
}, nil }, nil
} }
func userCodeFormHandler(o OpenIDProvider) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
UserCodeForm(w, r, o)
}
}
type UserCodeFormData struct {
AccesssToken string `schema:"access_token"`
UserCode string `schema:"user_code"`
RedirectURL string `schema:"redirect_url"`
}
func UserCodeForm(w http.ResponseWriter, r *http.Request, o OpenIDProvider) {
data, err := ParseUserCodeFormData(r, o.Decoder())
if err != nil {
RequestError(w, r, err)
return
}
storage, err := assertDeviceStorage(o.Storage())
if err != nil {
RequestError(w, r, err)
return
}
ctx := r.Context()
token, err := VerifyAccessToken(ctx, data.AccesssToken, o.AccessTokenVerifier(ctx))
if err != nil {
if se := storage.DenyDeviceAuthorization(ctx, data.UserCode); se != nil {
err = se
}
RequestError(w, r, err)
return
}
if err := storage.CompleteDeviceAuthorization(ctx, data.UserCode, token.GetSubject()); err != nil {
RequestError(w, r, err)
return
}
if data.RedirectURL != "" {
http.Redirect(w, r, data.RedirectURL, http.StatusSeeOther)
}
fmt.Fprintln(w, "Authorization successfull, please return to your device")
}
func ParseUserCodeFormData(r *http.Request, decoder httphelper.Decoder) (*UserCodeFormData, error) {
if err := r.ParseForm(); err != nil {
return nil, oidc.ErrInvalidRequest().WithDescription("cannot parse form").WithParent(err)
}
req := new(UserCodeFormData)
if err := decoder.Decode(req, r.Form); err != nil {
return nil, oidc.ErrInvalidRequest().WithDescription("cannot parse user code form").WithParent(err)
}
if req.AccesssToken == "" {
return nil, oidc.ErrInvalidRequest().WithDescription("access_token missing in form")
}
if req.UserCode == "" {
return nil, oidc.ErrInvalidRequest().WithDescription("user_code missing in form")
}
return req, nil
}

View file

@ -28,7 +28,6 @@ const (
defaultEndSessionEndpoint = "end_session" defaultEndSessionEndpoint = "end_session"
defaultKeysEndpoint = "keys" defaultKeysEndpoint = "keys"
defaultDeviceAuthzEndpoint = "/device_authorization" defaultDeviceAuthzEndpoint = "/device_authorization"
defaultUserCodeFormEndpoint = "/submit_user_code"
) )
var ( var (
@ -41,7 +40,6 @@ var (
EndSession: NewEndpoint(defaultEndSessionEndpoint), EndSession: NewEndpoint(defaultEndSessionEndpoint),
JwksURI: NewEndpoint(defaultKeysEndpoint), JwksURI: NewEndpoint(defaultKeysEndpoint),
DeviceAuthorization: NewEndpoint(defaultDeviceAuthzEndpoint), DeviceAuthorization: NewEndpoint(defaultDeviceAuthzEndpoint),
UserCodeForm: NewEndpoint(defaultUserCodeFormEndpoint),
} }
defaultCORSOptions = cors.Options{ defaultCORSOptions = cors.Options{
@ -100,7 +98,6 @@ func CreateRouter(o OpenIDProvider, interceptors ...HttpInterceptor) *mux.Router
router.HandleFunc(o.EndSessionEndpoint().Relative(), endSessionHandler(o)) router.HandleFunc(o.EndSessionEndpoint().Relative(), endSessionHandler(o))
router.HandleFunc(o.KeysEndpoint().Relative(), keysHandler(o.Storage())) router.HandleFunc(o.KeysEndpoint().Relative(), keysHandler(o.Storage()))
router.HandleFunc(o.DeviceAuthorizationEndpoint().Relative(), deviceAuthorizationHandler(o)) router.HandleFunc(o.DeviceAuthorizationEndpoint().Relative(), deviceAuthorizationHandler(o))
router.HandleFunc(o.UserCodeFormEndpoint().Relative(), userCodeFormHandler(o))
return router return router
} }
@ -137,7 +134,6 @@ type endpoints struct {
CheckSessionIframe Endpoint CheckSessionIframe Endpoint
JwksURI Endpoint JwksURI Endpoint
DeviceAuthorization Endpoint DeviceAuthorization Endpoint
UserCodeForm Endpoint
} }
// NewOpenIDProvider creates a provider. The provider provides (with HttpHandler()) // NewOpenIDProvider creates a provider. The provider provides (with HttpHandler())
@ -256,10 +252,6 @@ func (o *Provider) DeviceAuthorizationEndpoint() Endpoint {
return o.endpoints.DeviceAuthorization return o.endpoints.DeviceAuthorization
} }
func (o *Provider) UserCodeFormEndpoint() Endpoint {
return o.endpoints.UserCodeForm
}
func (o *Provider) KeysEndpoint() Endpoint { func (o *Provider) KeysEndpoint() Endpoint {
return o.endpoints.JwksURI return o.endpoints.JwksURI
} }