supports retype phone login challenge
This commit is contained in:
parent
bb7cdf1b53
commit
76645a6ecd
|
@ -34,8 +34,13 @@ import com.squareup.leakcanary.ServiceHeapDumpListener;
|
|||
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.activity.support.ComposeActivity;
|
||||
import org.mariotaku.twidere.util.net.NoIntercept;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/5/27.
|
||||
|
@ -45,7 +50,17 @@ public class DebugModeUtils {
|
|||
private static RefWatcher sRefWatcher;
|
||||
|
||||
public static void initForOkHttpClient(final OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new StethoInterceptor());
|
||||
final StethoInterceptor interceptor = new StethoInterceptor();
|
||||
|
||||
builder.addNetworkInterceptor(new Interceptor() {
|
||||
@Override
|
||||
public Response intercept(Chain chain) throws IOException {
|
||||
if (chain.request().tag() == NoIntercept.INSTANCE) {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
return interceptor.intercept(chain);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void initForApplication(final Application application) {
|
||||
|
|
|
@ -92,7 +92,6 @@ import org.mariotaku.twidere.util.ParseUtils;
|
|||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
import org.mariotaku.twidere.util.ThemeUtils;
|
||||
import org.mariotaku.twidere.util.TwidereActionModeForChildListener;
|
||||
import org.mariotaku.twidere.util.TwidereColorUtils;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.UserAgentUtils;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
|
@ -942,6 +941,9 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
|||
if ("Push".equalsIgnoreCase(challengeType)) {
|
||||
verificationHint.setText(R.string.login_verification_push_hint);
|
||||
editVerification.setVisibility(View.GONE);
|
||||
} else if ("RetypePhoneNumber".equalsIgnoreCase(challengeType)) {
|
||||
verificationHint.setText(R.string.login_challenge_retype_phone_hint);
|
||||
editVerification.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
verificationHint.setText(R.string.login_verification_pin_hint);
|
||||
editVerification.setVisibility(View.VISIBLE);
|
||||
|
|
|
@ -129,6 +129,8 @@ abstract class AbsUsersFragment<Data> extends AbsContentListRecyclerViewFragment
|
|||
|
||||
protected abstract boolean hasMoreData(Data data);
|
||||
|
||||
protected abstract Loader<Data> onCreateUsersLoader(Context context, Bundle args, boolean fromUser);
|
||||
protected abstract Loader<Data> onCreateUsersLoader(final Context context,
|
||||
@NonNull final Bundle args,
|
||||
final boolean fromUser);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||
|
@ -95,5 +96,5 @@ public abstract class CursorSupportUsersListFragment extends ParcelableUsersFrag
|
|||
}
|
||||
|
||||
@Override
|
||||
protected abstract BaseCursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser);
|
||||
protected abstract BaseCursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.IncomingFriendshipsLoader;
|
||||
|
@ -28,8 +29,7 @@ import org.mariotaku.twidere.loader.support.IncomingFriendshipsLoader;
|
|||
public class IncomingFriendshipsFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new IncomingFriendshipsLoader(context, accountId, getNextCursor(), getData(), fromUser);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.MutesUsersLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.MutesUsersLoader;
|
|||
public class MutesUsersListFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new MutesUsersLoader(context, account_id, getNextCursor(), getData(), fromUser);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
import org.mariotaku.twidere.adapter.iface.ILoadMoreSupportAdapter.IndicatorPosition;
|
||||
|
@ -42,7 +43,7 @@ public class SearchUsersFragment extends ParcelableUsersFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableUser>> onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public Loader<List<ParcelableUser>> onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID);
|
||||
final String query = args.getString(EXTRA_QUERY);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.StatusFavoritersLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.StatusFavoritersLoader;
|
|||
public class StatusFavoritersListFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long statusId = args.getLong(EXTRA_STATUS_ID, -1);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.IDsUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.StatusRetweetersLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.StatusRetweetersLoader;
|
|||
public class StatusRetweetersListFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public IDsUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long status_id = args.getLong(EXTRA_STATUS_ID, -1);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.UserBlocksLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.UserBlocksLoader;
|
|||
public class UserBlocksListFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
return new UserBlocksLoader(context, account_id, getNextCursor(), getData(), fromUser);
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.UserFollowersLoader;
|
||||
|
@ -53,7 +54,7 @@ public class UserFollowersFragment extends CursorSupportUsersListFragment {
|
|||
};
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.UserFriendsLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.UserFriendsLoader;
|
|||
public class UserFriendsFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long account_id = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
final long user_id = args.getLong(EXTRA_USER_ID, -1);
|
||||
|
|
|
@ -57,7 +57,7 @@ public class UserListMembersFragment extends CursorSupportUsersListFragment {
|
|||
};
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long listId = args.getLong(EXTRA_LIST_ID, -1);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mariotaku.twidere.loader.support.CursorSupportUsersLoader;
|
||||
import org.mariotaku.twidere.loader.support.UserListSubscribersLoader;
|
||||
|
@ -28,7 +29,7 @@ import org.mariotaku.twidere.loader.support.UserListSubscribersLoader;
|
|||
public class UserListSubscribersFragment extends CursorSupportUsersListFragment {
|
||||
|
||||
@Override
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public CursorSupportUsersLoader onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
final long listId = args.getLong(EXTRA_LIST_ID, -1);
|
||||
final long accountId = args.getLong(EXTRA_ACCOUNT_ID, -1);
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment.support;
|
|||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.Loader;
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class UsersListFragment extends ParcelableUsersFragment {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Loader<List<ParcelableUser>> onCreateUsersLoader(final Context context, final Bundle args, boolean fromUser) {
|
||||
public Loader<List<ParcelableUser>> onCreateUsersLoader(final Context context, @NonNull final Bundle args, boolean fromUser) {
|
||||
if (args == null) return null;
|
||||
if (args.containsKey(EXTRA_USERS))
|
||||
return new IntentExtrasUsersLoader(context, args, getData(), fromUser);
|
||||
|
|
|
@ -302,6 +302,8 @@ public class DataImportExportUtils implements Constants {
|
|||
}
|
||||
} catch (JSONException e) {
|
||||
return false;
|
||||
} catch (ClassCastException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
if (!TextUtils.isEmpty(authorizeResponseData.oauthPin)) {
|
||||
// Here we got OAuth PIN, just get access token directly
|
||||
return oauth.getAccessToken(requestToken, authorizeResponseData.oauthPin);
|
||||
} else if (authorizeResponseData.verification == null) {
|
||||
} else if (authorizeResponseData.challenge == null) {
|
||||
// No OAuth pin, or verification challenge, so treat as wrong password
|
||||
throw new WrongUserPassException();
|
||||
}
|
||||
// Go to password verification flow
|
||||
final String challengeType = authorizeResponseData.verification.challengeType;
|
||||
final String challengeType = authorizeResponseData.challenge.challengeType;
|
||||
final String loginVerification = loginVerificationCallback.getLoginVerification(challengeType);
|
||||
final AuthorizeRequestData verificationData = getVerificationData(authorizeResponseData,
|
||||
loginVerification);
|
||||
|
@ -124,7 +124,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
try {
|
||||
final AuthorizeRequestData data = new AuthorizeRequestData();
|
||||
final MultiValueMap<String> params = new MultiValueMap<>();
|
||||
final AuthorizeResponseData.Verification verification = authorizeResponseData.verification;
|
||||
final AuthorizeResponseData.Verification verification = authorizeResponseData.challenge;
|
||||
params.add("authenticity_token", verification.authenticityToken);
|
||||
params.add("user_id", verification.userId);
|
||||
params.add("challenge_id", verification.challengeId);
|
||||
|
@ -234,7 +234,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
final HtmlParsingConfiguration conf = new HtmlParsingConfiguration();
|
||||
final IAttoHandler handler = new AbstractStandardNonValidatingHtmlAttoHandler(conf) {
|
||||
boolean isOAuthPinDivOpened;
|
||||
boolean isLoginVerificationFormOpened;
|
||||
boolean isChallengeFormOpened;
|
||||
|
||||
@Override
|
||||
public void handleHtmlStandaloneElement(IHtmlElement element, boolean minimized,
|
||||
|
@ -252,7 +252,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
break;
|
||||
}
|
||||
case "form": {
|
||||
isLoginVerificationFormOpened = false;
|
||||
isChallengeFormOpened = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -263,51 +263,61 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
Map<String, String> attributes, int line, int col) {
|
||||
switch (elementName) {
|
||||
case "div": {
|
||||
if (attributes != null && "oauth_pin".equals(attributes.get("id"))) {
|
||||
if (attributes == null) break;
|
||||
if ("oauth_pin".equals(attributes.get("id"))) {
|
||||
isOAuthPinDivOpened = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "form": {
|
||||
if (attributes != null && "login-verification-form".equals(attributes.get("id"))) {
|
||||
isLoginVerificationFormOpened = true;
|
||||
if (attributes == null) break;
|
||||
final String id = attributes.get("id");
|
||||
if (id == null) break;
|
||||
switch (id) {
|
||||
case "login-verification-form":
|
||||
case "login-challenge-form": {
|
||||
isChallengeFormOpened = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "input":
|
||||
if (isLoginVerificationFormOpened && attributes != null) {
|
||||
if (attributes == null) break;
|
||||
if (isChallengeFormOpened) {
|
||||
final String name = attributes.get("name");
|
||||
if (TextUtils.isEmpty(name)) break;
|
||||
final String value = attributes.get("value");
|
||||
switch (name) {
|
||||
case "authenticity_token": {
|
||||
ensureVerification();
|
||||
data.verification.authenticityToken = value;
|
||||
data.challenge.authenticityToken = value;
|
||||
break;
|
||||
}
|
||||
case "challenge_id": {
|
||||
ensureVerification();
|
||||
data.verification.challengeId = value;
|
||||
data.challenge.challengeId = value;
|
||||
break;
|
||||
}
|
||||
case "challenge_type": {
|
||||
ensureVerification();
|
||||
data.verification.challengeType = value;
|
||||
data.challenge.challengeType = value;
|
||||
break;
|
||||
}
|
||||
case "platform": {
|
||||
ensureVerification();
|
||||
data.verification.platform = value;
|
||||
data.challenge.platform = value;
|
||||
break;
|
||||
}
|
||||
case "user_id": {
|
||||
ensureVerification();
|
||||
data.verification.userId = value;
|
||||
data.challenge.userId = value;
|
||||
break;
|
||||
}
|
||||
case "redirect_after_login": {
|
||||
ensureVerification();
|
||||
data.verification.redirectAfterLogin = value;
|
||||
data.challenge.redirectAfterLogin = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -317,8 +327,8 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
}
|
||||
|
||||
private void ensureVerification() {
|
||||
if (data.verification == null) {
|
||||
data.verification = new AuthorizeResponseData.Verification();
|
||||
if (data.challenge == null) {
|
||||
data.challenge = new AuthorizeResponseData.Verification();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,7 +494,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
|||
String referer;
|
||||
|
||||
public String oauthPin;
|
||||
public Verification verification;
|
||||
public Verification challenge;
|
||||
|
||||
static class Verification {
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
|||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.UserAgentUtils;
|
||||
import org.mariotaku.twidere.util.media.preview.PreviewMediaExtractor;
|
||||
import org.mariotaku.twidere.util.net.NoIntercept;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -130,8 +131,11 @@ public class TwidereMediaDownloader implements MediaDownloader, Constants {
|
|||
builder.method(method);
|
||||
builder.url(requestUri);
|
||||
builder.headers(additionalHeaders);
|
||||
builder.tag(NoIntercept.INSTANCE);
|
||||
final HttpResponse resp = mClient.newCall(builder.build()).execute();
|
||||
if (!resp.isSuccessful()) throw new IOException("Unable to get media, response code: " + resp.getStatus());
|
||||
if (!resp.isSuccessful()) {
|
||||
throw new IOException("Unable to get media, response code: " + resp.getStatus());
|
||||
}
|
||||
final Body body = resp.getBody();
|
||||
return new CacheDownloadLoader.DownloadResult(body.length(), body.stream());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.mariotaku.twidere.util.net;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 16/2/14.
|
||||
*/
|
||||
public class NoIntercept {
|
||||
public static final NoIntercept INSTANCE = new NoIntercept();
|
||||
}
|
|
@ -827,6 +827,7 @@
|
|||
<string name="link_copied_to_clipboard">Link copied to clipboard</string>
|
||||
<string name="login_verification">Login verification</string>
|
||||
<string name="login_verification_pin_hint">Check your phone for a PIN code and enter it to log in.</string>
|
||||
<string name="login_challenge_retype_phone_hint">Retype the phone number associated with your Twitter account.</string>
|
||||
<string name="login_verification_push_hint">Accept login verification request from Twitter app, once you approved the request, click OK.</string>
|
||||
<string name="login_verification_failed">Login verification failed.</string>
|
||||
<string name="saved_searches_already_saved_hint">Perhaps you already saved this search</string>
|
||||
|
|
Loading…
Reference in New Issue