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.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
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.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
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.Log;
|
||||||
import com.github.gotify.log.UncaughtExceptionHandler;
|
import com.github.gotify.log.UncaughtExceptionHandler;
|
||||||
import com.squareup.okhttp.HttpUrl;
|
import com.squareup.okhttp.HttpUrl;
|
||||||
import java.io.*;
|
import java.io.InputStream;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
@@ -55,8 +61,8 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
@BindView(R.id.sslGroup)
|
@BindView(R.id.sslGroup)
|
||||||
LinearLayout sslGroup;
|
LinearLayout sslGroup;
|
||||||
|
|
||||||
@BindView(R.id.showAdvanced)
|
@BindView(R.id.advanced_settings)
|
||||||
Button toggleAdvanced;
|
ImageView toggleAdvanced;
|
||||||
|
|
||||||
@BindView(R.id.disableValidateSSL)
|
@BindView(R.id.disableValidateSSL)
|
||||||
CheckBox disableSSLValidationCheckBox;
|
CheckBox disableSSLValidationCheckBox;
|
||||||
@@ -88,6 +94,8 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private boolean disableSSLValidation;
|
private boolean disableSSLValidation;
|
||||||
private String caCertContents;
|
private String caCertContents;
|
||||||
|
private AlertDialog advancedSettingsDialog;
|
||||||
|
private AdvancedDialog advancedDialog;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -101,6 +109,10 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@OnTextChanged(R.id.gotify_url)
|
@OnTextChanged(R.id.gotify_url)
|
||||||
public void onUrlChange() {
|
public void onUrlChange() {
|
||||||
|
invalidateUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void invalidateUrl() {
|
||||||
usernameField.setVisibility(View.GONE);
|
usernameField.setVisibility(View.GONE);
|
||||||
passwordField.setVisibility(View.GONE);
|
passwordField.setVisibility(View.GONE);
|
||||||
loginButton.setVisibility(View.GONE);
|
loginButton.setVisibility(View.GONE);
|
||||||
@@ -129,13 +141,29 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
.handleInUIThread(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl));
|
.handleInUIThread(this, onValidUrl(fixedUrl), onInvalidUrl(fixedUrl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.showAdvanced)
|
@OnClick(R.id.advanced_settings)
|
||||||
void toggleShowAdvanced() {
|
void toggleShowAdvanced() {
|
||||||
showAdvanced = !showAdvanced;
|
String selectedCertName =
|
||||||
disableSSLValidationCheckBox.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
caCertContents != null ? getNameOfCertContent(caCertContents) : null;
|
||||||
selectCACertificate.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
|
||||||
orTextView.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
advancedDialog =
|
||||||
caFileName.setVisibility(showAdvanced ? View.VISIBLE : View.GONE);
|
new AdvancedDialog(this)
|
||||||
|
.onDisableSSLChanged(
|
||||||
|
(ignored, disable) -> {
|
||||||
|
invalidateUrl();
|
||||||
|
disableSSLValidation = disable;
|
||||||
|
})
|
||||||
|
.onClickSelectCaCertificate(
|
||||||
|
() -> {
|
||||||
|
invalidateUrl();
|
||||||
|
doSelectCACertificate();
|
||||||
|
})
|
||||||
|
.onClickRemoveCaCertificate(
|
||||||
|
() -> {
|
||||||
|
invalidateUrl();
|
||||||
|
caCertContents = null;
|
||||||
|
})
|
||||||
|
.show(disableSSLValidation, selectedCertName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnCheckedChanged(R.id.disableValidateSSL)
|
@OnCheckedChanged(R.id.disableValidateSSL)
|
||||||
@@ -182,12 +210,12 @@ public class LoginActivity extends AppCompatActivity {
|
|||||||
throw new IllegalArgumentException("file path was invalid");
|
throw new IllegalArgumentException("file path was invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
String contents = Utils.readFileFromStream(fileStream);
|
String content = Utils.readFileFromStream(fileStream);
|
||||||
Certificate ca = CertUtils.parseCertificate(contents);
|
String name = getNameOfCertContent(content);
|
||||||
|
|
||||||
caFileName.setText(((X509Certificate) ca).getSubjectDN().getName());
|
|
||||||
// temporarily set the contents (don't store to settings until they decide to login)
|
// temporarily set the contents (don't store to settings until they decide to login)
|
||||||
caCertContents = contents;
|
caCertContents = content;
|
||||||
|
advancedDialog.showRemoveCACertificate(name);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Utils.showSnackBar(
|
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) {
|
private Callback.SuccessCallback<VersionInfo> onValidUrl(String url) {
|
||||||
return (version) -> {
|
return (version) -> {
|
||||||
settings.url(url);
|
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:id="@+id/checkurl"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
app:layout_constraintWidth_max="280dp"
|
|
||||||
android:background="@color/colorPrimaryDark"
|
android:background="@color/colorPrimaryDark"
|
||||||
android:text="@string/check_url"
|
android:text="@string/check_url"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toStartOf="@+id/advanced_settings"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="@+id/gotify_url"
|
||||||
app:layout_constraintTop_toBottomOf="@+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>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</ScrollView>
|
</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