#1956 openid,login by email: guide user, don't do infinite loop
Merged 2 years ago by praiskup. Opened 2 years ago by ttomecek.
copr/ ttomecek/copr fix-rhbz#1943925  into  main

@@ -20,7 +20,6 @@ 

  from coprs import oid

  from coprs.logic.complex_logic import ComplexLogic

  from coprs.logic.users_logic import UsersLogic

- from coprs.logic.coprs_logic import CoprsLogic

  from coprs.exceptions import ObjectNotFound

  

  
@@ -178,7 +177,43 @@ 

      return flask.redirect(oid.get_next_url())

  

  

+ def workaround_ipsilon_email_login_bug_handler(f):

+     """

+     We are working around an ipislon issue when people log in with their email,

+     ipsilon then yields incorrect openid.identity:

+ 

+       ERROR:root:Discovery verification failure for http://foo@fedoraproject.org.id.fedoraproject.org/

+ 

+     The error above raises an exception in python-openid thus restarting the login process

+     which turns into an infinite loop of requests. Since we drop the openid_error key from flask.session,

+     we'll prevent the infinite loop to happen.

+ 

+     Ref: https://pagure.io/ipsilon/issue/358

+     """

+ 

+     @functools.wraps(f)

+     def _the_handler(*args, **kwargs):

+         msg = flask.session.get("openid_error")

+         if msg and "No matching endpoint found after discovering" in msg:

+             # we need to advise to log out because the user will have an active FAS session

+             # and the only way to break it is to log out

+             logout_url = app.config["OPENID_PROVIDER_URL"] + "/logout"

+             message = (

+                     "You logged in using your email. <a href=\"https://pagure.io/ipsilon/issue/358\""

+                     " target=\"_blank\">This is not supported.</a> "

+                     "Please log in with your <em>FAS username</em> instead "

+                     "<a href=\"%s\">after logging out here</a>." % logout_url

+             )

+             flask.session.pop("openid_error")

+             flask.flash(message, "error")

+             # do not redirect to "/login" since it's gonna be an infinite loop

+             return flask.redirect("/")

+         return f(*args, **kwargs)

+     return _the_handler

+ 

+ 

  @misc.route("/login/", methods=["GET"])

+ @workaround_ipsilon_email_login_bug_handler

  @oid.loginhandler

  def login():

      if not app.config['FAS_LOGIN']:
@@ -399,7 +434,6 @@ 

      return response

  

  

- 

  def req_with_pagination(f):

      """

      Parse 'page=' option from GET url, and place it as the argument

The main problem is that FAS/ipsilon sets the email used during login as
openid.claimed_id instead of actual FAS username. This breaks openid
client logic badly.

flask_openid in this situation redirects to /login/, again, which causes
infinite request loop.

In this commit we create a new decorator to wrap our login method to
detect this situation and prevent it:

  1. detect this specific use case

  2. drop the openid_error from flask session

  3. flash a message they hit an auth bug

  4. ask them to log out and log in again with FAS username

  5. redirect to "/"

Build failed. More information on how to proceed and troubleshoot errors available at https://fedoraproject.org/wiki/Zuul-based-ci

rebased onto cf6d8e3d7e99415faeba9a0fd7579c072c0232b0

2 years ago

Build succeeded.

What?! Ok, ipsilon makes our (your Tom) life really hard...

Makes me feel that manual click on /login route will cause redirect to ipsilon, and automatic redirect back with the very same error message. IOW, the thing is that user is probably not going to be prompted for nick+password again, as we don't log-out from ipsilon.... :-(

Thank you for this PR!

@praiskup Pavel, that's a very good point wrt the logged session in ipsilon - that's exactly what happened to me while working on this issue. I got redirected back to copr frontend immediately after logging in for the first time in FAS.

Would it be possible to redirect to ipsilon's logout endpoint? I just tried https://id.fedoraproject.org/logout and it worked for me to log off, though we'd still need to first display the error message first. Alternatively we can mention this as s first step in the error message.

rebased onto 7fad6487596461473613fcbacbae1c116c72b100

2 years ago

Build succeeded.

I updated this PR:

  1. we now drop the openid_error

  2. and ask the user to log out and log in again with the FAS username

after trying different login scenarios, this worked the best for me

Thank you for the update!

  1. we now drop the openid_error
  2. and ask the user to log out and log in again with the FAS username

Yes, ^^ good ideas. I've sent you on IRC some simplification ideas, since this
patch is pretty hard to review (not wrong, not ugly, just hard to review as we
are not familiar with that OpenID logic).

Thank you for the update!

  1. we now drop the openid_error
  2. and ask the user to log out and log in again with the FAS username

Yes, ^^ good ideas. I've sent you on IRC some simplification ideas, since this
patch is pretty hard to review (not wrong, not ugly, just hard to review as we
are not familiar with that OpenID logic).

rebased onto e435bd1e8a1b770ad640f2f5fc3120afb327d232

2 years ago

that worked very well, thanks Pavel! this is now much simpler

Build succeeded.

Can you flash an error message here? It would be more visible... Otherwise looks nice.

rebased onto 5199858f19a008b28574eaea6c7bc452fc247a65

2 years ago

yup, that's a good idea! didn't know it can be customized

Build succeeded.

rebased onto 35d76ca

2 years ago

Build succeeded.

Pull-Request has been merged by praiskup

2 years ago
Metadata