fedilab-Android-App/app/src/main/java/app/fedilab/android/activities/LoginActivity.java

820 lines
42 KiB
Java
Raw Normal View History

/* Copyright 2017 Thomas Schneider
*
2019-05-18 11:10:30 +02:00
* This file is a part of Fedilab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
2019-05-18 11:10:30 +02:00
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
2019-05-18 11:10:30 +02:00
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
* see <http://www.gnu.org/licenses>. */
2019-05-18 11:10:30 +02:00
package app.fedilab.android.activities;
2019-02-23 14:23:31 +01:00
import android.Manifest;
2021-03-02 11:59:49 +01:00
import android.annotation.SuppressLint;
2019-05-24 15:13:28 +02:00
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
2019-02-23 14:23:31 +01:00
import android.content.pm.PackageManager;
2019-02-02 19:47:21 +01:00
import android.database.sqlite.SQLiteDatabase;
2018-12-11 19:17:14 +01:00
import android.graphics.Color;
2019-11-13 12:54:01 +01:00
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.text.util.Linkify;
2018-11-03 12:06:44 +01:00
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
2018-11-03 12:06:44 +01:00
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
2018-11-03 12:06:44 +01:00
import android.widget.ImageView;
2019-02-11 10:32:36 +01:00
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
2018-11-25 10:45:16 +01:00
2019-11-15 16:32:25 +01:00
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
2019-11-16 12:12:09 +01:00
import androidx.constraintlayout.widget.ConstraintLayout;
2019-11-15 16:32:25 +01:00
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
2018-12-11 19:17:14 +01:00
import com.elconfidencial.bubbleshowcase.BubbleShowCase;
import com.elconfidencial.bubbleshowcase.BubbleShowCaseBuilder;
import com.elconfidencial.bubbleshowcase.BubbleShowCaseListener;
2019-11-15 16:32:25 +01:00
import com.google.android.material.textfield.TextInputLayout;
2018-12-11 19:17:14 +01:00
2020-03-08 09:15:12 +01:00
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
2018-11-25 10:45:16 +01:00
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
2017-11-17 19:44:27 +01:00
import java.util.HashMap;
2018-11-25 10:45:16 +01:00
import app.fedilab.android.BuildConfig;
2019-11-15 16:32:25 +01:00
import app.fedilab.android.R;
import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask;
2019-05-18 11:10:30 +02:00
import app.fedilab.android.client.API;
import app.fedilab.android.client.Entities.Account;
import app.fedilab.android.client.Entities.InstanceNodeInfo;
import app.fedilab.android.client.GNUAPI;
import app.fedilab.android.client.HttpsConnection;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.sqlite.AccountDAO;
import app.fedilab.android.sqlite.Sqlite;
2018-11-25 10:45:16 +01:00
import es.dmoral.toasty.Toasty;
/**
* Created by Thomas on 23/04/2017.
* Login activity class which handles the connection
*/
2017-12-12 18:17:01 +01:00
public class LoginActivity extends BaseActivity {
2019-11-15 16:32:25 +01:00
public static boolean admin;
private static String client_id;
private static String client_secret;
private static boolean client_id_for_webview = false;
private static String instance;
2019-11-15 16:32:25 +01:00
private final int PICK_IMPORT = 5557;
private AutoCompleteTextView login_instance;
2017-10-18 09:42:20 +02:00
private EditText login_uid;
private EditText login_passwd;
2018-08-20 19:00:20 +02:00
private String oldSearch;
2019-02-13 14:32:54 +01:00
private Button connectionButton, connect_button;
2019-01-02 19:39:40 +01:00
private String actionToken;
2019-01-29 14:08:02 +01:00
private String autofilledInstance;
2019-02-02 14:53:08 +01:00
private UpdateAccountInfoAsyncTask.SOCIAL socialNetwork;
2019-02-02 19:47:21 +01:00
private String basicAuth;
2019-02-13 14:32:54 +01:00
private InstanceNodeInfo instanceNodeInfo;
2019-11-16 12:12:09 +01:00
private ConstraintLayout step_login_credential, step_instance;
2019-02-13 14:32:54 +01:00
private TextView instance_chosen;
2019-11-16 16:48:00 +01:00
private Thread thread = null;
2019-11-15 16:32:25 +01:00
2020-03-08 09:15:12 +01:00
public static String redirectUserToAuthorizeAndLogin(Context context, String clientId, String instance) {
2019-11-15 16:32:25 +01:00
String queryString = Helper.CLIENT_ID + "=" + clientId;
queryString += "&" + Helper.REDIRECT_URI + "=" + Uri.encode(Helper.REDIRECT_CONTENT_WEB);
queryString += "&" + Helper.RESPONSE_TYPE + "=code";
if (admin) {
queryString += "&" + Helper.SCOPE + "=" + Helper.OAUTH_SCOPES_ADMIN;
} else {
queryString += "&" + Helper.SCOPE + "=" + Helper.OAUTH_SCOPES;
}
return Helper.instanceWithProtocol(context, instance) + Helper.EP_AUTHORIZE + "?" + queryString;
}
2019-02-02 19:47:21 +01:00
2021-03-02 11:59:49 +01:00
@SuppressLint("ApplySharedPref")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
2019-01-29 14:08:02 +01:00
Bundle b = getIntent().getExtras();
2019-02-02 14:53:08 +01:00
socialNetwork = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON;
2019-06-19 14:58:57 +02:00
admin = false;
2019-09-06 17:55:14 +02:00
if (b != null) {
2019-01-29 14:08:02 +01:00
autofilledInstance = b.getString("instance", null);
2019-11-15 16:32:25 +01:00
if (instanceNodeInfo != null) {
2019-11-03 15:15:52 +01:00
socialNetwork = Helper.setSoftware(instanceNodeInfo.getName(), false);
}
2019-06-19 14:58:57 +02:00
admin = b.getBoolean("admin", false);
2019-01-29 14:08:02 +01:00
}
2019-04-19 13:05:20 +02:00
2019-09-06 17:55:14 +02:00
if (getIntent() != null && getIntent().getData() != null && getIntent().getData().toString().contains("mastalab://backtomastalab?code=")) {
String url = getIntent().getData().toString();
2019-11-15 16:32:25 +01:00
String[] val = url.split("code=");
String code = val[1];
final String action = "/oauth/token";
final HashMap<String, String> parameters = new HashMap<>();
parameters.put(Helper.CLIENT_ID, client_id);
parameters.put(Helper.CLIENT_SECRET, client_secret);
2019-09-06 17:55:14 +02:00
parameters.put(Helper.REDIRECT_URI, Helper.REDIRECT_CONTENT_WEB);
parameters.put("grant_type", "authorization_code");
2019-09-06 17:55:14 +02:00
parameters.put("code", code);
2020-03-08 09:15:12 +01:00
new Thread(() -> {
try {
final String response = new HttpsConnection(LoginActivity.this, instance).post(Helper.instanceWithProtocol(LoginActivity.this, instance) + action, 30, parameters, null);
JSONObject resobj;
try {
2020-03-08 09:15:12 +01:00
resobj = new JSONObject(response);
2020-07-25 11:36:46 +02:00
String token = resobj.getString("access_token");
2020-03-08 09:15:12 +01:00
String refresh_token = null;
if (resobj.has("refresh_token"))
2020-07-25 11:36:46 +02:00
refresh_token = resobj.getString("refresh_token");
2020-03-08 09:15:12 +01:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
2020-07-25 11:36:46 +02:00
editor.commit();
2020-03-08 09:15:12 +01:00
//Update the account with the token;
2021-01-19 17:43:51 +01:00
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, client_id, client_secret, refresh_token, instance, socialNetwork);
2020-03-08 09:15:12 +01:00
} catch (JSONException e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2020-03-08 09:15:12 +01:00
} catch (Exception e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
}).start();
2020-07-08 09:48:45 +02:00
} else {
2019-05-18 11:10:30 +02:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
2019-09-06 17:55:14 +02:00
switch (theme) {
2018-05-11 11:28:05 +02:00
case Helper.THEME_LIGHT:
2019-11-09 15:47:38 +01:00
setTheme(R.style.AppTheme_Fedilab);
2018-05-11 11:28:05 +02:00
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack);
break;
default:
setTheme(R.style.AppThemeDark);
}
2018-05-11 11:28:05 +02:00
setContentView(R.layout.activity_login);
2018-11-03 12:06:44 +01:00
ActionBar actionBar = getSupportActionBar();
2019-09-06 17:55:14 +02:00
if (actionBar != null) {
2019-05-18 11:10:30 +02:00
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
2018-11-03 12:06:44 +01:00
assert inflater != null;
2019-11-20 19:07:46 +01:00
View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(LoginActivity.this), false);
2019-11-15 19:36:39 +01:00
view.setBackground(new ColorDrawable(ContextCompat.getColor(LoginActivity.this, R.color.cyanea_primary)));
2018-11-03 12:06:44 +01:00
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
TextView toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title);
2020-03-08 09:15:12 +01:00
toolbar_close.setOnClickListener(v -> finish());
2018-11-03 12:06:44 +01:00
toolbar_title.setText(R.string.add_account);
}
2019-01-02 19:39:40 +01:00
2019-11-07 20:23:07 +01:00
TextView create_an_account_message = findViewById(R.id.create_an_account);
2019-11-05 19:51:18 +01:00
TextView create_an_account_peertube = findViewById(R.id.create_an_account_peertube);
2019-09-06 17:55:14 +02:00
SpannableString content_create = new SpannableString(getString(R.string.join_mastodon));
content_create.setSpan(new UnderlineSpan(), 0, content_create.length(), 0);
2019-11-10 14:39:26 +01:00
content_create.setSpan(new ForegroundColorSpan(ContextCompat.getColor(LoginActivity.this, R.color.cyanea_accent_reference)), 0, content_create.length(),
2019-11-07 20:23:07 +01:00
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
create_an_account_message.setText(content_create);
create_an_account_message.setOnClickListener(v -> {
Intent mainActivity = new Intent(LoginActivity.this, MastodonRegisterActivity.class);
startActivity(mainActivity);
});
2019-11-05 19:51:18 +01:00
content_create = new SpannableString(getString(R.string.join_peertube));
content_create.setSpan(new UnderlineSpan(), 0, content_create.length(), 0);
2019-11-10 14:39:26 +01:00
content_create.setSpan(new ForegroundColorSpan(ContextCompat.getColor(LoginActivity.this, R.color.cyanea_accent_reference)), 0, content_create.length(),
2019-11-07 20:23:07 +01:00
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
2019-11-05 19:51:18 +01:00
create_an_account_peertube.setText(content_create);
create_an_account_peertube.setOnClickListener(v -> {
Intent mainActivity = new Intent(LoginActivity.this, PeertubeRegisterActivity.class);
startActivity(mainActivity);
});
login_instance = findViewById(R.id.login_instance);
login_uid = findViewById(R.id.login_uid);
login_passwd = findViewById(R.id.login_passwd);
2019-02-13 14:32:54 +01:00
connect_button = findViewById(R.id.connect_button);
step_login_credential = findViewById(R.id.step_login_credential);
instance_chosen = findViewById(R.id.instance_chosen);
step_instance = findViewById(R.id.step_instance);
2019-02-02 19:47:21 +01:00
connectionButton = findViewById(R.id.login_button);
2019-11-16 16:48:00 +01:00
ImageView info_instance = findViewById(R.id.info_instance);
2019-09-25 15:18:41 +02:00
ImageView main_logo = findViewById(R.id.main_logo);
2020-04-08 12:42:15 +02:00
main_logo.setImageResource(Helper.getMainLogo(LoginActivity.this));
2019-02-02 19:47:21 +01:00
socialNetwork = UpdateAccountInfoAsyncTask.SOCIAL.MASTODON;
2019-02-11 10:32:36 +01:00
//Manage instances
2020-03-08 09:15:12 +01:00
info_instance.setOnClickListener(v -> showcaseInstance(false));
2018-12-11 19:17:14 +01:00
2019-02-13 14:32:54 +01:00
2020-03-08 09:15:12 +01:00
connect_button.setOnClickListener(v -> {
if (login_instance.getText() == null || login_instance.getText().toString().length() == 0) {
TextInputLayout login_instance_layout = findViewById(R.id.login_instance_layout);
login_instance_layout.setError(getString(R.string.toast_error_instance));
login_instance_layout.setErrorEnabled(true);
return;
}
instance = login_instance.getText().toString().trim().toLowerCase();
2020-07-14 19:50:54 +02:00
if (instance.length() == 0) {
2020-07-10 17:45:14 +02:00
return;
}
2020-03-08 09:15:12 +01:00
connect_button.setEnabled(false);
new Thread(() -> {
instanceNodeInfo = new API(LoginActivity.this).displayNodeInfo(instance);
runOnUiThread(() -> {
connect_button.setEnabled(true);
if (instanceNodeInfo != null && instanceNodeInfo.getName() != null) {
socialNetwork = Helper.setSoftware(instanceNodeInfo.getName(), false);
2021-01-24 16:05:51 +01:00
if (instanceNodeInfo.getName().equals("PLEROMA") || instanceNodeInfo.getName().equals("MASTODON")) {
2020-03-08 09:15:12 +01:00
client_id_for_webview = true;
retrievesClientId();
2021-01-24 16:05:51 +01:00
} else if (instanceNodeInfo.getName().equals("PIXELFED")) {
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
i.putExtra("social", socialNetwork);
i.putExtra("instance", instance);
startActivity(i);
2020-03-08 09:15:12 +01:00
} else {
client_id_for_webview = false;
if (instanceNodeInfo.getName().equals("PEERTUBE")) {
step_login_credential.setVisibility(View.VISIBLE);
step_instance.setVisibility(View.GONE);
instance_chosen.setText(instance);
retrievesClientId();
} else if (instanceNodeInfo.getName().equals("GNU") || instanceNodeInfo.getName().equals("FRIENDICA")) {
step_login_credential.setVisibility(View.VISIBLE);
step_instance.setVisibility(View.GONE);
instance_chosen.setText(instance);
2019-09-06 17:55:14 +02:00
}
2020-03-08 09:15:12 +01:00
}
} else if (instanceNodeInfo != null && instanceNodeInfo.isConnectionError()) {
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, getString(R.string.connect_error), Toast.LENGTH_LONG).show();
2020-03-08 09:15:12 +01:00
} else {
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
2020-03-08 09:15:12 +01:00
}
});
2019-02-13 14:32:54 +01:00
2020-03-08 09:15:12 +01:00
}).start();
2018-12-11 19:17:14 +01:00
});
2018-12-11 19:17:14 +01:00
showcaseInstance(true);
2020-03-08 09:15:12 +01:00
login_instance.setOnItemClickListener((parent, view, position, id) -> oldSearch = parent.getItemAtPosition(position).toString().trim());
login_instance.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
2019-11-16 16:48:00 +01:00
if (s.length() > 2) {
final String action = "/instances/search";
final HashMap<String, String> parameters = new HashMap<>();
2019-11-16 16:48:00 +01:00
String query = s.toString().trim();
2020-03-08 10:29:06 +01:00
if (query.startsWith("http://")) {
query = query.replace("http://", "");
2019-11-16 16:48:00 +01:00
}
2020-03-08 10:29:06 +01:00
if (query.startsWith("https://")) {
query = query.replace("https://", "");
2019-11-16 16:48:00 +01:00
}
parameters.put("q", query);
2018-08-21 18:50:10 +02:00
parameters.put("count", String.valueOf(1000));
parameters.put("name", String.valueOf(true));
2020-03-08 10:29:06 +01:00
if (thread != null && thread.isAlive()) {
2019-11-16 16:48:00 +01:00
thread.interrupt();
thread = null;
}
if (oldSearch == null || !oldSearch.equals(s.toString().trim())) {
2020-03-08 09:15:12 +01:00
thread = new Thread(() -> {
try {
2021-03-02 11:59:49 +01:00
String response = null;
try {
response = new HttpsConnection(LoginActivity.this, instance).get("https://instances.social/api/1.0" + action, 30, parameters, Helper.THEKINRAR_SECRET_TOKEN);
} catch (Exception ignored) {
}
2020-03-08 10:29:06 +01:00
if (response == null) {
2020-03-08 09:15:12 +01:00
return;
}
2021-03-02 11:59:49 +01:00
String finalResponse = response;
2020-03-08 09:15:12 +01:00
runOnUiThread(() -> {
String[] instances;
try {
2021-03-02 11:59:49 +01:00
JSONObject jsonObject = new JSONObject(finalResponse);
2020-03-08 09:15:12 +01:00
JSONArray jsonArray = jsonObject.getJSONArray("instances");
int length = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@"))
length++;
}
instances = new String[length];
int j = 0;
for (int i = 0; i < jsonArray.length(); i++) {
if (!jsonArray.getJSONObject(i).get("name").toString().contains("@")) {
instances[j] = jsonArray.getJSONObject(i).get("name").toString();
j++;
}
}
2020-03-08 09:15:12 +01:00
login_instance.setAdapter(null);
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this, android.R.layout.simple_list_item_1, instances);
login_instance.setAdapter(adapter);
if (login_instance.hasFocus() && !LoginActivity.this.isFinishing())
login_instance.showDropDown();
oldSearch = s.toString().trim();
2021-02-22 17:06:38 +01:00
} catch (JSONException e) {
e.printStackTrace();
2020-03-08 09:15:12 +01:00
}
});
} catch (Exception e) {
e.printStackTrace();
}
2019-11-16 16:48:00 +01:00
});
thread.start();
}
}
}
});
2019-11-19 19:23:20 +01:00
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA)
2019-02-02 19:47:21 +01:00
connectionButton.setEnabled(false);
2020-03-08 09:15:12 +01:00
login_instance.setOnFocusChangeListener((v, hasFocus) -> {
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
connectionButton.setEnabled(false);
}
TextInputLayout login_instance_layout = findViewById(R.id.login_instance_layout);
if (!hasFocus) {
retrievesClientId();
if (login_instance.getText() == null || login_instance.getText().toString().length() == 0) {
login_instance_layout.setError(getString(R.string.toast_error_instance));
login_instance_layout.setErrorEnabled(true);
}
2020-03-08 09:15:12 +01:00
} else {
login_instance_layout.setErrorEnabled(false);
}
});
final TextView login_issue = findViewById(R.id.login_issue);
SpannableString content = new SpannableString(getString(R.string.issue_login_title));
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
login_issue.setText(content);
2020-03-08 09:15:12 +01:00
login_issue.setOnClickListener(view -> {
2018-11-03 14:45:55 +01:00
2020-03-08 09:15:12 +01:00
int style;
2019-02-13 14:32:54 +01:00
2020-03-08 09:15:12 +01:00
SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme1 = sharedpreferences1.getInt(Helper.SET_THEME, Helper.THEME_DARK);
if (theme1 == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme1 == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
2020-03-08 09:15:12 +01:00
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this, style);
builder.setTitle(R.string.issue_login_title);
TextView message = new TextView(LoginActivity.this);
final SpannableString s =
new SpannableString(getText(R.string.issue_login_message));
Linkify.addLinks(s, Linkify.WEB_URLS);
message.setText(s);
message.setPadding((int) Helper.convertDpToPixel(10, LoginActivity.this), (int) Helper.convertDpToPixel(10, LoginActivity.this), (int) Helper.convertDpToPixel(10, LoginActivity.this), (int) Helper.convertDpToPixel(10, LoginActivity.this));
message.setMovementMethod(LinkMovementMethod.getInstance());
builder.setView(message);
builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss());
builder.setIcon(android.R.drawable.ic_dialog_alert).show();
});
2019-09-06 17:55:14 +02:00
if (autofilledInstance != null) {
2019-02-13 14:32:54 +01:00
login_instance.setText(autofilledInstance.trim());
retrievesClientId();
login_uid.requestFocus();
}
2019-01-30 10:01:26 +01:00
}
}
@Override
2019-09-06 17:55:14 +02:00
protected void onResume() {
super.onResume();
2019-01-02 19:39:40 +01:00
2019-09-06 17:55:14 +02:00
if (login_instance != null && login_instance.getText() != null && login_instance.getText().toString().length() > 0 && client_id_for_webview) {
2019-02-03 09:27:02 +01:00
connectionButton.setEnabled(false);
client_id_for_webview = false;
retrievesClientId();
}
}
2019-09-06 17:55:14 +02:00
private void retrievesClientId() {
2019-11-19 19:23:20 +01:00
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
2019-02-03 09:27:02 +01:00
String instanceFromField = login_instance.getText().toString().trim();
2020-03-08 10:29:06 +01:00
if (instanceFromField.startsWith("http://")) {
instanceFromField = instanceFromField.replace("http://", "");
2019-11-16 16:48:00 +01:00
}
2020-03-08 10:29:06 +01:00
if (instanceFromField.startsWith("https://")) {
instanceFromField = instanceFromField.replace("https://", "");
2019-11-16 16:48:00 +01:00
}
2019-09-06 17:55:14 +02:00
String host = instanceFromField;
2019-02-03 09:27:02 +01:00
try {
URL url = new URL(instanceFromField);
host = url.getHost();
2021-02-22 17:06:38 +01:00
} catch (MalformedURLException e) {
e.printStackTrace();
2019-09-06 17:55:14 +02:00
}
2021-02-22 17:06:38 +01:00
2019-02-03 09:27:02 +01:00
try {
2019-09-06 17:55:14 +02:00
instance = URLEncoder.encode(host, "utf-8");
2019-02-03 09:27:02 +01:00
} catch (UnsupportedEncodingException e) {
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
2019-02-03 09:27:02 +01:00
}
2019-09-06 17:55:14 +02:00
if (socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE)
2019-02-03 09:27:02 +01:00
actionToken = "/api/v1/oauth-clients/local";
2019-02-11 10:32:36 +01:00
else
actionToken = "/api/v1/apps";
2019-02-03 09:27:02 +01:00
final HashMap<String, String> parameters = new HashMap<>();
parameters.put(Helper.CLIENT_NAME, Helper.CLIENT_NAME_VALUE);
2019-09-06 17:55:14 +02:00
parameters.put(Helper.REDIRECT_URIS, client_id_for_webview ? Helper.REDIRECT_CONTENT_WEB : Helper.REDIRECT_CONTENT);
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
if (admin) {
2019-06-19 14:58:57 +02:00
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_ADMIN);
2019-09-06 17:55:14 +02:00
} else {
2019-06-19 14:58:57 +02:00
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES);
}
2019-09-06 17:55:14 +02:00
} else {
2019-02-03 09:27:02 +01:00
parameters.put(Helper.SCOPES, Helper.OAUTH_SCOPES_PEERTUBE);
}
2019-02-03 09:27:02 +01:00
parameters.put(Helper.WEBSITE, Helper.WEBSITE_VALUE);
2020-03-08 09:15:12 +01:00
new Thread(() -> {
try {
String response;
if (socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE)
2020-04-08 12:42:15 +02:00
response = new HttpsConnection(LoginActivity.this, instance).get(Helper.instanceWithProtocol(LoginActivity.this, instance) + actionToken, 30, parameters, null);
2020-03-08 09:15:12 +01:00
else
2020-04-08 12:42:15 +02:00
response = new HttpsConnection(LoginActivity.this, instance).post(Helper.instanceWithProtocol(LoginActivity.this, instance) + actionToken, 30, parameters, null);
2020-03-08 09:15:12 +01:00
runOnUiThread(() -> {
JSONObject resobj;
try {
resobj = new JSONObject(response);
client_id = resobj.get(Helper.CLIENT_ID).toString();
client_secret = resobj.get(Helper.CLIENT_SECRET).toString();
String id = null;
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE)
id = resobj.get(Helper.ID).toString();
manageClient(client_id, client_secret, id);
} catch (JSONException e) {
e.printStackTrace();
}
});
} catch (final Exception e) {
e.printStackTrace();
2019-04-16 17:07:51 +02:00
2020-03-08 09:15:12 +01:00
runOnUiThread(() -> {
2019-04-16 17:07:51 +02:00
2020-03-08 09:15:12 +01:00
String message;
if (e.getLocalizedMessage() != null && e.getLocalizedMessage().trim().length() > 0) {
if (e.getLocalizedMessage().length() < 100) {
message = e.getLocalizedMessage();
} else {
message = getString(R.string.long_api_error, "\ud83d\ude05");
2019-02-03 09:27:02 +01:00
}
2020-03-08 09:15:12 +01:00
} else if (e.getMessage() != null && e.getMessage().trim().length() > 0) {
if (e.getLocalizedMessage().length() < 100) {
message = e.getMessage();
} else {
message = getString(R.string.long_api_error, "\ud83d\ude05");
}
} else
message = getString(R.string.client_error);
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, message, Toast.LENGTH_LONG).show();
2020-03-08 09:15:12 +01:00
});
2019-02-03 09:27:02 +01:00
}
}).start();
2019-09-06 17:55:14 +02:00
} else {
2019-02-03 09:27:02 +01:00
connectionButton.setEnabled(true);
}
2020-03-08 09:15:12 +01:00
connectionButton.setOnClickListener(v -> {
connectionButton.setEnabled(false);
if (client_id_for_webview) {
client_id_for_webview = false;
retrievesClientId();
return;
}
2017-11-17 19:44:27 +01:00
2020-03-08 09:15:12 +01:00
final HashMap<String, String> parameters = new HashMap<>();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
parameters.put(Helper.CLIENT_ID, sharedpreferences.getString(Helper.CLIENT_ID, null));
parameters.put(Helper.CLIENT_SECRET, sharedpreferences.getString(Helper.CLIENT_SECRET, null));
}
parameters.put("grant_type", "password");
try {
parameters.put("username", URLEncoder.encode(login_uid.getText().toString().trim().toLowerCase(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
parameters.put("username", login_uid.getText().toString().trim().toLowerCase());
}
try {
parameters.put("password", URLEncoder.encode(login_passwd.getText().toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
parameters.put("password", login_passwd.getText().toString());
}
String oauthUrl = null;
if (socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) {
parameters.put("scope", " read write follow");
oauthUrl = "/oauth/token";
} else if (socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
parameters.put("scope", "user");
oauthUrl = "/api/v1/users/token";
} else if (socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.GNU || socialNetwork == UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
String instanceFromField = login_instance.getText().toString().trim();
String host;
2017-12-21 13:29:51 +01:00
try {
2020-03-08 09:15:12 +01:00
URL url = new URL(instanceFromField);
host = url.getHost();
} catch (MalformedURLException e) {
host = instanceFromField;
2017-12-21 13:29:51 +01:00
}
2017-11-27 08:02:18 +01:00
try {
2020-03-08 09:15:12 +01:00
instance = URLEncoder.encode(host, "utf-8");
2021-02-22 17:06:38 +01:00
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
2020-03-08 10:29:06 +01:00
}
2020-03-08 09:15:12 +01:00
String username = login_uid.getText().toString().trim().toLowerCase();
String password = login_passwd.getText().toString();
oauthUrl = "/api/account/verify_credentials.json";
String userpass = username + ":" + password;
basicAuth = "Basic " + new String(android.util.Base64.encode(userpass.getBytes(), android.util.Base64.NO_WRAP));
}
String finalOauthUrl = oauthUrl;
new Thread(() -> {
try {
String response;
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
2020-04-08 12:42:15 +02:00
response = new HttpsConnection(LoginActivity.this, instance).post(Helper.instanceWithProtocol(LoginActivity.this, instance) + finalOauthUrl, 30, parameters, null);
2020-03-08 09:15:12 +01:00
} else {
2020-04-08 12:42:15 +02:00
response = new HttpsConnection(LoginActivity.this, instance).get(Helper.instanceWithProtocol(LoginActivity.this, instance) + finalOauthUrl, 30, null, basicAuth);
2019-02-02 19:47:21 +01:00
}
2020-03-08 09:15:12 +01:00
runOnUiThread(() -> {
JSONObject resobj;
2020-07-27 19:08:16 +02:00
if (socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.GNU && socialNetwork != UpdateAccountInfoAsyncTask.SOCIAL.FRIENDICA) {
2020-03-08 09:15:12 +01:00
try {
resobj = new JSONObject(response);
2020-07-24 19:52:36 +02:00
String token = resobj.getString("access_token");
2020-03-08 09:15:12 +01:00
String refresh_token = null;
if (resobj.has("refresh_token"))
refresh_token = resobj.getString("refresh_token");
2020-04-25 19:20:42 +02:00
SharedPreferences.Editor editor = sharedpreferences.edit();
2020-03-08 09:15:12 +01:00
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, token);
editor.apply();
2020-07-24 19:52:36 +02:00
2020-03-08 09:15:12 +01:00
//Update the account with the token;
2020-06-06 18:42:12 +02:00
if (instance != null) {
2021-01-19 17:43:51 +01:00
new UpdateAccountInfoAsyncTask(LoginActivity.this, token, client_id, client_secret, refresh_token, instance, socialNetwork);
2020-06-06 18:42:12 +02:00
} else {
connectionButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
2020-03-08 09:15:12 +01:00
} catch (JSONException e) {
e.printStackTrace();
2019-02-02 19:47:21 +01:00
}
2020-07-27 19:08:16 +02:00
} else {
2020-03-08 09:15:12 +01:00
try {
resobj = new JSONObject(response);
2020-04-25 19:20:42 +02:00
Account account = GNUAPI.parseAccountResponse(resobj);
2020-03-08 09:15:12 +01:00
account.setToken(basicAuth);
2020-04-25 19:20:42 +02:00
SharedPreferences.Editor editor = sharedpreferences.edit();
2020-03-08 09:15:12 +01:00
editor.putString(Helper.PREF_KEY_OAUTH_TOKEN, basicAuth);
account.setInstance(instance);
2020-04-09 18:57:12 +02:00
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
2020-03-08 09:15:12 +01:00
boolean userExists = new AccountDAO(LoginActivity.this, db).userExist(account);
editor.putString(Helper.PREF_KEY_ID, account.getId());
editor.putBoolean(Helper.PREF_IS_MODERATOR, account.isModerator());
editor.putBoolean(Helper.PREF_IS_ADMINISTRATOR, account.isAdmin());
editor.putString(Helper.PREF_INSTANCE, instance);
editor.apply();
2020-07-25 19:05:16 +02:00
if (userExists) {
2020-03-08 09:15:12 +01:00
new AccountDAO(LoginActivity.this, db).updateAccount(account);
2020-07-27 19:08:16 +02:00
} else {
2020-03-08 09:15:12 +01:00
if (account.getUsername() != null && account.getCreated_at() != null)
new AccountDAO(LoginActivity.this, db).insertAccount(account);
2017-11-17 19:44:27 +01:00
}
2020-03-08 09:15:12 +01:00
editor.apply();
Intent mainActivity = new Intent(LoginActivity.this, MainActivity.class);
mainActivity.putExtra(Helper.INTENT_ACTION, Helper.ADD_USER_INTENT);
startActivity(mainActivity);
finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
2020-03-08 09:15:12 +01:00
});
} catch (final Exception e) {
e.printStackTrace();
runOnUiThread(() -> {
connectionButton.setEnabled(true);
2021-01-29 18:02:32 +01:00
String message;
if (e.getLocalizedMessage() != null && e.getLocalizedMessage().trim().length() > 0)
message = e.getLocalizedMessage();
else if (e.getMessage() != null && e.getMessage().trim().length() > 0)
message = e.getMessage();
else
message = getString(R.string.client_error);
Toasty.error(LoginActivity.this, message, Toast.LENGTH_LONG).show();
2020-03-08 09:15:12 +01:00
});
}
}).start();
});
}
2019-09-06 17:55:14 +02:00
private void manageClient(String client_id, String client_secret, String id) {
2019-04-06 17:12:35 +02:00
2019-09-06 17:55:14 +02:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.putString(Helper.ID, id);
editor.apply();
connectionButton.setEnabled(true);
if (client_id_for_webview) {
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
if (embedded_browser) {
Intent i = new Intent(LoginActivity.this, WebviewConnectActivity.class);
i.putExtra("social", socialNetwork);
i.putExtra("instance", instance);
startActivity(i);
} else {
2020-04-08 12:42:15 +02:00
String url = redirectUserToAuthorizeAndLogin(LoginActivity.this, client_id, instance);
2019-09-06 17:55:14 +02:00
Helper.openBrowser(LoginActivity.this, url);
2019-04-06 17:12:35 +02:00
}
2019-09-06 17:55:14 +02:00
}
2019-04-06 17:12:35 +02:00
}
@Override
2020-03-08 09:15:12 +01:00
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_login, menu);
if (BuildConfig.lite) {
menu.findItem(R.id.action_custom_tabs).setVisible(false);
menu.findItem(R.id.action_provider).setVisible(false);
}
2019-05-18 11:10:30 +02:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
boolean embedded_browser = sharedpreferences.getBoolean(Helper.SET_EMBEDDED_BROWSER, true);
2019-02-14 10:06:18 +01:00
menu.findItem(R.id.action_custom_tabs).setChecked(!embedded_browser);
boolean security_provider = sharedpreferences.getBoolean(Helper.SET_SECURITY_PROVIDER, true);
menu.findItem(R.id.action_provider).setChecked(security_provider);
2019-11-20 19:07:46 +01:00
return true;
}
@Override
2020-07-25 11:36:46 +02:00
public boolean onOptionsItemSelected(@NotNull MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_about) {
2020-04-08 12:42:15 +02:00
Intent intent = new Intent(LoginActivity.this, AboutActivity.class);
startActivity(intent);
2019-09-06 17:55:14 +02:00
} else if (id == R.id.action_privacy) {
2020-04-08 12:42:15 +02:00
Intent intent = new Intent(LoginActivity.this, PrivacyActivity.class);
startActivity(intent);
2019-09-06 17:55:14 +02:00
} else if (id == R.id.action_proxy) {
2020-04-08 12:42:15 +02:00
Intent intent = new Intent(LoginActivity.this, ProxyActivity.class);
2018-01-20 09:46:28 +01:00
startActivity(intent);
2019-09-06 17:55:14 +02:00
} else if (id == R.id.action_custom_tabs) {
item.setChecked(!item.isChecked());
2019-05-18 11:10:30 +02:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_EMBEDDED_BROWSER, !item.isChecked());
editor.apply();
return false;
2019-09-06 17:55:14 +02:00
} else if (id == R.id.action_provider) {
2019-02-14 10:06:18 +01:00
item.setChecked(!item.isChecked());
2019-05-18 11:10:30 +02:00
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
2019-02-14 10:06:18 +01:00
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean(Helper.SET_SECURITY_PROVIDER, item.isChecked());
editor.apply();
return false;
2019-09-06 17:55:14 +02:00
} else if (id == R.id.action_import_data) {
2019-11-03 09:49:35 +01:00
if (ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(LoginActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
TootActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
return true;
2019-02-23 14:23:31 +01:00
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
2019-03-14 10:44:33 +01:00
intent.addCategory(Intent.CATEGORY_OPENABLE);
2021-02-22 17:06:38 +01:00
intent.setType("*/*");
String[] mimetypes = {"*/*"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
startActivityForResult(intent, PICK_IMPORT);
}
return super.onOptionsItemSelected(item);
}
2019-02-23 14:23:31 +01:00
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
2019-05-18 11:10:30 +02:00
if (requestCode == PICK_IMPORT && resultCode == RESULT_OK) {
2019-02-23 14:23:31 +01:00
if (data == null || data.getData() == null) {
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, getString(R.string.toot_select_file_error), Toast.LENGTH_LONG).show();
2019-02-23 14:23:31 +01:00
return;
}
2020-04-08 12:42:15 +02:00
String filename = Helper.getFilePathFromURI(LoginActivity.this, data.getData());
2019-05-18 11:10:30 +02:00
Sqlite.importDB(LoginActivity.this, filename);
2019-09-06 17:55:14 +02:00
} else {
2020-04-08 12:42:15 +02:00
Toasty.error(LoginActivity.this, getString(R.string.toot_select_file_error), Toast.LENGTH_LONG).show();
2019-02-23 14:23:31 +01:00
}
}
2019-09-06 17:55:14 +02:00
private void showcaseInstance(final boolean loop) {
2018-12-11 19:17:14 +01:00
BubbleShowCaseBuilder showCaseBuilder = new BubbleShowCaseBuilder(LoginActivity.this)
.title(getString(R.string.instance))
.description(getString(R.string.showcase_instance))
2019-02-12 08:58:33 +01:00
.arrowPosition(BubbleShowCase.ArrowPosition.BOTTOM)
2018-12-11 19:17:14 +01:00
.backgroundColor(ContextCompat.getColor(LoginActivity.this, R.color.mastodonC4))
.textColor(Color.WHITE)
2019-02-12 08:58:33 +01:00
.titleTextSize(14)
.descriptionTextSize(12);
2019-09-06 17:55:14 +02:00
if (loop)
showCaseBuilder.showOnce("BUBBLE_SHOW_CASE_INSTANCE_ID");
showCaseBuilder.listener(new BubbleShowCaseListener() {
@Override
2020-03-08 09:15:12 +01:00
public void onTargetClick(@NotNull BubbleShowCase bubbleShowCase) {
2019-09-06 17:55:14 +02:00
if (loop) {
bubbleShowCase.finishSequence();
}
}
2020-03-08 10:29:06 +01:00
2019-09-06 17:55:14 +02:00
@Override
2020-03-08 09:15:12 +01:00
public void onCloseActionImageClick(@NotNull BubbleShowCase bubbleShowCase) {
2019-09-06 17:55:14 +02:00
if (loop) {
bubbleShowCase.finishSequence();
}
}
2020-03-08 10:29:06 +01:00
2019-09-06 17:55:14 +02:00
@Override
2020-03-08 09:15:12 +01:00
public void onBubbleClick(@NotNull BubbleShowCase bubbleShowCase) {
2019-09-06 17:55:14 +02:00
}
2020-03-08 10:29:06 +01:00
2019-09-06 17:55:14 +02:00
@Override
2020-03-08 09:15:12 +01:00
public void onBackgroundDimClick(@NotNull BubbleShowCase bubbleShowCase) {
2019-09-06 17:55:14 +02:00
}
})
.targetView(login_instance)
.show();
2018-12-11 19:17:14 +01:00
}
}