mirror of
https://github.com/xpipe-io/xpipe.git
synced 2026-08-23 17:56:29 +00:00
Rework [stage]
This commit is contained in:
@@ -1,13 +1,19 @@
|
||||
package io.xpipe.app.comp.base;
|
||||
|
||||
import io.xpipe.app.core.AppFontSizes;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
import io.xpipe.app.core.mode.AppOperationMode;
|
||||
|
||||
import io.xpipe.app.platform.PlatformThread;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.control.Button;
|
||||
|
||||
import lombok.Value;
|
||||
import lombok.experimental.NonFinal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@Value
|
||||
@@ -16,9 +22,7 @@ public class ModalButton {
|
||||
Runnable action;
|
||||
boolean close;
|
||||
boolean defaultButton;
|
||||
|
||||
@NonFinal
|
||||
Consumer<Button> augment;
|
||||
List<Consumer<Button>> augments = new ArrayList<>();
|
||||
|
||||
public ModalButton(String key, Runnable action, boolean close, boolean defaultButton) {
|
||||
this.key = key;
|
||||
@@ -68,7 +72,35 @@ public class ModalButton {
|
||||
}
|
||||
|
||||
public ModalButton augment(Consumer<Button> augment) {
|
||||
this.augment = augment;
|
||||
this.augments.add(augment);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModalButton loadingIndicator(ObservableValue<Boolean> busy) {
|
||||
return augment(button -> {
|
||||
button.graphicProperty()
|
||||
.bind(Bindings.createObjectBinding(
|
||||
() -> {
|
||||
return busy.getValue()
|
||||
? new LoadingIconComp(busy, AppFontSizes::base)
|
||||
.style("busy-loading-icon")
|
||||
.build()
|
||||
: null;
|
||||
},
|
||||
PlatformThread.sync(busy)));
|
||||
button.textProperty()
|
||||
.bind(Bindings.createStringBinding(
|
||||
() -> {
|
||||
return !busy.getValue() ? AppI18n.get(key) : null;
|
||||
},
|
||||
PlatformThread.sync(busy),
|
||||
AppI18n.activeLanguage()));
|
||||
});
|
||||
}
|
||||
|
||||
public ModalButton disable(ObservableValue<Boolean> b) {
|
||||
return augment(button -> {
|
||||
button.disableProperty().bind(PlatformThread.sync(b));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import atlantafx.base.util.Animations;
|
||||
import net.synedra.validatorfx.GraphicDecorationStackPane;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ModalOverlayComp extends RegionBuilder<Region> {
|
||||
|
||||
@@ -321,8 +322,8 @@ public class ModalOverlayComp extends RegionBuilder<Region> {
|
||||
if (mb.isDefaultButton()) {
|
||||
button.getStyleClass().add(Styles.ACCENT);
|
||||
}
|
||||
if (mb.getAugment() != null) {
|
||||
mb.getAugment().accept(button);
|
||||
for (Consumer<Button> augment : mb.getAugments()) {
|
||||
augment.accept(button);
|
||||
}
|
||||
button.managedProperty().bind(button.visibleProperty());
|
||||
button.setOnAction(event -> {
|
||||
|
||||
@@ -200,7 +200,7 @@ public class StoreEntryWrapper {
|
||||
.findFirst()
|
||||
.orElse(StoreViewState.get().getAllConnectionsCategory());
|
||||
category.setValue(newCat);
|
||||
accessScopeRestricted.setValue(entry.getAccessScope().isAccessRestricted());
|
||||
accessScopeRestricted.setValue(entry.getAccessScope().isAccessSubRestricted());
|
||||
pinToTop.setValue(entry.isPinToTop());
|
||||
|
||||
var orderedTags = entry.getTags().stream().sorted().toList();
|
||||
|
||||
@@ -17,9 +17,14 @@ import java.util.stream.Collectors;
|
||||
public class DataStoreAccessScope {
|
||||
|
||||
public static DataStoreAccessScope merge(List<DataStoreAccessScope> scopes) {
|
||||
var effectiveScopes = scopes.stream().filter(s -> !s.equals(vault())).collect(Collectors.toSet());
|
||||
if (effectiveScopes.isEmpty()) {
|
||||
return DataStoreAccessScope.vault();
|
||||
}
|
||||
|
||||
var matching = DataStorageAccessHandler.getInstance().getAllEncryptionPrincipals().stream()
|
||||
.filter(encryptionPrincipal -> {
|
||||
return scopes.stream().allMatch(s -> s.getPrincipals().contains(encryptionPrincipal));
|
||||
return effectiveScopes.stream().allMatch(s -> s.getPrincipals().contains(encryptionPrincipal));
|
||||
}).collect(Collectors.toSet());
|
||||
return !matching.isEmpty() ? of(matching) : DataStoreAccessScope.of(Set.of(EncryptionPrincipal.inaccessible()));
|
||||
}
|
||||
@@ -55,7 +60,7 @@ public class DataStoreAccessScope {
|
||||
this.principals = principals;
|
||||
}
|
||||
|
||||
public boolean isAccessRestricted() {
|
||||
public boolean isAccessSubRestricted() {
|
||||
var all = this.equals(encryption()) || this.equals(vault());
|
||||
return !all;
|
||||
}
|
||||
|
||||
@@ -57,9 +57,10 @@ public class DataStoreAccessScopeComp extends SimpleRegionBuilder {
|
||||
allPrincipals.removeIf(
|
||||
encryptionPrincipal -> encryptionPrincipal.getName().equals("vault"));
|
||||
allPrincipals.remove(handler.getEncryptAllPrincipal());
|
||||
allPrincipals.sort(Comparator.comparing(encryptionPrincipal -> encryptionPrincipal.getName()));
|
||||
|
||||
var selectedPrincipals = FXCollections.observableArrayList(
|
||||
scope.getValue().isAccessRestricted() ? scope.getValue().getPrincipals() : List.of());
|
||||
scope.getValue().isAccessSubRestricted() ? scope.getValue().getPrincipals() : List.of());
|
||||
selectedPrincipals.addListener((ListChangeListener<? super EncryptionPrincipal>) c -> {
|
||||
if (selectedPrincipals.isEmpty()) {
|
||||
scope.setValue(DataStoreAccessScope.encryption());
|
||||
|
||||
@@ -370,12 +370,15 @@ 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()
|
||||
|
||||
var currentScope = store instanceof AccessScopeStore s ? s.getAccessScope()
|
||||
: DataStoreAccessScope.encryption();
|
||||
var shouldEncrypt = (encryptIfRestricted && scope.isAccessRestricted())
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(currentScope);
|
||||
|
||||
var shouldEncrypt = (encryptIfRestricted && currentScope.isAccessSubRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
var encryptionChange = shouldEncrypt && !node.isEncrypted() || !shouldEncrypt && node.isEncrypted();
|
||||
var scopeTargetChange = !DataStoreAccessScope.getTargetScope(scope).equals(scope);
|
||||
var scopeTargetChange = !targetScope.equals(currentScope);
|
||||
return encryptionChange || scopeTargetChange;
|
||||
}
|
||||
|
||||
@@ -790,6 +793,17 @@ public class DataStoreEntry extends DataStorageElement {
|
||||
return;
|
||||
}
|
||||
|
||||
var newStore = getStore() instanceof AccessScopeStore s ? s.withUpdatedPrincipals() : getStore();
|
||||
var changedStore = !Objects.equals(getStore(), newStore);
|
||||
if (changedStore) {
|
||||
// This will take care of the encryption change for the node
|
||||
// we don't have to do this further down below
|
||||
storeNode = DataStoreEntryNode.of(newStore);
|
||||
dirty = true;
|
||||
notifyUpdate(false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
var newNode = storeNode.withUpdatedEncryption(this, true);
|
||||
if (!newNode.equals(storeNode)) {
|
||||
storeNode = newNode;
|
||||
|
||||
@@ -70,10 +70,10 @@ public class DataStoreEntryNode<T> {
|
||||
return null;
|
||||
}
|
||||
|
||||
var currentScope = enc.getSecret() != null ? enc.getSecret().getScope() : DataStoreAccessScope.vault();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(entry.getAccessScope());
|
||||
var currentScope = entry.getAccessScope();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(currentScope);
|
||||
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessRestricted())
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessSubRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
var encryptionChange = shouldEncrypt && !enc.isEncrypted() || !shouldEncrypt && enc.isEncrypted();
|
||||
var scopeTargetChange = !targetScope.equals(currentScope);
|
||||
@@ -111,10 +111,10 @@ public class DataStoreEntryNode<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
var currentScope = enc.getSecret() != null ? enc.getSecret().getScope() : DataStoreAccessScope.vault();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(entry.getAccessScope());
|
||||
var currentScope = entry.getAccessScope();
|
||||
var targetScope = DataStoreAccessScope.getTargetScope(currentScope);
|
||||
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessRestricted())
|
||||
var shouldEncrypt = (encryptIfRestricted && targetScope.isAccessSubRestricted())
|
||||
|| AppPrefs.get().encryptAllVaultData().get();
|
||||
var encryptionChange = shouldEncrypt && !enc.isEncrypted() || !shouldEncrypt && enc.isEncrypted();
|
||||
var scopeTargetChange = !targetScope.equals(currentScope);
|
||||
|
||||
@@ -174,7 +174,7 @@ public class IdentitySelectComp extends RegionBuilder<HBox> {
|
||||
: id.getClass().getSimpleName().equals("PasswordManagerIdentityStore")
|
||||
? AppI18n.get("passwordManagerIdentity")
|
||||
: id instanceof SyncedIdentityStore
|
||||
&& storeEntry.getAccessScope().isAccessRestricted()
|
||||
&& storeEntry.getAccessScope().isAccessSubRestricted()
|
||||
? (DataStorageAccessHandler.getInstance().getType() == DataStorageAccessType.ROLE
|
||||
? AppI18n.get("roleIdentity")
|
||||
: AppI18n.get("userIdentity"))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
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;
|
||||
@@ -130,7 +129,7 @@ public class SyncedIdentityStoreProvider extends IdentityStoreProvider {
|
||||
|
||||
@Override
|
||||
public String summaryString(StoreEntryWrapper wrapper) {
|
||||
if (!wrapper.getEntry().getAccessScope().isAccessRestricted()) {
|
||||
if (!wrapper.getEntry().getAccessScope().isAccessSubRestricted()) {
|
||||
return AppI18n.get("globalIdentity");
|
||||
}
|
||||
|
||||
|
||||
Generated
+2
-1
@@ -559,7 +559,8 @@ ptbNotice=Notice for the public test build
|
||||
userDeletionTitle=User deletion
|
||||
userDeletionContent=Do you want to delete this vault user? This will reencrypt all data using the default vault key. This will take a while.
|
||||
roleDeletionTitle=Role deletion
|
||||
roleDeletionContent=Do you want to delete this vault role? This will reencrypt all role-only identities and connection secrets and potentially make some entries which still use this role inaccessible. This will take a while.
|
||||
#force
|
||||
roleDeletionContent=Do you want to delete this vault role? This will reencrypt all identities and connection secrets that use this role. Any entries that are only accessible to this role will become available to all roles. This will take a while.
|
||||
killTransfer=Kill transfer
|
||||
destination=Destination
|
||||
configuration=Configuration
|
||||
|
||||
Reference in New Issue
Block a user