Skip to content

Commit

Permalink
Migrate keychain entries on Mac on provider change
Browse files Browse the repository at this point in the history
  • Loading branch information
purejava committed Dec 2, 2024
1 parent f7e65f4 commit 97a0f9c
Showing 1 changed file with 38 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package org.cryptomator.ui.preferences;

import org.apache.commons.lang3.SystemUtils;
import org.cryptomator.common.Environment;
import org.cryptomator.common.Passphrase;
import org.cryptomator.common.keychain.KeychainManager;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.integrations.autostart.AutoStartProvider;
import org.cryptomator.integrations.autostart.ToggleAutoStartFailedException;
import org.cryptomator.integrations.common.NamedServiceProvider;
import org.cryptomator.integrations.keychain.KeychainAccessException;
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
import org.cryptomator.integrations.quickaccess.QuickAccessService;
import org.cryptomator.ui.common.FxController;
Expand All @@ -14,6 +18,7 @@

import javax.inject.Inject;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
Expand All @@ -36,6 +41,7 @@ public class GeneralPreferencesController implements FxController {
private final Application application;
private final Environment environment;
private final List<KeychainAccessProvider> keychainAccessProviders;
private final KeychainManager keychain;
private final FxApplicationWindows appWindows;
public CheckBox useKeychainCheckbox;
public ChoiceBox<KeychainAccessProvider> keychainBackendChoiceBox;
Expand All @@ -48,11 +54,12 @@ public class GeneralPreferencesController implements FxController {
public ToggleGroup nodeOrientation;

@Inject
GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, Optional<AutoStartProvider> autoStartProvider, List<KeychainAccessProvider> keychainAccessProviders, Application application, Environment environment, FxApplicationWindows appWindows) {
GeneralPreferencesController(@PreferencesWindow Stage window, Settings settings, Optional<AutoStartProvider> autoStartProvider, List<KeychainAccessProvider> keychainAccessProviders, KeychainManager keychain, Application application, Environment environment, FxApplicationWindows appWindows) {
this.window = window;
this.settings = settings;
this.autoStartProvider = autoStartProvider;
this.keychainAccessProviders = keychainAccessProviders;
this.keychain = keychain;
this.quickAccessServices = QuickAccessService.get().toList();
this.application = application;
this.environment = environment;
Expand All @@ -73,6 +80,7 @@ public void initialize() {
Bindings.bindBidirectional(settings.keychainProvider, keychainBackendChoiceBox.valueProperty(), keychainSettingsConverter);
useKeychainCheckbox.selectedProperty().bindBidirectional(settings.useKeychain);
keychainBackendChoiceBox.disableProperty().bind(useKeychainCheckbox.selectedProperty().not());
keychainBackendChoiceBox.valueProperty().addListener(this::migrateKeychainEntriesOnMac);

useQuickAccessCheckbox.selectedProperty().bindBidirectional(settings.useQuickAccess);
var quickAccessSettingsConverter = new ServiceToSettingsConverter<>(quickAccessServices);
Expand All @@ -83,6 +91,35 @@ public void initialize() {
quickAccessServiceChoiceBox.disableProperty().bind(useQuickAccessCheckbox.selectedProperty().not());
}

public void migrateKeychainEntriesOnMac(Observable observable) {
if (!SystemUtils.IS_OS_MAC) {
return;
}

var provider = keychainBackendChoiceBox.getSelectionModel().getSelectedItem();
var providerId = "org.cryptomator.macos.keychain.MacSystemKeychainAccess";
var isSystemKeychain = provider.getClass().getName().equals(providerId);

List<String> vaults = settings.directories.stream()
.map(vault -> vault.id)
.toList();

if (!vaults.isEmpty()) {
LOG.info("Migrating keychain entries for vaults: {}", vaults);
}
for (String vaultId :vaults) {
try {
if (keychain.isPassphraseStored(vaultId)) {
var passphrase = keychain.loadPassphrase(vaultId);
keychain.deletePassphrase(vaultId);
keychain.storePassphrase(vaultId, vaultId, new Passphrase(passphrase), !isSystemKeychain);
}
} catch (KeychainAccessException e) {
LOG.error("Failed to migrate keychain entries.", e);
}
}
}

public boolean isAutoStartSupported() {
return autoStartProvider.isPresent();
}
Expand Down

0 comments on commit 97a0f9c

Please sign in to comment.