mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-09-25 09:55:52 +00:00
Rework
This commit is contained in:
@@ -14,6 +14,7 @@ import io.xpipe.app.pwman.PasswordManagerKeyConfiguration;
|
||||
import io.xpipe.core.KeyValue;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.ReadOnlyBooleanWrapper;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.geometry.Insets;
|
||||
@@ -45,7 +46,7 @@ public class PasswordManagerAgentStrategy implements SshIdentityStrategy {
|
||||
return AppI18n.get("passwordManagerEmpty");
|
||||
}
|
||||
|
||||
if (!pwman.getKeyConfiguration().supportsAgent()) {
|
||||
if (!pwman.getKeyConfiguration().useAgent()) {
|
||||
return AppI18n.get("passwordManagerNoAgentSupport");
|
||||
}
|
||||
|
||||
@@ -67,9 +68,10 @@ public class PasswordManagerAgentStrategy implements SshIdentityStrategy {
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("passwordManagerSshKeyConfig")
|
||||
.addComp(pwmanDisplay)
|
||||
.hide(pwmanProp.isNull())
|
||||
.hide(Bindings.or(pwmanProp.isNull(), new ReadOnlyBooleanWrapper(!config.isAllowPasswordAgentKeyChoice())))
|
||||
.nameAndDescription("publicKey")
|
||||
.addComp(new SshAgentKeyListComp(config.getFileSystem(), p, publicKey), publicKey)
|
||||
.hide(!config.isAllowPasswordAgentKeyChoice())
|
||||
.nameAndDescription("forwardAgent")
|
||||
.addToggle(forward)
|
||||
.nonNull()
|
||||
@@ -86,7 +88,7 @@ public class PasswordManagerAgentStrategy implements SshIdentityStrategy {
|
||||
|
||||
private PasswordManagerKeyConfiguration getConfig() {
|
||||
var pwman = AppPrefs.get().passwordManager().getValue();
|
||||
return pwman != null && pwman.getKeyConfiguration() != null && pwman.getKeyConfiguration().supportsAgent() ? pwman.getKeyConfiguration() : null;
|
||||
return pwman != null && pwman.getKeyConfiguration() != null && pwman.getKeyConfiguration().useAgent() ? pwman.getKeyConfiguration() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,10 @@ public class SshAgentKeyList {
|
||||
String name;
|
||||
}
|
||||
|
||||
public static void validate(DataStoreEntryRef<ShellStore> ref, SshIdentityStrategy strategy, String publicKey) {
|
||||
|
||||
}
|
||||
|
||||
public static List<Entry> listAgentIdentities(DataStoreEntryRef<ShellStore> ref, SshIdentityStrategy strategy) throws Exception {
|
||||
var session = ref.getStore().getOrStartSession();
|
||||
strategy.prepareParent(session);
|
||||
|
||||
@@ -17,5 +17,6 @@ public class SshIdentityStrategyChoiceConfig {
|
||||
Supplier<Boolean> perUserKeyFileCheck;
|
||||
boolean allowKeyFileSync;
|
||||
boolean allowAgentForward;
|
||||
boolean allowPasswordAgentKeyChoice;
|
||||
ObservableValue<DataStoreEntryRef<ShellStore>> fileSystem;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ import java.util.UUID;
|
||||
|
||||
public interface DataStoreProvider {
|
||||
|
||||
default boolean allowCreation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
default boolean showIncompleteInfo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -122,7 +122,8 @@ public class StoreCreationDialog {
|
||||
name,
|
||||
prov,
|
||||
base,
|
||||
dataStoreProvider -> (category != null && category.equals(dataStoreProvider.getCreationCategory()))
|
||||
dataStoreProvider -> (category != null && dataStoreProvider.allowCreation() &&
|
||||
category.equals(dataStoreProvider.getCreationCategory()))
|
||||
|| dataStoreProvider.equals(prov),
|
||||
consumer,
|
||||
false,
|
||||
|
||||
@@ -153,7 +153,7 @@ public class StoreCreationMenu {
|
||||
});
|
||||
|
||||
int lastOrder = providers.getFirst().getOrderPriority();
|
||||
for (io.xpipe.app.ext.DataStoreProvider dataStoreProvider : providers) {
|
||||
for (var dataStoreProvider : providers) {
|
||||
if (dataStoreProvider.getOrderPriority() != lastOrder) {
|
||||
menu.getItems().add(new SeparatorMenuItem());
|
||||
lastOrder = dataStoreProvider.getOrderPriority();
|
||||
@@ -167,6 +167,7 @@ public class StoreCreationMenu {
|
||||
StoreCreationDialog.showCreation(dataStoreProvider, category);
|
||||
event.consume();
|
||||
});
|
||||
item.setDisable(!dataStoreProvider.allowCreation());
|
||||
menu.getItems().add(item);
|
||||
}
|
||||
return menu;
|
||||
|
||||
@@ -61,7 +61,7 @@ public class BitwardenPasswordManager implements PasswordManager {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static OptionsBuilder createOptions(Property<BitwardenPasswordManager> p) {
|
||||
var agentStrategy = new SimpleObjectProperty<>(p.getValue().keyStrategy);
|
||||
var keyStrategy = new SimpleObjectProperty<>(p.getValue().keyStrategy);
|
||||
|
||||
AtomicReference<Region> button = new AtomicReference<>();
|
||||
var testButton = new ButtonComp(AppI18n.observable("sync"), new FontIcon("mdi2r-refresh"), () -> {
|
||||
@@ -76,18 +76,18 @@ public class BitwardenPasswordManager implements PasswordManager {
|
||||
testButton.apply(struc -> button.set(struc));
|
||||
testButton.padding(new Insets(6, 10, 6, 6));
|
||||
|
||||
var agentStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
var keyStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
.allowNull(true)
|
||||
.available(List.of(PasswordManagerKeyStrategy.Agent.class))
|
||||
.property(agentStrategy)
|
||||
.property(keyStrategy)
|
||||
.build();
|
||||
|
||||
return new OptionsBuilder()
|
||||
.addComp(testButton)
|
||||
.nameAndDescription("passwordManagerKeyStrategy")
|
||||
.sub(agentStrategyChoice.build(), agentStrategy)
|
||||
.sub(keyStrategyChoice.build(), keyStrategy)
|
||||
.bind(() -> {
|
||||
return BitwardenPasswordManager.builder().keyStrategy(agentStrategy.getValue()).build();
|
||||
return BitwardenPasswordManager.builder().keyStrategy(keyStrategy.getValue()).build();
|
||||
}, p);
|
||||
}
|
||||
|
||||
@@ -260,26 +260,6 @@ public class BitwardenPasswordManager implements PasswordManager {
|
||||
|
||||
@Override
|
||||
public PasswordManagerKeyConfiguration getKeyConfiguration() {
|
||||
return new PasswordManagerKeyConfiguration() {
|
||||
@Override
|
||||
public boolean supportsInlineSshKeys() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAgent() {
|
||||
return keyStrategy != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsJoinedEntries() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) {
|
||||
return keyStrategy.getSshIdentityStrategy(publicKey, forward);
|
||||
}
|
||||
};
|
||||
return PasswordManagerKeyConfiguration.of(true, false, keyStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class KeePassXcPasswordManager implements PasswordManager {
|
||||
@SuppressWarnings("unused")
|
||||
public static OptionsBuilder createOptions(Property<KeePassXcPasswordManager> p) {
|
||||
var keyStrategy = new SimpleObjectProperty<>(p.getValue().getKeyStrategy());
|
||||
var agentStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
var keyStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
.allowNull(true)
|
||||
.available(List.of(PasswordManagerKeyStrategy.KeePassXcOpenSshAgent.class, PasswordManagerKeyStrategy.KeePassXcPageant.class))
|
||||
.property(keyStrategy)
|
||||
@@ -95,7 +95,7 @@ public class KeePassXcPasswordManager implements PasswordManager {
|
||||
.hide(Bindings.isEmpty(prop))
|
||||
.addProperty(prop)
|
||||
.nameAndDescription("passwordManagerKeyStrategy")
|
||||
.sub(agentStrategyChoice.build(), keyStrategy)
|
||||
.sub(keyStrategyChoice.build(), keyStrategy)
|
||||
.bind(
|
||||
() -> {
|
||||
return new KeePassXcPasswordManager(prop, keyStrategy.getValue());
|
||||
|
||||
@@ -404,7 +404,7 @@ public class KeeperPasswordManager implements PasswordManager {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static OptionsBuilder createOptions(Property<KeeperPasswordManager> p) {
|
||||
var agentStrategy = new SimpleObjectProperty<>(p.getValue().getKeyStrategy());
|
||||
var keyStrategy = new SimpleObjectProperty<>(p.getValue().getKeyStrategy());
|
||||
var mfa = new SimpleObjectProperty<>(p.getValue().getTwoFactorAuth() != null ? p.getValue().getTwoFactorAuth() : new KeeperAuth.None());
|
||||
|
||||
var choice = OptionsChoiceBuilder.builder()
|
||||
@@ -412,10 +412,10 @@ public class KeeperPasswordManager implements PasswordManager {
|
||||
.available(KeeperAuth.getClasses())
|
||||
.property(mfa)
|
||||
.build();
|
||||
var agentStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
var keyStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
.allowNull(true)
|
||||
.available(List.of(PasswordManagerKeyStrategy.Agent.class))
|
||||
.property(agentStrategy)
|
||||
.available(List.of(PasswordManagerKeyStrategy.Inline.class, PasswordManagerKeyStrategy.Agent.class))
|
||||
.property(keyStrategy)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -423,11 +423,12 @@ public class KeeperPasswordManager implements PasswordManager {
|
||||
.nameAndDescription("keeper2fa")
|
||||
.sub(choice.build(), mfa)
|
||||
.nameAndDescription("passwordManagerKeyStrategy")
|
||||
.sub(agentStrategyChoice.build(), agentStrategy)
|
||||
.sub(keyStrategyChoice.build(), keyStrategy)
|
||||
.bind(
|
||||
() -> {
|
||||
return KeeperPasswordManager.builder()
|
||||
.twoFactorAuth(mfa.get())
|
||||
.keyStrategy(keyStrategy.get())
|
||||
.build();
|
||||
},
|
||||
p);
|
||||
|
||||
@@ -39,19 +39,19 @@ public class OnePasswordManager implements PasswordManager {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static OptionsBuilder createOptions(Property<OnePasswordManager> p) {
|
||||
var agentStrategy = new SimpleObjectProperty<>(p.getValue().getKeyStrategy());
|
||||
var keyStrategy = new SimpleObjectProperty<>(p.getValue().getKeyStrategy());
|
||||
|
||||
var agentStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
var keyStrategyChoice = OptionsChoiceBuilder.builder()
|
||||
.allowNull(true)
|
||||
.available(List.of(PasswordManagerKeyStrategy.Agent.class))
|
||||
.property(agentStrategy)
|
||||
.property(keyStrategy)
|
||||
.build();
|
||||
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("passwordManagerKeyStrategy")
|
||||
.sub(agentStrategyChoice.build(), agentStrategy)
|
||||
.sub(keyStrategyChoice.build(), keyStrategy)
|
||||
.bind(() -> {
|
||||
return OnePasswordManager.builder().keyStrategy(agentStrategy.getValue()).build();
|
||||
return OnePasswordManager.builder().keyStrategy(keyStrategy.getValue()).build();
|
||||
}, p);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,13 @@ public interface PasswordManagerKeyConfiguration {
|
||||
static PasswordManagerKeyConfiguration of(boolean inline, boolean joined, PasswordManagerKeyStrategy strategy) {
|
||||
return new PasswordManagerKeyConfiguration() {
|
||||
@Override
|
||||
public boolean supportsInlineSshKeys() {
|
||||
return inline;
|
||||
public boolean useInline() {
|
||||
return (strategy == null || !strategy.useAgent()) && inline && joined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAgent() {
|
||||
return strategy != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsJoinedEntries() {
|
||||
return joined;
|
||||
public boolean useAgent() {
|
||||
return strategy != null && strategy.useAgent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -31,17 +26,12 @@ public interface PasswordManagerKeyConfiguration {
|
||||
static PasswordManagerKeyConfiguration none() {
|
||||
return new PasswordManagerKeyConfiguration() {
|
||||
@Override
|
||||
public boolean supportsInlineSshKeys() {
|
||||
public boolean useInline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAgent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsJoinedEntries() {
|
||||
public boolean useAgent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -52,11 +42,9 @@ public interface PasswordManagerKeyConfiguration {
|
||||
};
|
||||
}
|
||||
|
||||
boolean supportsInlineSshKeys();
|
||||
boolean useInline();
|
||||
|
||||
boolean supportsAgent();
|
||||
|
||||
boolean supportsJoinedEntries();
|
||||
boolean useAgent();
|
||||
|
||||
SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ public interface PasswordManagerKeyStrategy {
|
||||
return "inlineKey";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAgent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) {
|
||||
return null;
|
||||
@@ -52,6 +57,11 @@ public interface PasswordManagerKeyStrategy {
|
||||
|
||||
FilePath customSocket;
|
||||
|
||||
@Override
|
||||
public boolean useAgent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static String getOptionsNameKey() {
|
||||
return "keyAgent";
|
||||
@@ -134,6 +144,11 @@ public interface PasswordManagerKeyStrategy {
|
||||
property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAgent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) {
|
||||
return OpenSshAgentStrategy.builder().build();
|
||||
@@ -157,12 +172,19 @@ public interface PasswordManagerKeyStrategy {
|
||||
property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAgent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward) {
|
||||
return PageantStrategy.builder().build();
|
||||
}
|
||||
}
|
||||
|
||||
boolean useAgent();
|
||||
|
||||
SshIdentityStrategy getSshIdentityStrategy(String publicKey, boolean forward);
|
||||
|
||||
static List<Class<?>> getClasses() {
|
||||
|
||||
@@ -152,6 +152,7 @@ public class IdentityChoiceBuilder {
|
||||
.allowAgentForward(allowAgentForward)
|
||||
.allowKeyFileSync(true)
|
||||
.perUserKeyFileCheck(() -> false)
|
||||
.allowPasswordAgentKeyChoice(true)
|
||||
.fileSystem(fileSystem)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
|
||||
var sshIdentityChoiceConfig = SshIdentityStrategyChoiceConfig.builder()
|
||||
.allowAgentForward(true)
|
||||
.allowKeyFileSync(false)
|
||||
.allowPasswordAgentKeyChoice(true)
|
||||
.perUserKeyFileCheck(() -> false)
|
||||
.build();
|
||||
|
||||
|
||||
+29
-11
@@ -51,7 +51,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
return true;
|
||||
}
|
||||
|
||||
private PasswordManager.Result retrieveCredentials() {
|
||||
private PasswordManager.Result retrieve() {
|
||||
if (!checkOutdatedOrRefresh()) {
|
||||
var r = getCache("result", PasswordManager.Result.class, null);
|
||||
if (r != null) {
|
||||
@@ -79,6 +79,18 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
new UnsupportedOperationException("Identity " + key + " does not provide a username"));
|
||||
}
|
||||
|
||||
if (sshKey != null) {
|
||||
var pwman = AppPrefs.get().passwordManager().getValue();
|
||||
if (pwman.getKeyConfiguration().useInline() && r.getSshKey() == null) {
|
||||
throw ErrorEventFactory.expected(
|
||||
new UnsupportedOperationException("Identity " + key + " does not provide an SSH key"));
|
||||
}
|
||||
|
||||
if (pwman.getKeyConfiguration().useAgent()) {
|
||||
SshAgentKeyList.validate();
|
||||
}
|
||||
}
|
||||
|
||||
setCache("lastQueried", Instant.now());
|
||||
setCache("result", r);
|
||||
|
||||
@@ -87,7 +99,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
|
||||
public UsernameStrategy getUsername() {
|
||||
return new UsernameStrategy.Dynamic(() -> {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
var effective = r != null && r.getCredentials() != null && r.getCredentials().getUsername() != null ? r.getCredentials().getUsername() : "unknown";
|
||||
return effective;
|
||||
});
|
||||
@@ -102,7 +114,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
return new SecretQuery() {
|
||||
@Override
|
||||
public SecretQueryResult query(String prompt) {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
if (r == null || r.getCredentials() == null || r.getCredentials().getPassword() == null) {
|
||||
return new SecretQueryResult(null, SecretQueryState.RETRIEVAL_FAILURE);
|
||||
}
|
||||
@@ -138,15 +150,15 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
}
|
||||
|
||||
var strat = r.getKeyConfiguration();
|
||||
if (strat == null || (!strat.supportsInlineSshKeys() && !strat.supportsAgent())) {
|
||||
if (strat == null || (!strat.useInline() && !strat.useAgent())) {
|
||||
return def;
|
||||
}
|
||||
|
||||
if (strat.supportsInlineSshKeys() && strat.supportsJoinedEntries()) {
|
||||
if (strat.useInline()) {
|
||||
return new SshIdentityStrategy() {
|
||||
@Override
|
||||
public void prepareParent(ShellControl parent) throws Exception {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
if (r == null || r.getSshKey() == null || r.getSshKey().getPrivateKey() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -157,7 +169,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
|
||||
@Override
|
||||
public void buildCommand(CommandBuilder builder) {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
if (r == null || r.getSshKey() == null || r.getSshKey().getPrivateKey() == null) {
|
||||
return;
|
||||
}
|
||||
@@ -168,7 +180,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
|
||||
@Override
|
||||
public List<KeyValue> configOptions(ShellControl sc) throws Exception {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
if (r == null || r.getSshKey() == null || r.getSshKey().getPrivateKey() == null) {
|
||||
return List.of();
|
||||
}
|
||||
@@ -179,7 +191,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
|
||||
@Override
|
||||
public String getPublicKey() {
|
||||
var r = retrieveCredentials();
|
||||
var r = retrieve();
|
||||
if (r == null || r.getSshKey() == null || r.getSshKey().getPublicKey() == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -189,17 +201,23 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
};
|
||||
}
|
||||
|
||||
var agentStrat = strat.getSshIdentityStrategy(null, false);
|
||||
if (strat.useAgent() && sshKey != null) {
|
||||
return sshKey;
|
||||
}
|
||||
|
||||
return new NoIdentityStrategy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
Validators.nonNull(key);
|
||||
if (sshKey != null) {
|
||||
sshKey.checkComplete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate() {
|
||||
retrieveCredentials();
|
||||
retrieve();
|
||||
}
|
||||
}
|
||||
|
||||
+22
-15
@@ -1,30 +1,28 @@
|
||||
package io.xpipe.ext.base.identity;
|
||||
|
||||
import io.xpipe.app.cred.SshIdentityStrategy;
|
||||
import io.xpipe.app.cred.PasswordManagerAgentStrategy;
|
||||
import io.xpipe.app.cred.SshIdentityStrategyChoiceConfig;
|
||||
import io.xpipe.app.ext.DataStore;
|
||||
import io.xpipe.app.ext.DataStoreCreationCategory;
|
||||
import io.xpipe.app.ext.GuiDialog;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.platform.OptionsChoiceBuilder;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.PasswordManagerTestComp;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import io.xpipe.app.storage.DataStorageUserHandler;
|
||||
import io.xpipe.app.storage.DataStoreCategory;
|
||||
import io.xpipe.app.storage.DataStoreEntry;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PasswordManagerIdentityStoreProvider extends IdentityStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStoreCreationCategory getCreationCategory() {
|
||||
return AppPrefs.get().passwordManager().getValue() != null ? DataStoreCreationCategory.IDENTITY : null;
|
||||
public boolean allowCreation() {
|
||||
return AppPrefs.get().passwordManager().getValue() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,21 +33,30 @@ public class PasswordManagerIdentityStoreProvider extends IdentityStoreProvider
|
||||
var sshKey = new SimpleObjectProperty<>(st.getSshKey());
|
||||
var perUser = new SimpleBooleanProperty(st.isPerUser());
|
||||
|
||||
var pwMan = AppPrefs.get().passwordManager().getValue();
|
||||
var showKeyChoice = pwMan == null || !pwMan.getKeyConfiguration().useInline();
|
||||
var sshIdentityChoiceConfig = SshIdentityStrategyChoiceConfig.builder()
|
||||
.allowAgentForward(true)
|
||||
.allowKeyFileSync(true)
|
||||
.allowPasswordAgentKeyChoice(showKeyChoice)
|
||||
.perUserKeyFileCheck(() -> false)
|
||||
.fileSystem(new ReadOnlyObjectWrapper<>(DataStorage.get().local().ref()))
|
||||
.build();
|
||||
var sshKeyChoice = OptionsChoiceBuilder.builder().allowNull(true)
|
||||
.available(SshIdentityStrategy.getClasses()).property(sshKey).build();
|
||||
.customConfiguration(sshIdentityChoiceConfig)
|
||||
.available(List.of(PasswordManagerAgentStrategy.class)).property(sshKey).build();
|
||||
var hideSshKeyChoice = Bindings.createBooleanBinding(() -> {
|
||||
var pwman = AppPrefs.get().passwordManager().getValue();
|
||||
var strat = pwman.getKeyConfiguration();
|
||||
return !strat.supportsAgent() ||
|
||||
(strat.supportsJoinedEntries() && strat.supportsInlineSshKeys());
|
||||
});
|
||||
return !strat.useAgent() && !strat.useInline();
|
||||
}, AppPrefs.get().passwordManager());
|
||||
|
||||
var comp = new PasswordManagerTestComp(key, false);
|
||||
var testComp = new PasswordManagerTestComp(key, false);
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("passwordManagerKey")
|
||||
.addComp(comp.hgrow(), key)
|
||||
.addComp(testComp.hgrow(), key)
|
||||
.nonNull()
|
||||
.nameAndDescription("sshKey")
|
||||
.nameAndDescription("passwordManagerIdentityAgentKey")
|
||||
.sub(sshKeyChoice.build(), sshKey)
|
||||
.hide(hideSshKeyChoice)
|
||||
.nameAndDescription(
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.xpipe.app.hub.comp.StoreEntryWrapper;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.platform.OptionsChoiceBuilder;
|
||||
import io.xpipe.app.platform.Validator;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.prefs.VaultAuthentication;
|
||||
import io.xpipe.app.secret.EncryptedValue;
|
||||
import io.xpipe.app.secret.SecretNoneStrategy;
|
||||
@@ -29,8 +30,8 @@ import java.util.UUID;
|
||||
public class SyncedIdentityStoreProvider extends IdentityStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStoreCreationCategory getCreationCategory() {
|
||||
return DataStorage.get().supportsSync() ? DataStoreCreationCategory.IDENTITY : null;
|
||||
public boolean allowCreation() {
|
||||
return DataStorage.get().supportsSync();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,6 +76,7 @@ public class SyncedIdentityStoreProvider extends IdentityStoreProvider {
|
||||
var sshIdentityChoiceConfig = SshIdentityStrategyChoiceConfig.builder()
|
||||
.allowAgentForward(true)
|
||||
.allowKeyFileSync(true)
|
||||
.allowPasswordAgentKeyChoice(true)
|
||||
.perUserKeyFileCheck(() -> perUser.get())
|
||||
.build();
|
||||
|
||||
|
||||
Generated
+6
-2
@@ -1454,7 +1454,8 @@ terminalPromptConfiguration=Terminal prompt configuration
|
||||
terminalPromptConfig=Config file
|
||||
terminalPromptConfigDescription=The custom config file to apply to the prompt. This config will be automatically set up on the target system when the terminal is initialized and used as the default prompt config.\n\nIf you want to use the existing default config file on each system, you can leave this field empty.
|
||||
passwordManagerKey=Password manager key
|
||||
passwordManagerKeyDescription=The password manager identifier of the secret
|
||||
#force
|
||||
passwordManagerKeyDescription=The password manager identifier of the credentials entry
|
||||
passwordManagerAgent=Password manager agent
|
||||
dockerComposeProject.displayName=Docker compose project
|
||||
dockerComposeProject.displayDescription=Group containers of a compose project together
|
||||
@@ -1532,7 +1533,8 @@ customVncCommandDescription=The custom command to execute to launch VNC sessions
|
||||
vncConnections=VNC connections
|
||||
passwordManagerIdentity=Password manager identity
|
||||
passwordManagerIdentity.displayName=Password manager identity
|
||||
passwordManagerIdentity.displayDescription=Retrieve username and password of an identity from your password manager
|
||||
#force
|
||||
passwordManagerIdentity.displayDescription=Retrieve credentials of an identity from your password manager
|
||||
passwordCopied=Connection password copied to clipboard
|
||||
errorOccurred=Error occurred
|
||||
actionMacro.displayName=Action macro
|
||||
@@ -2010,3 +2012,5 @@ keePassXcPageant=Use Pageant
|
||||
passwordManagerSshAgentSocket=SSH agent socket
|
||||
passwordManagerSshAgentSocketDescription=Override the default agent socket location that should be used.
|
||||
passwordManagerSshKeysNotSupported=The current password manager configuration does not support retrieving SSH keys
|
||||
passwordManagerIdentityAgentKey=Additional SSH key
|
||||
passwordManagerIdentityAgentKeyDescription=The SSH key to use from the password manager SSH agent
|
||||
|
||||
Reference in New Issue
Block a user