Use an dialog to show advanced settings

This commit is contained in:
Jannis Mattheis
2018-11-10 14:42:05 +01:00
committed by Galen Abell
parent 78a7f1319e
commit bcfa8ac221
5 changed files with 185 additions and 19 deletions

View File

@@ -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);
}
}
}

View File

@@ -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);

View 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>

View File

@@ -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>

View 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>