diff options
author | Christoph Böhmwalder <christoph@boehmwalder.at> | 2017-12-26 14:35:25 +0100 |
---|---|---|
committer | Mohamed Zenadi <zeapo@users.noreply.github.com> | 2017-12-26 14:35:25 +0100 |
commit | e41287cb164b734dd19dc63d88235dd75509547d (patch) | |
tree | ff5800cb95a0047c16a5c4809cffcd9e49a126bc | |
parent | 916d63f9bec5d624350b62a1d0eaec677a6b214f (diff) |
show age for passwords in detail view (#339)
* show age for passwords in detail view
Implements #330.
This fetches the latest commit where the respective password file was
changed from the current HEAD and outputs the relative time since
the last change on the decrypt page.
* Move lastChanged logic out of PgpActivity
This nicely encapsulates the lastChanged logic (and thus separates it
from dependencies like git). The last changed date is now passed as a
timestamp using the Intent's extra info.
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/PasswordStore.java | 31 | ||||
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt | 22 | ||||
-rw-r--r-- | app/src/main/res/layout/decrypt_layout.xml | 13 | ||||
-rw-r--r-- | app/src/main/res/values-cs/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-de/strings.xml | 2 | ||||
-rw-r--r-- | app/src/main/res/values-fr/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-ja/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-ru/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-zh-rCN/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values-zh-rTW/strings.xml | 1 | ||||
-rw-r--r-- | app/src/main/res/values/strings.xml | 2 |
11 files changed, 76 insertions, 0 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java index acfadf99..99593700 100644 --- a/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java +++ b/app/src/main/java/com/zeapo/pwdstore/PasswordStore.java @@ -42,7 +42,9 @@ import com.zeapo.pwdstore.utils.PasswordRepository; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.revwalk.RevCommit; import java.io.File; import java.util.ArrayList; @@ -406,11 +408,40 @@ public class PasswordStore extends AppCompatActivity { } } + private String getRelativePath(String fullPath, String repositoryPath) { + return fullPath.replace(repositoryPath, "").replaceAll("/+", "/"); + } + + public int getLastChangedTimestamp(String fullPath) { + File repoPath = PasswordRepository.getRepositoryDirectory(this); + Repository repository = PasswordRepository.getRepository(repoPath); + + if (repository == null) { + return -1; + } + + Git git = new Git(repository); + String relativePath = getRelativePath(fullPath, repoPath.getAbsolutePath()).substring(1); + Iterable<RevCommit> iterable; + + try { + iterable = git.log().addPath(relativePath).call(); + } catch (GitAPIException e) { + System.out.println("Exception caught :("); + e.printStackTrace(); + return -1; + } + + RevCommit latestCommit = iterable.iterator().next(); + return latestCommit.getCommitTime(); + } + public void decryptPassword(PasswordItem item) { Intent intent = new Intent(this, PgpActivity.class); intent.putExtra("NAME", item.toString()); intent.putExtra("FILE_PATH", item.getFile().getAbsolutePath()); intent.putExtra("REPO_PATH", PasswordRepository.getRepositoryDirectory(getApplicationContext()).getAbsolutePath()); + intent.putExtra("LAST_CHANGED_TIMESTAMP", getLastChangedTimestamp(item.getFile().getAbsolutePath())); intent.putExtra("OPERATION", "DECRYPT"); // Adds shortcut diff --git a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt index 19b71b72..1a8a5051 100644 --- a/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt +++ b/app/src/main/java/com/zeapo/pwdstore/crypto/PgpActivity.kt @@ -12,6 +12,7 @@ import android.os.SystemClock import android.preference.PreferenceManager import android.support.v7.app.AppCompatActivity import android.text.TextUtils +import android.text.format.DateUtils import android.text.method.PasswordTransformationMethod import android.util.Log import android.view.* @@ -20,6 +21,7 @@ import com.zeapo.pwdstore.PasswordEntry import com.zeapo.pwdstore.R import com.zeapo.pwdstore.UserPreference import com.zeapo.pwdstore.pwgenDialogFragment +import com.zeapo.pwdstore.utils.PasswordRepository import com.zeapo.pwdstore.utils.Totp import kotlinx.android.synthetic.main.decrypt_layout.* import kotlinx.android.synthetic.main.encrypt_layout.* @@ -47,6 +49,7 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { private val fullPath: String by lazy { intent.getStringExtra("FILE_PATH") } private val name: String by lazy { getName(fullPath, repoPath) } + private val lastChangedString: CharSequence by lazy { getLastChangedString(intent.getIntExtra("LAST_CHANGED_TIMESTAMP", -1)) } private val relativeParentPath: String by lazy { getParentPath(fullPath, repoPath) } private val settings: SharedPreferences by lazy { PreferenceManager.getDefaultSharedPreferences(this) } @@ -76,6 +79,13 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { setContentView(R.layout.decrypt_layout) crypto_password_category_decrypt.text = relativeParentPath crypto_password_file.text = name + + crypto_password_last_changed.text = try { + this.resources.getString(R.string.last_changed, lastChangedString) + } catch (e: RuntimeException) { + showToast(getString(R.string.get_last_changed_failed)) + "" + } } "ENCRYPT" -> { setContentView(R.layout.encrypt_layout) @@ -514,6 +524,18 @@ class PgpActivity : AppCompatActivity(), OpenPgpServiceConnection.OnBound { delayTask?.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) } + /** + * Gets a relative string describing when this shape was last changed + * (e.g. "one hour ago") + */ + private fun getLastChangedString(timeStamp: Int): CharSequence { + if (timeStamp < 0) { + throw RuntimeException() + } + + return DateUtils.getRelativeTimeSpanString(this, timeStamp.toLong() * 1000, true) + } + @SuppressLint("StaticFieldLeak") inner class DelayShow(val activity: PgpActivity) : AsyncTask<Void, Int, Boolean>() { private val pb: ProgressBar by lazy { pbLoading } diff --git a/app/src/main/res/layout/decrypt_layout.xml b/app/src/main/res/layout/decrypt_layout.xml index 48247c57..e5095d66 100644 --- a/app/src/main/res/layout/decrypt_layout.xml +++ b/app/src/main/res/layout/decrypt_layout.xml @@ -43,6 +43,19 @@ android:textSize="24sp" android:textStyle="bold" tools:ignore="HardcodedText" /> + + <TextView + android:id="@+id/crypto_password_last_changed" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_marginLeft="16dp" + android:layout_marginStart="16dp" + android:text="LAST CHANGED HERE" + android:textColor="@color/grey_500" + android:textIsSelectable="false" + android:textSize="18sp" + tools:ignore="HardcodedText" /> </LinearLayout> <ImageView diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 5feaec77..a8bb0a50 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -153,4 +153,5 @@ <string name="no_repo_selected">Nebyl vybrát externí repozitář</string> <string name="send_plaintext_password_to">Odeslat heslo jako plaintext za použití…</string> <string name="show_password">Pokaż hasło</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 80b16cd9..8c63a37b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -194,4 +194,6 @@ <string name="autofill_ins_1_hint">Bildschirmfoto Accessibility Services</string> <string name="autofill_ins_2_hint">Bildschirmfoto des Schalters in Accessibility Services</string> <string name="autofill_ins_3_hint">Bildschirmfoto von Autofill in Aktion</string> + <string name="last_changed">Zuletzt geändert %s</string> + <string name="get_last_changed_failed">Das Abrufen des letzten Änderungsdatums ist fehlgeschlagen.</string> </resources> diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 3180a494..6db46765 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -186,4 +186,5 @@ <string name="show_extra_content_pref_title">Afficher le contenu supplémentaire</string> <string name="username">Nom d\'utilisateur</string> <string name="ssh_key_does_not_exist">Impossible d\'ouvrir la clef ssh, merci de vérifier que le ficher existe</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources> diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 9ab13ff0..def249be 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -157,4 +157,5 @@ <string name="no_repo_selected">外部リポジトリが選択されていません</string> <string name="send_plaintext_password_to">パスワードをプレーンテキストとして送信…</string> <string name="show_password">パスワードを表示</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources> diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 24fe4e58..d8177901 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -188,4 +188,5 @@ <string name="autofill_paste">Вставить</string> <string name="autofill_paste_username">Вставить имя пользователя?\n\n%s</string> <string name="autofill_toast_username">Выберите поле ввода для вставки имени пользователя.\nИмя пользователя можно вставить в течение %d секунд.</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources> diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ba6dfa5a..bcba3ca2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -121,4 +121,5 @@ <string name="server_resulting_url">生成的 URL</string> <string name="autofill_apps_match_ellipsis">匹配…</string> <string name="pref_crypto_title">加密</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources>
\ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 43e51818..d0970f00 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -121,4 +121,5 @@ <string name="server_resulting_url">生成的 URL</string> <string name="autofill_apps_match_ellipsis">匹配…</string> <string name="pref_crypto_title">加密</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd286625..8a5f0e39 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -98,6 +98,7 @@ <string name="copy_password">Copy password</string> <string name="copy_username">Copy username</string> <string name="share_as_plaintext">Share as plaintext</string> + <string name="last_changed">Last changed %s</string> <!-- Preferences --> <string name="pref_git_title">Git</string> @@ -217,4 +218,5 @@ <string name="commit_hash">Commit hash</string> <string name="crypto_password_edit_hint">p@ssw0rd!</string> <string name="crypto_extra_edit_hint">username: something other extra content</string> + <string name="get_last_changed_failed">Failed to get last changed date</string> </resources> |