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

[GH-198]:Fixed issue #198 'Handle case where a user's refresh token expires' #256

Merged
merged 15 commits into from
Nov 12, 2024

Conversation

Kshitij-Katiyar
Copy link
Contributor

Summary

  • Added the logic that if an API request fails, with the error refresh token expired then marking the user inactive in the KV store and also sending a DM to the user to reconnect their account.

  • If the user is marked as inactive, aborting any future API requests done for this user, and logging via the WARN log level.

  • Issue #198

@mattermost-build
Copy link

Hello @Kshitij-Katiyar,

Thanks for your pull request! A Core Committer will review your pull request soon. For code contributions, you can learn more about the review process here.

@Kshitij-Katiyar
Copy link
Contributor Author

@m1lt0n Not able to add you as a reviewer here.

@m1lt0n m1lt0n self-requested a review April 19, 2023 08:20
@codecov-commenter
Copy link

codecov-commenter commented Apr 20, 2023

Codecov Report

Attention: Patch coverage is 42.85714% with 16 lines in your changes are missing coverage. Please review.

Project coverage is 27.31%. Comparing base (b1bcb7b) to head (b9312d9).

Files Patch % Lines
server/command/create_event.go 0.00% 7 Missing ⚠️
server/command/find_meeting_times.go 0.00% 3 Missing ⚠️
server/mscalendar/calendar.go 0.00% 3 Missing ⚠️
server/mscalendar/client.go 0.00% 1 Missing ⚠️
server/mscalendar/subscription.go 0.00% 1 Missing ⚠️
server/mscalendar/user.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #256      +/-   ##
==========================================
+ Coverage   23.71%   27.31%   +3.59%     
==========================================
  Files          62       44      -18     
  Lines        3087     2541     -546     
==========================================
- Hits          732      694      -38     
+ Misses       2274     1771     -503     
+ Partials       81       76       -5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

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

Great work on this @Kshitij-Katiyar 👍

I have a few requests mainly pertaining to avoiding DM'ing a user multiple times, and putting in some defensive code to avoid token expiry issues.

server/mscalendar/availability_test.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_notification_data.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/get_me.go Outdated Show resolved Hide resolved
server/remote/msgraph/check_user_status.go Outdated Show resolved Hide resolved
@mattermost-build
Copy link

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

@hanzei hanzei added the Work In Progress Not yet ready for review label May 9, 2023
@mickmister
Copy link
Contributor

@Kshitij-Katiyar This issue has become a more pressing issue, so I would prioritize this PR if possible. There some remaining change requests, though the main one is here #256 (comment)

@mattermost-build
Copy link

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

server/remote/remote.go Outdated Show resolved Hide resolved
@mickmister mickmister added 3: QA Review Requires review by a QA tester and removed Lifecycle/1:stale Work In Progress Not yet ready for review labels May 30, 2023
@mickmister
Copy link
Contributor

@Kshitij-Katiyar Can you please provide testing steps for this PR for @DHaussermann

@Kshitij-Katiyar
Copy link
Contributor Author

Kshitij-Katiyar commented Jun 6, 2023

@Kshitij-Katiyar Can you please provide testing steps for this PR for @DHaussermann

@DHaussermann Testing steps:-

  • First connect the user using command /mscalender connect.
  • Wait for the refresh token to expire. I have manually deleted that that's why I don't know the time for that but I can search for it.
  • If the user's token is expired, try to run any slash command which will call the ms-calender API like CRUD operations of the calendar, etc.
  • Then the user should get the DM and in the server log stating that the user is marked inactive, please disconnect and connect the account again.
  • After this, all APIs should start working again.

@DHaussermann
Copy link

Hi @Kshitij-Katiyar
Yes I was curious about the step of waiting for the refresh token to expire. I see the token value in the DB store but I think the expiry must occur on the MS side correct?

Also I'm a bit stuck here because the token could take possibly weeks to expire and simply by invalidating it in the data store, am I thang just hitting a different code path?

If so, I'm not sure if there is functional testing I can cover here. Maybe some type of test build that will mimic the refresh process is an option?

@@ -295,6 +305,79 @@ func (s *pluginStore) StoreUserActiveEvents(mattermostUserID string, events []st
return kvstore.StoreJSON(s.userKV, mattermostUserID, u)
}

// RefreshAndStoreToken checks whether the current access token is expired or not. If it is,
// then it refreshes the token and stores the new pair of access and refresh tokens in kv store.
func (s *pluginStore) RefreshAndStoreToken(token *oauth2.Token, oconf *oauth2.Config, mattermostUserID string) (*oauth2.Token, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@Kshitij-Katiyar This is where much of the functionality was added in this PR. I'm thinking we can test this function and CheckUserConnected directly. What do you think?

We basically want to emulate this in a test since this is the code that is applied throughout the PR:

	if !c.tokenHelpers.CheckUserConnected(c.mattermostUserID) {
		c.Logger.Warnf(LogUserInactive, c.mattermostUserID)
		return nil, errors.New(ErrorUserInactive)
	}
	err := someCallToAPI // this can be whatever we want in the test
	if err != nil {
		c.tokenHelpers.DisconnectUserFromStoreIfNecessary(err, c.mattermostUserID)

We can use a "real" KV store in the test with one of the following strategies:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wiggin77 Writing test cases for these functions without refactoring is challenging because many of the functions used within them are standalone and not implemented by any interface, making it difficult to mock them.

One workaround is to use monkeyPatch. However, this approach isn't currently used in the plugin, and introducing it just for this test case might not be ideal. Additionally, no test cases have been added for any store or msgraph functions so far, possibly because adding them is not straightforward.

Copy link
Member

Choose a reason for hiding this comment

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

This method can be unit tested with a memory store.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @wiggin77,
I looked into the memoryStore and its implementation in Mattermost. It seems useful for mocking the config store in Mattermost and other similar stores within Mattermost plugins. However, I’m unsure how it applies to our current use case. Could you provide some guidance on this?

Copy link
Member

Choose a reason for hiding this comment

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

A solution needs to be found here. If the implementation does not lend itself to writing clean unit tests, then the implementation needs to be refactored.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wiggin77 I think we can merge this PR for now
I have created a separate issue for the unit tests #423 for the same..

@wiggin77 wiggin77 added the 2: Dev Review Requires review by a core committer label Aug 10, 2024
Copy link
Member

@wiggin77 wiggin77 left a comment

Choose a reason for hiding this comment

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

Approving based on future unit tests being added. (#423)

@Kshitij-Katiyar
Copy link
Contributor Author

There was an issue with the execution slash commands involving any external API call if executed with an expired or invalid refresh token. Fixed it in this commit by checking for the expired token error in execution of related slash commands

@raghavaggarwal2308
Copy link
Contributor

@wiggin77 This PR has been dev tested properly. I do not think we need to get it QA tested as it won't be readily tested because we have to manually go into the DB and change the refresh token multiple times. Please let me know your thoughts on merging this?

@wiggin77
Copy link
Member

/update-branch

@mattermost-build
Copy link

We don't have permissions to update this PR, please contact the submitter to apply the update.

@wiggin77
Copy link
Member

Please let me know your thoughts on merging this?

Ok

@raghavaggarwal2308 raghavaggarwal2308 added 4: Reviews Complete All reviewers have approved the pull request and removed 2: Dev Review Requires review by a core committer 3: QA Review Requires review by a QA tester labels Nov 12, 2024
@raghavaggarwal2308 raghavaggarwal2308 merged commit 12efca2 into mattermost:master Nov 12, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4: Reviews Complete All reviewers have approved the pull request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants