From 3ac9c7d8e70e9102dba19526ee48ab7597e954b3 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sat, 5 Sep 2020 22:48:42 +0530 Subject: [PATCH] PasswordRepository: add custom FS factory for symlink capabilities (#1081) Co-authored-by: Fabian Henneke --- CHANGELOG.md | 1 + .../pwdstore/utils/PasswordRepository.kt | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae99f685..6cc0ca28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file. - Remember HTTPS password during a sync operation - Unable to use show/hide password option for password/passphrase after first attempt was wrong - TOTP values shown might some times be stale and considered invalid by sites +- Symlinks are no longer clobbered by the app (only available on Android 8 and above) ## [1.11.3] - 2020-08-27 diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt index 662210b2..fe79a8ea 100644 --- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt +++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRepository.kt @@ -6,10 +6,14 @@ package com.zeapo.pwdstore.utils import android.content.Context import android.content.SharedPreferences +import android.os.Build +import androidx.annotation.RequiresApi import androidx.core.content.edit import com.zeapo.pwdstore.Application import java.io.File import java.io.FileFilter +import java.nio.file.Files +import java.nio.file.LinkOption import java.util.Comparator import org.eclipse.jgit.api.Git import org.eclipse.jgit.lib.Repository @@ -17,9 +21,37 @@ import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.transport.RefSpec import org.eclipse.jgit.transport.RemoteConfig import org.eclipse.jgit.transport.URIish +import org.eclipse.jgit.util.FS +import org.eclipse.jgit.util.FS_POSIX_Java6 open class PasswordRepository protected constructor() { + private class FS_POSIX_Java6_with_optional_symlinks : FS_POSIX_Java6() { + + override fun supportsSymlinks() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + + @RequiresApi(Build.VERSION_CODES.O) + override fun isSymLink(file: File) = Files.isSymbolicLink(file.toPath()) + + @RequiresApi(Build.VERSION_CODES.O) + override fun readSymLink(file: File) = Files.readSymbolicLink(file.toPath()).toString() + + @RequiresApi(Build.VERSION_CODES.O) + override fun createSymLink(source: File, target: String) { + val sourcePath = source.toPath() + if (Files.exists(sourcePath, LinkOption.NOFOLLOW_LINKS)) + Files.delete(sourcePath) + Files.createSymbolicLink(sourcePath, File(target).toPath()) + } + } + + private class Java7FSFactory : FS.FSFactory() { + + override fun detect(cygwinUsed: Boolean?): FS { + return FS_POSIX_Java6_with_optional_symlinks() + } + } + enum class PasswordSortOrder(val comparator: Comparator) { FOLDER_FIRST(Comparator { p1: PasswordItem, p2: PasswordItem -> @@ -75,6 +107,7 @@ open class PasswordRepository protected constructor() { val builder = FileRepositoryBuilder() try { repository = builder.setGitDir(localDir) + .setFS(Java7FSFactory().detect(null)) .readEnvironment() .build() } catch (e: Exception) {