commit
7517c65075
16 changed files with 469 additions and 34 deletions
|
@ -32,7 +32,7 @@ dependencies {
|
|||
compile 'com.jcraft:jsch:0.1.52'
|
||||
compile 'org.apache.commons:commons-io:1.3.2'
|
||||
compile 'com.jayway.android.robotium:robotium-solo:5.3.1'
|
||||
compile 'com.melnykov:floatingactionbutton:1.2.0'
|
||||
compile 'com.android.support:design:22.2.0'
|
||||
compile 'net.rdrei.android.dirchooser:library:2.1@aar'
|
||||
compile group: 'com.google.guava', name: 'guava', version: '18.0'
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||
</activity>
|
||||
|
||||
<activity android:name=".SshKeyGen"
|
||||
android:parentActivityName=".PasswordStore">
|
||||
|
||||
<meta-data android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="net.rdrei.android.dirchooser.DirectoryChooserActivity" />
|
||||
</application>
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.app.Fragment;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
@ -13,7 +14,6 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.melnykov.fab.FloatingActionButton;
|
||||
import com.zeapo.pwdstore.utils.PasswordItem;
|
||||
import com.zeapo.pwdstore.utils.PasswordRecyclerAdapter;
|
||||
import com.zeapo.pwdstore.utils.PasswordRepository;
|
||||
|
@ -77,8 +77,13 @@ public class PasswordFragment extends Fragment{
|
|||
// // Set the adapter
|
||||
recyclerView.setAdapter(recyclerAdapter);
|
||||
|
||||
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab);
|
||||
fab.attachToRecyclerView(recyclerView);
|
||||
final FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
((PasswordStore) getActivity()).createPassword();
|
||||
}
|
||||
});
|
||||
|
||||
registerForContextMenu(recyclerView);
|
||||
return view;
|
||||
|
|
|
@ -326,7 +326,7 @@ public class PasswordStore extends AppCompatActivity {
|
|||
startActivityForResult(intent, PgpHandler.REQUEST_CODE_DECRYPT_AND_VERIFY);
|
||||
}
|
||||
|
||||
public void createPassword(View v) {
|
||||
public void createPassword() {
|
||||
if (!PasswordRepository.isInitialized()) {
|
||||
new AlertDialog.Builder(this)
|
||||
.setMessage(this.getResources().getString(R.string.creation_dialog_text))
|
||||
|
|
231
app/src/main/java/com/zeapo/pwdstore/SshKeyGen.java
Normal file
231
app/src/main/java/com/zeapo/pwdstore/SshKeyGen.java
Normal file
|
@ -0,0 +1,231 @@
|
|||
package com.zeapo.pwdstore;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.KeyPair;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class SshKeyGen extends AppCompatActivity {
|
||||
|
||||
// SSH key generation UI
|
||||
public static class SshKeyGenFragment extends Fragment {
|
||||
public SshKeyGenFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
final View v = inflater.inflate(R.layout.fragment_ssh_keygen, container, false);
|
||||
Typeface monoTypeface = Typeface.createFromAsset(getActivity().getAssets(), "fonts/sourcecodepro.ttf");
|
||||
|
||||
Spinner spinner = (Spinner) v.findViewById(R.id.length);
|
||||
Integer[] lengths = new Integer[]{2048, 4096};
|
||||
ArrayAdapter<Integer> adapter = new ArrayAdapter<>(getActivity(),
|
||||
android.R.layout.simple_spinner_dropdown_item, lengths);
|
||||
spinner.setAdapter(adapter);
|
||||
|
||||
((EditText) v.findViewById(R.id.passphrase)).setTypeface(monoTypeface);
|
||||
|
||||
CheckBox checkbox = (CheckBox) v.findViewById(R.id.show_passphrase);
|
||||
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
EditText editText = (EditText) v.findViewById(R.id.passphrase);
|
||||
int selection = editText.getSelectionEnd();
|
||||
if (isChecked) {
|
||||
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
|
||||
} else {
|
||||
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
}
|
||||
editText.setSelection(selection);
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
// Displays the generated public key .ssh_key.pub
|
||||
public static class ShowSshKeyFragment extends DialogFragment {
|
||||
public ShowSshKeyFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
LayoutInflater inflater = getActivity().getLayoutInflater();
|
||||
final View v = inflater.inflate(R.layout.fragment_show_ssh_key, null);
|
||||
builder.setView(v);
|
||||
|
||||
TextView textView = (TextView) v.findViewById(R.id.public_key);
|
||||
File file = new File(getActivity().getFilesDir() + "/.ssh_key.pub");
|
||||
try {
|
||||
textView.setText(FileUtils.readFileToString(file));
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
builder.setPositiveButton(getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (getActivity() instanceof SshKeyGen)
|
||||
getActivity().finish();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNegativeButton(getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
builder.setNeutralButton(getResources().getString(R.string.ssh_keygen_copy), null);
|
||||
|
||||
final AlertDialog ad = builder.setTitle("Your public key").create();
|
||||
ad.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
Button b = ad.getButton(AlertDialog.BUTTON_NEUTRAL);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextView textView = (TextView) v.findViewById(R.id.public_key);
|
||||
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("public key", textView.getText().toString());
|
||||
clipboard.setPrimaryClip(clip);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
setTitle("Generate SSH Key");
|
||||
|
||||
setContentView(R.layout.activity_ssh_keygen);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(android.R.id.content, new SshKeyGenFragment()).commit();
|
||||
}
|
||||
}
|
||||
|
||||
private class generateTask extends AsyncTask<View, Void, Exception> {
|
||||
private ProgressDialog pd;
|
||||
|
||||
protected Exception doInBackground(View... views) {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(views[0].getWindowToken(), 0);
|
||||
|
||||
Spinner spinner = (Spinner) findViewById(R.id.length);
|
||||
int length = (Integer) spinner.getSelectedItem();
|
||||
|
||||
EditText editText = (EditText) findViewById(R.id.passphrase);
|
||||
String passphrase = editText.getText().toString();
|
||||
|
||||
editText = (EditText) findViewById(R.id.comment);
|
||||
String comment = editText.getText().toString();
|
||||
|
||||
JSch jsch = new JSch();
|
||||
try {
|
||||
KeyPair kp = KeyPair.genKeyPair(jsch, KeyPair.RSA, length);
|
||||
|
||||
File file = new File(getFilesDir() + "/.ssh_key");
|
||||
FileOutputStream out = new FileOutputStream(file, false);
|
||||
kp.writePrivateKey(out, passphrase.getBytes());
|
||||
|
||||
file = new File(getFilesDir() + "/.ssh_key.pub");
|
||||
out = new FileOutputStream(file, false);
|
||||
kp.writePublicKey(out, comment);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
pd = ProgressDialog.show(SshKeyGen.this, "", "Generating keys");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Exception e) {
|
||||
super.onPostExecute(e);
|
||||
pd.dismiss();
|
||||
if (e == null) {
|
||||
Toast.makeText(SshKeyGen.this, "SSH-key generated", Toast.LENGTH_LONG).show();
|
||||
DialogFragment df = new ShowSshKeyFragment();
|
||||
df.show(getFragmentManager(), "public_key");
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean("use_generated_key", true);
|
||||
editor.apply();
|
||||
} else {
|
||||
new AlertDialog.Builder(SshKeyGen.this)
|
||||
.setTitle("Error while trying to generate the ssh-key")
|
||||
.setMessage(getResources().getString(R.string.ssh_key_error_dialog_text) + e.getMessage())
|
||||
.setPositiveButton(getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
// pass
|
||||
}
|
||||
}).show();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when 'Generate' button of SshKeyGenFragment clicked. Generates a
|
||||
// private and public key, then replaces the SshKeyGenFragment with a
|
||||
// ShowSshKeyFragment which displays the public key.
|
||||
public void generate(View view) {
|
||||
new generateTask().execute(view);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.zeapo.pwdstore;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -82,6 +83,24 @@ public class UserPreference extends AppCompatActivity {
|
|||
}
|
||||
});
|
||||
|
||||
findPreference("ssh_keygen").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
callingActivity.makeSshKey();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
findPreference("ssh_see_key").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
DialogFragment df = new SshKeyGen.ShowSshKeyFragment();
|
||||
df.show(getFragmentManager(), "public_key");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
findPreference("git_server_info").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
|
@ -164,6 +183,13 @@ public class UserPreference extends AppCompatActivity {
|
|||
findPreference("pref_select_external").setOnPreferenceChangeListener(resetRepo);
|
||||
findPreference("git_external").setOnPreferenceChangeListener(resetRepo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final SharedPreferences sharedPreferences = getPreferenceManager().getSharedPreferences();
|
||||
findPreference("ssh_see_key").setEnabled(sharedPreferences.getBoolean("use_generated_key", false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -175,6 +201,9 @@ public class UserPreference extends AppCompatActivity {
|
|||
case "get_ssh_key":
|
||||
getSshKey();
|
||||
break;
|
||||
case "make_ssh_key":
|
||||
makeSshKey();
|
||||
break;
|
||||
case "git_external":
|
||||
selectExternalGitRepository();
|
||||
break;
|
||||
|
@ -220,6 +249,16 @@ public class UserPreference extends AppCompatActivity {
|
|||
startActivityForResult(intent, IMPORT_SSH_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a key generator to generate a public/private key pair
|
||||
*/
|
||||
public void makeSshKey() {
|
||||
Intent intent = new Intent(getApplicationContext(), SshKeyGen.class);
|
||||
startActivity(intent);
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
private void copySshKey(Uri uri) throws IOException {
|
||||
InputStream sshKey = this.getContentResolver().openInputStream(uri);
|
||||
byte[] privateKey = IOUtils.toByteArray(sshKey);
|
||||
|
@ -238,6 +277,10 @@ public class UserPreference extends AppCompatActivity {
|
|||
}
|
||||
copySshKey(data.getData());
|
||||
Toast.makeText(this, this.getResources().getString(R.string.ssh_key_success_dialog_title), Toast.LENGTH_LONG).show();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean("use_generated_key", false);
|
||||
editor.apply();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -92,7 +92,7 @@ public abstract class GitOperation {
|
|||
new AlertDialog.Builder(callingActivity)
|
||||
.setMessage(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_text))
|
||||
.setTitle(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_title))
|
||||
.setPositiveButton(callingActivity.getResources().getString(R.string.dialog_ok), new DialogInterface.OnClickListener() {
|
||||
.setPositiveButton(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_import), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
try {
|
||||
|
@ -106,12 +106,28 @@ public abstract class GitOperation {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).setNegativeButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
// Do nothing...
|
||||
}
|
||||
}).show();
|
||||
})
|
||||
.setNegativeButton(callingActivity.getResources().getString(R.string.ssh_preferences_dialog_generate), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
try {
|
||||
// Duplicated code
|
||||
Intent intent = new Intent(callingActivity.getApplicationContext(), UserPreference.class);
|
||||
intent.putExtra("operation", "make_ssh_key");
|
||||
callingActivity.startActivityForResult(intent, GET_SSH_KEY_FROM_CLONE);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Exception caught :(");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNeutralButton(callingActivity.getResources().getString(R.string.dialog_cancel), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
// Finish the blank GitActivity so user doesn't have to press back
|
||||
callingActivity.finish();
|
||||
}
|
||||
}).show();
|
||||
} else {
|
||||
final EditText passphrase = new EditText(callingActivity);
|
||||
passphrase.setHint("Passphrase");
|
||||
|
|
|
@ -86,16 +86,16 @@ public class pwgenDialogFragment extends DialogFragment {
|
|||
@Override
|
||||
public void onShow(DialogInterface dialog) {
|
||||
setPreferences();
|
||||
EditText textView = (EditText) view.findViewById(R.id.passwordText);
|
||||
textView.setText(pwgen.generate(getActivity().getApplicationContext()).get(0));
|
||||
EditText editText = (EditText) view.findViewById(R.id.passwordText);
|
||||
editText.setText(pwgen.generate(getActivity().getApplicationContext()).get(0));
|
||||
|
||||
Button b = ad.getButton(AlertDialog.BUTTON_NEUTRAL);
|
||||
b.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setPreferences();
|
||||
EditText textView = (EditText) getDialog().findViewById(R.id.passwordText);
|
||||
textView.setText(pwgen.generate(getActivity().getApplicationContext()).get(0));
|
||||
EditText editText = (EditText) view.findViewById(R.id.passwordText);
|
||||
editText.setText(pwgen.generate(callingActivity.getApplicationContext()).get(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -120,9 +120,9 @@ public class pwgenDialogFragment extends DialogFragment {
|
|||
if (!((CheckBox) getDialog().findViewById(R.id.pronounceable)).isChecked()) {
|
||||
preferences.add("s");
|
||||
}
|
||||
EditText textView = (EditText) getDialog().findViewById(R.id.lengthNumber);
|
||||
EditText editText = (EditText) getDialog().findViewById(R.id.lengthNumber);
|
||||
try {
|
||||
int length = Integer.valueOf(textView.getText().toString());
|
||||
int length = Integer.valueOf(editText.getText().toString());
|
||||
return pwgen.setPrefs(getActivity().getApplicationContext(), preferences, length);
|
||||
} catch(NumberFormatException e) {
|
||||
return pwgen.setPrefs(getActivity().getApplicationContext(), preferences);
|
||||
|
|
7
app/src/main/res/layout/activity_ssh_keygen.xml
Normal file
7
app/src/main/res/layout/activity_ssh_keygen.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?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">
|
||||
|
||||
</LinearLayout>
|
28
app/src/main/res/layout/fragment_show_ssh_key.xml
Normal file
28
app/src/main/res/layout/fragment_show_ssh_key.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/public_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:textIsSelectable="true"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/public_key_tip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:text="@string/ssh_keygen_tip"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
73
app/src/main/res/layout/fragment_ssh_keygen.xml
Normal file
73
app/src/main/res/layout/fragment_ssh_keygen.xml
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_length"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/ssh_keygen_length"/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/length"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:spinnerMode="dropdown"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/passphrase"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/ssh_keygen_passphrase"
|
||||
android:inputType="textPassword"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ssh_keygen_show_passphrase"
|
||||
android:id="@+id/show_passphrase"
|
||||
android:checked="false"
|
||||
android:layout_marginTop="8dp"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
app:hintTextAppearance="@style/TextAppearance.AppCompat"
|
||||
android:layout_marginTop="8dp">
|
||||
<EditText
|
||||
android:id="@+id/comment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/ssh_keygen_comment"
|
||||
android:inputType="textShortMessage"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/generate_ssh_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:onClick="generate"
|
||||
android:text="@string/ssh_keygen_generate"/>
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:fab="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="com.zeapo.pwdstore.PasswordFragment">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="com.zeapo.pwdstore.PasswordFragment">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/pass_recycler"
|
||||
|
@ -17,17 +17,18 @@
|
|||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"/>
|
||||
|
||||
<com.melnykov.fab.FloatingActionButton
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:src="@drawable/ic_action_new"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_gravity="bottom|end"
|
||||
app:elevation="6dp"
|
||||
app:pressedTranslationZ="12dp"
|
||||
app:backgroundTint="@color/blue_grey_500"
|
||||
app:rippleColor="@color/blue_grey_50"
|
||||
app:borderWidth="0dp"
|
||||
android:layout_margin="@dimen/fab_compat_margin"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_margin="@dimen/activity_vertical_margin"
|
||||
android:onClick="createPassword"
|
||||
fab:fab_colorNormal="@color/blue_grey_500"
|
||||
fab:fab_colorPressed="@color/blue_grey_800"
|
||||
fab:fab_colorRipple="@color/blue_grey_50"/>
|
||||
android:layout_alignParentRight="true"/>
|
||||
</RelativeLayout>
|
||||
|
|
4
app/src/main/res/values-v21/dimens.xml
Normal file
4
app/src/main/res/values-v21/dimens.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="fab_compat_margin">16dp</dimen>
|
||||
</resources>
|
|
@ -2,4 +2,5 @@
|
|||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="fab_compat_margin">0dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -47,8 +47,10 @@
|
|||
<string name="read_only_dialog_text">You are about to use a read-only repository, you will not be able to push to it</string>
|
||||
<string name="forget_username_dialog_text">Did you forget to specify a username?</string>
|
||||
<string name="set_information_dialog_text">You have to set the information about the server before synchronizing with the server</string>
|
||||
<string name="ssh_preferences_dialog_text">Please import your SSH key file in the preferences</string>
|
||||
<string name="ssh_preferences_dialog_text">Please import or generate your SSH key file in the preferences</string>
|
||||
<string name="ssh_preferences_dialog_title">No SSH key</string>
|
||||
<string name="ssh_preferences_dialog_import">Import</string>
|
||||
<string name="ssh_preferences_dialog_generate">Generate</string>
|
||||
<string name="passphrase_dialog_title">Authenticate</string>
|
||||
<string name="passphrase_dialog_text">Please provide the passphrase for your SSH key. Leave it empty if there is no passphrase.</string>
|
||||
<string name="password_dialog_text">Please provide the password for this repository</string>
|
||||
|
@ -94,7 +96,9 @@
|
|||
<string name="pref_git_username_title">Username</string>
|
||||
<string name="pref_git_username_hint">username</string>
|
||||
<string name="pref_edit_server_info">Edit git server settings</string>
|
||||
<string name="pref_ssh_title">Import ssh-key</string>
|
||||
<string name="pref_ssh_title">Import SSH key</string>
|
||||
<string name="pref_ssh_keygen_title">Generate SSH key pair</string>
|
||||
<string name="pref_ssh_see_key_title">View generated public SSH key</string>
|
||||
<string name="pref_git_delete_repo">Delete repository</string>
|
||||
<string name="pref_dialog_delete_title">Clear repository</string>
|
||||
<string name="pref_dialog_delete_msg">Do you want to delete the current password store directory? This will not clear your configuration.</string>
|
||||
|
@ -122,6 +126,15 @@
|
|||
<string name="pwgen_uppercase">Uppercase</string>
|
||||
<string name="pwgen_ambiguous">Ambiguous</string>
|
||||
|
||||
<!-- ssh keygen fragment -->
|
||||
<string name="ssh_keygen_length">Length</string>
|
||||
<string name="ssh_keygen_passphrase">Passphrase</string>
|
||||
<string name="ssh_keygen_comment">Comment</string>
|
||||
<string name="ssh_keygen_generate">Generate</string>
|
||||
<string name="ssh_keygen_copy">Copy</string>
|
||||
<string name="ssh_keygen_tip">Provide this public key to your Git server.</string>
|
||||
<string name="ssh_keygen_show_passphrase">Show passphrase</string>
|
||||
|
||||
<!-- Misc -->
|
||||
<string name="dialog_ok">OK</string>
|
||||
<string name="dialog_yes">Yes</string>
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
<Preference
|
||||
android:key="ssh_key"
|
||||
android:title="@string/pref_ssh_title" />
|
||||
<Preference
|
||||
android:key="ssh_keygen"
|
||||
android:title="@string/pref_ssh_keygen_title" />
|
||||
<Preference
|
||||
android:key="ssh_see_key"
|
||||
android:title="@string/pref_ssh_see_key_title" />
|
||||
<Preference
|
||||
android:key="git_delete_repo"
|
||||
android:summary="Deletes local repository"
|
||||
|
|
Loading…
Reference in a new issue