Commit 30254dde authored by Tiago Cunha's avatar Tiago Cunha

2FA worked out

parent 3671697f
......@@ -84,7 +84,7 @@ public class MethodCallHelper {
if (TextUtils.isEmpty(errMessageJson)) {
return Task.forError(exception);
}
String errType = new JSONObject(errMessageJson).getString("error");
String errType = new JSONObject(errMessageJson).optString("error");
String errMessage = new JSONObject(errMessageJson).getString("message");
if (TwoStepAuthException.TYPE.equals(errType)) {
......@@ -220,6 +220,33 @@ public class MethodCallHelper {
});
}
public Task<Void> twoStepCodeLogin(final String usernameOrEmail, final String password,
final String twoStepCode) {
return call("login", TIMEOUT_MS, () -> {
JSONObject loginParam = new JSONObject();
if (Patterns.EMAIL_ADDRESS.matcher(usernameOrEmail).matches()) {
loginParam.put("user", new JSONObject().put("email", usernameOrEmail));
} else {
loginParam.put("user", new JSONObject().put("username", usernameOrEmail));
}
loginParam.put("password", new JSONObject()
.put("digest", CheckSum.sha256(password))
.put("algorithm", "sha-256"));
JSONObject twoStepParam = new JSONObject();
twoStepParam.put("login", loginParam);
twoStepParam.put("code", twoStepCode);
JSONObject param = new JSONObject();
param.put("totp", twoStepParam);
return new JSONArray().put(param);
}).onSuccessTask(CONVERT_TO_JSON_OBJECT)
.onSuccessTask(task -> Task.forResult(task.getResult().getString("token")))
.onSuccessTask(this::saveToken);
}
/**
* Logout.
*/
......
......@@ -26,6 +26,8 @@ public class LoginFragment extends AbstractServerConfigFragment implements Login
private View btnEmail;
private View waitingView;
private TextView txtUsername;
private TextView txtPasswd;
@Override
protected int getLayout() {
......@@ -46,8 +48,8 @@ public class LoginFragment extends AbstractServerConfigFragment implements Login
@Override
protected void onSetupView() {
btnEmail = rootView.findViewById(R.id.btn_login_with_email);
final TextView txtUsername = (TextView) rootView.findViewById(R.id.editor_username);
final TextView txtPasswd = (TextView) rootView.findViewById(R.id.editor_passwd);
txtUsername = (TextView) rootView.findViewById(R.id.editor_username);
txtPasswd = (TextView) rootView.findViewById(R.id.editor_passwd);
waitingView = rootView.findViewById(R.id.waiting);
btnEmail.setOnClickListener(
view -> presenter.login(txtUsername.getText().toString(), txtPasswd.getText().toString()));
......@@ -117,7 +119,9 @@ public class LoginFragment extends AbstractServerConfigFragment implements Login
@Override
public void showTwoStepAuth() {
showFragmentWithBackStack(TwoStepAuthFragment.create(hostname));
showFragmentWithBackStack(TwoStepAuthFragment.create(
hostname, txtUsername.getText().toString(), txtPasswd.getText().toString()
));
}
@Override
......
package chat.rocket.android.fragment.server_config;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.api.MethodCallHelper;
public class TwoStepAuthFragment extends AbstractServerConfigFragment
implements TwoStepAuthContract.View {
private static final String ARG_USERNAME_OR_EMAIL = "usernameOrEmail";
private static final String ARG_PASSWORD = "password";
private View waitingView;
private View submitButton;
private TwoStepAuthContract.Presenter presenter;
public static TwoStepAuthFragment create(String hostname) {
public static TwoStepAuthFragment create(String hostname, String usernameOrEmail,
String password) {
Bundle args = new Bundle();
args.putString(AbstractServerConfigFragment.KEY_HOSTNAME, hostname);
args.putString(ARG_USERNAME_OR_EMAIL, usernameOrEmail);
args.putString(ARG_PASSWORD, password);
TwoStepAuthFragment fragment = new TwoStepAuthFragment();
fragment.setArguments(args);
......@@ -23,16 +33,51 @@ public class TwoStepAuthFragment extends AbstractServerConfigFragment
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args == null || !args.containsKey(ARG_USERNAME_OR_EMAIL) || !args
.containsKey(ARG_PASSWORD)) {
finish();
return;
}
presenter = new TwoStepAuthPresenter(
new MethodCallHelper(getContext(), hostname),
args.getString(ARG_USERNAME_OR_EMAIL),
args.getString(ARG_PASSWORD)
);
}
@Override
public void onResume() {
super.onResume();
presenter.bindView(this);
}
@Override
public void onPause() {
presenter.release();
super.onPause();
}
@Override
public void showLoading() {
submitButton.setEnabled(false);
waitingView.setVisibility(View.VISIBLE);
}
@Override
public void hideLoading() {
waitingView.setVisibility(View.GONE);
submitButton.setEnabled(true);
}
@Override
public void showError(String message) {
Snackbar.make(rootView, message, Snackbar.LENGTH_LONG).show();
}
@Override
......@@ -46,7 +91,9 @@ public class TwoStepAuthFragment extends AbstractServerConfigFragment
final TextView twoStepCodeTextView = (TextView) rootView.findViewById(R.id.two_step_code);
final View submit = rootView.findViewById(R.id.btn_two_step_login);
submit.setOnClickListener(view -> {});
submitButton = rootView.findViewById(R.id.btn_two_step_login);
submitButton.setOnClickListener(view -> {
presenter.onCode(twoStepCodeTextView.getText().toString());
});
}
}
package chat.rocket.android.fragment.server_config;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.shared.BasePresenter;
public class TwoStepAuthPresenter extends BasePresenter<TwoStepAuthContract.View>
implements TwoStepAuthContract.Presenter {
private final MethodCallHelper methodCallHelper;
private final String usernameOrEmail;
private final String password;
public TwoStepAuthPresenter(MethodCallHelper methodCallHelper, String usernameOrEmail,
String password) {
this.methodCallHelper = methodCallHelper;
this.usernameOrEmail = usernameOrEmail;
this.password = password;
}
@Override
public void onCode(String twoStepAuthCode) {
view.showLoading();
methodCallHelper.twoStepCodeLogin(usernameOrEmail, password, twoStepAuthCode)
.continueWith(task -> {
if (task.isFaulted()) {
view.hideLoading();
view.showError(task.getError().getMessage());
}
return null;
});
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment