Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Respond with Redirect URL for already handled requests #2473

Merged
merged 6 commits into from
Apr 23, 2021

Conversation

svrakitin
Copy link
Contributor

@svrakitin svrakitin commented Apr 16, 2021

Related issue

Closes #1569

Proposed changes

  • Use 410 Gone instead of 409 Conflict for already handled requests
  • Respond with redirect_to when getting Login/Consent/Logout requests which have already been handled.
  • Make it more consistent by replacing WasUsed with WasHandled everywhere.

Checklist

  • I have read the contributing guidelines.
  • I have read the security policy.
  • I confirm that this pull request does not address a security
    vulnerability. If this pull request addresses a security. vulnerability, I
    confirm that I got green light (please contact
    security@ory.sh) from the maintainers to push
    the changes.
  • I have added tests that prove my fix is effective or that my feature
    works.
  • I have added or changed the documentation.

@svrakitin svrakitin changed the title fix: Allow to already handled requests from Admin API fix: Allow access to already handled requests from Admin API Apr 16, 2021
Copy link
Contributor

@Benehiko Benehiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it necessary to change everything from WasUsed to WasHandled? Other than that it looks good to me :)

spec/api.json Show resolved Hide resolved
@svrakitin
Copy link
Contributor Author

Was it necessary to change everything from WasUsed to WasHandled? Other than that it looks good to me :)

@Benehiko I just made it more consistent as both WasUsed and WasHandled were mentioned in the code. I believe that request cannot really be used, it can be handled tho. :)

Benehiko
Benehiko previously approved these changes Apr 19, 2021
Copy link
Contributor

@Benehiko Benehiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really appreciate the contribution :)
I'll approve this, but will require further feedback from @aeneasr

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you! I've added a more descriptive comment. Can you please apply that comment to all the definitions of WasHandled?

Alternatively to this approach, we could do:

h.r.Writer().WriteError(w, r, x.ErrConflict.WithReason("Consent request has been used already").WithDetail("redirect_to", r.ReturnURL))

and write a custom swagger error object for this (so not genericError but e.g. requestWasHandledError.

What do you think? Is the 429 to counter intuitive? In my view, this is an error and should be treated as an error. If the dev does not check for this, the flow will end up in an irrecoverable error for the user.

Alternatively we could also let hydra redirect the user to the RequestURL if we encounter a used login / consent request?

consent/types.go Outdated Show resolved Hide resolved
@svrakitin
Copy link
Contributor Author

svrakitin commented Apr 22, 2021

@aeneasr I think replying with 409 Conflict on GET is not very intuitive as I would only expect conflict when mutating some state. If we still want to have an error here an alternative could be using different status code (i.e. 410 Gone) and still responding with redirect_to/request_url in a different swagger object as you mentioned. But maybe changing status code now will break someone.

@svrakitin
Copy link
Contributor Author

@aeneasr Updated PR to keep 409, but respond with redirect_to.

@svrakitin svrakitin changed the title fix: Allow access to already handled requests from Admin API fix: Respond with Redirect URL for already handled requests Apr 22, 2021
@svrakitin svrakitin requested a review from aeneasr April 22, 2021 12:17
@aeneasr
Copy link
Member

aeneasr commented Apr 23, 2021

410 Gone is a good idea!

@aeneasr
Copy link
Member

aeneasr commented Apr 23, 2021

True, it is a breaking change - but given that we fix the behavior which was basically completely broken before it is ok. We'll document it :)

@svrakitin
Copy link
Contributor Author

Will make it 410 then! Thanks

@aeneasr aeneasr merged commit e3d9158 into ory:master Apr 23, 2021
@aeneasr
Copy link
Member

aeneasr commented Apr 23, 2021

Awesome @svrakitin !

mitar pushed a commit to mitar/hydra that referenced this pull request May 13, 2021
…ry#2473)

Closes ory#1569

BREAKING CHANGE: This patch makes it so that already handled consent/login/logout requests respond with 410 Gone instead of 409 Conflict. Additionally, a URL is included that the user should be redirected to!

Co-authored-by: hackerman <3372410+aeneasr@users.noreply.github.com>
@sneko
Copy link

sneko commented Jul 28, 2021

Hi @svrakitin ,

Just upgraded my Hydra instance to benefit from your PR (thanks).

I noticed with my Go client I'm able to get the *admin.GetLoginRequestGone when running GetLoginRequest, which seems expected.

But when doing AcceptLoginRequest (I was doing only this one before when the user submit credentials), I get this type of error:
*runtime.APIError
(and once stringified it gives response status code does not match any response statuses defined for this endpoint in the swagger spec (status 409): {})

It brings to me some questions:

  • It seems the 409 is still used for accepting a login?
  • Should the Go client have the possible "Gone" error on AcceptLoginRequest as for GetLoginRequest? Or should I always do a Get before Accept just to make sure it's valid (considering in won't expire between both requests?

Thank you,

@svrakitin
Copy link
Contributor Author

Hey @sneko,

I think it makes sense to revisit status codes for accept endpoints as well. For now as a workaround you can get login request first. 409 is used for accept, but it's not even mentioned in the swagger spec, thats why you get this generic error.

You can either submit a PR to fix that or I will find some time later this month.

@sneko
Copy link

sneko commented Jul 28, 2021

@svrakitin just noticed that:

Some users started the flow into a specific browser, and then, due to confirmation through email... they went to another browser.

And even if they had a code challenge not used, GetLoginRequest was returning no Gone error, but the following AcceptLoginRequest was returning response status code does not match any response statuses defined for this endpoint in the swagger spec (status 409): {}.

I wonder what could make the difference so Hydra is complaining?

Let's see my code:

	getResponse, err := s.hydra.Admin.GetLoginRequest(&hydra_admin.GetLoginRequestParams{
		Context:        ctx,
		LoginChallenge: challenge,
	})
	if err != nil {
                 return err
	}

and

	acceptResponse, err := s.hydra.Admin.AcceptLoginRequest(&hydra_admin.AcceptLoginRequestParams{
		Context:        ctx,
		LoginChallenge: challenge,
		Body: &hydra_models.AcceptLoginRequest{
			Subject:     &auth.UserID,
			Remember:    true,
			RememberFor: int64(0), // Must be in seconds, and "0" for browser session lifetime
		},
	})
	if err != nil {
                 return err
	}

For me it's not coming from the missing Gone, I could still look for status 409 in the stringified error to adjust my frontend... but I don't get why the getter is a success if accepting is not :(

@svrakitin
Copy link
Contributor Author

@sneko Could it be some race condition when you have multiple requests for the same challenge? It can be users refreshing/reusing the email confirmation page if you accept the challenge automatically there.

@svrakitin svrakitin deleted the allow-get-handled-requests branch July 28, 2021 17:12
@sneko
Copy link

sneko commented Jul 28, 2021

@svrakitin after investigating it's on our side. An error came after the return of Hydra so the user didn't get the redirectTo URL. Sorry about that!

Thanks for the help 👍 :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

No way to handle 409 GetLoginRequestConflict.
4 participants