some refactoring with nicer icons...

This commit is contained in:
Zeapo 2014-08-06 20:35:03 +01:00
parent 17ba2275ec
commit c3696b2f49
9 changed files with 212 additions and 118 deletions

38
README.md Normal file
View file

@ -0,0 +1,38 @@
PwdStore
========
This application tries to be 100% compatible with [pass](http://www.zx2c4.com/projects/password-store/)
Feautres
========
- Clone an existing pass repository
- List the passwords
- Handle the directories as categories
- Decrypt the password files (first line is the password, the rest is extra data)
- Add a new password to the current category (or no category if added at the root)
Libraries
=========
This project uses three libraries:
- [OpenKeyChain](https://github.com/open-keychain/open-keychain) for encryption and decryption of passwords
- [JGit]() a pretty good git lib
- [Apache's FileUtils]() for files manipulations
TODOs
=====
- Initialize a new pass repository
- Pull from/Push to a pass repository
- Create a new cateogry
- Multi-select (for password deletion)
- Multiple password stores (multiple git repositories).
- More UI enhancements
Needed
======
- Icons: the current ones are CC, but would be great to have our own icons
- UI enhancements: any UI changes or suggestions are welcome

View file

@ -80,6 +80,13 @@ public class PasswordStore extends Activity implements ToCloneOrNot.OnFragmentI
} }
return true; return true;
case R.id.menu_add_password:
createPassword(getCurrentFocus());
break;
case R.id.menu_add_category:
break;
case R.id.referesh: case R.id.referesh:
PasswordFragment plist; PasswordFragment plist;
if (null != if (null !=
@ -204,7 +211,6 @@ public class PasswordStore extends Activity implements ToCloneOrNot.OnFragmentI
try { try {
Intent intent = new Intent(this, PgpHandler.class); Intent intent = new Intent(this, PgpHandler.class);
intent.putExtra("PGP-ID", FileUtils.readFileToString(PasswordRepository.getFile("/.gpg-id"))); intent.putExtra("PGP-ID", FileUtils.readFileToString(PasswordRepository.getFile("/.gpg-id")));
intent.putExtra("NAME", "test.gpg");
intent.putExtra("FILE_PATH", this.currentDir.getAbsolutePath()); intent.putExtra("FILE_PATH", this.currentDir.getAbsolutePath());
intent.putExtra("Operation", "ENCRYPT"); intent.putExtra("Operation", "ENCRYPT");
// TODO Define different operations here // TODO Define different operations here
@ -217,6 +223,7 @@ public class PasswordStore extends Activity implements ToCloneOrNot.OnFragmentI
protected void onActivityResult(int requestCode, int resultCode, protected void onActivityResult(int requestCode, int resultCode,
Intent data) { Intent data) {
System.out.println(resultCode); System.out.println(resultCode);
checkLocalRepository(this.currentDir); if (resultCode == RESULT_OK)
checkLocalRepository(this.currentDir);
} }
} }

View file

@ -2,7 +2,9 @@ package com.zeapo.pwdstore.crypto;
import android.app.ActionBar; import android.app.ActionBar;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentSender; import android.content.IntentSender;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -20,7 +22,6 @@ import android.widget.LinearLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.GridLayout.LayoutParams;
import com.zeapo.pwdstore.R; import com.zeapo.pwdstore.R;
import com.zeapo.pwdstore.UserPreference; import com.zeapo.pwdstore.UserPreference;
@ -37,7 +38,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
public class PgpHandler extends Activity { public class PgpHandler extends Activity {
@ -67,14 +67,9 @@ public class PgpHandler extends Activity {
Bundle extra = getIntent().getExtras(); Bundle extra = getIntent().getExtras();
if (extra.getString("Operation").equals("DECRYPT")) { if (extra.getString("Operation").equals("DECRYPT")) {
setContentView(R.layout.decrypt_layout); setContentView(R.layout.decrypt_layout);
((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME")); ((TextView) findViewById(R.id.crypto_password_file)).setText(extra.getString("NAME"));
findViewById(R.id.crypto_show_button).setVisibility(View.VISIBLE);
} else if (extra.getString("Operation").equals("ENCRYPT")) { } else if (extra.getString("Operation").equals("ENCRYPT")) {
setContentView(R.layout.encrypt_layout); setContentView(R.layout.encrypt_layout);
((EditText) findViewById(R.id.crypto_password_edit)).setText(extra.getString("NAME"));
findViewById(R.id.crypto_password_edit_layout).setVisibility(View.VISIBLE);
} }
// some persistance // some persistance
@ -113,6 +108,7 @@ public class PgpHandler extends Activity {
int id = item.getItemId(); int id = item.getItemId();
switch (id) { switch (id) {
case android.R.id.home: case android.R.id.home:
setResult(RESULT_OK);
finish(); finish();
return true; return true;
} }
@ -130,6 +126,8 @@ public class PgpHandler extends Activity {
case R.id.crypto_cancel_add: case R.id.crypto_cancel_add:
finish(); finish();
break; break;
case R.id.crypto_delete_button:
deletePassword();
default: default:
// should not happen // should not happen
@ -267,7 +265,7 @@ public class PgpHandler extends Activity {
showToast(os.toString()); showToast(os.toString());
} }
setResult(998); setResult(RESULT_OK);
finish(); finish();
} catch (Exception e) { } catch (Exception e) {
Log.e(Constants.TAG, "UnsupportedEncodingException", e); Log.e(Constants.TAG, "UnsupportedEncodingException", e);
@ -341,9 +339,20 @@ public class PgpHandler extends Activity {
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[] {"default"}); data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[] {"default"});
data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true); data.putExtra(OpenPgpApi.EXTRA_REQUEST_ASCII_ARMOR, true);
String name = ((EditText) findViewById(R.id.crypto_password_file_edit)).getText().toString();
String pass = ((EditText) findViewById(R.id.crypto_password_edit)).getText().toString(); String pass = ((EditText) findViewById(R.id.crypto_password_edit)).getText().toString();
String extra = ((EditText) findViewById(R.id.crypto_extra_edit)).getText().toString(); String extra = ((EditText) findViewById(R.id.crypto_extra_edit)).getText().toString();
if (name.isEmpty()) {
showToast("Please provide a file name");
return;
}
if (pass.isEmpty()) {
showToast("You cannot use an empty password or empty extra content");
return;
}
ByteArrayInputStream is; ByteArrayInputStream is;
try { try {
@ -360,13 +369,26 @@ public class PgpHandler extends Activity {
} }
private void deletePassword() {
new AlertDialog.Builder(this).
setMessage("Are you sure you want to delete the password " +
getIntent().getExtras().getString("NAME")
)
.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
(new File(getIntent().getExtras().getString("FILE_PATH"))).delete();
setResult(RESULT_OK);
finish();
}
})
.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
public void getKeyIds(Intent data) { }
data.setAction(OpenPgpApi.ACTION_GET_KEY_IDS); })
data.putExtra(OpenPgpApi.EXTRA_USER_IDS, new String[]{getIntent().getExtras().getString("PGP-ID")}); .show();
OpenPgpApi api = new OpenPgpApi(this, mServiceConnection.getService());
api.executeApiAsync(data, null, null, new MyCallback(false, null, REQUEST_CODE_GET_KEY_IDS));
} }
@Override @Override
@ -383,30 +405,14 @@ public class PgpHandler extends Activity {
* interaction, for example selected key ids. * interaction, for example selected key ids.
*/ */
switch (requestCode) { switch (requestCode) {
// case REQUEST_CODE_SIGN: {
// sign(data);
// break;
// }
case REQUEST_CODE_ENCRYPT: { case REQUEST_CODE_ENCRYPT: {
encrypt(data); encrypt(data);
break; break;
} }
// case REQUEST_CODE_SIGN_AND_ENCRYPT: {
// signAndEncrypt(data);
// break;
// }
case REQUEST_CODE_DECRYPT_AND_VERIFY: { case REQUEST_CODE_DECRYPT_AND_VERIFY: {
decryptAndVerify(data); decryptAndVerify(data);
break; break;
} }
// case REQUEST_CODE_GET_KEY: {
// getKey(data);
// break;
// }
case REQUEST_CODE_GET_KEY_IDS: {
getKeyIds(data);
break;
}
} }
} }
} }

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle"
android:dither="true">
<corners android:radius="2dp"/>
<solid android:color="#ccc" />
</shape>
</item>
<item android:bottom="2dp">
<shape android:shape="rectangle" android:dither="true">
<corners android:radius="2dp" />
<solid android:color="@android:color/holo_red_light" />
<padding android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp" />
</shape>
</item>
</layer-list>

View file

@ -20,7 +20,7 @@
<ImageButton <ImageButton
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_add" android:src="@drawable/ico_add"
android:background="@drawable/oval" android:background="@drawable/oval"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:onClick="createPassword" android:onClick="createPassword"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -11,105 +11,123 @@
android:orientation="vertical" android:orientation="vertical"
android:background="#eee"> android:background="#eee">
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/rectangle"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/holo_orange_dark"
android:text="Large Text"
android:id="@+id/crypto_password_file"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_column="0"
android:layout_row="0"/>
<ImageButton
android:id="@+id/crypto_show_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_key"
android:background="@android:drawable/screen_background_light_transparent"
android:layout_gravity="center_vertical"
android:visibility="invisible"
android:onClick="handleClick"
android:layout_column="2"
android:layout_row="0"/>
</GridLayout>
<LinearLayout <LinearLayout
android:id="@+id/crypto_container"
android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="fill_parent"
android:background="@drawable/rectangle" android:orientation="vertical">
android:layout_marginTop="@dimen/activity_vertical_margin"
android:visibility="invisible">
<GridLayout <GridLayout
android:id="@+id/crypto_password_show_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:background="@drawable/rectangle"
android:orientation="horizontal">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textStyle="bold" android:textColor="@android:color/holo_orange_dark"
android:textColor="@android:color/black" android:text="Large Text"
android:text="Password: " android:id="@+id/crypto_password_file"
android:layout_row="0" android:layout_gravity="center_vertical"
android:layout_column="0"/> android:layout_marginLeft="8dp"
<TextView android:layout_column="0"
android:id="@+id/crypto_password_show" android:layout_row="0"/>
<ImageButton
android:id="@+id/crypto_show_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:typeface="monospace" android:src="@drawable/ico_add"
android:textColor="@android:color/black" android:background="@android:drawable/screen_background_light_transparent"
android:layout_gravity="center_vertical"
android:onClick="handleClick"
android:layout_column="2" android:layout_column="2"
android:layout_row="0"/> android:layout_row="0"/>
<ProgressBar
android:id="@+id/pbLoading"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
style="?android:attr/progressBarStyleHorizontal"
android:layout_row="1"
android:layout_column="0"
android:layout_columnSpan="3"/>
</GridLayout> </GridLayout>
<LinearLayout <LinearLayout
android:id="@+id/crypto_extra_show_layout" android:id="@+id/crypto_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/rectangle"
android:layout_marginTop="@dimen/activity_vertical_margin"
android:visibility="invisible"> android:visibility="invisible">
<TextView <GridLayout
android:layout_width="wrap_content" android:id="@+id/crypto_password_show_layout"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:textStyle="bold"
android:textColor="@android:color/black"
android:text="Extra content: "/>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<TextView
android:id="@+id/crypto_extra_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:typeface="monospace"/>
</ScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="@android:color/black"
android:text="Password: "
android:layout_row="0"
android:layout_column="0"/>
<TextView
android:id="@+id/crypto_password_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:typeface="monospace"
android:textColor="@android:color/black"
android:layout_column="2"
android:layout_row="0"/>
<ProgressBar
android:id="@+id/pbLoading"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
style="?android:attr/progressBarStyleHorizontal"
android:layout_row="1"
android:layout_column="0"
android:layout_columnSpan="3"/>
</GridLayout>
<LinearLayout
android:id="@+id/crypto_extra_show_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="invisible">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="@android:color/black"
android:text="Extra content: "/>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/crypto_extra_show"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:typeface="monospace"/>
</ScrollView>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> <ImageButton
android:id="@+id/crypto_delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ico_del"
android:background="@drawable/oval"
android:layout_gravity="center_vertical"
android:onClick="handleClick"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
</RelativeLayout>

View file

@ -98,7 +98,7 @@
<ImageButton <ImageButton
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:src="@android:drawable/ic_input_add" android:src="@drawable/ico_check"
android:background="@drawable/oval" android:background="@drawable/oval"
android:id="@+id/crypto_confirm_add" android:id="@+id/crypto_confirm_add"
android:onClick="handleClick" android:onClick="handleClick"
@ -109,7 +109,7 @@
<ImageButton <ImageButton
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:src="@android:drawable/ic_delete" android:src="@drawable/ico_cancel"
android:background="@drawable/oval" android:background="@drawable/oval"
android:id="@+id/crypto_cancel_add" android:id="@+id/crypto_cancel_add"
android:onClick="handleClick" android:onClick="handleClick"

View file

@ -1,6 +1,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
tools:context=".pwdstore" > tools:context=".pwdstore" >
<item android:id="@+id/menu_add_password"
android:title="New password"/>
<item android:id="@+id/menu_add_category"
android:title="New category"/>
<item android:id="@+id/referesh" <item android:id="@+id/referesh"
android:title="Refresh" android:title="Refresh"
android:showAsAction="ifRoom" android:showAsAction="ifRoom"
@ -8,8 +14,6 @@
<item android:id="@+id/user_pref" <item android:id="@+id/user_pref"
android:title="Settings" android:title="Settings"
android:orderInCategory="100" android:orderInCategory="100"/>
android:showAsAction="ifRoom"
android:icon="@android:drawable/ic_menu_manage"/>
</menu> </menu>

View file

@ -5,8 +5,5 @@
<org.openintents.openpgp.util.OpenPgpListPreference <org.openintents.openpgp.util.OpenPgpListPreference
android:key="openpgp_provider_list" android:key="openpgp_provider_list"
android:title="Select OpenPGP Provider!" /> android:title="Select OpenPGP Provider!" />
<Preference
android:key="openpgp_provider_demo"
android:title="OpenPGP Provider Demo" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>