mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-08-23 01:36:33 +00:00
Rework
This commit is contained in:
@@ -107,7 +107,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
|
||||
return new LabelGraphic.IconGraphic("mdomz-settings");
|
||||
}
|
||||
|
||||
if (!DataStorage.get().supportsSync()
|
||||
if (!DataStorage.get().syncEnabled()
|
||||
|| (!category.getCategory().canShare())) {
|
||||
return new LabelGraphic.IconGraphic("mdi2g-git");
|
||||
}
|
||||
@@ -155,7 +155,7 @@ public class StoreCategoryComp extends SimpleRegionBuilder {
|
||||
var dragOver = new SimpleBooleanProperty();
|
||||
var dragIntoIndicator = createDragIntoIndicator(dragOver);
|
||||
|
||||
var showStatus = hover.or(new SimpleBooleanProperty(DataStorage.get().supportsSync()))
|
||||
var showStatus = hover.or(new SimpleBooleanProperty(DataStorage.get().syncEnabled()))
|
||||
.or(showing)
|
||||
.or(focus);
|
||||
var h = new HorizontalComp(List.of(
|
||||
|
||||
@@ -86,7 +86,7 @@ public class StoreCategoryConfigComp extends SimpleRegionBuilder {
|
||||
var options = new OptionsBuilder();
|
||||
|
||||
var specialCategorySync = !wrapper.getCategory().canShare();
|
||||
var syncDisable = !DataStorage.get().supportsSync()
|
||||
var syncDisable = !DataStorage.get().syncEnabled()
|
||||
|| ((sync.getValue() == null || !sync.getValue())
|
||||
&& !wrapper.getCategory().canShare());
|
||||
options.title("sync")
|
||||
|
||||
@@ -167,7 +167,7 @@ public interface StoreEntryBadge {
|
||||
return null;
|
||||
}
|
||||
|
||||
return of("mdi2c-console", s).withCopyAction();
|
||||
return of("mdi2c-console", s);
|
||||
}
|
||||
|
||||
static StoreEntryBadge ofKey(String s) {
|
||||
|
||||
@@ -22,7 +22,7 @@ public class StoreIdentitiesIntroComp extends SimpleRegionBuilder {
|
||||
top.setButtonDefault(true);
|
||||
top.setButtonGraphic(new LabelGraphic.IconGraphic("mdi2p-play-circle"));
|
||||
top.setButtonAction(() -> {
|
||||
var canSync = DataStorage.get().supportsSync();
|
||||
var canSync = DataStorage.get().syncEnabled();
|
||||
var prov = canSync
|
||||
? DataStoreProvider.byId("syncedIdentity").orElseThrow()
|
||||
: DataStoreProvider.byId("localIdentity").orElseThrow();
|
||||
|
||||
@@ -6,6 +6,7 @@ import io.xpipe.app.util.OsType;
|
||||
|
||||
import java.nio.file.AccessDeniedException;
|
||||
import java.nio.file.FileSystemException;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.util.*;
|
||||
|
||||
@@ -114,6 +115,10 @@ public class ErrorEventFactory {
|
||||
b.expected();
|
||||
}
|
||||
|
||||
if (t instanceof InvalidPathException ipe) {
|
||||
b.description("Invalid file path: " + ipe.getMessage());
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,32 @@ import javax.crypto.SecretKey;
|
||||
|
||||
public interface EncryptionPrincipal {
|
||||
|
||||
static EncryptionPrincipal inaccessible() {
|
||||
var dummyId = UUID.fromString("73e2d533-6fa4-497e-87a8-24da4fdf4d63");
|
||||
return new EncryptionPrincipal() {
|
||||
|
||||
@Override
|
||||
public UUID getUuid() {
|
||||
return dummyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "inaccessible";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAccessible() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecretKey getSecretKey() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static EncryptionPrincipal getTargetPrincipal(EncryptionPrincipal principal) {
|
||||
if (!principal.isAccessible()) {
|
||||
return principal;
|
||||
|
||||
@@ -132,7 +132,7 @@ public abstract class DataStorage {
|
||||
}
|
||||
|
||||
private void dispose() {
|
||||
save(true);
|
||||
save(true, true);
|
||||
var finalizing = false;
|
||||
for (DataStoreEntry entry : getStoreEntries()) {
|
||||
// Prevent blocking of shutdown
|
||||
@@ -202,7 +202,7 @@ public abstract class DataStorage {
|
||||
localIdentities.get().setParentCategory(ALL_IDENTITIES_CATEGORY_UUID);
|
||||
}
|
||||
|
||||
if (supportsSync()) {
|
||||
if (syncEnabled()) {
|
||||
var sharedIdentities = getStoreCategoryIfPresent(SYNCED_IDENTITIES_CATEGORY_UUID);
|
||||
if (sharedIdentities.isEmpty()) {
|
||||
var cat = DataStoreCategory.createNew(
|
||||
@@ -267,9 +267,9 @@ public abstract class DataStorage {
|
||||
|
||||
public abstract void saveAsync();
|
||||
|
||||
public abstract void save(boolean dispose);
|
||||
public abstract void save(boolean dispose, boolean forceSync);
|
||||
|
||||
public abstract boolean supportsSync();
|
||||
public abstract boolean syncEnabled();
|
||||
|
||||
public boolean shouldSync(DataStoreCategory category) {
|
||||
// Don't sync lone identities category
|
||||
|
||||
@@ -207,6 +207,10 @@ public class DataStorageSecret {
|
||||
newEntries.add(newEntry);
|
||||
}
|
||||
|
||||
if (newEntries.equals(entries)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return new DataStorageSecret(newEntries, secret);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -15,6 +16,14 @@ import java.util.stream.Collectors;
|
||||
@ToString
|
||||
public class DataStoreAccessScope {
|
||||
|
||||
public static DataStoreAccessScope merge(List<DataStoreAccessScope> scopes) {
|
||||
var matching = DataStorageAccessHandler.getInstance().getAllEncryptionPrincipals().stream()
|
||||
.filter(encryptionPrincipal -> {
|
||||
return scopes.stream().allMatch(s -> s.getPrincipals().contains(encryptionPrincipal));
|
||||
}).collect(Collectors.toSet());
|
||||
return !matching.isEmpty() ? of(matching) : DataStoreAccessScope.of(Set.of(EncryptionPrincipal.inaccessible()));
|
||||
}
|
||||
|
||||
public static DataStoreAccessScope getTargetScope(DataStoreAccessScope scope) {
|
||||
var newPrincipals = scope.getPrincipals().stream()
|
||||
.map(encryptionPrincipal -> EncryptionPrincipal.getTargetPrincipal(encryptionPrincipal))
|
||||
@@ -32,11 +41,6 @@ public class DataStoreAccessScope {
|
||||
Set.of(DataStorageAccessHandler.getInstance().getEncryptAllPrincipal()));
|
||||
}
|
||||
|
||||
public static DataStoreAccessScope current() {
|
||||
var handler = DataStorageAccessHandler.getInstance();
|
||||
return new DataStoreAccessScope(handler.getCurrentEncryptionPrincipals());
|
||||
}
|
||||
|
||||
public static DataStoreAccessScope of(Set<EncryptionPrincipal> encryptionPrincipals) {
|
||||
return new DataStoreAccessScope(encryptionPrincipals);
|
||||
}
|
||||
|
||||
@@ -370,8 +370,7 @@ public class DataStoreEntry extends DataStorageElement {
|
||||
}
|
||||
|
||||
// Check whether we need to write the node due to external changes
|
||||
var scope = store instanceof AccessScopeStore s && s.getAccessScope() != null
|
||||
? s.getAccessScope()
|
||||
var scope = store instanceof AccessScopeStore s ? s.getAccessScope()
|
||||
: DataStoreAccessScope.encryption();
|
||||
var shouldEncrypt = (encryptIfRestricted && scope.isAccessRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
@@ -425,7 +424,7 @@ public class DataStoreEntry extends DataStorageElement {
|
||||
|
||||
public DataStoreAccessScope getAccessScope() {
|
||||
try {
|
||||
if (getStore() instanceof AccessScopeStore s && s.getAccessScope() != null) {
|
||||
if (getStore() instanceof AccessScopeStore s) {
|
||||
return s.getAccessScope();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
@@ -768,7 +767,7 @@ public class DataStoreEntry extends DataStorageElement {
|
||||
|
||||
DataStoreAccessScope newAccessScope = null;
|
||||
try {
|
||||
if (newStore instanceof AccessScopeStore u && u.getAccessScope() != null) {
|
||||
if (newStore instanceof AccessScopeStore u) {
|
||||
newAccessScope = u.getAccessScope();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
@@ -70,15 +70,17 @@ public class DataStoreEntryNode<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
var scope = entry.getAccessScope();
|
||||
var shouldEncrypt = (encryptIfRestricted && scope.isAccessRestricted())
|
||||
var currentScope = enc.getSecret() != null ? enc.getSecret().getScope() : DataStoreAccessScope.vault();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(entry.getAccessScope());
|
||||
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
var encryptionChange = shouldEncrypt && !enc.isEncrypted() || !shouldEncrypt && enc.isEncrypted();
|
||||
var scopeTargetChange = !DataStoreAccessScope.getTargetScope(scope).equals(scope);
|
||||
var scopeTargetChange = !targetScope.equals(currentScope);
|
||||
var valueChange = !getValue().equals(newValue);
|
||||
if (encryptionChange || valueChange || scopeTargetChange) {
|
||||
return new DataStoreEntryNode<>(
|
||||
shouldEncrypt ? EncryptedValue.of(newValue, scope) : EncryptedValue.ofRaw(newValue), false);
|
||||
shouldEncrypt ? EncryptedValue.of(newValue, targetScope) : EncryptedValue.ofRaw(newValue), false);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
@@ -99,25 +101,27 @@ public class DataStoreEntryNode<T> {
|
||||
}
|
||||
|
||||
if (getValue() instanceof AccessScopeStore s
|
||||
&& (s.getAccessScope() == null || !s.getAccessScope().isAccessible())) {
|
||||
&& !s.getAccessScope().isAccessible()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
T newValue = getValue() instanceof AccessScopeStore s ? (T) s.withUpdatedPrincipals() : getValue();
|
||||
if (newValue instanceof AccessScopeStore s
|
||||
&& (s.getAccessScope() == null || !s.getAccessScope().isAccessible())) {
|
||||
&& !s.getAccessScope().isAccessible()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
var scope = entry.getAccessScope();
|
||||
var shouldEncrypt = (encryptIfRestricted && scope.isAccessRestricted())
|
||||
var currentScope = enc.getSecret() != null ? enc.getSecret().getScope() : DataStoreAccessScope.vault();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(entry.getAccessScope());
|
||||
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
var encryptionChange = shouldEncrypt && !enc.isEncrypted() || !shouldEncrypt && enc.isEncrypted();
|
||||
var scopeTargetChange = !DataStoreAccessScope.getTargetScope(scope).equals(scope);
|
||||
var scopeTargetChange = !targetScope.equals(currentScope);
|
||||
var valueChange = !getValue().equals(newValue);
|
||||
if (encryptionChange || scopeTargetChange || valueChange) {
|
||||
return new DataStoreEntryNode<>(
|
||||
shouldEncrypt ? EncryptedValue.of(newValue, scope) : EncryptedValue.ofRaw(newValue), false);
|
||||
shouldEncrypt ? EncryptedValue.of(newValue, targetScope) : EncryptedValue.ofRaw(newValue), false);
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -48,10 +48,10 @@ public class ImpersistentStorage extends DataStorage {
|
||||
public void saveAsync() {}
|
||||
|
||||
@Override
|
||||
public synchronized void save(boolean dispose) {}
|
||||
public synchronized void save(boolean dispose, boolean forceSync) {}
|
||||
|
||||
@Override
|
||||
public boolean supportsSync() {
|
||||
public boolean syncEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,11 +392,11 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
ThreadHelper.runAsync(() -> {
|
||||
save(false);
|
||||
save(false, false);
|
||||
});
|
||||
}
|
||||
|
||||
public void save(boolean dispose) {
|
||||
public void save(boolean dispose, boolean forceSync) {
|
||||
try {
|
||||
// If another save operation is in progress, we have to wait on dispose
|
||||
// Otherwise the application may quit and kill the daemon thread that is performing the other save operation
|
||||
@@ -408,8 +408,11 @@ public class StandardStorage extends DataStorage {
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't need to wait on normal saves though
|
||||
if (!dispose && !busyIo.tryLock()) {
|
||||
// Wait for sync lock
|
||||
if (forceSync) {
|
||||
busyIo.lock();
|
||||
} else if (!dispose && !busyIo.tryLock()) {
|
||||
// We don't need to wait on normal saves though
|
||||
saveQueued = true;
|
||||
return;
|
||||
}
|
||||
@@ -426,8 +429,10 @@ public class StandardStorage extends DataStorage {
|
||||
if (syncEnabled) {
|
||||
GlobalTimer.delay(
|
||||
() -> {
|
||||
if (saveActive.get()) {
|
||||
AppLayoutModel.get().showQueueEntry(queueEntry, null, false);
|
||||
synchronized (queueEntry) {
|
||||
if (saveActive.get()) {
|
||||
AppLayoutModel.get().showQueueEntry(queueEntry, null, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
Duration.ofSeconds(5));
|
||||
@@ -499,8 +504,10 @@ public class StandardStorage extends DataStorage {
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
saveActive.set(false);
|
||||
queueEntry.hide();
|
||||
synchronized (queueEntry) {
|
||||
saveActive.set(false);
|
||||
queueEntry.hide();
|
||||
}
|
||||
|
||||
busyIo.unlock();
|
||||
if (!dispose && saveQueued) {
|
||||
@@ -545,7 +552,7 @@ public class StandardStorage extends DataStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsSync() {
|
||||
public boolean syncEnabled() {
|
||||
return dataStorageSyncHandler.supportsSync();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package io.xpipe.app.store;
|
||||
|
||||
import io.xpipe.app.storage.DataStoreAccessScope;
|
||||
|
||||
public interface AccessScopeDependencyStore extends AccessScopeStore, DependentDataStore {
|
||||
|
||||
default DataStoreAccessScope getAccessScope() {
|
||||
var deps = getDependencies();
|
||||
var scopes = deps.stream().map(ref -> ref.getStore() instanceof AccessScopeStore s ? s.getAccessScope() : null)
|
||||
.filter(s -> s != null)
|
||||
.toList();
|
||||
if (scopes.isEmpty()) {
|
||||
return DataStoreAccessScope.encryption();
|
||||
}
|
||||
|
||||
return DataStoreAccessScope.merge(scopes);
|
||||
}
|
||||
}
|
||||
@@ -466,7 +466,7 @@ public class AppJacksonModule extends SimpleModule {
|
||||
var e = DataStorage.get()
|
||||
.getStoreEntryIfPresent(id)
|
||||
.filter(dataStoreEntry -> dataStoreEntry.getValidity() != DataStoreEntry.Validity.LOAD_FAILED
|
||||
|| !dataStoreEntry.getStoreNode().isAccessible())
|
||||
|| (dataStoreEntry.getStoreNode() != null && !dataStoreEntry.getStoreNode().isAccessible()))
|
||||
.orElse(null);
|
||||
if (e == null) {
|
||||
return null;
|
||||
|
||||
@@ -39,9 +39,9 @@ the calculation of the default scrollbar skin.
|
||||
|
||||
Without this, the min height will be too small
|
||||
*/
|
||||
.root .scroll-bar >.decrement-button >.decrement-arrow {
|
||||
.root .scroll-bar:vertical >.decrement-button >.decrement-arrow {
|
||||
-fx-padding: 0 3 0 4;
|
||||
}
|
||||
.root .scroll-bar >.increment-button >.increment-arrow {
|
||||
.root .scroll-bar:vertical >.increment-button >.increment-arrow {
|
||||
-fx-padding: 0 3 0 4;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,14 @@
|
||||
-fx-background-radius: 4;
|
||||
-fx-font-size: 1.0em;
|
||||
-fx-padding: 2 5 2 5;
|
||||
-fx-background-color: -color-bg-default-transparent;
|
||||
}
|
||||
|
||||
.root:light .store-entry-badge {
|
||||
-fx-background-color: derive(-color-bg-default-transparent, -5%);
|
||||
}
|
||||
|
||||
.root:dark .store-entry-badge {
|
||||
-fx-background-color: derive(-color-bg-default-transparent, 5%);
|
||||
}
|
||||
|
||||
.store-entry-badge:focused {
|
||||
|
||||
@@ -77,7 +77,7 @@ public class IdentityChoiceBuilder {
|
||||
|
||||
private void addSyncCheckListener() {
|
||||
identity.addListener((observable, oldValue, newValue) -> {
|
||||
if (DataStorage.get().supportsSync()
|
||||
if (DataStorage.get().syncEnabled()
|
||||
&& syncedBase.getValue()
|
||||
&& newValue instanceof IdentityValue.Ref r
|
||||
&& r.unwrap() instanceof LocalIdentityStore) {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class LocalIdentityConvertHubLeafProvider implements HubLeafProvider<Loca
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(DataStoreEntryRef<LocalIdentityStore> o) {
|
||||
return DataStorage.get().supportsSync() && !MultiIdentityStore.isExclusivelyHeld(o.asNeeded());
|
||||
return DataStorage.get().syncEnabled() && !MultiIdentityStore.isExclusivelyHeld(o.asNeeded());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package io.xpipe.ext.base.identity;
|
||||
|
||||
import io.xpipe.app.beacon.BeaconAuthMethod;
|
||||
import io.xpipe.app.identity.NoIdentityStrategy;
|
||||
import io.xpipe.app.identity.SshIdentityStrategy;
|
||||
import io.xpipe.app.identity.UsernameStrategy;
|
||||
import io.xpipe.app.secret.EncryptedValue;
|
||||
import io.xpipe.app.secret.SecretNoneStrategy;
|
||||
import io.xpipe.app.secret.SecretRetrievalStrategy;
|
||||
import io.xpipe.app.storage.DataStoreAccessScope;
|
||||
import io.xpipe.app.storage.DataStoreEntryRef;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import io.xpipe.app.store.AccessScopeStore;
|
||||
import io.xpipe.app.store.DataStore;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import lombok.Value;
|
||||
@@ -23,12 +27,26 @@ import java.util.List;
|
||||
@Value
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class LocalIdentityStore extends IdentityStore {
|
||||
public class LocalIdentityStore extends IdentityStore implements AccessScopeStore {
|
||||
|
||||
String username;
|
||||
EncryptedValue<SecretRetrievalStrategy> password;
|
||||
EncryptedValue<SshIdentityStrategy> sshIdentity;
|
||||
|
||||
@Override
|
||||
public DataStoreAccessScope getAccessScope() {
|
||||
return DataStoreAccessScope.encryption();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataStore withUpdatedPrincipals() {
|
||||
return LocalIdentityStore.builder()
|
||||
.username(username)
|
||||
.password(password != null ? password.withUpdatedPrincipals() : null)
|
||||
.sshIdentity(sshIdentity != null ? sshIdentity.withUpdatedPrincipals() : null)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
var user = getUsername().hasUser()
|
||||
|
||||
@@ -5,10 +5,7 @@ import io.xpipe.app.identity.NoIdentityStrategy;
|
||||
import io.xpipe.app.identity.SshIdentityStrategyChoiceConfig;
|
||||
import io.xpipe.app.platform.OptionsBuilder;
|
||||
import io.xpipe.app.platform.OptionsChoiceBuilder;
|
||||
import io.xpipe.app.secret.EncryptedValue;
|
||||
import io.xpipe.app.secret.SecretNoneStrategy;
|
||||
import io.xpipe.app.secret.SecretRetrievalStrategy;
|
||||
import io.xpipe.app.secret.SecretStrategyChoiceConfig;
|
||||
import io.xpipe.app.secret.*;
|
||||
import io.xpipe.app.storage.*;
|
||||
import io.xpipe.app.store.DataStore;
|
||||
import io.xpipe.app.util.*;
|
||||
@@ -39,9 +36,10 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
|
||||
var pass = new SimpleObjectProperty<>(st.getPassword());
|
||||
var identity = new SimpleObjectProperty<>(st.getSshIdentity());
|
||||
|
||||
var current = DataStoreAccessScope.encryption();
|
||||
var sshIdentityChoiceConfig = SshIdentityStrategyChoiceConfig.builder()
|
||||
.allowKeyFileSync(false)
|
||||
.scopeCheck(() -> DataStoreAccessScope.current())
|
||||
.scopeCheck(() -> current)
|
||||
.build();
|
||||
|
||||
var passwordChoice = OptionsChoiceBuilder.builder()
|
||||
@@ -70,12 +68,12 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
|
||||
.password(
|
||||
st.getEncryptedPassword() != null
|
||||
? st.getEncryptedPassword().with(pass.get())
|
||||
: EncryptedValue.of(pass.get(), DataStoreAccessScope.current()))
|
||||
: EncryptedValue.of(pass.get(), current))
|
||||
.sshIdentity(
|
||||
st.getEncryptedSshIdentity() != null
|
||||
? st.getEncryptedSshIdentity()
|
||||
.with(identity.get())
|
||||
: EncryptedValue.of(identity.get(), DataStoreAccessScope.current()))
|
||||
: EncryptedValue.of(identity.get(), current))
|
||||
.build();
|
||||
},
|
||||
store)
|
||||
@@ -84,9 +82,10 @@ public class LocalIdentityStoreProvider extends IdentityStoreProvider {
|
||||
|
||||
@Override
|
||||
public DataStore defaultStore(DataStoreCategory category) {
|
||||
var current = DataStoreAccessScope.encryption();
|
||||
return LocalIdentityStore.builder()
|
||||
.password(EncryptedValue.of(new SecretNoneStrategy(), DataStoreAccessScope.current()))
|
||||
.sshIdentity(EncryptedValue.of(new NoIdentityStrategy(), DataStoreAccessScope.current()))
|
||||
.password(EncryptedValue.of(new SecretNoneStrategy(), current))
|
||||
.sshIdentity(EncryptedValue.of(new NoIdentityStrategy(), current))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class MultiIdentityConvertHubLeafProvider implements HubLeafProvider<Mult
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(DataStoreEntryRef<MultiIdentityStore> o) {
|
||||
return DataStorage.get().supportsSync()
|
||||
return DataStorage.get().syncEnabled()
|
||||
&& o.getStore().areAnyChildrenLocal()
|
||||
&& o.getStore().areAllIdentitiesAccessible()
|
||||
&& !o.getStore().hasNestedMultiIdentities();
|
||||
|
||||
@@ -53,6 +53,11 @@ public class MultiIdentityStore extends IdentityStore
|
||||
Boolean exclusive;
|
||||
DataStoreAccessScope accessScope;
|
||||
|
||||
@Override
|
||||
public DataStoreAccessScope getAccessScope() {
|
||||
return accessScope != null ? accessScope : DataStoreAccessScope.encryption();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
var selected = getSelected();
|
||||
|
||||
@@ -32,12 +32,15 @@ import java.util.List;
|
||||
public class SyncedIdentityStore extends IdentityStore implements AccessScopeStore {
|
||||
|
||||
String username;
|
||||
// We can encrypt it with only the vault key as
|
||||
// per user stores are additionally encrypted on the entry level
|
||||
EncryptedValue<SecretRetrievalStrategy> password;
|
||||
EncryptedValue<SshIdentityStrategy> sshIdentity;
|
||||
DataStoreAccessScope accessScope;
|
||||
|
||||
@Override
|
||||
public DataStoreAccessScope getAccessScope() {
|
||||
return accessScope != null ? accessScope : DataStoreAccessScope.encryption();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toSummary() {
|
||||
var user = getUsername().hasUser()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package io.xpipe.ext.base.identity;
|
||||
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.AppProperties;
|
||||
import io.xpipe.app.hub.creation.StoreCreationModel;
|
||||
import io.xpipe.app.hub.entry.StoreEntryWrapper;
|
||||
import io.xpipe.app.identity.KeyFileStrategy;
|
||||
@@ -10,6 +11,7 @@ import io.xpipe.app.identity.SshIdentityStrategyChoiceConfig;
|
||||
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.DataStorageAccessType;
|
||||
import io.xpipe.app.secret.*;
|
||||
import io.xpipe.app.storage.*;
|
||||
@@ -27,7 +29,7 @@ public class SyncedIdentityStoreProvider extends IdentityStoreProvider {
|
||||
|
||||
@Override
|
||||
public boolean allowCreation() {
|
||||
return DataStorage.get().supportsSync();
|
||||
return AppPrefs.get().enableGitStorage().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,7 +33,7 @@ public class SyncConfigHubLeafProvider implements HubLeafProvider<SyncConfigStor
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(DataStoreEntryRef<SyncConfigStore> o) {
|
||||
return DataStorage.get().supportsSync() && !o.get().getProvider().isSyncable(o.get());
|
||||
return DataStorage.get().syncEnabled() && !o.get().getProvider().isSyncable(o.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Generated
+5
-1
@@ -2081,7 +2081,8 @@ certificateRole=Role name
|
||||
certificateRoleDescription=The role with which to sign the public key
|
||||
testConfig=Test configuration
|
||||
testConfigDescription=Verify that the configuration works
|
||||
applyingVaultChanges=Applying vault changes ...
|
||||
#force
|
||||
applyingVaultChanges=Applying vault encryption changes ...
|
||||
allowExternalApiRequests=Allow external API requests
|
||||
allowExternalApiRequestsDescription=By default, the API server is only listening on localhost. If you want to accept connections from outside localhost as well, you can enable this option.
|
||||
certificateRenewCommand=Certificate renewal command
|
||||
@@ -2337,3 +2338,6 @@ vaultMigratedTitle=Vault migration
|
||||
vaultMigratedContent=Your vault was migrated. Note that the migration removed any kind of vault users/groups, so you will have to recreate them in the settings menu.
|
||||
vaultMigratedGitContent=Your vault was migrated. Note that the migration removed any kind of vault users/groups, so you will have to recreate them in the settings menu.\n\nOnce you have done this, you can also reenable the git git sync as well.
|
||||
orderDisabledNotice=Reordering not possible in current sort mode
|
||||
skipAllRoles=Skip all roles
|
||||
skipRole=Skip role
|
||||
disableRole=Disable role
|
||||
|
||||
Reference in New Issue
Block a user