mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-01-11 15:53:53 +01:00
implemented Push 2FA (approve request on official client)
This commit is contained in:
parent
3b16568474
commit
b720abe8b2
@ -44,7 +44,7 @@ dependencies {
|
||||
compile 'com.android.support:support-v4:23.1.0'
|
||||
compile 'com.bluelinelabs:logansquare:1.1.0'
|
||||
compile 'org.apache.commons:commons-lang3:3.4'
|
||||
compile 'com.github.mariotaku.RestFu:library:0.9.6'
|
||||
compile 'com.github.mariotaku.RestFu:library:0.9.7'
|
||||
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1'
|
||||
compile 'com.github.mariotaku:SQLiteQB:88291f3a28'
|
||||
compile 'com.github.mariotaku.LoganSquareExtension:core:b6f53c9a4d'
|
||||
|
@ -93,8 +93,8 @@ dependencies {
|
||||
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
|
||||
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1'
|
||||
compile 'com.github.mariotaku:PickNCrop:1dff3ed574'
|
||||
compile 'com.github.mariotaku.RestFu:library:0.9.6'
|
||||
compile 'com.github.mariotaku.RestFu:okhttp:0.9.6'
|
||||
compile 'com.github.mariotaku.RestFu:library:0.9.7'
|
||||
compile 'com.github.mariotaku.RestFu:okhttp:0.9.7'
|
||||
compile 'com.diogobernardino:williamchart:2.0.1'
|
||||
compile 'com.lnikkila:extendedtouchview:0.1.0'
|
||||
compile 'com.google.dagger:dagger:2.0.1'
|
||||
|
@ -56,6 +56,7 @@ import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.meizu.flyme.reflect.StatusBarProxy;
|
||||
@ -84,6 +85,7 @@ import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator;
|
||||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticationException;
|
||||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.AuthenticityTokenException;
|
||||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.LoginVerificationException;
|
||||
import org.mariotaku.twidere.util.OAuthPasswordAuthenticator.WrongUserPassException;
|
||||
import org.mariotaku.twidere.util.ParseUtils;
|
||||
import org.mariotaku.twidere.util.SharedPreferencesWrapper;
|
||||
@ -459,6 +461,8 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
Toast.makeText(this, R.string.wrong_api_key, Toast.LENGTH_SHORT).show();
|
||||
} else if (result.exception instanceof WrongUserPassException) {
|
||||
Toast.makeText(this, R.string.wrong_username_password, Toast.LENGTH_SHORT).show();
|
||||
} else if (result.exception instanceof LoginVerificationException) {
|
||||
Toast.makeText(this, R.string.login_verification_failed, Toast.LENGTH_SHORT).show();
|
||||
} else if (result.exception instanceof AuthenticationException) {
|
||||
showErrorMessage(this, getString(R.string.action_signing_in), result.exception.getCause(), true);
|
||||
} else {
|
||||
@ -790,7 +794,7 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
String challengeResponse;
|
||||
|
||||
@Override
|
||||
public String getLoginVerification() {
|
||||
public String getLoginVerification(final String challengeType) {
|
||||
// Dismiss current progress dialog
|
||||
publishProgress(new Runnable() {
|
||||
@Override
|
||||
@ -807,6 +811,7 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
public void run() {
|
||||
InputLoginVerificationDialogFragment df = new InputLoginVerificationDialogFragment();
|
||||
df.setCallback(InputLoginVerificationCallback.this);
|
||||
df.setChallengeType(challengeType);
|
||||
df.show(activity.getSupportFragmentManager(), null);
|
||||
}
|
||||
});
|
||||
@ -840,9 +845,10 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
|
||||
}
|
||||
|
||||
public static class InputLoginVerificationDialogFragment extends BaseSupportDialogFragment implements DialogInterface.OnClickListener {
|
||||
public static class InputLoginVerificationDialogFragment extends BaseSupportDialogFragment implements DialogInterface.OnClickListener, DialogInterface.OnShowListener {
|
||||
|
||||
private SignInTask.InputLoginVerificationCallback callback;
|
||||
private String challengeType;
|
||||
|
||||
public void setCallback(SignInTask.InputLoginVerificationCallback callback) {
|
||||
this.callback = callback;
|
||||
@ -862,7 +868,9 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
builder.setView(R.layout.dialog_login_verification_code);
|
||||
builder.setPositiveButton(android.R.string.ok, this);
|
||||
builder.setNegativeButton(android.R.string.cancel, this);
|
||||
return builder.create();
|
||||
final AlertDialog dialog = builder.create();
|
||||
dialog.setOnShowListener(this);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -880,6 +888,24 @@ public class SignInActivity extends BaseAppCompatActivity implements OnClickList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setChallengeType(String challengeType) {
|
||||
this.challengeType = challengeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
final AlertDialog alertDialog = (AlertDialog) dialog;
|
||||
final TextView verificationHint = (TextView) alertDialog.findViewById(R.id.verification_hint);
|
||||
final EditText editVerification = (EditText) alertDialog.findViewById(R.id.edit_verification_code);
|
||||
if ("Push".equalsIgnoreCase(challengeType)) {
|
||||
verificationHint.setText(R.string.login_verification_push_hint);
|
||||
editVerification.setVisibility(View.GONE);
|
||||
} else {
|
||||
verificationHint.setText(R.string.login_verification_pin_hint);
|
||||
editVerification.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class SignInResponse {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.squareup.okhttp.HttpUrl;
|
||||
@ -53,6 +54,7 @@ import org.mariotaku.twidere.model.RequestType;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.net.CookieManager;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -84,8 +86,8 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
}
|
||||
final String location = response.header("Location");
|
||||
final Response.Builder builder = response.newBuilder();
|
||||
if (!TextUtils.isEmpty(location)) {
|
||||
final HttpUrl originalLocation = HttpUrl.parse(location);
|
||||
if (!TextUtils.isEmpty(location) && !endpoint.checkEndpoint(location)) {
|
||||
final HttpUrl originalLocation = HttpUrl.get(URI.create("https://api.twitter.com/").resolve(location));
|
||||
final HttpUrl.Builder locationBuilder = HttpUrl.parse(endpoint.getUrl()).newBuilder();
|
||||
for (String pathSegments : originalLocation.pathSegments()) {
|
||||
locationBuilder.addPathSegment(pathSegments);
|
||||
@ -130,12 +132,14 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
throw new WrongUserPassException();
|
||||
}
|
||||
// Go to password verification flow
|
||||
final String challengeType = authorizeResponseData.verification.challengeType;
|
||||
final String loginVerification = loginVerificationCallback.getLoginVerification(challengeType);
|
||||
final AuthorizeRequestData verificationData = getVerificationData(authorizeResponseData,
|
||||
loginVerificationCallback.getLoginVerification());
|
||||
loginVerification);
|
||||
authorizeResponseData = getAuthorizeResponseData(requestToken,
|
||||
verificationData, username, password);
|
||||
if (TextUtils.isEmpty(authorizeResponseData.oauthPin)) {
|
||||
throw new VerificationCodeException();
|
||||
throw new LoginVerificationException();
|
||||
}
|
||||
return oauth.getAccessToken(requestToken, authorizeResponseData.oauthPin);
|
||||
} catch (final IOException | NullPointerException | TwitterException e) {
|
||||
@ -144,7 +148,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
}
|
||||
|
||||
private AuthorizeRequestData getVerificationData(AuthorizeResponseData authorizeResponseData,
|
||||
String challengeResponse) throws IOException, VerificationCodeException {
|
||||
@Nullable String challengeResponse) throws IOException, LoginVerificationException {
|
||||
RestHttpResponse response = null;
|
||||
try {
|
||||
final AuthorizeRequestData data = new AuthorizeRequestData();
|
||||
@ -159,7 +163,9 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
final ArrayList<Pair<String, String>> requestHeaders = new ArrayList<>();
|
||||
requestHeaders.add(Pair.create("User-Agent", userAgent));
|
||||
|
||||
params.add(Pair.create("challenge_response", challengeResponse));
|
||||
if (!TextUtils.isEmpty(challengeResponse)) {
|
||||
params.add(Pair.create("challenge_response", challengeResponse));
|
||||
}
|
||||
final FormTypedBody authorizationResultBody = new FormTypedBody(params);
|
||||
|
||||
final RestHttpRequest.Builder authorizeResultBuilder = new RestHttpRequest.Builder();
|
||||
@ -170,9 +176,12 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
authorizeResultBuilder.extra(RequestType.API);
|
||||
response = client.execute(authorizeResultBuilder.build());
|
||||
parseAuthorizeRequestData(response, data);
|
||||
if (TextUtils.isEmpty(data.authenticityToken)) {
|
||||
throw new LoginVerificationException();
|
||||
}
|
||||
return data;
|
||||
} catch (AttoParseException e) {
|
||||
throw new VerificationCodeException();
|
||||
throw new LoginVerificationException();
|
||||
} finally {
|
||||
Utils.closeSilently(response);
|
||||
}
|
||||
@ -440,7 +449,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
}
|
||||
|
||||
public interface LoginVerificationCallback {
|
||||
String getLoginVerification();
|
||||
String getLoginVerification(String challengeType);
|
||||
}
|
||||
|
||||
public static class AuthenticationException extends Exception {
|
||||
@ -469,7 +478,7 @@ public class OAuthPasswordAuthenticator implements Constants {
|
||||
|
||||
}
|
||||
|
||||
public static final class VerificationCodeException extends AuthenticationException {
|
||||
public static final class LoginVerificationException extends AuthenticationException {
|
||||
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,10 @@
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/verification_hint"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/element_spacing_normal"
|
||||
android:text="@string/login_verification_hint" />
|
||||
android:text="@string/login_verification_pin_hint" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_verification_code"
|
||||
|
@ -820,5 +820,7 @@
|
||||
<string name="copy_link">Copy link</string>
|
||||
<string name="link_copied_to_clipboard">Link copied to clipboard</string>
|
||||
<string name="login_verification">Login verification</string>
|
||||
<string name="login_verification_hint">Please check your phone for a PIN code and enter it to log in.</string>
|
||||
<string name="login_verification_pin_hint">Check your phone for a PIN code and enter it to log in.</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>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user