mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-09-26 10:25:44 +00:00
Rework
This commit is contained in:
@@ -39,22 +39,26 @@ public class PasswordManagerAgentStrategy implements SshIdentityAgentStrategy {
|
||||
var identifier =
|
||||
new SimpleStringProperty(p.getValue() != null ? p.getValue().getIdentifier() : null);
|
||||
|
||||
var pwmanBinding = Bindings.createObjectBinding(() -> {
|
||||
var pwmanError = Bindings.createObjectBinding(() -> {
|
||||
var pwman = AppPrefs.get().passwordManager().getValue();
|
||||
if (pwman == null) {
|
||||
return AppI18n.get("passwordManagerEmpty");
|
||||
}
|
||||
|
||||
if (!pwman.getKeyConfiguration().useAgent()) {
|
||||
if (!pwman.supportsKeyConfiguration()) {
|
||||
return AppI18n.get("passwordManagerNoAgentSupport");
|
||||
}
|
||||
|
||||
if (!pwman.getKeyConfiguration().useAgent()) {
|
||||
return AppI18n.get("passwordManagerNoAgentConfigured");
|
||||
}
|
||||
|
||||
return null;
|
||||
}, AppPrefs.get().passwordManager(), AppI18n.activeLanguage());
|
||||
var pwmanProp = new SimpleStringProperty();
|
||||
pwmanProp.bind(pwmanBinding);
|
||||
var pwmanErrorProp = new SimpleStringProperty();
|
||||
pwmanErrorProp.bind(pwmanError);
|
||||
var pwmanDisplay = new HorizontalComp(List.of(
|
||||
new LabelComp(pwmanProp)
|
||||
new LabelComp(pwmanErrorProp)
|
||||
.maxWidth(10000)
|
||||
.apply(label -> label.setAlignment(Pos.CENTER_LEFT))
|
||||
.hgrow(),
|
||||
@@ -67,9 +71,10 @@ public class PasswordManagerAgentStrategy implements SshIdentityAgentStrategy {
|
||||
return new OptionsBuilder()
|
||||
.nameAndDescription("passwordManagerSshKeyConfig")
|
||||
.addComp(pwmanDisplay)
|
||||
.hide(pwmanProp.isNull())
|
||||
.hide(pwmanErrorProp.isNull())
|
||||
.nameAndDescription(useKeyName() ? "agentKeyName" : "publicKey")
|
||||
.addComp(new SshAgentKeyListComp(config.getFileSystem(), p, identifier, useKeyName()), identifier)
|
||||
.disable(pwmanErrorProp.isNotNull())
|
||||
.nonNull()
|
||||
.hide(!config.isAllowAgentForward())
|
||||
.bind(
|
||||
|
||||
@@ -61,7 +61,7 @@ public class SshAgentKeyList {
|
||||
|
||||
var type = matcher.group(1);
|
||||
var publicKey = matcher.group(2);
|
||||
var name = matcher.groupCount() > 3 ? matcher.group(3) : null;
|
||||
var name = matcher.groupCount() > 2 ? matcher.group(3) : null;
|
||||
list.add(new Entry(type, publicKey, name));
|
||||
}
|
||||
return list;
|
||||
|
||||
@@ -74,6 +74,7 @@ public class SshAgentKeyListComp extends SimpleRegionBuilder {
|
||||
});
|
||||
entryButton.setMinWidth(400);
|
||||
entryButton.setAlignment(Pos.CENTER_LEFT);
|
||||
entryButton.setMnemonicParsing(false);
|
||||
content.getChildren().add(entryButton);
|
||||
}
|
||||
popover.setContentNode(content);
|
||||
|
||||
@@ -52,6 +52,7 @@ public class SshAgentTestComp extends SimpleRegionBuilder {
|
||||
entryButton.getStyleClass().add(Styles.FLAT);
|
||||
entryButton.setMinWidth(400);
|
||||
entryButton.setAlignment(Pos.CENTER_LEFT);
|
||||
entryButton.setMnemonicParsing(false);
|
||||
content.getChildren().add(entryButton);
|
||||
}
|
||||
popover.setContentNode(content);
|
||||
|
||||
@@ -234,6 +234,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
|
||||
newCategory.setOnAction(event -> {
|
||||
StoreViewState.get().createNewCategory(category);
|
||||
});
|
||||
newCategory.setDisable(!DataStorage.get().canCreateStoreCategoryWithin(category.getCategory()));
|
||||
contextMenu.getItems().add(newCategory);
|
||||
|
||||
contextMenu.getItems().add(new SeparatorMenuItem());
|
||||
|
||||
@@ -107,12 +107,11 @@ public class PasswordManagerTestComp extends SimpleRegionBuilder {
|
||||
}
|
||||
|
||||
List<String> elements = new ArrayList<>();
|
||||
if (r.getCredentials() != null && r.getCredentials().getUsername() != null) {
|
||||
elements.add(r.getCredentials().getUsername());
|
||||
}
|
||||
|
||||
if (r.getCredentials() != null && r.getCredentials().getPassword() != null) {
|
||||
elements.add("[" + r.getCredentials().getPassword().getSecretValue() + "]");
|
||||
if (r.getCredentials() != null) {
|
||||
elements.add(r.getCredentials().getUsername() != null ? r.getCredentials().getUsername() : "<no user>");
|
||||
elements.add(r.getCredentials().getPassword() != null ? ("[" + r.getCredentials().getPassword().getSecretValue() + "]") : "<no password>");
|
||||
} else {
|
||||
elements.add("<no credentials>");
|
||||
}
|
||||
|
||||
if (r.getSshKey() != null) {
|
||||
|
||||
@@ -273,6 +273,11 @@ public class BitwardenPasswordManager implements PasswordManager {
|
||||
return "https://bitwarden.com/";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordManagerKeyConfiguration getKeyConfiguration() {
|
||||
return PasswordManagerKeyConfiguration.of(true, false, true, keyStrategy, getSocketLocation());
|
||||
|
||||
@@ -24,6 +24,11 @@ public class DashlanePasswordManager implements PasswordManager {
|
||||
private static ShellControl SHELL;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return LocalShell.getShell().view().findProgram("dcli").isPresent();
|
||||
|
||||
@@ -47,6 +47,11 @@ public class EnpassPasswordManager implements PasswordManager {
|
||||
private static ShellControl SHELL;
|
||||
private final FilePath vaultPath;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return LocalShell.getShell().view().findProgram("enpass-cli").isPresent();
|
||||
|
||||
@@ -38,6 +38,11 @@ import java.util.*;
|
||||
@JsonTypeName("hashicorpVault")
|
||||
public class HashicorpVaultPasswordManager implements PasswordManager {
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
public interface VaultAuth {
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ public class KeePassXcPasswordManager implements PasswordManager {
|
||||
private final List<KeePassXcAssociationKey> associationKeys;
|
||||
private final PasswordManagerKeyStrategy keyStrategy;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return findKeePassProxy().isPresent();
|
||||
|
||||
@@ -51,6 +51,11 @@ public class KeeperPasswordManager implements PasswordManager {
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return LocalShell.getShell().view().findProgram("keeper-commander").isPresent();
|
||||
|
||||
@@ -37,6 +37,11 @@ public class LastpassPasswordManager implements PasswordManager {
|
||||
|
||||
private static ShellControl SHELL;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static OptionsBuilder createOptions(Property<LastpassPasswordManager> p) {
|
||||
return new OptionsBuilder()
|
||||
|
||||
@@ -31,6 +31,11 @@ import java.util.regex.Pattern;
|
||||
@Getter
|
||||
public class OnePasswordManager implements PasswordManager {
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordManagerKeyConfiguration getKeyConfiguration() {
|
||||
return PasswordManagerKeyConfiguration.of(true, false, true, keyStrategy, getSocketLocation());
|
||||
|
||||
@@ -47,6 +47,11 @@ public class PassboltPasswordManager implements PasswordManager {
|
||||
private final InPlaceSecretValue passphrase;
|
||||
private final Path privateKey;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return LocalShell.getShell().view().findProgram("passbolt").isPresent();
|
||||
|
||||
@@ -92,6 +92,8 @@ public interface PasswordManager {
|
||||
|
||||
String getWebsite();
|
||||
|
||||
boolean supportsKeyConfiguration();
|
||||
|
||||
PasswordManagerKeyConfiguration getKeyConfiguration();
|
||||
|
||||
boolean selectInitial() throws Exception;
|
||||
|
||||
@@ -42,6 +42,11 @@ public class PasswordManagerCommand implements PasswordManager {
|
||||
return PasswordManagerKeyConfiguration.none();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static OptionsBuilder createOptions(Property<PasswordManagerCommand> property) {
|
||||
var template = new SimpleObjectProperty<PasswordManagerCommandTemplate>();
|
||||
|
||||
@@ -25,6 +25,11 @@ import java.util.List;
|
||||
@Getter
|
||||
public class ProtonPasswordManager implements PasswordManager {
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordManagerKeyConfiguration getKeyConfiguration() {
|
||||
return PasswordManagerKeyConfiguration.of(false, false, true, keyStrategy, getSocketLocation());
|
||||
|
||||
@@ -39,6 +39,11 @@ public class PsonoPasswordManager implements PasswordManager {
|
||||
private final InPlaceSecretValue apiSecretKey;
|
||||
private final String serverUrl;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean selectInitial() throws Exception {
|
||||
return LocalShell.getShell().view().findProgram("psonoci").isPresent();
|
||||
|
||||
@@ -17,6 +17,11 @@ public class WindowsCredentialManager implements PasswordManager {
|
||||
|
||||
private static boolean loaded = false;
|
||||
|
||||
@Override
|
||||
public boolean supportsKeyConfiguration() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PasswordManagerKeyConfiguration getKeyConfiguration() {
|
||||
return PasswordManagerKeyConfiguration.none();
|
||||
|
||||
@@ -423,6 +423,7 @@ public abstract class DataStorage {
|
||||
other.finalizeEntry();
|
||||
}
|
||||
}
|
||||
entry.finalizeEntry();
|
||||
}
|
||||
|
||||
private Collection<DataStoreEntryRef<?>> getDependencies(DataStoreEntry entry) {
|
||||
@@ -1028,6 +1029,10 @@ public abstract class DataStorage {
|
||||
saveAsync();
|
||||
}
|
||||
|
||||
public boolean canCreateStoreCategoryWithin(@NonNull DataStoreCategory cat) {
|
||||
return !cat.getUuid().equals(ALL_IDENTITIES_CATEGORY_UUID);
|
||||
}
|
||||
|
||||
public boolean canDeleteStoreCategory(@NonNull DataStoreCategory cat) {
|
||||
if (cat.getParentCategory() == null) {
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import java.util.stream.Stream
|
||||
plugins {
|
||||
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
|
||||
id 'org.gradlex.extra-java-module-info' version '1.14' apply false
|
||||
id("com.diffplug.spotless") version "8.2.1" apply false
|
||||
id("com.diffplug.spotless") version "8.3.0" apply false
|
||||
}
|
||||
|
||||
allprojects { subproject ->
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.xpipe.ext.base.identity;
|
||||
import io.xpipe.app.cred.UsernameStrategy;
|
||||
import io.xpipe.app.ext.DataStore;
|
||||
import io.xpipe.app.ext.SelfReferentialStore;
|
||||
import io.xpipe.app.ext.ValidationException;
|
||||
import io.xpipe.app.secret.SecretRetrievalStrategy;
|
||||
import io.xpipe.app.cred.SshIdentityStrategy;
|
||||
|
||||
@@ -24,7 +25,7 @@ public abstract class IdentityStore implements SelfReferentialStore, DataStore {
|
||||
public abstract SshIdentityStrategy getSshIdentity();
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
public void checkComplete() throws ValidationException {
|
||||
if (getPassword() != null) {
|
||||
getPassword().checkComplete();
|
||||
}
|
||||
|
||||
@@ -160,6 +160,7 @@ public interface IdentityValue {
|
||||
public void checkComplete() throws ValidationException {
|
||||
Validators.nonNull(ref);
|
||||
Validators.isType(ref, IdentityStore.class);
|
||||
ref.getStore().checkComplete();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.xpipe.app.cred.*;
|
||||
import io.xpipe.app.ext.InternalCacheDataStore;
|
||||
import io.xpipe.app.ext.UserScopeStore;
|
||||
import io.xpipe.app.ext.ValidatableStore;
|
||||
import io.xpipe.app.ext.ValidationException;
|
||||
import io.xpipe.app.issue.ErrorEventFactory;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.process.CommandBuilder;
|
||||
@@ -73,6 +74,11 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
new UnsupportedOperationException("Credentials were requested but not supplied"));
|
||||
}
|
||||
|
||||
if (r.getSshKey() != null && r.getCredentials() == null) {
|
||||
throw ErrorEventFactory.expected(
|
||||
new UnsupportedOperationException("Identity " + key + " does not provide credentials, only a key. Use another credentials entry as a base and reference the key via the password manager agent option instead"));
|
||||
}
|
||||
|
||||
if (r.getCredentials() == null) {
|
||||
throw ErrorEventFactory.expected(
|
||||
new UnsupportedOperationException("Identity " + key + " does not provide credentials"));
|
||||
@@ -219,7 +225,7 @@ public class PasswordManagerIdentityStore extends IdentityStore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
public void checkComplete() throws ValidationException {
|
||||
Validators.nonNull(key);
|
||||
if (sshKey != null) {
|
||||
sshKey.checkComplete();
|
||||
|
||||
@@ -53,7 +53,7 @@ public class SyncedIdentityStore extends IdentityStore implements UserScopeStore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkComplete() throws Throwable {
|
||||
public void checkComplete() throws ValidationException {
|
||||
super.checkComplete();
|
||||
if (getSshIdentity() instanceof KeyFileStrategy f) {
|
||||
if (!f.getFile().isInDataDirectory()) {
|
||||
|
||||
Generated
+2
-1
@@ -2007,7 +2007,8 @@ passwordManagerKeyStrategy=SSH key retrieval method
|
||||
passwordManagerKeyStrategyDescription=How to retrieve SSH keys stored in the password manager. When disabled, no keys can be retrieved. When an SSH agent is configured, the agent must be properly started in the password manager.
|
||||
sshAgentNoKeys=The agent does not have any keys at the moment
|
||||
sshAgentHasKeys=The agent currently offers the following keys:
|
||||
passwordManagerNoAgentSupport=Password manager does not support retrieving SSH keys
|
||||
passwordManagerNoAgentSupport=Password manager does not support retrieving SSH keys via an agent
|
||||
passwordManagerNoAgentConfigured=XPipe is not configured for retrieving SSH keys from the agent
|
||||
passwordManagerEmpty=No password manager is configured
|
||||
passwordManagerSshKeyConfig=Password manager configuration
|
||||
passwordManagerSshKeyConfigDescription=Check the status of the password manager
|
||||
|
||||
Reference in New Issue
Block a user