Skip to content

feat: associates user by email for oauth when tpa is required - #25935

Merged
waheedahmed merged 1 commit into
openedx:masterfrom
open-craft:nizar/tpa_associate_by_email_waffle_switch
Apr 2, 2021
Merged

feat: associates user by email for oauth when tpa is required#25935
waheedahmed merged 1 commit into
openedx:masterfrom
open-craft:nizar/tpa_associate_by_email_waffle_switch

Conversation

@nizarmah

@nizarmah nizarmah commented Dec 23, 2020

Copy link
Copy Markdown
Contributor

Description

Currently, in the edX platform, if you try to login with an SSO account using the login form, a username is generated for you based on the email that is used with the SSO provider.

The username is generated using the pipeline third_party_auth.pipeline.get_username.

If the username already exists in the platform, you run into a small conflict which sends you back to the login form and requests the following:
image

It basically requests that you link your edX account and your SSO account.

However, sometimes we would want the edX account and SSO account to be associated by email. There's already a special pipeline available in the platform for that, third_party_auth.pipeline.associate_by_email_if_login_api. Sadly, however, it is only available for a certain entry method of authentication, called login_api.

So in order to start associating the edX account and SSO account by email, this pull request adds a waffle switch.

Update: After a lot of reading through the code and investigation, it seems like the login_api auth entry is no longer used. Accordingly, I took the liberty of removing said pipeline and replacing it with something that seemed useful. Now the pipeline runs whenever third party authentication is required.

Update: After @waheedahmed's findings, which is that login_api is in fact still used, and @zamanafzal's request, which is to make the functionality specific to Oauth providers, a new pipeline was added to associate the user by email only when the following conditions are met:

  • The social auth provider is an Oauth2 provider
  • The ENABLE_REQUIRE_THIRD_PARTY_AUTH is enabled

Supporting information

Testing instructions

Preparation

Please send an email to nizar at opencraft.com, requesting to be added as a test user to the Google SSO used for this sandbox.

You need a Google Account, because you'll be using the same email address when registering through the form and through the SSO.

Reproducing the problem

Logging in with the SSO

Login with the Google SSO over at the sandbox with default behavior

Removing Social Auth Record

Sign in as staff:edx into the django admin and delete the user social auth for your user.

Logging in with the SSO, again...

Login, again, with the Google SSO over at the sandbox with default behavior. After doing that, you should receive a similar screenshot
image

Testing the fix

Logging in with the SSO

Login with the Google SSO over at the sandbox with default behavior

Removing Social Auth Record

Sign in as staff:edx into the django admin and delete the user social auth for your user.

Logging in with the SSO, again...

Login, again, with the Google SSO over at the sandbox with default behavior. After that, you should be able to directly login 😃

Settings

EDXAPP_LMS_ENV_EXTRA:
  ENABLE_REQUIRE_THIRD_PARTY_AUTH: true

@openedx-webhooks

Copy link
Copy Markdown

Thanks for the pull request, @nizarmah! I've created OSPR-5312 to keep track of it in JIRA, where we prioritize reviews. Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

@openedx-webhooks openedx-webhooks added needs triage open-source-contribution PR author is not from Axim or 2U labels Dec 23, 2020
@nizarmah
nizarmah force-pushed the nizar/tpa_associate_by_email_waffle_switch branch 2 times, most recently from 53a6fb5 to 2290f04 Compare December 23, 2020 05:45
@nizarmah
nizarmah force-pushed the nizar/tpa_associate_by_email_waffle_switch branch 5 times, most recently from 8208877 to 914410a Compare December 26, 2020 03:09
@nizarmah

Copy link
Copy Markdown
Contributor Author

Sorry for all the messy force pushes! I just wanted to clean the history before any reviewer took a look. I have been testing on the sandbox, which made pushing to the branch just more convenient.

@nizarmah
nizarmah force-pushed the nizar/tpa_associate_by_email_waffle_switch branch from e1fa76f to 2f727ba Compare December 28, 2020 12:48
@gabor-boros

Copy link
Copy Markdown
Contributor

👍 🎉

  • I tested what's in the test instructions
  • I read through the code
  • NA I checked for accessibility issues
  • NA Includes documentation
  • NA I made sure any change in configuration variables is reflected in the corresponding client's configuration-secure repository.

@nizarmah

Copy link
Copy Markdown
Contributor Author

@natabene, I hope you and the members on the edX team are having/have had a nice holiday!
This is ready for edX's review 👍🏼

@natabene

Copy link
Copy Markdown
Contributor

@nizarmah Thanks, lining this up for our review.

@bradenmacdonald

bradenmacdonald commented Jan 13, 2021

Copy link
Copy Markdown
Contributor

This will likely need product review but I would be inclined to suggest making this the default behavior and deprecating the previous behavior with the yellow message ("You have successfully signed in but there's no linked account"). Everyone I've ever talked to about the current flow has said it's confusing.

The most common case is that the user's SSO email matches their existing account's email, and in that case it should automatically link (if we trust the SSO provider), which I believe is what's happening here.

The "edge case" is that the user's SSO email is different from their existing account's email; in that case if they want to "link" instead of creating a new account, they can always sign in to their existing account, go to the account settings page, and link the accounts from there. That's how most other websites work anyways.

It may also be necessary to enable this per provider, because we don't necessarily trust every provider's "email" field (e.g. user logs in via their company provider and company provider was hacked to say that they own the email of an edX employee, we don't want to log them in to the edX employee's account).

@natabene

Copy link
Copy Markdown
Contributor

@nasthagiri Are you ok with this going to core committers?

@nasthagiri

Copy link
Copy Markdown
Contributor

@natabene Yes, I am.

@bradenmacdonald +1 to your suggestion of changing the default. @wajeeha-khalid can provide Product input on this.

@waheedahmed waheedahmed left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just one concern otherwise looks good now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It will enable it by default for each auth entry in the oauth2 provider's case and I believe the purpose of associate_by_email_if_login_api is failed here. Don’t you think we need to put it under the feature flag ENABLE_REQUIRE_THIRD_PARTY_AUTH?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

And if we are making it the default behavior in the oauth2 providers case, then I think we can change this check if auth_entry == AUTH_ENTRY_LOGIN_API: to something if is_oauth_provider(backend.name, **kwargs) and auth_entry in ALLOWED_AUTH_ENTRIES: instead of this new pipeline function.

ALLOWED_AUTH_ENTRIES will be a list of auth entries you want to allow here. e.g. login_api, login, register.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@waheedahmed Yes, I do think we need to put it under the feature flag ENABLE_REQUIRE_THIRD_PARTY_AUTH, that's a great point.

Your recommendation about the ALLOWED_AUTH_ENTRIES is great, but I'm hesitant to make such a change because it can be considered "breaking".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@waheedahmed may you please check the latest changes? I added the setting check. I also added a test to verify that it is working 😃

I thought of adding another test, when the flag is disabled, but I believe test_new_account_registration_assigns_distinct_username_on_collision already covers the default case. Let me know though, please, if you don't consider that to be enough 👍🏼

@nizarmah nizarmah changed the title [SE-3816] Substitutes the login_api auth entry with required tpa check feat: associates user by email for oauth when tpa is required Mar 25, 2021
@nizarmah
nizarmah force-pushed the nizar/tpa_associate_by_email_waffle_switch branch from 7bd19f9 to 776912e Compare March 25, 2021 15:00
@nizarmah
nizarmah requested a review from waheedahmed March 26, 2021 03:09

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This test is passing even with ENABLE_REQUIRE_THIRD_PARTY_AUTH=False, shouldn’t it fail without this setting enabled?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

😯 it should indeed fail without this setting enabled... I'll look into it. Sorry about that!

@nizarmah

Copy link
Copy Markdown
Contributor Author

@waheedahmed sorry for this taking so much longer than it should 😞

Anyway, I updated the tests, and I also added some additional tests for the utils I added 👍🏼
I made sure to test everything extensively this time, instead of rushing it.

I went also with a different approach for the test, which is just the opposite of test_signin_fails_if_no_account_associated.
I just had to mock certain stuff because the pipeline made things pretty difficult.

This should be ready for your review again 😁

cc @natabene

@robrap

robrap commented Mar 30, 2021

Copy link
Copy Markdown
Contributor

For historical purposes, would you mind updating the PR description? Thank you.

@nizarmah
nizarmah requested a review from waheedahmed March 30, 2021 14:15
@nizarmah

Copy link
Copy Markdown
Contributor Author

@robrap thanks for the reminder 👍🏼 The description has been updated, and I made sure to link to two important messages in the pull request. 😄

@waheedahmed waheedahmed left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A small nit otherwise looks good now 👍, please squash your commits and let me know when it's ready to merge.

Thanks!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since you have already defined the return value within the mock call, I guess you can remove this unnecessary as statement _mock_get_associated_user_by_email_response.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure! 👍🏼

I also removed _mock_associate_by_email since it was also not used 😃

This should be addressed by now. I also squashed by the way.

This change associates users signing in using oauth providers when tpa is required, verifying that only a single database user is associated with the email.

For more information as to why this was added in a separate pipeline, check edx-platform#25935.
@nizarmah
nizarmah force-pushed the nizar/tpa_associate_by_email_waffle_switch branch from fd6541c to a9285b6 Compare April 1, 2021 16:57
@nizarmah

nizarmah commented Apr 1, 2021

Copy link
Copy Markdown
Contributor Author

@waheedahmed 🥳 awesome!

Thank you a lot for the review and for being patient with me through this change 😅

I addressed your nit and squashed. This is ready to be merged 👍🏼 (once the builds pass)

@edx-status-bot

Copy link
Copy Markdown

Your PR has finished running tests. There were no failures.

@waheedahmed
waheedahmed merged commit 4cb4be6 into openedx:master Apr 2, 2021
@openedx-webhooks

Copy link
Copy Markdown

@nizarmah 🎉 Your pull request was merged!

Please take a moment to answer a two question survey so we can improve your experience in the future.

@nizarmah
nizarmah deleted the nizar/tpa_associate_by_email_waffle_switch branch April 2, 2021 06:33
@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production.

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

nizarmah added a commit to open-craft/openedx-platform that referenced this pull request Apr 3, 2021
0x29a pushed a commit to open-craft/openedx-platform that referenced this pull request Apr 20, 2021
…edx#25935)

(cherry picked from commit 914410a47b50933e5a92e2e77e0dbc85ff405cce)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.