diff --git a/consent/handler.go b/consent/handler.go index 6219d86e783..c31addef8f8 100644 --- a/consent/handler.go +++ b/consent/handler.go @@ -251,7 +251,7 @@ func (h *Handler) DeleteLoginSession(w http.ResponseWriter, r *http.Request, ps // 200: loginRequest // 400: genericError // 404: genericError -// 409: genericError +// 410: requestWasHandledResponse // 500: genericError func (h *Handler) GetLoginRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { challenge := stringsx.Coalesce( @@ -269,10 +269,10 @@ func (h *Handler) GetLoginRequest(w http.ResponseWriter, r *http.Request, ps htt h.r.Writer().WriteError(w, r, err) return } - if request.WasHandled { - h.r.Writer().WriteError(w, r, x.ErrConflict.WithDebug("Login request has been used already")) - return + h.r.Writer().WriteCode(w, r, http.StatusGone, &RequestWasHandledResponse{ + RedirectTo: request.RequestURL, + }) } request.Client = sanitizeClient(request.Client) @@ -476,7 +476,7 @@ func (h *Handler) RejectLoginRequest(w http.ResponseWriter, r *http.Request, ps // Responses: // 200: consentRequest // 404: genericError -// 409: genericError +// 410: requestWasHandledResponse // 500: genericError func (h *Handler) GetConsentRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { challenge := stringsx.Coalesce( @@ -494,8 +494,9 @@ func (h *Handler) GetConsentRequest(w http.ResponseWriter, r *http.Request, ps h return } if request.WasHandled { - h.r.Writer().WriteError(w, r, x.ErrConflict.WithDebug("Consent request has been used already")) - return + h.r.Writer().WriteCode(w, r, http.StatusGone, &RequestWasHandledResponse{ + RedirectTo: request.RequestURL, + }) } if request.RequestedScope == nil { @@ -751,6 +752,7 @@ func (h *Handler) RejectLogoutRequest(w http.ResponseWriter, r *http.Request, ps // Responses: // 200: logoutRequest // 404: genericError +// 410: requestWasHandledResponse // 500: genericError func (h *Handler) GetLogoutRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { challenge := stringsx.Coalesce( @@ -758,16 +760,16 @@ func (h *Handler) GetLogoutRequest(w http.ResponseWriter, r *http.Request, ps ht r.URL.Query().Get("challenge"), ) - c, err := h.r.ConsentManager().GetLogoutRequest(r.Context(), challenge) + request, err := h.r.ConsentManager().GetLogoutRequest(r.Context(), challenge) if err != nil { h.r.Writer().WriteError(w, r, err) return } - - if c.WasUsed { - h.r.Writer().WriteError(w, r, x.ErrConflict.WithDebug("Logout request has been used already")) - return + if request.WasHandled { + h.r.Writer().WriteCode(w, r, http.StatusGone, &RequestWasHandledResponse{ + RedirectTo: request.RequestURL, + }) } - h.r.Writer().Write(w, r, c) + h.r.Writer().Write(w, r, request) } diff --git a/consent/handler_test.go b/consent/handler_test.go index 8a9a1e7fb1f..70f1a423759 100644 --- a/consent/handler_test.go +++ b/consent/handler_test.go @@ -39,13 +39,13 @@ import ( func TestGetLogoutRequest(t *testing.T) { for k, tc := range []struct { - exists bool - used bool - status int + exists bool + handled bool + status int }{ {false, false, http.StatusNotFound}, {true, false, http.StatusOK}, - {true, true, http.StatusConflict}, + {true, true, http.StatusGone}, } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { key := fmt.Sprint(k) @@ -58,9 +58,9 @@ func TestGetLogoutRequest(t *testing.T) { cl := &client.Client{OutfacingID: "client" + key} require.NoError(t, reg.ClientManager().CreateClient(context.Background(), cl)) require.NoError(t, reg.ConsentManager().CreateLogoutRequest(context.TODO(), &LogoutRequest{ - Client: cl, - ID: challenge, - WasUsed: tc.used, + Client: cl, + ID: challenge, + WasHandled: tc.handled, })) } @@ -86,7 +86,7 @@ func TestGetLoginRequest(t *testing.T) { }{ {false, false, http.StatusNotFound}, {true, false, http.StatusOK}, - {true, true, http.StatusConflict}, + {true, true, http.StatusGone}, } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { key := fmt.Sprint(k) @@ -104,7 +104,7 @@ func TestGetLoginRequest(t *testing.T) { })) if tc.handled { - _, err := reg.ConsentManager().HandleLoginRequest(context.Background(), challenge, &HandledLoginRequest{ID: challenge, WasUsed: true}) + _, err := reg.ConsentManager().HandleLoginRequest(context.Background(), challenge, &HandledLoginRequest{ID: challenge, WasHandled: true}) require.NoError(t, err) } } @@ -131,7 +131,7 @@ func TestGetConsentRequest(t *testing.T) { }{ {false, false, http.StatusNotFound}, {true, false, http.StatusOK}, - {true, true, http.StatusConflict}, + {true, true, http.StatusGone}, } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { key := fmt.Sprint(k) @@ -150,8 +150,8 @@ func TestGetConsentRequest(t *testing.T) { if tc.handled { _, err := reg.ConsentManager().HandleConsentRequest(context.Background(), challenge, &HandledConsentRequest{ - ID: challenge, - WasUsed: true, + ID: challenge, + WasHandled: true, }) require.NoError(t, err) } diff --git a/consent/janitor_consent_test_helper.go b/consent/janitor_consent_test_helper.go index 71b92ac738b..21f319d818e 100644 --- a/consent/janitor_consent_test_helper.go +++ b/consent/janitor_consent_test_helper.go @@ -22,7 +22,7 @@ func NewHandledLoginRequest(challenge string, hasError bool, requestedAt time.Ti return &HandledLoginRequest{ ID: challenge, Error: deniedErr, - WasUsed: true, + WasHandled: true, RequestedAt: requestedAt, AuthenticatedAt: authenticatedAt, } @@ -47,6 +47,6 @@ func NewHandledConsentRequest(challenge string, hasError bool, requestedAt time. Error: deniedErr, RequestedAt: requestedAt, AuthenticatedAt: authenticatedAt, - WasUsed: true, + WasHandled: true, } } diff --git a/consent/manager_test_helpers.go b/consent/manager_test_helpers.go index 777878f653e..960fd50d865 100644 --- a/consent/manager_test_helpers.go +++ b/consent/manager_test_helpers.go @@ -114,7 +114,7 @@ func MockLogoutRequest(key string, withClient bool) (c *LogoutRequest) { RPInitiated: true, RequestURL: "http://request-me/", PostLogoutRedirectURI: "http://redirect-me/", - WasUsed: false, + WasHandled: false, Accepted: false, Client: cl, } @@ -164,7 +164,7 @@ func MockAuthRequest(key string, authAt bool) (c *LoginRequest, h *HandledLoginR Subject: c.Subject, ACR: "acr", ForceSubjectIdentifier: "forced-subject", - WasUsed: false, + WasHandled: false, } return c, h @@ -193,7 +193,7 @@ func SaneMockHandleConsentRequest(t *testing.T, m Manager, c *ConsentRequest, au GrantedScope: []string{"scopea", "scopeb"}, GrantedAudience: []string{"auda", "audb"}, Error: rde, - WasUsed: false, + WasHandled: false, HandledAt: sqlxx.NullTime(time.Now().UTC().Add(-time.Minute)), } @@ -798,7 +798,7 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager x.Fosit got2, err := m.GetLogoutRequest(context.Background(), "challenge"+tc.key) require.NoError(t, err) - assert.False(t, got2.WasUsed) + assert.False(t, got2.WasHandled) assert.False(t, got2.Accepted) compareLogoutRequest(t, c, got2) @@ -811,7 +811,7 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager x.Fosit got3, err := m.VerifyAndInvalidateLogoutRequest(context.Background(), "verifier"+tc.key) require.NoError(t, err) assert.True(t, got3.Accepted) - assert.True(t, got3.WasUsed) + assert.True(t, got3.WasHandled) compareLogoutRequest(t, c, got3) _, err = m.VerifyAndInvalidateLogoutRequest(context.Background(), "verifier"+tc.key) @@ -820,7 +820,7 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager x.Fosit got2, err = m.GetLogoutRequest(context.Background(), "challenge"+tc.key) require.NoError(t, err) compareLogoutRequest(t, got3, got2) - assert.True(t, got2.WasUsed) + assert.True(t, got2.WasHandled) } else { require.NoError(t, m.RejectLogoutRequest(context.Background(), "challenge"+tc.key)) _, err = m.GetLogoutRequest(context.Background(), "challenge"+tc.key) diff --git a/consent/types.go b/consent/types.go index 5558ca98083..4eb3b8506e7 100644 --- a/consent/types.go +++ b/consent/types.go @@ -151,6 +151,16 @@ func (e *RequestDeniedError) Value() (driver.Value, error) { return string(value), nil } +// The response payload sent when there is an attempt to access already handled request. +// +// swagger:model requestWasHandledResponse +type RequestWasHandledResponse struct { + // Original request URL to which you should redirect the user if request was already handled. + // + // required: true + RedirectTo string `json:"redirect_to"` +} + // The request payload used to accept a consent request. // // swagger:model acceptConsentRequest @@ -178,11 +188,16 @@ type HandledConsentRequest struct { // HandledAt contains the timestamp the consent request was handled. HandledAt sqlxx.NullTime `json:"handled_at" db:"handled_at"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_used"` + ConsentRequest *ConsentRequest `json:"-" db:"-"` Error *RequestDeniedError `json:"-" db:"error"` RequestedAt time.Time `json:"-" db:"requested_at"` AuthenticatedAt sqlxx.NullTime `json:"-" db:"authenticated_at"` - WasUsed bool `json:"-" db:"was_used"` SessionIDToken sqlxx.MapStringInterface `db:"session_id_token" json:"-"` SessionAccessToken sqlxx.MapStringInterface `db:"session_access_token" json:"-"` @@ -250,11 +265,16 @@ type PreviousConsentSession struct { // HandledAt contains the timestamp the consent request was handled. HandledAt sqlxx.NullTime `json:"handled_at" db:"handled_at"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_used"` + ConsentRequest *ConsentRequest `json:"consent_request" db:"-"` Error *RequestDeniedError `json:"-" db:"error"` RequestedAt time.Time `json:"-" db:"requested_at"` AuthenticatedAt sqlxx.NullTime `json:"-" db:"authenticated_at"` - WasUsed bool `json:"-" db:"was_used"` SessionIDToken sqlxx.MapStringInterface `db:"session_id_token" json:"-"` SessionAccessToken sqlxx.MapStringInterface `db:"session_access_token" json:"-"` @@ -309,11 +329,16 @@ type HandledLoginRequest struct { // data. Context sqlxx.JSONRawMessage `json:"context" db:"context"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_used"` + LoginRequest *LoginRequest `json:"-" db:"-"` Error *RequestDeniedError `json:"-" db:"error"` RequestedAt time.Time `json:"-" db:"requested_at"` AuthenticatedAt sqlxx.NullTime `json:"-" db:"authenticated_at"` - WasUsed bool `json:"-" db:"was_used"` } func (_ HandledLoginRequest) TableName() string { @@ -412,9 +437,14 @@ type LogoutRequest struct { // RPInitiated is set to true if the request was initiated by a Relying Party (RP), also known as an OAuth 2.0 Client. RPInitiated bool `json:"rp_initiated" db:"rp_initiated"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_used"` + Verifier string `json:"-" db:"verifier"` PostLogoutRedirectURI string `json:"-" db:"redir_url"` - WasUsed bool `json:"-" db:"was_used"` Accepted bool `json:"-" db:"accepted"` Rejected bool `db:"rejected" json:"-"` ClientID sql.NullString `json:"-" db:"client_id"` @@ -510,13 +540,18 @@ type LoginRequest struct { // channel logout. It's value can generally be used to associate consecutive login requests by a certain user. SessionID sqlxx.NullString `json:"session_id" db:"login_session_id"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_handled,r"` + ForceSubjectIdentifier string `json:"-" db:"-"` // this is here but has no meaning apart from sql_helper working properly. Verifier string `json:"-" db:"verifier"` CSRF string `json:"-" db:"csrf"` AuthenticatedAt sqlxx.NullTime `json:"-" db:"authenticated_at"` RequestedAt time.Time `json:"-" db:"requested_at"` - WasHandled bool `json:"-" db:"was_handled,r"` } func (_ LoginRequest) TableName() string { @@ -596,6 +631,12 @@ type ConsentRequest struct { // Context contains arbitrary information set by the login endpoint or is empty if not set. Context sqlxx.JSONRawMessage `json:"context,omitempty" db:"context"` + // If set to true means that the request was already handled. This + // can happen on form double-submit or other errors. If this is set + // we recommend redirecting the user to `request_url` to re-initiate + // the flow. + WasHandled bool `json:"-" db:"was_handled,r"` + // ForceSubjectIdentifier is the value from authentication (if set). ForceSubjectIdentifier string `json:"-" db:"forced_subject_identifier"` SubjectIdentifier string `json:"-" db:"-"` @@ -603,7 +644,6 @@ type ConsentRequest struct { CSRF string `json:"-" db:"csrf"` AuthenticatedAt sqlxx.NullTime `json:"-" db:"authenticated_at"` RequestedAt time.Time `json:"-" db:"requested_at"` - WasHandled bool `json:"-" db:"was_handled,r"` } func (_ ConsentRequest) TableName() string { diff --git a/internal/httpclient/client/admin/get_consent_request_responses.go b/internal/httpclient/client/admin/get_consent_request_responses.go index a6971f683f7..4c3a77cce5b 100644 --- a/internal/httpclient/client/admin/get_consent_request_responses.go +++ b/internal/httpclient/client/admin/get_consent_request_responses.go @@ -35,8 +35,8 @@ func (o *GetConsentRequestReader) ReadResponse(response runtime.ClientResponse, return nil, err } return nil, result - case 409: - result := NewGetConsentRequestConflict() + case 410: + result := NewGetConsentRequestGone() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } @@ -116,29 +116,29 @@ func (o *GetConsentRequestNotFound) readResponse(response runtime.ClientResponse return nil } -// NewGetConsentRequestConflict creates a GetConsentRequestConflict with default headers values -func NewGetConsentRequestConflict() *GetConsentRequestConflict { - return &GetConsentRequestConflict{} +// NewGetConsentRequestGone creates a GetConsentRequestGone with default headers values +func NewGetConsentRequestGone() *GetConsentRequestGone { + return &GetConsentRequestGone{} } -/* GetConsentRequestConflict describes a response with status code 409, with default header values. +/* GetConsentRequestGone describes a response with status code 410, with default header values. -genericError +requestWasHandledResponse */ -type GetConsentRequestConflict struct { - Payload *models.GenericError +type GetConsentRequestGone struct { + Payload *models.RequestWasHandledResponse } -func (o *GetConsentRequestConflict) Error() string { - return fmt.Sprintf("[GET /oauth2/auth/requests/consent][%d] getConsentRequestConflict %+v", 409, o.Payload) +func (o *GetConsentRequestGone) Error() string { + return fmt.Sprintf("[GET /oauth2/auth/requests/consent][%d] getConsentRequestGone %+v", 410, o.Payload) } -func (o *GetConsentRequestConflict) GetPayload() *models.GenericError { +func (o *GetConsentRequestGone) GetPayload() *models.RequestWasHandledResponse { return o.Payload } -func (o *GetConsentRequestConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { +func (o *GetConsentRequestGone) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - o.Payload = new(models.GenericError) + o.Payload = new(models.RequestWasHandledResponse) // response payload if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { diff --git a/internal/httpclient/client/admin/get_login_request_responses.go b/internal/httpclient/client/admin/get_login_request_responses.go index 463c35611c5..5f33c029b20 100644 --- a/internal/httpclient/client/admin/get_login_request_responses.go +++ b/internal/httpclient/client/admin/get_login_request_responses.go @@ -41,8 +41,8 @@ func (o *GetLoginRequestReader) ReadResponse(response runtime.ClientResponse, co return nil, err } return nil, result - case 409: - result := NewGetLoginRequestConflict() + case 410: + result := NewGetLoginRequestGone() if err := result.readResponse(response, consumer, o.formats); err != nil { return nil, err } @@ -154,29 +154,29 @@ func (o *GetLoginRequestNotFound) readResponse(response runtime.ClientResponse, return nil } -// NewGetLoginRequestConflict creates a GetLoginRequestConflict with default headers values -func NewGetLoginRequestConflict() *GetLoginRequestConflict { - return &GetLoginRequestConflict{} +// NewGetLoginRequestGone creates a GetLoginRequestGone with default headers values +func NewGetLoginRequestGone() *GetLoginRequestGone { + return &GetLoginRequestGone{} } -/* GetLoginRequestConflict describes a response with status code 409, with default header values. +/* GetLoginRequestGone describes a response with status code 410, with default header values. -genericError +requestWasHandledResponse */ -type GetLoginRequestConflict struct { - Payload *models.GenericError +type GetLoginRequestGone struct { + Payload *models.RequestWasHandledResponse } -func (o *GetLoginRequestConflict) Error() string { - return fmt.Sprintf("[GET /oauth2/auth/requests/login][%d] getLoginRequestConflict %+v", 409, o.Payload) +func (o *GetLoginRequestGone) Error() string { + return fmt.Sprintf("[GET /oauth2/auth/requests/login][%d] getLoginRequestGone %+v", 410, o.Payload) } -func (o *GetLoginRequestConflict) GetPayload() *models.GenericError { +func (o *GetLoginRequestGone) GetPayload() *models.RequestWasHandledResponse { return o.Payload } -func (o *GetLoginRequestConflict) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { +func (o *GetLoginRequestGone) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { - o.Payload = new(models.GenericError) + o.Payload = new(models.RequestWasHandledResponse) // response payload if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { diff --git a/internal/httpclient/client/admin/get_logout_request_responses.go b/internal/httpclient/client/admin/get_logout_request_responses.go index 441dcf929d9..da75a5cdd29 100644 --- a/internal/httpclient/client/admin/get_logout_request_responses.go +++ b/internal/httpclient/client/admin/get_logout_request_responses.go @@ -35,6 +35,12 @@ func (o *GetLogoutRequestReader) ReadResponse(response runtime.ClientResponse, c return nil, err } return nil, result + case 410: + result := NewGetLogoutRequestGone() + if err := result.readResponse(response, consumer, o.formats); err != nil { + return nil, err + } + return nil, result case 500: result := NewGetLogoutRequestInternalServerError() if err := result.readResponse(response, consumer, o.formats); err != nil { @@ -110,6 +116,38 @@ func (o *GetLogoutRequestNotFound) readResponse(response runtime.ClientResponse, return nil } +// NewGetLogoutRequestGone creates a GetLogoutRequestGone with default headers values +func NewGetLogoutRequestGone() *GetLogoutRequestGone { + return &GetLogoutRequestGone{} +} + +/* GetLogoutRequestGone describes a response with status code 410, with default header values. + +requestWasHandledResponse +*/ +type GetLogoutRequestGone struct { + Payload *models.RequestWasHandledResponse +} + +func (o *GetLogoutRequestGone) Error() string { + return fmt.Sprintf("[GET /oauth2/auth/requests/logout][%d] getLogoutRequestGone %+v", 410, o.Payload) +} +func (o *GetLogoutRequestGone) GetPayload() *models.RequestWasHandledResponse { + return o.Payload +} + +func (o *GetLogoutRequestGone) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error { + + o.Payload = new(models.RequestWasHandledResponse) + + // response payload + if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF { + return err + } + + return nil +} + // NewGetLogoutRequestInternalServerError creates a GetLogoutRequestInternalServerError with default headers values func NewGetLogoutRequestInternalServerError() *GetLogoutRequestInternalServerError { return &GetLogoutRequestInternalServerError{} diff --git a/internal/httpclient/models/plugin_config_interface.go b/internal/httpclient/models/plugin_config_interface.go index 73a75d00a44..3e77cc86694 100644 --- a/internal/httpclient/models/plugin_config_interface.go +++ b/internal/httpclient/models/plugin_config_interface.go @@ -20,6 +20,9 @@ import ( // swagger:model PluginConfigInterface type PluginConfigInterface struct { + // Protocol to use for clients connecting to the plugin. + ProtocolScheme string `json:"ProtocolScheme,omitempty"` + // socket // Required: true Socket *string `json:"Socket"` diff --git a/internal/httpclient/models/request_was_handled_response.go b/internal/httpclient/models/request_was_handled_response.go new file mode 100644 index 00000000000..5430cd2ef03 --- /dev/null +++ b/internal/httpclient/models/request_was_handled_response.go @@ -0,0 +1,71 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// RequestWasHandledResponse The response payload sent when there is an attempt to access already handled request. +// +// swagger:model requestWasHandledResponse +type RequestWasHandledResponse struct { + + // Original request URL to which you should redirect the user if request was already handled. + // Required: true + RedirectTo *string `json:"redirect_to"` +} + +// Validate validates this request was handled response +func (m *RequestWasHandledResponse) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateRedirectTo(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *RequestWasHandledResponse) validateRedirectTo(formats strfmt.Registry) error { + + if err := validate.Required("redirect_to", "body", m.RedirectTo); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this request was handled response based on context it is used +func (m *RequestWasHandledResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *RequestWasHandledResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *RequestWasHandledResponse) UnmarshalBinary(b []byte) error { + var res RequestWasHandledResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/internal/httpclient/models/volume.go b/internal/httpclient/models/volume.go index a8a725e2cf8..a27d9734b32 100644 --- a/internal/httpclient/models/volume.go +++ b/internal/httpclient/models/volume.go @@ -42,7 +42,8 @@ type Volume struct { // Required: true Options map[string]string `json:"Options"` - // The level at which the volume exists. Either `global` for cluster-wide, or `local` for machine level. + // The level at which the volume exists. Either `global` for cluster-wide, + // or `local` for machine level. // Required: true Scope *string `json:"Scope"` diff --git a/internal/testhelpers/janitor_test_helper.go b/internal/testhelpers/janitor_test_helper.go index 34ee3df7dd2..9b07fc75deb 100644 --- a/internal/testhelpers/janitor_test_helper.go +++ b/internal/testhelpers/janitor_test_helper.go @@ -239,7 +239,7 @@ func (j *JanitorConsentTestHelper) LoginTimeoutSetup(ctx context.Context, cm con ID: j.flushLoginRequests[0].ID, RequestedAt: j.flushLoginRequests[0].RequestedAt, AuthenticatedAt: j.flushLoginRequests[0].AuthenticatedAt, - WasUsed: true, + WasHandled: true, }) require.NoError(t, err) @@ -274,7 +274,7 @@ func (j *JanitorConsentTestHelper) ConsentTimeoutSetup(ctx context.Context, cm c ID: r.ID, AuthenticatedAt: r.AuthenticatedAt, RequestedAt: r.RequestedAt, - WasUsed: true, + WasHandled: true, }) require.NoError(t, err) } @@ -287,7 +287,7 @@ func (j *JanitorConsentTestHelper) ConsentTimeoutSetup(ctx context.Context, cm c // Create at least 1 consent request that has been accepted _, err = cm.HandleConsentRequest(ctx, j.flushConsentRequests[0].ID, &consent.HandledConsentRequest{ ID: j.flushConsentRequests[0].ID, - WasUsed: true, + WasHandled: true, RequestedAt: j.flushConsentRequests[0].RequestedAt, AuthenticatedAt: j.flushConsentRequests[0].AuthenticatedAt, }) diff --git a/oauth2/oauth2_provider_mock_test.go b/oauth2/oauth2_provider_mock_test.go index 0c718aa21a6..2038f65931c 100644 --- a/oauth2/oauth2_provider_mock_test.go +++ b/oauth2/oauth2_provider_mock_test.go @@ -14,30 +14,30 @@ import ( fosite "github.com/ory/fosite" ) -// MockOAuth2Provider is a mock of OAuth2Provider interface +// MockOAuth2Provider is a mock of OAuth2Provider interface. type MockOAuth2Provider struct { ctrl *gomock.Controller recorder *MockOAuth2ProviderMockRecorder } -// MockOAuth2ProviderMockRecorder is the mock recorder for MockOAuth2Provider +// MockOAuth2ProviderMockRecorder is the mock recorder for MockOAuth2Provider. type MockOAuth2ProviderMockRecorder struct { mock *MockOAuth2Provider } -// NewMockOAuth2Provider creates a new mock instance +// NewMockOAuth2Provider creates a new mock instance. func NewMockOAuth2Provider(ctrl *gomock.Controller) *MockOAuth2Provider { mock := &MockOAuth2Provider{ctrl: ctrl} mock.recorder = &MockOAuth2ProviderMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockOAuth2Provider) EXPECT() *MockOAuth2ProviderMockRecorder { return m.recorder } -// IntrospectToken mocks base method +// IntrospectToken mocks base method. func (m *MockOAuth2Provider) IntrospectToken(arg0 context.Context, arg1 string, arg2 fosite.TokenType, arg3 fosite.Session, arg4 ...string) (fosite.TokenType, fosite.AccessRequester, error) { m.ctrl.T.Helper() varargs := []interface{}{arg0, arg1, arg2, arg3} @@ -51,14 +51,14 @@ func (m *MockOAuth2Provider) IntrospectToken(arg0 context.Context, arg1 string, return ret0, ret1, ret2 } -// IntrospectToken indicates an expected call of IntrospectToken +// IntrospectToken indicates an expected call of IntrospectToken. func (mr *MockOAuth2ProviderMockRecorder) IntrospectToken(arg0, arg1, arg2, arg3 interface{}, arg4 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]interface{}{arg0, arg1, arg2, arg3}, arg4...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IntrospectToken", reflect.TypeOf((*MockOAuth2Provider)(nil).IntrospectToken), varargs...) } -// NewAccessRequest mocks base method +// NewAccessRequest mocks base method. func (m *MockOAuth2Provider) NewAccessRequest(arg0 context.Context, arg1 *http.Request, arg2 fosite.Session) (fosite.AccessRequester, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewAccessRequest", arg0, arg1, arg2) @@ -67,13 +67,13 @@ func (m *MockOAuth2Provider) NewAccessRequest(arg0 context.Context, arg1 *http.R return ret0, ret1 } -// NewAccessRequest indicates an expected call of NewAccessRequest +// NewAccessRequest indicates an expected call of NewAccessRequest. func (mr *MockOAuth2ProviderMockRecorder) NewAccessRequest(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAccessRequest", reflect.TypeOf((*MockOAuth2Provider)(nil).NewAccessRequest), arg0, arg1, arg2) } -// NewAccessResponse mocks base method +// NewAccessResponse mocks base method. func (m *MockOAuth2Provider) NewAccessResponse(arg0 context.Context, arg1 fosite.AccessRequester) (fosite.AccessResponder, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewAccessResponse", arg0, arg1) @@ -82,13 +82,13 @@ func (m *MockOAuth2Provider) NewAccessResponse(arg0 context.Context, arg1 fosite return ret0, ret1 } -// NewAccessResponse indicates an expected call of NewAccessResponse +// NewAccessResponse indicates an expected call of NewAccessResponse. func (mr *MockOAuth2ProviderMockRecorder) NewAccessResponse(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAccessResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).NewAccessResponse), arg0, arg1) } -// NewAuthorizeRequest mocks base method +// NewAuthorizeRequest mocks base method. func (m *MockOAuth2Provider) NewAuthorizeRequest(arg0 context.Context, arg1 *http.Request) (fosite.AuthorizeRequester, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewAuthorizeRequest", arg0, arg1) @@ -97,13 +97,13 @@ func (m *MockOAuth2Provider) NewAuthorizeRequest(arg0 context.Context, arg1 *htt return ret0, ret1 } -// NewAuthorizeRequest indicates an expected call of NewAuthorizeRequest +// NewAuthorizeRequest indicates an expected call of NewAuthorizeRequest. func (mr *MockOAuth2ProviderMockRecorder) NewAuthorizeRequest(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAuthorizeRequest", reflect.TypeOf((*MockOAuth2Provider)(nil).NewAuthorizeRequest), arg0, arg1) } -// NewAuthorizeResponse mocks base method +// NewAuthorizeResponse mocks base method. func (m *MockOAuth2Provider) NewAuthorizeResponse(arg0 context.Context, arg1 fosite.AuthorizeRequester, arg2 fosite.Session) (fosite.AuthorizeResponder, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewAuthorizeResponse", arg0, arg1, arg2) @@ -112,13 +112,13 @@ func (m *MockOAuth2Provider) NewAuthorizeResponse(arg0 context.Context, arg1 fos return ret0, ret1 } -// NewAuthorizeResponse indicates an expected call of NewAuthorizeResponse +// NewAuthorizeResponse indicates an expected call of NewAuthorizeResponse. func (mr *MockOAuth2ProviderMockRecorder) NewAuthorizeResponse(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAuthorizeResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).NewAuthorizeResponse), arg0, arg1, arg2) } -// NewIntrospectionRequest mocks base method +// NewIntrospectionRequest mocks base method. func (m *MockOAuth2Provider) NewIntrospectionRequest(arg0 context.Context, arg1 *http.Request, arg2 fosite.Session) (fosite.IntrospectionResponder, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewIntrospectionRequest", arg0, arg1, arg2) @@ -127,13 +127,13 @@ func (m *MockOAuth2Provider) NewIntrospectionRequest(arg0 context.Context, arg1 return ret0, ret1 } -// NewIntrospectionRequest indicates an expected call of NewIntrospectionRequest +// NewIntrospectionRequest indicates an expected call of NewIntrospectionRequest. func (mr *MockOAuth2ProviderMockRecorder) NewIntrospectionRequest(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewIntrospectionRequest", reflect.TypeOf((*MockOAuth2Provider)(nil).NewIntrospectionRequest), arg0, arg1, arg2) } -// NewRevocationRequest mocks base method +// NewRevocationRequest mocks base method. func (m *MockOAuth2Provider) NewRevocationRequest(arg0 context.Context, arg1 *http.Request) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewRevocationRequest", arg0, arg1) @@ -141,91 +141,91 @@ func (m *MockOAuth2Provider) NewRevocationRequest(arg0 context.Context, arg1 *ht return ret0 } -// NewRevocationRequest indicates an expected call of NewRevocationRequest +// NewRevocationRequest indicates an expected call of NewRevocationRequest. func (mr *MockOAuth2ProviderMockRecorder) NewRevocationRequest(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewRevocationRequest", reflect.TypeOf((*MockOAuth2Provider)(nil).NewRevocationRequest), arg0, arg1) } -// WriteAccessError mocks base method +// WriteAccessError mocks base method. func (m *MockOAuth2Provider) WriteAccessError(arg0 http.ResponseWriter, arg1 fosite.AccessRequester, arg2 error) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteAccessError", arg0, arg1, arg2) } -// WriteAccessError indicates an expected call of WriteAccessError +// WriteAccessError indicates an expected call of WriteAccessError. func (mr *MockOAuth2ProviderMockRecorder) WriteAccessError(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteAccessError", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteAccessError), arg0, arg1, arg2) } -// WriteAccessResponse mocks base method +// WriteAccessResponse mocks base method. func (m *MockOAuth2Provider) WriteAccessResponse(arg0 http.ResponseWriter, arg1 fosite.AccessRequester, arg2 fosite.AccessResponder) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteAccessResponse", arg0, arg1, arg2) } -// WriteAccessResponse indicates an expected call of WriteAccessResponse +// WriteAccessResponse indicates an expected call of WriteAccessResponse. func (mr *MockOAuth2ProviderMockRecorder) WriteAccessResponse(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteAccessResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteAccessResponse), arg0, arg1, arg2) } -// WriteAuthorizeError mocks base method +// WriteAuthorizeError mocks base method. func (m *MockOAuth2Provider) WriteAuthorizeError(arg0 http.ResponseWriter, arg1 fosite.AuthorizeRequester, arg2 error) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteAuthorizeError", arg0, arg1, arg2) } -// WriteAuthorizeError indicates an expected call of WriteAuthorizeError +// WriteAuthorizeError indicates an expected call of WriteAuthorizeError. func (mr *MockOAuth2ProviderMockRecorder) WriteAuthorizeError(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteAuthorizeError", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteAuthorizeError), arg0, arg1, arg2) } -// WriteAuthorizeResponse mocks base method +// WriteAuthorizeResponse mocks base method. func (m *MockOAuth2Provider) WriteAuthorizeResponse(arg0 http.ResponseWriter, arg1 fosite.AuthorizeRequester, arg2 fosite.AuthorizeResponder) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteAuthorizeResponse", arg0, arg1, arg2) } -// WriteAuthorizeResponse indicates an expected call of WriteAuthorizeResponse +// WriteAuthorizeResponse indicates an expected call of WriteAuthorizeResponse. func (mr *MockOAuth2ProviderMockRecorder) WriteAuthorizeResponse(arg0, arg1, arg2 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteAuthorizeResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteAuthorizeResponse), arg0, arg1, arg2) } -// WriteIntrospectionError mocks base method +// WriteIntrospectionError mocks base method. func (m *MockOAuth2Provider) WriteIntrospectionError(arg0 http.ResponseWriter, arg1 error) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteIntrospectionError", arg0, arg1) } -// WriteIntrospectionError indicates an expected call of WriteIntrospectionError +// WriteIntrospectionError indicates an expected call of WriteIntrospectionError. func (mr *MockOAuth2ProviderMockRecorder) WriteIntrospectionError(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteIntrospectionError", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteIntrospectionError), arg0, arg1) } -// WriteIntrospectionResponse mocks base method +// WriteIntrospectionResponse mocks base method. func (m *MockOAuth2Provider) WriteIntrospectionResponse(arg0 http.ResponseWriter, arg1 fosite.IntrospectionResponder) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteIntrospectionResponse", arg0, arg1) } -// WriteIntrospectionResponse indicates an expected call of WriteIntrospectionResponse +// WriteIntrospectionResponse indicates an expected call of WriteIntrospectionResponse. func (mr *MockOAuth2ProviderMockRecorder) WriteIntrospectionResponse(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteIntrospectionResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteIntrospectionResponse), arg0, arg1) } -// WriteRevocationResponse mocks base method +// WriteRevocationResponse mocks base method. func (m *MockOAuth2Provider) WriteRevocationResponse(arg0 http.ResponseWriter, arg1 error) { m.ctrl.T.Helper() m.ctrl.Call(m, "WriteRevocationResponse", arg0, arg1) } -// WriteRevocationResponse indicates an expected call of WriteRevocationResponse +// WriteRevocationResponse indicates an expected call of WriteRevocationResponse. func (mr *MockOAuth2ProviderMockRecorder) WriteRevocationResponse(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteRevocationResponse", reflect.TypeOf((*MockOAuth2Provider)(nil).WriteRevocationResponse), arg0, arg1) diff --git a/persistence/sql/migratest/exptected_data.go b/persistence/sql/migratest/exptected_data.go index 1c554a4c70c..d4bd9a7cbe8 100644 --- a/persistence/sql/migratest/exptected_data.go +++ b/persistence/sql/migratest/exptected_data.go @@ -138,7 +138,7 @@ func expectedConsent(i int) (*consent.ConsentRequest, *consent.LoginRequest, *co Remember: true, RememberFor: i, ID: fmt.Sprintf("challenge-%04d", i), - WasUsed: true, + WasHandled: true, Error: &consent.RequestDeniedError{}, SessionIDToken: map[string]interface{}{ fmt.Sprintf("session_id_token-%04d", i): fmt.Sprintf("%04d", i), @@ -156,7 +156,7 @@ func expectedConsent(i int) (*consent.ConsentRequest, *consent.LoginRequest, *co Context: sqlxx.JSONRawMessage(fmt.Sprintf("{\"context\": \"%04d\"}", i)), Error: &consent.RequestDeniedError{}, ID: fmt.Sprintf("challenge-%04d", i), - WasUsed: true, + WasHandled: true, } fols := &consent.ForcedObfuscatedLoginSession{ Subject: fmt.Sprintf("subject-%04d", i), @@ -170,7 +170,7 @@ func expectedConsent(i int) (*consent.ConsentRequest, *consent.LoginRequest, *co RPInitiated: true, Verifier: fmt.Sprintf("verifier-%04d", i), PostLogoutRedirectURI: fmt.Sprintf("http://post_logout/%04d", i), - WasUsed: true, + WasHandled: true, Accepted: true, Rejected: false, } diff --git a/persistence/sql/persister_consent.go b/persistence/sql/persister_consent.go index cad6e15359f..31af5a759ee 100644 --- a/persistence/sql/persister_consent.go +++ b/persistence/sql/persister_consent.go @@ -179,7 +179,7 @@ func (p *Persister) HandleConsentRequest(ctx context.Context, challenge string, return nil, sqlcon.HandleError(err) } - if hr.WasUsed { + if hr.WasHandled { return nil, errorsx.WithStack(x.ErrConflict.WithHint("The consent request was already used and can no longer be changed.")) } @@ -205,11 +205,11 @@ func (p *Persister) VerifyAndInvalidateConsentRequest(ctx context.Context, verif return sqlcon.HandleError(err) } - if r.WasUsed { + if r.WasHandled { return errorsx.WithStack(fosite.ErrInvalidRequest.WithDebug("Consent verifier has been used already.")) } - r.WasUsed = true + r.WasHandled = true return c.Update(&r) }) } @@ -238,11 +238,11 @@ func (p *Persister) VerifyAndInvalidateLoginRequest(ctx context.Context, verifie return sqlcon.HandleError(err) } - if d.WasUsed { + if d.WasHandled { return errorsx.WithStack(fosite.ErrInvalidRequest.WithDebug("Login verifier has been used already.")) } - d.WasUsed = true + d.WasHandled = true return sqlcon.HandleError(c.Update(&d)) }) } diff --git a/spec/api.json b/spec/api.json index 1989a01df26..2286073fe5c 100755 --- a/spec/api.json +++ b/spec/api.json @@ -935,10 +935,10 @@ "$ref": "#/definitions/genericError" } }, - "409": { - "description": "genericError", + "410": { + "description": "requestWasHandledResponse", "schema": { - "$ref": "#/definitions/genericError" + "$ref": "#/definitions/requestWasHandledResponse" } }, "500": { @@ -1105,10 +1105,10 @@ "$ref": "#/definitions/genericError" } }, - "409": { - "description": "genericError", + "410": { + "description": "requestWasHandledResponse", "schema": { - "$ref": "#/definitions/genericError" + "$ref": "#/definitions/requestWasHandledResponse" } }, "500": { @@ -1290,6 +1290,12 @@ "$ref": "#/definitions/genericError" } }, + "410": { + "description": "requestWasHandledResponse", + "schema": { + "$ref": "#/definitions/requestWasHandledResponse" + } + }, "500": { "description": "genericError", "schema": { @@ -2153,6 +2159,10 @@ "Types" ], "properties": { + "ProtocolScheme": { + "description": "Protocol to use for clients connecting to the plugin.", + "type": "string" + }, "Socket": { "description": "socket", "type": "string" @@ -3147,6 +3157,19 @@ } } }, + "requestWasHandledResponse": { + "type": "object", + "title": "The response payload sent when there is an attempt to access already handled request.", + "required": [ + "redirect_to" + ], + "properties": { + "redirect_to": { + "description": "Original request URL to which you should redirect the user if request was already handled.", + "type": "string" + } + } + }, "userinfoResponse": { "description": "The userinfo response", "type": "object",