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

TwitterAuthClient doesn't provide a way to clear the authorization state. #76

Closed
nishkarsh opened this Issue Jan 9, 2017 · 4 comments

Comments

3 participants
@nishkarsh

nishkarsh commented Jan 9, 2017

  • Steps to reproduce:
  1. Implement custom login button for twitter.
  2. Initiate login by calling TwitterAuthClient.authorize(Activity activity, Callback<TwitterSession> callback) onClick() of login button.
  3. Generate a notification from the app that takes the user to any other screen of the app from where login can again be initiated.
  4. Click on the notification, it should take user to the app on a different screen.
  5. Initiate login again.
  • Actual behaviour:
    Login fails with the following stacktrace:
01-09 21:16:46.806 com.intentfilter.android W/Twitter: Authorize already in progress
01-09 21:16:46.807 com.intentfilter.android E/Twitter: Authorization completed with an error
                                com.twitter.sdk.android.core.TwitterAuthException: Authorize failed.
                                    at com.twitter.sdk.android.core.identity.TwitterAuthClient.handleAuthorize(TwitterAuthClient.java:110)
                                    at com.twitter.sdk.android.core.identity.TwitterAuthClient.authorize(TwitterAuthClient.java:101)
                                    at com.intentfilter.android.view.profile.login.LoginFragment.initiateTwitterLogin(LoginFragment.java:109)
                                    at com.intentfilter.android.view.profile.login.LoginFragment_ViewBinding$2.doClick(LoginFragment_ViewBinding.java:41)
                                    at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
                                    at android.view.View.performClick(View.java:5207)
                                    at android.view.View$PerformClick.run(View.java:21168)
                                    at android.os.Handler.handleCallback(Handler.java:746)
                                    at android.os.Handler.dispatchMessage(Handler.java:95)
                                    at android.os.Looper.loop(Looper.java:148)
                                    at android.app.ActivityThread.main(ActivityThread.java:5443)
                                    at java.lang.reflect.Method.invoke(Native Method)
                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

The exact problem seems to be that authState.beginAuthorize(activity, oauthHandler) is called when initiating login but authState.endAuthorize() is only called when onActivityResult() is received. This makes isAuthorizeInProgress() to return true when authorize() is called again due to state not being cleared. However, in case when user doesn't come back to the same Activity again, there is no way onActivityResult() would be received. To handle such cases, there should be a way to clear the authorization state by explicitly calling a method.

  • Expected behavior:
    As there could be multiple places in the app from where login can be triggered, there should be a way to clear authorization state explicitly.

@nishkarsh nishkarsh changed the title TwitterCore doesn't provide a way to clear the authorization state. TwitterAuthClient doesn't provide a way to clear the authorization state. Jan 9, 2017

@LaurieScheepers

This comment has been minimized.

LaurieScheepers commented May 11, 2017

Yeah, I'm having the same issue and after hours of searching I can't find a workaround.

What a horrible bug! Can't believe they haven't fixed it yet.

@nishkarsh Have you managed to get a workaround for this issue?

@nishkarsh

This comment has been minimized.

nishkarsh commented May 11, 2017

@LaurieScheepers Unfortunately I had to go with using reflection to access the state and explicitly call endAuthorize(). Couldn't find any other workaround.

private void endAuthorizeInProgress() {
        try {
            Field authStateField = twitterAuthClient.getClass().getDeclaredField("authState");
            authStateField.setAccessible(true);
            Object authState = authStateField.get(twitterAuthClient);
            Method endAuthorize = authState.getClass().getDeclaredMethod("endAuthorize");
            endAuthorize.invoke(authState);
        } catch (NoSuchFieldException | SecurityException | InvocationTargetException |
                NoSuchMethodException | IllegalAccessException e) {
            logger.e("Couldn't end authorize in progress.", e);
        }
    }

I don't know why my pull request that has a fix for this hasn't been accepted yet.

@LaurieScheepers

This comment has been minimized.

LaurieScheepers commented May 11, 2017

@nishkarsh Thanks a lot man! I saw your pull request, will comment on it.

@adamc01

This comment has been minimized.

Member

adamc01 commented May 15, 2017

Thank you for reporting this issue. We have merged your fix internally and it will be reflective in the next release.

@adamc01 adamc01 closed this May 15, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment