215 lines
7.8 KiB
Java
215 lines
7.8 KiB
Java
package space.rocketnine.xenia;
|
|
|
|
import android.app.Activity;
|
|
import android.app.AlertDialog;
|
|
import android.content.Context;
|
|
import android.content.DialogInterface;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.net.Uri;
|
|
import android.os.Bundle;
|
|
import android.text.InputType;
|
|
import android.util.Base64;
|
|
import android.util.Log;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.widget.AdapterView;
|
|
import android.widget.ArrayAdapter;
|
|
import android.widget.Button;
|
|
import android.widget.EditText;
|
|
import android.widget.ListView;
|
|
import android.widget.TextView;
|
|
import android.widget.Toast;
|
|
|
|
import java.io.IOException;
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
public class CertificatesActivity extends Activity {
|
|
String addSiteAddress = "";
|
|
Uri addSiteCertificate;
|
|
Uri addSitePrivateKey;
|
|
int requestCodeCertificate = 1965;
|
|
int requestCodePrivateKey = 1966;
|
|
ArrayAdapter<String> adapter;
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_certificates);
|
|
|
|
getActionBar().setDisplayHomeAsUpEnabled(true);
|
|
getActionBar().setDisplayShowHomeEnabled(true);
|
|
|
|
List<String> sitesList = new ArrayList<String>();
|
|
adapter = new ArrayAdapter<String>(this,
|
|
android.R.layout.simple_list_item_1, android.R.id.text1, sitesList);
|
|
|
|
updateSiteList();
|
|
|
|
ListView listView = findViewById(R.id.certificatesList);
|
|
listView.setAdapter(adapter);
|
|
|
|
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
@Override
|
|
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
|
|
String site = (String) adapterView.getItemAtPosition(position);
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(CertificatesActivity.this);
|
|
builder.setTitle("Remove certificate");
|
|
|
|
TextView tv = new TextView(CertificatesActivity.this);
|
|
tv.setText("Are you sure you want to remove the certificate for " + site + "?");
|
|
tv.setPadding(14, 14, 14, 14);
|
|
builder.setView(tv);
|
|
|
|
builder.setPositiveButton("Remove", (dialog, which) -> {
|
|
SharedPreferences prefs = getSharedPreferences("xenia", Context.MODE_PRIVATE);
|
|
|
|
Set<String> sites = prefs.getStringSet("certs", new HashSet<String>());
|
|
if (sites.contains(site)) {
|
|
sites.remove(site);
|
|
prefs.edit().putStringSet("certs", sites).apply();
|
|
}
|
|
|
|
prefs.edit().putString("cert_" + site, "").putString("key_" + site, "").apply();
|
|
|
|
updateSiteList();
|
|
|
|
Toast.makeText(CertificatesActivity.this, "Restart Xenia to apply changes", Toast.LENGTH_LONG).show();
|
|
});
|
|
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
|
|
|
builder.show();
|
|
}
|
|
});
|
|
}
|
|
|
|
private void updateSiteList() {
|
|
adapter.clear();
|
|
|
|
SharedPreferences prefs = getSharedPreferences("xenia", Context.MODE_PRIVATE);
|
|
Set<String> sites = prefs.getStringSet("certs", new HashSet<String>());
|
|
List<String> sitesList = new ArrayList<String>(sites);
|
|
|
|
adapter.addAll(sitesList);
|
|
}
|
|
|
|
private void selectCertificate(String siteAddress) {
|
|
addSiteAddress = siteAddress;
|
|
|
|
Toast.makeText(CertificatesActivity.this, "Select certificate file", Toast.LENGTH_LONG).show();
|
|
|
|
Intent intent = new Intent()
|
|
.setType("*/*")
|
|
.setAction(Intent.ACTION_GET_CONTENT);
|
|
startActivityForResult(Intent.createChooser(intent, "Select certificate file"), requestCodeCertificate);
|
|
}
|
|
|
|
private void selectPrivateKey() {
|
|
Toast.makeText(CertificatesActivity.this, "Select private key", Toast.LENGTH_LONG).show();
|
|
|
|
Intent intent = new Intent()
|
|
.setType("*/*")
|
|
.setAction(Intent.ACTION_GET_CONTENT);
|
|
startActivityForResult(Intent.createChooser(intent, "Select certificate private key"), requestCodePrivateKey);
|
|
}
|
|
|
|
private void addSite() {
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(CertificatesActivity.this);
|
|
builder.setTitle("Enter domain (without www)");
|
|
|
|
final EditText input = new EditText(this);
|
|
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
|
|
builder.setView(input);
|
|
|
|
builder.setPositiveButton("Continue", (dialog, which) -> {
|
|
// Handler is set below
|
|
});
|
|
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
|
|
|
AlertDialog dialog = builder.create();
|
|
dialog.show();
|
|
|
|
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
|
|
positiveButton.setOnClickListener(v -> {
|
|
if (input.getText().toString().isEmpty() || input.getText().toString().contains("/")) {
|
|
Toast.makeText(CertificatesActivity.this, "Please enter only the domain (no slashes)", Toast.LENGTH_LONG).show();
|
|
return;
|
|
}
|
|
|
|
selectCertificate(input.getText().toString());
|
|
dialog.dismiss();
|
|
});
|
|
}
|
|
|
|
private void finishAddingSite() {
|
|
Log.d("xenia", addSiteAddress);
|
|
Log.d("xenia", addSiteCertificate.toString());
|
|
Log.d("xenia", addSitePrivateKey.toString());
|
|
|
|
byte[] certificateData;
|
|
byte[] privateKeyData;
|
|
try {
|
|
certificateData = App.readFile(CertificatesActivity.this, addSiteCertificate);
|
|
privateKeyData = App.readFile(CertificatesActivity.this, addSitePrivateKey);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
return;
|
|
}
|
|
|
|
SharedPreferences prefs = getSharedPreferences("xenia", Context.MODE_PRIVATE);
|
|
|
|
Set<String> sites = prefs.getStringSet("certs", new HashSet<String>());
|
|
if (!sites.contains(addSiteAddress)) {
|
|
sites.add(addSiteAddress);
|
|
prefs.edit().putStringSet("sites", sites).apply();
|
|
}
|
|
|
|
prefs.edit().putString("cert_" + addSiteAddress, new String(Base64.encode(certificateData, Base64.DEFAULT))).putString("key_" + addSiteAddress, new String(Base64.encode(privateKeyData, Base64.DEFAULT))).apply();
|
|
|
|
updateSiteList();
|
|
|
|
addSiteAddress = "";
|
|
|
|
Toast.makeText(CertificatesActivity.this, "Restart Xenia to apply changes", Toast.LENGTH_LONG).show();
|
|
}
|
|
|
|
@Override
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
Log.d("xenia", "result code " + resultCode);
|
|
if (requestCode == requestCodeCertificate && resultCode == RESULT_OK) {
|
|
addSiteCertificate = data.getData();
|
|
selectPrivateKey();
|
|
} else if (requestCode == requestCodePrivateKey && resultCode == RESULT_OK) {
|
|
addSitePrivateKey = data.getData();
|
|
finishAddingSite();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
|
// Inflate the menu; this adds items to the action bar if it is present.
|
|
getMenuInflater().inflate(R.menu.menu_certificates, menu);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
switch (item.getItemId()) {
|
|
case android.R.id.home:
|
|
finish();
|
|
return true;
|
|
case R.id.navigation_add_site:
|
|
addSite();
|
|
return true;
|
|
default:
|
|
return super.onOptionsItemSelected(item);
|
|
}
|
|
}
|
|
|
|
} |