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

Add OAuth authentication #47

Merged
merged 46 commits into from
Aug 13, 2024
Merged

Add OAuth authentication #47

merged 46 commits into from
Aug 13, 2024

Conversation

iamdharmesh
Copy link
Collaborator

@iamdharmesh iamdharmesh commented Aug 6, 2024

Description of the Change

The PR replaces the existing API key-based authentication flow with OAuth authentication to improve the overall connection flow experience. Here are the details of the tasks covered in this PR.

  • Utilize the mailchimpapp.com service to generate an access token
  • Encrypt the access token before we store it
  • Switch all API requests to use the access token instead of an API key
  • Handle potential error states where an access token expires or is revoked
  • Backward compatibility for sites that are currently using an API key (We don’t have a UI for viewing or modifying an existing key; the user has to log out to set a new key. Therefore, we can completely replace the API key form with the connect button.)

Aug-07-2024 16-31-27

Note

  • For the logout process, no API is called to revoke the access token or disconnect the integration on the Mailchimp side. I checked the Mailchimp for WooCommerce plugin and didn’t find any API call for this. I also reviewed the API documentation but didn’t find any API for revoking tokens. Since Mailchimp uses non-expiring tokens, it is crucial to revoke the token upon logout.
  • The PR uses the woocommerce.mailchimpapp.com OAuth middleware server to connect with Mailchimp. We will need to update it to the WordPress server once it is set up.

Closes #9

How to test the Change

New setup:

  1. Go to the Mailchimp settings page; the "Connect Account" button should be visible there.
  2. Click on the "Connect Account" button. This will open a pop-up with the Mailchimp login form.
  3. Complete the process in the pop-up window. The settings page should reload with the logged-in UI and settings options.
  4. Verify that the list and form fields data are loaded correctly based on the selected field.
  5. For browsers with pop-ups blocked, a modal with information will be shown, where the user can try again after allowing pop-ups.
  6. Verify that closing the pop-up without logging in or during intermediate steps is handled correctly.
  7. Regression testing: Perform overall regression testing to ensure all functionality works properly with the new OAuth authentication.
    • Admin settings page options
    • Adding/removing form fields from Mailchimp
    • Subscription form widget and block on the front end (rendering and submission as per settings)
  8. Click the "Logout" button.
  9. Verify that the settings page starts displaying the login page to connect the Mailchimp account.

Existing Users

  1. Set up the plugin with the trunk branch and configure it using API key authentication.
  2. Check out this PR branch and ensure that everything continues to work as it did (overall regression testing).
  3. Click "Logout."
  4. Connect your account by clicking the Connect Account button and ensure everything works as expected.

Changelog Entry

Added - OAuth authentication for connecting a Mailchimp account with WordPress.

Credits

Props @jeffpaul @dkotter @iamdharmesh

Checklist:

  • I agree to follow this project's Code of Conduct.
  • I have updated the documentation accordingly.
  • I have added tests to cover my change.
  • All new and existing tests pass.

@iamdharmesh iamdharmesh self-assigned this Aug 6, 2024
@github-actions github-actions bot added this to the 1.7.0 milestone Aug 6, 2024
views/setup_page.php Outdated Show resolved Hide resolved
views/setup_page.php Outdated Show resolved Hide resolved
js/admin.js Show resolved Hide resolved
@iamdharmesh iamdharmesh changed the title [WIP] Add OAuth authentication Add OAuth authentication Aug 7, 2024
@iamdharmesh iamdharmesh marked this pull request as ready for review August 7, 2024 13:12
@github-actions github-actions bot added the needs:code-review This requires code review. label Aug 7, 2024
includes/class-mailchimp-admin.php Outdated Show resolved Hide resolved
includes/class-mailchimp-admin.php Outdated Show resolved Hide resolved
includes/class-mailchimp-admin.php Outdated Show resolved Hide resolved
includes/class-mailchimp-admin.php Outdated Show resolved Hide resolved
includes/class-mailchimp-admin.php Outdated Show resolved Hide resolved
includes/class-mailchimp-data-encryption.php Outdated Show resolved Hide resolved
includes/class-mailchimp-data-encryption.php Outdated Show resolved Hide resolved
includes/class-mailchimp-data-encryption.php Outdated Show resolved Hide resolved
views/setup_page.php Outdated Show resolved Hide resolved
views/setup_page.php Outdated Show resolved Hide resolved
@dkotter
Copy link
Collaborator

dkotter commented Aug 7, 2024

@iamdharmesh We'll also want to ensure the readmes get updated with information on how encryption works and the need to set the custom defines, with a warning that if this isn't done, decryption may fail (if the LOGGED_IN_SALT changes) and the authentication flow will need to be gone through again

@dkotter
Copy link
Collaborator

dkotter commented Aug 8, 2024

@iamdharmesh Code looks good here and tests well, nice work!

I do have feedback on a few things that I think is worth addressing:

  1. In simulating an access token failure (I just directly modified the token in the database so it was invalid) the forms on the front-end still show, though the forms won't work. My opinion here is we should hide those forms if we don't have valid credentials. Note this will need to work for a shortcode form, widget form and block form.

  2. In testing what happens if decryption fails (I modified the salt we use to encrypt things) I noticed the block form and widget form don't show (there is a PHP warning attempt to read property datacenter on bool that I'm wondering is what's causing those not to render) but the shortcode form does show. Ideally as above, we don't show any of those forms if we don't have valid credentials

  3. This is more an edge case due to how I was testing but if I modified the access token, I get an admin message letting me know I need to re-authenticate. If I modify the access token to be valid again, that message still shows. Again, this is an edge case but seems like once we have a valid API call made, we should clear out that error message

  4. The admin notice we show overlaps weird in our settings page. I'm assuming some minor markup or CSS changes would fix this and ensure the notice shows above our header:

admin notice on settings page
  1. Also wondering if we should change that notice from a warning to an error, since things won't work until the connection is reestablished.

@dkotter
Copy link
Collaborator

dkotter commented Aug 8, 2024

^ The above are things I think we for sure should look at addressing. Here's a few things I'm raising for discussion purposes (cc / @jeffpaul @iamdharmesh):

  1. For existing users, we allow them to continue to use their API key with no problems, which is the correct approach. There is no prompt though to update to the new connection method. Wondering if we want to show an admin notice letting them know there's a new authentication method they should update to? Not sure how hard we want to push that, especially initially. I think the ideal would be to get everyone using OAuth but maybe this is something we add in a follow up release?

  2. For our encryption, we look for two custom constants first (MAILCHIMP_SF_ENCRYPTION_KEY and MAILCHIMP_SF_ENCRYPTION_SALT). This is documented in the readme but the reality here is most sites won't set these. We then try using some constants that are typically set across all WordPress sites (LOGGED_IN_KEY and LOGGED_IN_SALT). If these aren't set, we then fallback to a hardcoded string.

    Our experience on a couple other projects has shown us that some security plugins will periodically rotate those core WordPress salts. This causes the decryption to no longer work for sites that aren't using the custom constants and will require the site to go through the authentication process again.

    There's a couple options to consider here. We can leave this as-is, noting it is the most secure implementation and we have documentation on how to avoid this issue. Or we could remove the use of those core WordPress salts, meaning we would only rely on the custom constants or fallback to the hardcoded strings. This would prevent situations where decryption no longer works (so a better user experience) but is less secure for those that don't set those constants (which will probably be most sites)

@jeffpaul
Copy link
Collaborator

jeffpaul commented Aug 8, 2024

For existing users, we allow them to continue to use their API key with no problems, which is the correct approach. There is no prompt though to update to the new connection method. Wondering if we want to show an admin notice letting them know there's a new authentication method they should update to? Not sure how hard we want to push that, especially initially. I think the ideal would be to get everyone using OAuth but maybe this is something we add in a follow up release?

I agree that some sort of admin notice, sigh adding another one to folks already likely clogged up admin notices, to direct folks who are using the API Key to disconnect and reconnect via OAuth would be ideal and within this release.

There's a couple options to consider here. We can leave this as-is, noting it is the most secure implementation and we have documentation on how to avoid this issue. Or we could remove the use of those core WordPress salts, meaning we would only rely on the custom constants or fallback to the hardcoded strings. This would prevent situations where decryption no longer works (so a better user experience) but is less secure for those that don't set those constants (which will probably be most sites)

I think its fine to leave as-is. Ensuring we've got a good FAQ item in the readme as well as details for the Woo.com product documentation on the topic will be helpful to direct folks to that run into the core salts being rotated and then, finally, properly adding the MC constants instead.

@iamdharmesh
Copy link
Collaborator Author

Thanks for the detailed feedback @dkotter. I have address those in 57c0058.

I agree that some sort of admin notice, sigh adding another one to folks already likely clogged up admin notices, to direct folks who are using the API Key to disconnect and reconnect via OAuth would be ideal and within this release.

Thanks for confirming @jeffpaul. Could you please help with adjust the wording of the notice on how hard we want to push the users to switch to OAuth. eg: is deprecated vs is going to deprecated in future.

(Heads up! It looks like you're using an API key to connect with Mailchimp, which is now deprecated. Please log out and reconnect your Mailchimp account using the new OAuth authentication by clicking the "Connect Account" button.)

For encryption (#2), @dkotter I am more inclined towards keeping it as it is.

Thank you.

@jeffpaul
Copy link
Collaborator

@iamdharmesh I'm fine with that existing notice noting deprecated.

@dkotter dkotter modified the milestones: 1.7.0, 1.6.0 Aug 12, 2024
@iamdharmesh
Copy link
Collaborator Author

@iamdharmesh I'm fine with that existing notice noting deprecated.

@jeffpaul This is added in 4175774

@dkotter
Copy link
Collaborator

dkotter commented Aug 13, 2024

For the logout process, no API is called to revoke the access token or disconnect the integration on the Mailchimp side. I checked the Mailchimp for WooCommerce plugin and didn’t find any API call for this. I also reviewed the API documentation but didn’t find any API for revoking tokens. Since Mailchimp uses non-expiring tokens, it is crucial to revoke the token upon logout.

@dkotter can you coordinate with @justin0440 / Vextras (in case we need to proxy through their wordpress.mailchimpapp.com service) to confirm what API should be used on logout to disconnect the respective WordPress site from the connected Mailchimp account?

Sounds like there isn't a public facing API to do this, so the approach we're taking here is the best we can do for now

@dkotter dkotter merged commit ef1a6f5 into develop Aug 13, 2024
8 checks passed
@dkotter dkotter deleted the enhancement/9 branch August 13, 2024 17:19
@dkotter dkotter mentioned this pull request Aug 13, 2024
1 task
@dkotter dkotter mentioned this pull request Aug 26, 2024
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs:code-review This requires code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add OAuth login
4 participants