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

WIP: documenting attempts to flash a custom message for /login page without disrupting the login redirect flows #29

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rudokemper
Copy link
Member

Unfortunately, while the work in #28 to flash a welcome message on the login page worked in that regard, it also broke the login flow functionality, and I missed that in testing. With that code change, pressing "sign in with auth0" redirected the user to a non-functional route /loginauth0?next= instead of to auth0 for authentication.

I spent a good amount of time wrapping my head around ways to work around this, to the best of my knowledge of how Flask AppBuilder and Superset and auth0 work together, and trying to stay within the confines of superset_config.py (as in, keeping the deploy structure in this repo and not messing with any Superset code directly). I wasn't able to come up with a solution yet, so here I am documenting my work to date as I tried a couple of things already.

Not a huge priority to resolve this; not having the flashed message is not blocking anyone, but we do occasionally have to explain the ambiguity about the meaning of "Sign in with auth0" to some first-time users.

For posterity, the initially attempted approach in #28 was to customize the login page, akin to how we handle custom flashed messages for the oauth_authorized view...

class CustomAuthOAuthView(AuthOAuthView):
    @expose("/login")
    def login(self) -> WerkzeugResponse:
        flash(translate("Welcome! Please sign up or log in by pressing 'Sign in with auth0' to access the application"), "info")
        return super().login()

Here is what I tried before I decided to put this down for the time being, and submit this draft PR for future reference.

Returning the auth0 url instead of super().login()

First, instead of

return super().login()

I tried to return the auth URL:

return redirect(f"https://{AUTH0_DOMAIN}/authorize?response_type=code&client_id={get_env_variable('AUTH0_CLIENTID')}&redirect_uri={url_for('AuthOAuthView.oauth_authorized', provider='auth0', _external=True)}&scope=openid+profile+email")

This does not work, as accessing /login bypasses the login screen entirely and routes the user to this URL, resulting in auth0 callback page errors.

Rewriting the actual redirect url in the login page

Next, I tried to rewrite the seemingly non-functional url in the login page.

In this branch, there is a code block where I've exposed the custom login method, and stored super().login() in a response variable:

response = super().login()

When I investigated the contents of reponse, I saw that it's really just an HTML page with some javascript that redirects the user to baseLoginUrl + provider + next upon pressing the "sign in with auth0" button. In response, baseLoginUrl is set to "login" and provider is "auth".

I noticed that our functional deployments of superset redirect to /login/auth0?next=, so I was hoping the omission of a forward slash in baseLoginUrl was the issue (hence the invalid url /loginauth0?next=). So the first thing I tried was to rewrite the baseLoginUrl from login to login/, in the hopes that would work. Unfortunately it did not.

Then, I tried to completely replace that URL with the expected auth0 URL, as per the code in this branch:

    @expose("/login")
    def login(self) -> WerkzeugResponse:
        flash(translate("Welcome! Please sign up or log in by pressing 'Sign in with auth0' to access the application"), "info")
        response = super().login()

        auth0_domain = os.getenv('AUTH0_DOMAIN')
        auth0_client_id = os.getenv('AUTH0_CLIENTID')
        redirect_uri = url_for('CustomAuthOAuthView.oauth_authorized', provider='auth0', _external=True)
        auth0_url = f"https://{auth0_domain}/authorize?response_type=code&client_id={auth0_client_id}&redirect_uri={redirect_uri}&scope=openid+profile+email"

        response = response.replace(
            'window.location.href = baseLoginUrl + provider + next;',
            f'window.location.href = "{auth0_url}";'
        )

        return response

This partially worked: in this flow, I am redirected to auth0 for authentication. However, upon completion, I am for some reason returned back to the login page, where I am met with the "You are not yet authorized to access this application. Please contact a GuardianConnector administrator for access." message. Even though I have authenticated successfully with auth0 and am approved to use the application. Since the auth0_url above seemed sound, I wasn't sure what to do next to troubleshoot that.

Using before_request

I looked into trying something like before_request(flash_welcome_message), ala...

def translate(message):
    locale = str(get_locale())
    return translations.get(message, {}).get(locale, message)

def flash_login_message():
    if request.path == "/login":
        flash(translate("Welcome! Please sign up or log in by pressing 'Sign in with auth0' to access the application"), "info")

app = create_app()
app.before_request(flash_login_message)

But this didn't entirely work, and required importing AppBuilder and (in my opinion) getting too deep into the Superset app scaffolding process for what should ideally be a light-weight implementation of a message.

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.

1 participant