Use an dialog to show advanced settings
This commit is contained in:
committed by
Galen Abell
parent
78a7f1319e
commit
bcfa8ac221
@@ -0,0 +1,96 @@
|
||||
package com.github.gotify.login;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import com.github.gotify.R;
|
||||
|
||||
class AdvancedDialog {
|
||||
|
||||
private Context context;
|
||||
private ViewHolder holder;
|
||||
private CompoundButton.OnCheckedChangeListener onCheckedChangeListener;
|
||||
private Runnable onClickSelectCaCertificate;
|
||||
private Runnable onClickRemoveCaCertificate;
|
||||
|
||||
AdvancedDialog(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
AdvancedDialog onDisableSSLChanged(
|
||||
CompoundButton.OnCheckedChangeListener onCheckedChangeListener) {
|
||||
this.onCheckedChangeListener = onCheckedChangeListener;
|
||||
return this;
|
||||
}
|
||||
|
||||
AdvancedDialog onClickSelectCaCertificate(Runnable onClickSelectCaCertificate) {
|
||||
this.onClickSelectCaCertificate = onClickSelectCaCertificate;
|
||||
return this;
|
||||
}
|
||||
|
||||
AdvancedDialog onClickRemoveCaCertificate(Runnable onClickRemoveCaCertificate) {
|
||||
this.onClickRemoveCaCertificate = onClickRemoveCaCertificate;
|
||||
return this;
|
||||
}
|
||||
|
||||
AdvancedDialog show(boolean disableSSL, @Nullable String selectedCertificate) {
|
||||
|
||||
View dialogView =
|
||||
LayoutInflater.from(context).inflate(R.layout.advanced_settings_dialog, null);
|
||||
holder = new ViewHolder(dialogView);
|
||||
holder.disableSSL.setChecked(disableSSL);
|
||||
holder.disableSSL.setOnCheckedChangeListener(onCheckedChangeListener);
|
||||
|
||||
if (selectedCertificate == null) {
|
||||
showSelectCACertificate();
|
||||
} else {
|
||||
showRemoveCACertificate(selectedCertificate);
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(context)
|
||||
.setView(dialogView)
|
||||
.setTitle("Advanced Settings")
|
||||
.setPositiveButton("Done", (ignored, ignored2) -> {})
|
||||
.show();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void showSelectCACertificate() {
|
||||
holder.toggleCaCert.setText("Select CA Certificate");
|
||||
holder.toggleCaCert.setOnClickListener((a) -> onClickSelectCaCertificate.run());
|
||||
holder.selectedCaCertificate.setText("No certificate selected");
|
||||
}
|
||||
|
||||
void showRemoveCACertificate(String certificate) {
|
||||
holder.toggleCaCert.setText("Remove CA Certificate");
|
||||
holder.toggleCaCert.setOnClickListener(
|
||||
(a) -> {
|
||||
showSelectCACertificate();
|
||||
onClickRemoveCaCertificate.run();
|
||||
});
|
||||
holder.selectedCaCertificate.setText(certificate);
|
||||
}
|
||||
|
||||
class ViewHolder {
|
||||
@BindView(R.id.disableSSL)
|
||||
CheckBox disableSSL;
|
||||
|
||||
@BindView(R.id.toggle_ca_cert)
|
||||
Button toggleCaCert;
|
||||
|
||||
@BindView(R.id.seleceted_ca_cert)
|
||||
TextView selectedCaCertificate;
|
||||
|
||||
ViewHolder(View view) {
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,13 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.*;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
@@ -34,7 +40,7 @@ import com.github.gotify.init.InitializationActivity;
|
||||
import com.github.gotify.log.Log;
|
||||
import com.github.gotify.log.UncaughtExceptionHandler;
|
||||
import com.squareup.okhttp.HttpUrl;
|
||||
import java.io.*;
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
@@ -55,8 +61,8 @@ public class LoginActivity extends AppCompatActivity {
|
||||
@BindView(R.id.sslGroup)
|
||||
LinearLayout sslGroup;
|
||||
|
||||
@BindView(R.id.showAdvanced)
|
||||
Button toggleAdvanced;
|
||||
@BindView(R.id.advanced_settings)
|
||||
ImageView toggleAdvanced;
|
||||
|
||||
@BindView(R.id.disableValidateSSL)
|
||||
CheckBox disableSSLValidationCheckBox;
|
||||
@@ -88,6 +94,8 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
private boolean disableSSLValidation;
|
||||
private String caCertContents;
|
||||
private AlertDialog advancedSettingsDialog;
|
||||
private AdvancedDialog advancedDialog;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -101,6 +109,10 @@ public class LoginActivity extends AppCompatActivity {
|
||||
|
||||
@OnTextChanged(R.id.gotify_url)
|
||||
public void onUrlChange() {
|
||||
invalidateUrl();
|
||||
}
|
||||
|
||||
private void invalidateUrl() {
|
||||
usernameField.setVisibility(View.GONE);
|
||||
passwordField.setVisibility(View.GONE);
|
||||
loginButton.setVisibility(View.GONE);
|
||||
@@ -129,13 +141,29 @@ public class LoginActivity extends AppCompatActivity {
|
||||
.handleInUIThread(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl));
|
||||
}
|
||||
|
||||
@OnClick(R.id.showAdvanced)
|
||||
@OnClick(R.id.advanced_settings)
|
||||
void toggleShowAdvanced() {
|
||||
showAdvanced = !showAdvanced;
|
||||
disableSSLValidationCheckBox.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
selectCACertificate.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
orTextView.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
caFileName.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
||||
String selectedCertName =
|
||||
caCertContents != null ? getNameOfCertContent(caCertContents) : null;
|
||||
|
||||
advancedDialog =
|
||||
new AdvancedDialog(this)
|
||||
.onDisableSSLChanged(
|
||||
(ignored, disable) -> {
|
||||
invalidateUrl();
|
||||
disableSSLValidation = disable;
|
||||
})
|
||||
.onClickSelectCaCertificate(
|
||||
() -> {
|
||||
invalidateUrl();
|
||||
doSelectCACertificate();
|
||||
})
|
||||
.onClickRemoveCaCertificate(
|
||||
() -> {
|
||||
invalidateUrl();
|
||||
caCertContents = null;
|
||||
})
|
||||
.show(disableSSLValidation, selectedCertName);
|
||||
}
|
||||
|
||||
@OnCheckedChanged(R.id.disableValidateSSL)
|
||||
@@ -182,12 +210,12 @@ public class LoginActivity extends AppCompatActivity {
|
||||
throw new IllegalArgumentException("file path was invalid");
|
||||
}
|
||||
|
||||
String contents = Utils.readFileFromStream(fileStream);
|
||||
Certificate ca = CertUtils.parseCertificate(contents);
|
||||
String content = Utils.readFileFromStream(fileStream);
|
||||
String name = getNameOfCertContent(content);
|
||||
|
||||
caFileName.setText(((X509Certificate) ca).getSubjectDN().getName());
|
||||
// temporarily set the contents (don't store to settings until they decide to login)
|
||||
caCertContents = contents;
|
||||
caCertContents = content;
|
||||
advancedDialog.showRemoveCACertificate(name);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Utils.showSnackBar(
|
||||
@@ -195,6 +223,11 @@ public class LoginActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private String getNameOfCertContent(String content) {
|
||||
Certificate ca = CertUtils.parseCertificate(content);
|
||||
return ((X509Certificate) ca).getSubjectDN().getName();
|
||||
}
|
||||
|
||||
private Callback.SuccessCallback<VersionInfo> onValidUrl(String url) {
|
||||
return (version) -> {
|
||||
settings.url(url);
|
||||
|
||||
4
app/src/main/res/drawable/ic_settings.xml
Normal file
4
app/src/main/res/drawable/ic_settings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<vector android:height="24dp" android:viewportHeight="20"
|
||||
android:viewportWidth="20" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M15.95,10.78c0.03,-0.25 0.05,-0.51 0.05,-0.78s-0.02,-0.53 -0.06,-0.78l1.69,-1.32c0.15,-0.12 0.19,-0.34 0.1,-0.51l-1.6,-2.77c-0.1,-0.18 -0.31,-0.24 -0.49,-0.18l-1.99,0.8c-0.42,-0.32 -0.86,-0.58 -1.35,-0.78L12,2.34c-0.03,-0.2 -0.2,-0.34 -0.4,-0.34H8.4c-0.2,0 -0.36,0.14 -0.39,0.34l-0.3,2.12c-0.49,0.2 -0.94,0.47 -1.35,0.78l-1.99,-0.8c-0.18,-0.07 -0.39,0 -0.49,0.18l-1.6,2.77c-0.1,0.18 -0.06,0.39 0.1,0.51l1.69,1.32c-0.04,0.25 -0.07,0.52 -0.07,0.78s0.02,0.53 0.06,0.78L2.37,12.1c-0.15,0.12 -0.19,0.34 -0.1,0.51l1.6,2.77c0.1,0.18 0.31,0.24 0.49,0.18l1.99,-0.8c0.42,0.32 0.86,0.58 1.35,0.78l0.3,2.12c0.04,0.2 0.2,0.34 0.4,0.34h3.2c0.2,0 0.37,-0.14 0.39,-0.34l0.3,-2.12c0.49,-0.2 0.94,-0.47 1.35,-0.78l1.99,0.8c0.18,0.07 0.39,0 0.49,-0.18l1.6,-2.77c0.1,-0.18 0.06,-0.39 -0.1,-0.51l-1.67,-1.32zM10,13c-1.65,0 -3,-1.35 -3,-3s1.35,-3 3,-3 3,1.35 3,3 -1.35,3 -3,3z"/>
|
||||
</vector>
|
||||
@@ -202,17 +202,26 @@
|
||||
android:id="@+id/checkurl"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintWidth_max="280dp"
|
||||
android:background="@color/colorPrimaryDark"
|
||||
android:text="@string/check_url"
|
||||
android:textColor="@android:color/white"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/gotify_url" />
|
||||
app:layout_constraintEnd_toStartOf="@+id/advanced_settings"
|
||||
app:layout_constraintStart_toStartOf="@+id/gotify_url"
|
||||
app:layout_constraintTop_toBottomOf="@+id/gotify_url"
|
||||
app:layout_constraintWidth_max="280dp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/advanced_settings"
|
||||
style="@style/Widget.AppCompat.Button.Borderless"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/check_url"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintEnd_toEndOf="@+id/gotify_url"
|
||||
app:layout_constraintTop_toTopOf="@+id/checkurl"
|
||||
app:srcCompat="@drawable/ic_settings" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
|
||||
24
app/src/main/res/layout/advanced_settings_dialog.xml
Normal file
24
app/src/main/res/layout/advanced_settings_dialog.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="20dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/disableSSL"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Disable SSL Validation" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/toggle_ca_cert"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Select CA Certificate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/seleceted_ca_cert"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="No Certificate selected" />
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user