Skip to content

Commit

Permalink
Merge branch 'release/1.2.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
infeo committed Aug 1, 2023
2 parents 1cf9ebb + 947533b commit f240475
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Windows-specific implementations of [integrations-api](https://github.com/crypto

This project uses the following JVM properties:
* `cryptomator.integrationsWin.autoStartShellLinkName` - Name of the shell link, which is placed in the Windows startup folder to start application on user login
* `cryptomator.integrationsWin.keychainPaths` - Colon separated list of paths, which are checked for encrypted data
* `cryptomator.integrationsWin.keychainPaths` - List of file paths, which are checked for data encrypted with the Windows data protection api

## Building

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.cryptomator</groupId>
<artifactId>integrations-win</artifactId>
<version>1.2.1</version>
<version>1.2.2</version>

<name>Cryptomator Integrations for Windows</name>
<description>Provides optional Windows services used by Cryptomator</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,14 @@

/**
* Windows implementation for the {@link KeychainAccessProvider} based on the <a href="https://en.wikipedia.org/wiki/Data_Protection_API">data protection API</a>.
* The storage locations to check for encrypted data can be set with the JVM property {@value KEYCHAIN_PATHS_PROPERTY} as a colon({@value PATH_LIST_SEP}) separated list of paths.
* The storage locations to check for encrypted data can be set with the JVM property {@value KEYCHAIN_PATHS_PROPERTY} with the paths seperated with the character defined in the JVM property path.separator.
*/
@Priority(1000)
@OperatingSystem(OperatingSystem.Value.WINDOWS)
public class WindowsProtectedKeychainAccess implements KeychainAccessProvider {

private static final String KEYCHAIN_PATHS_PROPERTY = "cryptomator.integrationsWin.keychainPaths";
private static final Logger LOG = LoggerFactory.getLogger(WindowsProtectedKeychainAccess.class);
private static final String PATH_LIST_SEP = ":";
private static final Path USER_HOME_REL = Path.of("~");
private static final Path USER_HOME = Path.of(System.getProperty("user.home"));
private static final Gson GSON = new GsonBuilder() //
Expand All @@ -72,8 +71,13 @@ public WindowsProtectedKeychainAccess() {
}

private static List<Path> readKeychainPathsFromEnv() {
return Optional.ofNullable(System.getProperty(KEYCHAIN_PATHS_PROPERTY))
.stream().flatMap(rawPaths -> Arrays.stream(rawPaths.split(PATH_LIST_SEP)))
var keychainPaths = System.getProperty(KEYCHAIN_PATHS_PROPERTY, "");
return parsePaths(keychainPaths, System.getProperty("path.separator"));
}

// visible for testing
static List<Path> parsePaths(String listOfPaths, String pathSeparator) {
return Arrays.stream(listOfPaths.split(pathSeparator))
.filter(Predicate.not(String::isEmpty))
.map(Path::of)
.map(WindowsProtectedKeychainAccess::resolveHomeDir)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
Expand Down Expand Up @@ -46,4 +48,35 @@ public void testStoreAndLoad() throws KeychainAccessException {
Assertions.assertNull(keychain.loadPassphrase("nonExistingPassword"));
}

@Nested
public class ParsePaths {
@Test
@DisplayName("String is split with path separator")
public void testParsePaths() {
String paths = "C:\\foo\\bar;bar\\kuz";
var result = WindowsProtectedKeychainAccess.parsePaths(paths, ";");
Assertions.assertEquals(2, result.size());
Assertions.assertTrue(result.contains(Path.of("C:\\foo\\bar")));
Assertions.assertTrue(result.contains(Path.of("bar\\kuz")));
}

@Test
@DisplayName("Empty string returns empty list")
public void testParsePathsEmpty() {
var result = WindowsProtectedKeychainAccess.parsePaths("", ";");
Assertions.assertEquals(0, result.size());
}

@Test
@DisplayName("Strings starting with ~ are resolved to user home")
public void testParsePathsUserHome() {
var userHome = Path.of(System.getProperty("user.home"));
var result = WindowsProtectedKeychainAccess.parsePaths("this\\~\\not;~\\foo\\bar", ";");
Assertions.assertEquals(2, result.size());
Assertions.assertTrue(result.contains(Path.of("this\\~\\not")));
Assertions.assertTrue(result.contains(userHome.resolve("foo\\bar")));
}

}

}

0 comments on commit f240475

Please sign in to comment.