diff --git a/pkg/op/config.go b/pkg/op/config.go index d339a30..c40ed39 100644 --- a/pkg/op/config.go +++ b/pkg/op/config.go @@ -28,7 +28,6 @@ type Configuration interface { EndSessionEndpoint() Endpoint KeysEndpoint() Endpoint DeviceAuthorizationEndpoint() Endpoint - UserCodeFormEndpoint() Endpoint AuthMethodPostSupported() bool CodeMethodS256Supported() bool diff --git a/pkg/op/device.go b/pkg/op/device.go index ab276b8..99cb330 100644 --- a/pkg/op/device.go +++ b/pkg/op/device.go @@ -18,7 +18,7 @@ import ( type DeviceAuthorizationConfig struct { Lifetime int PollInterval int - UserFormURL string + UserFormURL string // the URL where the user must go to authorize the device UserCode UserCodeConfig } @@ -88,8 +88,7 @@ func DeviceAuthorization(w http.ResponseWriter, r *http.Request, o OpenIDProvide VerificationURI: config.UserFormURL, } - endpoint := o.UserCodeFormEndpoint().Absolute(IssuerFromContext(r.Context())) - response.VerificationURIComplete = fmt.Sprintf("%s?user_code=%s", endpoint, userCode) + response.VerificationURIComplete = fmt.Sprintf("%s?user_code=%s", config.UserFormURL, userCode) httphelper.MarshalJSON(w, response) return nil @@ -179,7 +178,7 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang defer cancel() r = r.WithContext(ctx) - clientID, authenticated, err := ClientIDFromRequest(r, exchanger) + clientID, clientAuthenticated, err := ClientIDFromRequest(r, exchanger) if err != nil { return err } @@ -197,7 +196,7 @@ func deviceAccessToken(w http.ResponseWriter, r *http.Request, exchanger Exchang if err != nil { return err } - if !authenticated { + if !clientAuthenticated { if m := client.AuthMethod(); m != oidc.AuthMethodNone { // Livio: Does this mean "public" client? return oidc.ErrInvalidClient().WithParent(ErrNoClientCredentials). 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) { - tokenType := AccessTokenTypeBearer // not sure if this is the correct type? - - accessToken, refreshToken, validity, err := CreateAccessToken(ctx, tokenRequest, tokenType, creator, client, "") + accessToken, refreshToken, validity, err := CreateAccessToken(ctx, tokenRequest, AccessTokenTypeBearer, creator, client, "") if err != nil { return nil, err } @@ -266,69 +263,3 @@ func CreateDeviceTokenResponse(ctx context.Context, tokenRequest TokenRequest, c ExpiresIn: uint64(validity.Seconds()), }, 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 -} diff --git a/pkg/op/op.go b/pkg/op/op.go index a618dc0..91c89cc 100644 --- a/pkg/op/op.go +++ b/pkg/op/op.go @@ -28,7 +28,6 @@ const ( defaultEndSessionEndpoint = "end_session" defaultKeysEndpoint = "keys" defaultDeviceAuthzEndpoint = "/device_authorization" - defaultUserCodeFormEndpoint = "/submit_user_code" ) var ( @@ -41,7 +40,6 @@ var ( EndSession: NewEndpoint(defaultEndSessionEndpoint), JwksURI: NewEndpoint(defaultKeysEndpoint), DeviceAuthorization: NewEndpoint(defaultDeviceAuthzEndpoint), - UserCodeForm: NewEndpoint(defaultUserCodeFormEndpoint), } 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.KeysEndpoint().Relative(), keysHandler(o.Storage())) router.HandleFunc(o.DeviceAuthorizationEndpoint().Relative(), deviceAuthorizationHandler(o)) - router.HandleFunc(o.UserCodeFormEndpoint().Relative(), userCodeFormHandler(o)) return router } @@ -137,7 +134,6 @@ type endpoints struct { CheckSessionIframe Endpoint JwksURI Endpoint DeviceAuthorization Endpoint - UserCodeForm Endpoint } // NewOpenIDProvider creates a provider. The provider provides (with HttpHandler()) @@ -256,10 +252,6 @@ func (o *Provider) DeviceAuthorizationEndpoint() Endpoint { return o.endpoints.DeviceAuthorization } -func (o *Provider) UserCodeFormEndpoint() Endpoint { - return o.endpoints.UserCodeForm -} - func (o *Provider) KeysEndpoint() Endpoint { return o.endpoints.JwksURI }