Skip to content

Re-provision Slack after primary email changes - #307

Open
404Navdeep wants to merge 15 commits into
hackclub:mainfrom
404Navdeep:slackid-reprovisoning
Open

Re-provision Slack after primary email changes#307
404Navdeep wants to merge 15 commits into
hackclub:mainfrom
404Navdeep:slackid-reprovisoning

Conversation

@404Navdeep

Copy link
Copy Markdown

Re-provision Slack after primary email changes

What this PR does

When a user changes their primary email, we now reprovision their Slack account after the email change is completed.
The reprovisioning logic:

  • Keeps the current Slack account if it's still the correct one.
  • Links an existing Slack account if one already exists for the new email.
  • Creates a new Slack account if needed.
  • Handles failures gracefully without interrupting the email change process.

Tests

  • Added specs covering:
  • Keeping the same Slack account.
  • Linking a different existing Slack account.
  • Creating a new Slack account.
  • Handling reprovisioning failures.
  • Ensuring email changes still complete even if Slack reprovisioning fails.

Why?

I originally had a Slack account with email A. Later that account got deactivated. Before joining Slack again, I changed my primary email in Hack Club Auth to email B.

Then I clicked Join Slack. SCIMService.find_or_create_user gets called from both LoginsController and SamlController:

SCIMService.find_or_create_user(
  identity: current_identity,
  scenario: scenario
)

Inside app/services/scim_service.rb, it looks for an existing Slack user using the current primary email:

email = identity.primary_email
existing_slack_id = find_existing_user_by_email(email)

and find_existing_user_by_email does:

req.params["filter"] = "emails eq \"#{email}\""

Since my HCA email was now email B, it looked for a Slack account with email B. My old Slack account still had email A, so it couldn't find it and instead created a completely new Slack account.

After that, HCA saved the new Slack ID to my identity.

Later I changed my HCA email back to email A and my old Slack account was reactivated. But SAML still logged me into the new account because it only provisions if slack_id is missing:

return if current_identity.slack_id.present?

So it never tried to find my original account again.

I think the main issue is that provisioning only looks at the current email the first time. If someone changes their email before provisioning, it's really easy to accidentally create a duplicate Slack account that stays linked forever.

@404Navdeep

Copy link
Copy Markdown
Author

One possible fix could be to automatically reprovision Slack whenever an identity's primary email changes.

Right now, once identity.slack_id is set, SAML provisioning immediately returns:
return if current_identity.slack_id.present?

This means if someone changes their primary email before or after provisioning, the Slack link is never revalidated.
Instead, when the primary email changes, HCA could:

  1. Clear the current slack_id (or temporarily ignore it).
  2. Run SCIMService.find_or_create_user again.
  3. Update identity.slack_id if a different Slack account is found.

This would keep the Slack link in sync with the identity's current email and would have prevented the duplicate account issue I ran into.

This pr used this approach!

@leowilkin

Copy link
Copy Markdown
Member

We don't want to re-provision a user's Slack when they change their email - this inadvertently creates unused Slack accounts.

User signs up > gets Slack Acct. #A > changes email on Slack > clicks sign in on Auth > Slack Acct. #B gets created.

Since my HCA email was now email B, it looked for a Slack account with email B. My old Slack account still had email A, so it couldn't find it and instead created a completely new Slack account.

The solution to this is just to email auth/identity@hackclub.com, and get your Slack account email updated.

@404Navdeep

Copy link
Copy Markdown
Author

User signs up > gets Slack Acct. #A > changes email on Slack > clicks sign in on Auth > Slack Acct. #B gets created.

This is not the correct flow this would activate.

User signs up > Clicks Join Slack > gets Slack Acct. #A > changes email on Slack > changes email on HCA > Slack Acct. #A still gets linked to the same HCA account.

But..

User signs up > Clicks Join Slack > gets Slack Acct. #A > changes email on HCA > Clicks Join Slack > Slack Acct. #B gets created.

If we dont want it to create account we can edit that.
There is also another case:

User has 2 slack accounts #A & #B > changes email on HCA to match #A > Auth's into Slack Account #A > changes email on HCA to match #B > Auth's into Slack Account #B

@leowilkin

Copy link
Copy Markdown
Member

We want people to have one slack account though.. because that is the Slack account that is 'verified'

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.

2 participants