mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-04-23 16:09:20 -04:00
Rework encryption
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
package io.xpipe.app.ext;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
|
||||
public interface PrefsHandler {
|
||||
|
||||
<T> void addSetting(String id, Class<T> c, Property<T> property, Comp<?> comp, boolean requiresRestart);
|
||||
<T> void addSetting(String id, JavaType t, Property<T> property, Comp<?> comp, boolean requiresRestart);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
||||
import com.fasterxml.jackson.databind.type.TypeFactory;
|
||||
import io.xpipe.app.comp.Comp;
|
||||
import io.xpipe.app.core.*;
|
||||
import io.xpipe.app.core.mode.OperationMode;
|
||||
@@ -551,8 +554,7 @@ public class AppPrefs {
|
||||
private <T> T loadValue(AppPrefsStorageHandler handler, Mapping value) {
|
||||
T def = (T) value.getProperty().getValue();
|
||||
Property<T> property = (Property<T>) value.getProperty();
|
||||
Class<T> clazz = (Class<T>) value.getValueClass();
|
||||
var val = handler.loadObject(value.getKey(), clazz, def);
|
||||
var val = handler.loadObject(value.getKey(), value.getValueType(), def);
|
||||
property.setValue(val);
|
||||
return val;
|
||||
}
|
||||
@@ -607,28 +609,47 @@ public class AppPrefs {
|
||||
|
||||
String key;
|
||||
Property<?> property;
|
||||
Class<?> valueClass;
|
||||
JavaType valueType;
|
||||
boolean vaultSpecific;
|
||||
boolean requiresRestart;
|
||||
String licenseFeatureId;
|
||||
|
||||
public Mapping(
|
||||
String key, Property<?> property, Class<?> valueClass, boolean vaultSpecific, boolean requiresRestart) {
|
||||
String key, Property<?> property, Class<?> valueType, boolean vaultSpecific, boolean requiresRestart) {
|
||||
this.key = key;
|
||||
this.property = property;
|
||||
this.valueClass = valueClass;
|
||||
this.valueType = SimpleType.constructUnsafe(valueType);
|
||||
this.vaultSpecific = vaultSpecific;
|
||||
this.requiresRestart = requiresRestart;
|
||||
this.licenseFeatureId = null;
|
||||
}
|
||||
|
||||
public Mapping(
|
||||
String key, Property<?> property, JavaType valueType, boolean vaultSpecific, boolean requiresRestart) {
|
||||
this.key = key;
|
||||
this.property = property;
|
||||
this.valueType = valueType;
|
||||
this.vaultSpecific = vaultSpecific;
|
||||
this.requiresRestart = requiresRestart;
|
||||
this.licenseFeatureId = null;
|
||||
}
|
||||
|
||||
|
||||
public static class MappingBuilder {
|
||||
|
||||
MappingBuilder valueClass(Class<?> clazz) {
|
||||
this.valueType(TypeFactory.defaultInstance().constructType(clazz));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private class PrefsHandlerImpl implements PrefsHandler {
|
||||
|
||||
@Override
|
||||
public <T> void addSetting(String id, Class<T> c, Property<T> property, Comp<?> comp, boolean requiresRestart) {
|
||||
var m = new Mapping(id, property, c, false, requiresRestart);
|
||||
public <T> void addSetting(String id, JavaType t, Property<T> property, Comp<?> comp, boolean requiresRestart) {
|
||||
var m = new Mapping(id, property, t, false, requiresRestart);
|
||||
customEntries.put(m, comp);
|
||||
mapping.add(m);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.xpipe.app.prefs;
|
||||
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import io.xpipe.app.ext.PrefsChoiceValue;
|
||||
import io.xpipe.app.issue.ErrorEvent;
|
||||
import io.xpipe.app.issue.TrackEvent;
|
||||
@@ -16,6 +17,7 @@ import org.apache.commons.io.FileUtils;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static io.xpipe.app.ext.PrefsChoiceValue.getAll;
|
||||
import static io.xpipe.app.ext.PrefsChoiceValue.getSupported;
|
||||
@@ -77,7 +79,7 @@ public class AppPrefsStorageHandler {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T loadObject(String id, Class<T> type, T defaultObject) {
|
||||
public <T> T loadObject(String id, JavaType type, T defaultObject) {
|
||||
var tree = getContent(id);
|
||||
if (tree == null) {
|
||||
TrackEvent.withDebug("Preferences value not found")
|
||||
@@ -87,10 +89,10 @@ public class AppPrefsStorageHandler {
|
||||
return defaultObject;
|
||||
}
|
||||
|
||||
if (PrefsChoiceValue.class.isAssignableFrom(type)) {
|
||||
var all = getAll(type);
|
||||
if (PrefsChoiceValue.class.isAssignableFrom(type.getRawClass())) {
|
||||
List<T> all = (List<T>) getAll(type.getRawClass());
|
||||
if (all != null) {
|
||||
Class<PrefsChoiceValue> cast = (Class<PrefsChoiceValue>) type;
|
||||
Class<PrefsChoiceValue> cast = (Class<PrefsChoiceValue>) type.getRawClass();
|
||||
var in = tree.asText();
|
||||
var found = all.stream()
|
||||
.filter(t -> ((PrefsChoiceValue) t).getId().equalsIgnoreCase(in))
|
||||
|
||||
@@ -45,7 +45,7 @@ public class DataStorageNode {
|
||||
}
|
||||
|
||||
try {
|
||||
var secret = JacksonMapper.getDefault().treeToValue(node, DataStorageSecret.class);
|
||||
var secret = DataStorageSecret.deserialize(node);
|
||||
if (secret == null) {
|
||||
return new DataStorageNode(node, false, true, false);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package io.xpipe.app.storage;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.util.EncryptionToken;
|
||||
import io.xpipe.app.util.PasswordLockSecretValue;
|
||||
import io.xpipe.app.util.VaultKeySecretValue;
|
||||
import io.xpipe.core.util.EncryptedSecretValue;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
||||
@@ -10,11 +16,50 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Value
|
||||
public class DataStorageSecret {
|
||||
|
||||
public static DataStorageSecret deserialize(JsonNode tree) throws IOException {
|
||||
if (!tree.isObject()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var legacy = JacksonMapper.getDefault().treeToValue(tree, EncryptedSecretValue.class);
|
||||
if (legacy != null) {
|
||||
// Don't cache legacy node
|
||||
return new DataStorageSecret(EncryptionToken.ofVaultKey(), null, legacy.inPlace());
|
||||
}
|
||||
|
||||
var obj = (ObjectNode) tree;
|
||||
if (!obj.has("secret")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var secretTree = obj.required("secret");
|
||||
var secret = JacksonMapper.getDefault().treeToValue(secretTree, SecretValue.class);
|
||||
if (secret == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hadLock = AppPrefs.get().getLockCrypt().get() != null
|
||||
&& !AppPrefs.get().getLockCrypt().get().isEmpty();
|
||||
var tokenNode = obj.get("encryptedToken");
|
||||
var token =
|
||||
tokenNode != null ? JacksonMapper.getDefault().treeToValue(tokenNode, EncryptionToken.class) : null;
|
||||
if (token == null) {
|
||||
var userToken = hadLock;
|
||||
if (userToken && DataStorageUserHandler.getInstance().getActiveUser() == null) {
|
||||
return null;
|
||||
}
|
||||
token = userToken ? EncryptionToken.ofUser() : EncryptionToken.ofVaultKey();
|
||||
}
|
||||
|
||||
return new DataStorageSecret(token, secretTree, secret);
|
||||
}
|
||||
|
||||
public static DataStorageSecret ofCurrentSecret(SecretValue internalSecret) {
|
||||
var handler = DataStorageUserHandler.getInstance();
|
||||
return new DataStorageSecret(
|
||||
@@ -41,7 +86,7 @@ public class DataStorageSecret {
|
||||
this.internalSecret = internalSecret;
|
||||
}
|
||||
|
||||
public boolean requiresRewrite() {
|
||||
public boolean requiresRewrite(boolean allowUserSecretKey) {
|
||||
var isVault = encryptedToken.isVault();
|
||||
var isUser = encryptedToken.isUser();
|
||||
var userHandler = DataStorageUserHandler.getInstance();
|
||||
@@ -53,12 +98,17 @@ public class DataStorageSecret {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We don't want to use the new user key
|
||||
if (!allowUserSecretKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
var hasUserKey = userHandler.getActiveUser() != null;
|
||||
// Switch from vault to user
|
||||
if (hasUserKey && isVault) {
|
||||
if (hasUserKey && isVault && allowUserSecretKey) {
|
||||
return true;
|
||||
}
|
||||
// Switch from user to vault
|
||||
@@ -69,9 +119,9 @@ public class DataStorageSecret {
|
||||
return false;
|
||||
}
|
||||
|
||||
public JsonNode rewrite() {
|
||||
public JsonNode rewrite(boolean allowUserSecretKey) {
|
||||
var handler = DataStorageUserHandler.getInstance();
|
||||
if (handler != null && handler.getActiveUser() != null && encryptedToken.isUser()) {
|
||||
if (handler != null && handler.getActiveUser() != null && allowUserSecretKey) {
|
||||
var val = new PasswordLockSecretValue(getSecret());
|
||||
originalNode = JacksonMapper.getDefault().valueToTree(val);
|
||||
encryptedToken = EncryptionToken.ofUser();
|
||||
@@ -84,6 +134,24 @@ public class DataStorageSecret {
|
||||
return originalNode;
|
||||
}
|
||||
|
||||
public void serialize(JsonGenerator jgen, boolean allowUserSecretKey) throws IOException {
|
||||
var mapper = JacksonMapper.getDefault();
|
||||
var tree = JsonNodeFactory.instance.objectNode();
|
||||
tree.set("encryptedToken", mapper.valueToTree(getEncryptedToken()));
|
||||
|
||||
// Preserve same output if not changed
|
||||
if (getOriginalNode() != null && !requiresRewrite(allowUserSecretKey)) {
|
||||
tree.set("secret", getOriginalNode());
|
||||
jgen.writeTree(tree);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reencrypt
|
||||
var val = rewrite(allowUserSecretKey);
|
||||
tree.set("secret", val);
|
||||
jgen.writeTree(tree);
|
||||
}
|
||||
|
||||
public char[] getSecret() {
|
||||
return internalSecret != null ? internalSecret.getSecret() : new char[0];
|
||||
}
|
||||
|
||||
@@ -391,9 +391,7 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
deleteLeftovers();
|
||||
if (dispose) {
|
||||
dataStorageUserHandler.save();
|
||||
}
|
||||
dataStorageUserHandler.save();
|
||||
dataStorageSyncHandler.afterStorageSave();
|
||||
if (dispose) {
|
||||
disposed = true;
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package io.xpipe.app.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
|
||||
import com.fasterxml.jackson.databind.type.SimpleType;
|
||||
import io.xpipe.app.ext.LocalStore;
|
||||
import io.xpipe.app.prefs.AppPrefs;
|
||||
import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.terminal.ExternalTerminalType;
|
||||
import io.xpipe.core.util.EncryptedSecretValue;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import io.xpipe.core.util.SecretValue;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.*;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
|
||||
import java.io.CharArrayReader;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -29,10 +28,10 @@ public class AppJacksonModule extends SimpleModule {
|
||||
addDeserializer(DataStoreEntryRef.class, new DataStoreEntryRefDeserializer());
|
||||
addSerializer(ContextualFileReference.class, new LocalFileReferenceSerializer());
|
||||
addDeserializer(ContextualFileReference.class, new LocalFileReferenceDeserializer());
|
||||
addSerializer(DataStorageSecret.class, new DataStoreSecretSerializer());
|
||||
addDeserializer(DataStorageSecret.class, new DataStoreSecretDeserializer());
|
||||
addSerializer(ExternalTerminalType.class, new ExternalTerminalTypeSerializer());
|
||||
addDeserializer(ExternalTerminalType.class, new ExternalTerminalTypeDeserializer());
|
||||
addSerializer(EncryptedValue.class, new EncryptedValueSerializer());
|
||||
addDeserializer(EncryptedValue.class, new EncryptedValueDeserializer());
|
||||
|
||||
context.addSerializers(_serializers);
|
||||
context.addDeserializers(_deserializers);
|
||||
@@ -76,69 +75,49 @@ public class AppJacksonModule extends SimpleModule {
|
||||
}
|
||||
}
|
||||
|
||||
public static class DataStoreSecretSerializer extends JsonSerializer<DataStorageSecret> {
|
||||
@SuppressWarnings("all")
|
||||
public static class EncryptedValueSerializer extends JsonSerializer<EncryptedValue> {
|
||||
|
||||
@Override
|
||||
public void serialize(DataStorageSecret value, JsonGenerator jgen, SerializerProvider provider)
|
||||
public void serialize(EncryptedValue value, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException {
|
||||
var mapper = JacksonMapper.getDefault();
|
||||
var tree = JsonNodeFactory.instance.objectNode();
|
||||
tree.set("encryptedToken", mapper.valueToTree(value.getEncryptedToken()));
|
||||
|
||||
// Preserve same output if not changed
|
||||
if (value.getOriginalNode() != null && !value.requiresRewrite()) {
|
||||
tree.set("secret", value.getOriginalNode());
|
||||
jgen.writeTree(tree);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reencrypt
|
||||
var val = value.rewrite();
|
||||
tree.set("secret", val);
|
||||
jgen.writeTree(tree);
|
||||
value.getSecret().serialize(jgen, value.allowUserSecretKey());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DataStoreSecretDeserializer extends JsonDeserializer<DataStorageSecret> {
|
||||
@SuppressWarnings("all")
|
||||
public static class EncryptedValueDeserializer extends JsonDeserializer<EncryptedValue> implements ContextualDeserializer {
|
||||
|
||||
private boolean useCurrentSecretKey;
|
||||
private Class<?> type;
|
||||
|
||||
@Override
|
||||
public DataStorageSecret deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
var tree = JacksonMapper.getDefault().readTree(p);
|
||||
if (!tree.isObject()) {
|
||||
return null;
|
||||
}
|
||||
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
|
||||
JavaType wrapperType = property.getType();
|
||||
JavaType valueType = wrapperType.containedType(0);
|
||||
var deserializer = new EncryptedValueDeserializer();
|
||||
var useCurrentSecretKey = !wrapperType.equals(SimpleType.constructUnsafe(EncryptedValue.VaultKey.class));
|
||||
deserializer.useCurrentSecretKey = useCurrentSecretKey;
|
||||
deserializer.type = valueType.getRawClass();
|
||||
return deserializer;
|
||||
}
|
||||
|
||||
var legacy = JacksonMapper.getDefault().treeToValue(tree, EncryptedSecretValue.class);
|
||||
if (legacy != null) {
|
||||
// Don't cache legacy node
|
||||
return new DataStorageSecret(EncryptionToken.ofVaultKey(), null, legacy.inPlace());
|
||||
}
|
||||
|
||||
var obj = (ObjectNode) tree;
|
||||
if (!obj.has("secret")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var secretTree = obj.required("secret");
|
||||
var secret = JacksonMapper.getDefault().treeToValue(secretTree, SecretValue.class);
|
||||
@Override
|
||||
public EncryptedValue<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||
Object value;
|
||||
var secret = DataStorageSecret.deserialize(JacksonMapper.getDefault().readTree(p));
|
||||
if (secret == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hadLock = AppPrefs.get().getLockCrypt().get() != null
|
||||
&& !AppPrefs.get().getLockCrypt().get().isEmpty();
|
||||
var tokenNode = obj.get("encryptedToken");
|
||||
var token =
|
||||
tokenNode != null ? JacksonMapper.getDefault().treeToValue(tokenNode, EncryptionToken.class) : null;
|
||||
if (token == null) {
|
||||
var migrateToUser = hadLock;
|
||||
if (migrateToUser && DataStorageUserHandler.getInstance().getActiveUser() == null) {
|
||||
var raw = JacksonMapper.getDefault().readValue(p, type);
|
||||
if (raw != null) {
|
||||
value = raw;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
token = migrateToUser ? EncryptionToken.ofUser() : EncryptionToken.ofVaultKey();
|
||||
} else {
|
||||
value = JacksonMapper.getDefault().readValue(new CharArrayReader(secret.getSecret()), type);
|
||||
}
|
||||
|
||||
return new DataStorageSecret(token, secretTree, secret);
|
||||
var perUser = useCurrentSecretKey || secret.getEncryptedToken().isUser();
|
||||
return perUser ? new EncryptedValue.CurrentKey<>(value, secret) : new EncryptedValue.VaultKey<>(value, secret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
68
app/src/main/java/io/xpipe/app/util/EncryptedValue.java
Normal file
68
app/src/main/java/io/xpipe/app/util/EncryptedValue.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package io.xpipe.app.util;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.storage.DataStorageSecret;
|
||||
import io.xpipe.app.storage.DataStorageUserHandler;
|
||||
import io.xpipe.core.util.JacksonMapper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
|
||||
@JsonSubTypes({
|
||||
@JsonSubTypes.Type(value = EncryptedValue.VaultKey.class),
|
||||
@JsonSubTypes.Type(value = EncryptedValue.CurrentKey.class),
|
||||
})
|
||||
public abstract class EncryptedValue<T> {
|
||||
|
||||
private final T value;
|
||||
private final DataStorageSecret secret;
|
||||
|
||||
public abstract boolean allowUserSecretKey();
|
||||
|
||||
@JsonTypeName("current")
|
||||
public static class CurrentKey<T> extends EncryptedValue<T> {
|
||||
|
||||
public CurrentKey(T value, DataStorageSecret secret) {
|
||||
super(value, secret);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> CurrentKey<T> of(T value) {
|
||||
var handler = DataStorageUserHandler.getInstance();
|
||||
var s = JacksonMapper.getDefault().writeValueAsString(value);
|
||||
var secret = new VaultKeySecretValue(s.toCharArray());
|
||||
return new CurrentKey<>(value, DataStorageSecret.ofSecret(secret,
|
||||
handler.getActiveUser() != null ? EncryptionToken.ofUser() : EncryptionToken.ofVaultKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowUserSecretKey() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonTypeName("vault")
|
||||
public static class VaultKey<T> extends EncryptedValue<T> {
|
||||
|
||||
public VaultKey(T value, DataStorageSecret secret) {
|
||||
super(value, secret);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public static <T> VaultKey<T> of(T value) {
|
||||
var s = JacksonMapper.getDefault().writeValueAsString(value);
|
||||
var secret = new VaultKeySecretValue(s.toCharArray());
|
||||
return new VaultKey<>(value, DataStorageSecret.ofSecret(secret, EncryptionToken.ofVaultKey()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowUserSecretKey() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,9 +52,9 @@ public interface SecretRetrievalStrategy {
|
||||
@Jacksonized
|
||||
class InPlace implements SecretRetrievalStrategy {
|
||||
|
||||
DataStorageSecret value;
|
||||
InPlaceSecretValue value;
|
||||
|
||||
public InPlace(DataStorageSecret value) {
|
||||
public InPlace(InPlaceSecretValue value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public interface SecretRetrievalStrategy {
|
||||
@Override
|
||||
public SecretQueryResult query(String prompt) {
|
||||
return new SecretQueryResult(
|
||||
value != null ? value.getInternalSecret() : InPlaceSecretValue.of(""),
|
||||
value,
|
||||
SecretQueryState.NORMAL);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ import java.util.List;
|
||||
|
||||
public class SecretRetrievalStrategyHelper {
|
||||
|
||||
private static OptionsBuilder inPlace(Property<SecretRetrievalStrategy.InPlace> p, boolean allowUserSecretKey) {
|
||||
private static OptionsBuilder inPlace(Property<SecretRetrievalStrategy.InPlace> p) {
|
||||
var original = p.getValue() != null ? p.getValue().getValue() : null;
|
||||
var secretProperty = new SimpleObjectProperty<>(
|
||||
p.getValue() != null && p.getValue().getValue() != null
|
||||
? p.getValue().getValue().getInternalSecret().inPlace()
|
||||
? p.getValue().getValue()
|
||||
: null);
|
||||
return new OptionsBuilder()
|
||||
.addComp(new SecretFieldComp(secretProperty, true), secretProperty)
|
||||
@@ -38,10 +38,7 @@ public class SecretRetrievalStrategyHelper {
|
||||
newSecret != null ? newSecret.getSecret() : new char[0],
|
||||
original != null ? original.getSecret() : new char[0]);
|
||||
var val = changed
|
||||
? (allowUserSecretKey
|
||||
? DataStorageSecret.ofCurrentSecret(secretProperty.getValue())
|
||||
: DataStorageSecret.ofSecret(
|
||||
secretProperty.getValue(), EncryptionToken.ofVaultKey()))
|
||||
? secretProperty.getValue()
|
||||
: original;
|
||||
return new SecretRetrievalStrategy.InPlace(val);
|
||||
},
|
||||
@@ -91,7 +88,7 @@ public class SecretRetrievalStrategyHelper {
|
||||
}
|
||||
|
||||
public static OptionsBuilder comp(
|
||||
Property<SecretRetrievalStrategy> s, boolean allowNone, boolean allowUserSecretKey) {
|
||||
Property<SecretRetrievalStrategy> s, boolean allowNone) {
|
||||
SecretRetrievalStrategy strat = s.getValue();
|
||||
var inPlace = new SimpleObjectProperty<>(strat instanceof SecretRetrievalStrategy.InPlace i ? i : null);
|
||||
var passwordManager =
|
||||
@@ -102,7 +99,7 @@ public class SecretRetrievalStrategyHelper {
|
||||
if (allowNone) {
|
||||
map.put(AppI18n.observable("app.none"), new OptionsBuilder());
|
||||
}
|
||||
map.put(AppI18n.observable("app.password"), inPlace(inPlace, allowUserSecretKey));
|
||||
map.put(AppI18n.observable("app.password"), inPlace(inPlace));
|
||||
map.put(AppI18n.observable("app.passwordManager"), passwordManager(passwordManager));
|
||||
map.put(AppI18n.observable("app.customCommand"), customCommand(customCommand));
|
||||
map.put(AppI18n.observable("app.prompt"), new OptionsBuilder());
|
||||
|
||||
Reference in New Issue
Block a user