forked from mirrors/Fedilab
Peertube 2FA support
This commit is contained in:
parent
9fd834eb44
commit
408e51c0a6
6 changed files with 58 additions and 23 deletions
|
@ -17,18 +17,12 @@ package app.fedilab.android.peertube.activities;
|
||||||
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.updateCredential;
|
import static app.fedilab.android.peertube.client.RetrofitPeertubeAPI.updateCredential;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.text.style.ForegroundColorSpan;
|
|
||||||
import android.text.style.UnderlineSpan;
|
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.preference.PreferenceManager;
|
import androidx.preference.PreferenceManager;
|
||||||
|
@ -160,6 +154,7 @@ public class LoginActivity extends BaseBarActivity {
|
||||||
oauthParams.setClient_secret(client_secret);
|
oauthParams.setClient_secret(client_secret);
|
||||||
oauthParams.setGrant_type("password");
|
oauthParams.setGrant_type("password");
|
||||||
oauthParams.setScope("user");
|
oauthParams.setScope("user");
|
||||||
|
oauthParams.x_peertube_otp = binding.loginOtp.getText().toString().isEmpty() ? null : binding.loginOtp.getText().toString();
|
||||||
if (binding.loginUid.getText() != null) {
|
if (binding.loginUid.getText() != null) {
|
||||||
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
||||||
}
|
}
|
||||||
|
@ -169,22 +164,21 @@ public class LoginActivity extends BaseBarActivity {
|
||||||
try {
|
try {
|
||||||
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
||||||
proceedLogin(token, finalInstance);
|
proceedLogin(token, finalInstance);
|
||||||
} catch (final Exception e) {
|
|
||||||
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
|
|
||||||
Token token = null;
|
|
||||||
try {
|
|
||||||
token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
|
|
||||||
} catch (Error ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
proceedLogin(token, finalInstance);
|
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
runOnUiThread(() -> {
|
if (e.getError() != null && e.getError().contains("missing_two_factor")) {
|
||||||
Toasty.error(LoginActivity.this, e.getError() != null && !e.getError().isEmpty() ? e.getError() : getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
|
runOnUiThread(() -> {
|
||||||
binding.loginButton.setEnabled(true);
|
binding.loginOtpContainer.setVisibility(View.VISIBLE);
|
||||||
});
|
binding.loginOtp.setFocusable(true);
|
||||||
|
binding.loginOtp.requestFocus();
|
||||||
e.printStackTrace();
|
binding.loginButton.setEnabled(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
Toasty.error(LoginActivity.this, e.getError() != null && !e.getError().isEmpty() ? e.getError() : getString(R.string.toast_error), Toasty.LENGTH_SHORT).show();
|
||||||
|
binding.loginButton.setEnabled(true);
|
||||||
|
});
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,6 +122,18 @@ public interface PeertubeService {
|
||||||
@Field("password") String password,
|
@Field("password") String password,
|
||||||
@Field("externalAuthToken") String externalAuthToken);
|
@Field("externalAuthToken") String externalAuthToken);
|
||||||
|
|
||||||
|
@FormUrlEncoded
|
||||||
|
@POST("users/token")
|
||||||
|
Call<Token> otpConnetion(
|
||||||
|
@Header("x-peertube-otp") String externalAuthToken,
|
||||||
|
@Field("client_id") String client_id,
|
||||||
|
@Field("client_secret") String client_secret,
|
||||||
|
@Field("response_type") String response_type,
|
||||||
|
@Field("grant_type") String grant_type,
|
||||||
|
@Field("scope") String scope,
|
||||||
|
@Field("username") String username,
|
||||||
|
@Field("password") String password);
|
||||||
|
|
||||||
//TOKEN
|
//TOKEN
|
||||||
//Refresh
|
//Refresh
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
|
|
|
@ -267,7 +267,9 @@ public class RetrofitPeertubeAPI {
|
||||||
public Token manageToken(OauthParams oauthParams) throws Error {
|
public Token manageToken(OauthParams oauthParams) throws Error {
|
||||||
PeertubeService peertubeService = init();
|
PeertubeService peertubeService = init();
|
||||||
Call<Token> refreshTokenCall = null;
|
Call<Token> refreshTokenCall = null;
|
||||||
if (oauthParams.getGrant_type().compareTo("password") == 0) {
|
if (oauthParams.x_peertube_otp != null) {
|
||||||
|
refreshTokenCall = peertubeService.otpConnetion(oauthParams.x_peertube_otp, oauthParams.getClient_id(), oauthParams.getClient_secret(), "code", oauthParams.getGrant_type(), "upload", oauthParams.getUsername(), oauthParams.getPassword());
|
||||||
|
} else if (oauthParams.getGrant_type().compareTo("password") == 0) {
|
||||||
refreshTokenCall = peertubeService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getUsername(), oauthParams.getPassword());
|
refreshTokenCall = peertubeService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getUsername(), oauthParams.getPassword());
|
||||||
} else if (oauthParams.getGrant_type().compareTo("refresh_token") == 0) {
|
} else if (oauthParams.getGrant_type().compareTo("refresh_token") == 0) {
|
||||||
refreshTokenCall = peertubeService.refreshToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getRefresh_token(), oauthParams.getGrant_type());
|
refreshTokenCall = peertubeService.refreshToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getRefresh_token(), oauthParams.getGrant_type());
|
||||||
|
|
|
@ -44,6 +44,9 @@ public class OauthParams {
|
||||||
private String code;
|
private String code;
|
||||||
@SerializedName("redirect_uri")
|
@SerializedName("redirect_uri")
|
||||||
private String redirect_uri;
|
private String redirect_uri;
|
||||||
|
@SerializedName("x_peertube_otp")
|
||||||
|
public String x_peertube_otp;
|
||||||
|
|
||||||
|
|
||||||
public String getClient_secret() {
|
public String getClient_secret() {
|
||||||
return client_secret;
|
return client_secret;
|
||||||
|
|
4
app/src/main/res/layouts/mastodon/values/strings.xml
Normal file
4
app/src/main/res/layouts/mastodon/values/strings.xml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="otp_message">Two factor authentication token</string>
|
||||||
|
</resources>
|
|
@ -18,6 +18,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="24dp">
|
android:padding="24dp">
|
||||||
|
@ -73,6 +74,25 @@
|
||||||
android:singleLine="true" />
|
android:singleLine="true" />
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/login_otp_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:passwordToggleEnabled="true"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/login_otp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/otp_message"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="numberPassword"
|
||||||
|
android:singleLine="true" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
android:id="@+id/login_button"
|
android:id="@+id/login_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -81,6 +101,6 @@
|
||||||
android:text="@string/login"
|
android:text="@string/login"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/login_passwd_container" />
|
app:layout_constraintTop_toBottomOf="@id/login_otp_container" />
|
||||||
|
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
Loading…
Reference in a new issue