mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-21 20:21:27 +00:00
Merge branch 'feature/files-in-use' into feature/notify-fallback
# Conflicts: # src/main/java/org/cryptomator/common/EventMap.java # src/main/java/org/cryptomator/common/vaults/Vault.java
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
/**
|
||||
* Objects which has some kind of owner.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface FilsystemOwnerSupplier {
|
||||
|
||||
/**
|
||||
* Get the object owner.
|
||||
*
|
||||
* @return the object owner
|
||||
*/
|
||||
String getOwner();
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ package org.cryptomator.common.vaults;
|
||||
|
||||
import org.apache.commons.lang3.SystemUtils;
|
||||
import org.cryptomator.common.Constants;
|
||||
import org.cryptomator.common.FilsystemOwnerSupplier;
|
||||
import org.cryptomator.common.mount.Mounter;
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
@@ -149,14 +150,17 @@ public class Vault {
|
||||
LOG.warn("Limiting cleartext filename length on this device to {}.", vaultSettings.maxCleartextFilenameLength.get());
|
||||
}
|
||||
|
||||
CryptoFileSystemProperties fsProps = CryptoFileSystemProperties.cryptoFileSystemProperties() //
|
||||
var fsPropsBuilder = CryptoFileSystemProperties.cryptoFileSystemProperties() //
|
||||
.withKeyLoader(keyLoader) //
|
||||
.withFlags(flags) //
|
||||
.withMaxCleartextNameLength(vaultSettings.maxCleartextFilenameLength.get()) //
|
||||
.withVaultConfigFilename(Constants.VAULTCONFIG_FILENAME) //
|
||||
.withFilesystemEventConsumer(this::consumeVaultEvent) //
|
||||
.build();
|
||||
return CryptoFileSystemProvider.newFileSystem(getPath(), fsProps);
|
||||
.withFilesystemEventConsumer(this::consumeVaultEvent);
|
||||
if (keyLoader instanceof FilsystemOwnerSupplier oo) {
|
||||
fsPropsBuilder.withOwnerGetter(oo::getOwner);
|
||||
}
|
||||
|
||||
return CryptoFileSystemProvider.newFileSystem(getPath(), fsPropsBuilder.build());
|
||||
}
|
||||
|
||||
private void destroyCryptoFileSystem() {
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.cryptomator.cryptofs.event.BrokenFileNodeEvent;
|
||||
import org.cryptomator.cryptofs.event.ConflictResolutionFailedEvent;
|
||||
import org.cryptomator.cryptofs.event.ConflictResolvedEvent;
|
||||
import org.cryptomator.cryptofs.event.DecryptionFailedEvent;
|
||||
import org.cryptomator.cryptofs.event.FileIsInUseEvent;
|
||||
import org.cryptomator.cryptofs.event.FilesystemEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -101,6 +102,7 @@ public class FileSystemEventAggregator {
|
||||
case ConflictResolutionFailedEvent(_, _, Path conflictingCiphertext, _) -> conflictingCiphertext;
|
||||
case BrokenDirFileEvent(_, Path ciphertext) -> ciphertext;
|
||||
case BrokenFileNodeEvent(_, _, Path ciphertext) -> ciphertext;
|
||||
case FileIsInUseEvent(_, _, Path ciphertext, _, _, _) -> ciphertext;
|
||||
};
|
||||
return new FSEventBucket(v, p, event.getClass());
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.cryptomator.ui.eventview;
|
||||
|
||||
import org.cryptomator.cryptofs.event.FileIsInUseEvent;
|
||||
import org.cryptomator.event.FSEventBucket;
|
||||
import org.cryptomator.event.FSEventBucketContent;
|
||||
import org.cryptomator.event.FileSystemEventAggregator;
|
||||
@@ -115,7 +116,7 @@ public class EventListCellController implements FxController {
|
||||
eventActionsMenu.hide();
|
||||
eventActionsMenu.getItems().clear();
|
||||
eventTooltip.setText(item.getKey().vault().getDisplayName());
|
||||
addAction("generic.action.dismiss", () -> {
|
||||
addLocalizedAction("generic.action.dismiss", () -> {
|
||||
fileSystemEventAggregator.remove(item.getKey());
|
||||
});
|
||||
switch (item.getValue().mostRecentEvent()) {
|
||||
@@ -124,20 +125,36 @@ public class EventListCellController implements FxController {
|
||||
case DecryptionFailedEvent fse -> this.adjustToDecryptionFailedEvent(fse);
|
||||
case BrokenDirFileEvent fse -> this.adjustToBrokenDirFileEvent(fse);
|
||||
case BrokenFileNodeEvent fse -> this.adjustToBrokenFileNodeEvent(fse);
|
||||
case FileIsInUseEvent fse -> this.adjustToFileInUseEvent(fse);
|
||||
}
|
||||
}
|
||||
|
||||
private void adjustToFileInUseEvent(FileIsInUseEvent fse) {
|
||||
eventIcon.setValue(FontAwesome5Icon.TIMES);
|
||||
eventMessage.setValue("File is in use by " + fse.owner());
|
||||
var indexFileName = fse.cleartextPath().lastIndexOf("/");
|
||||
eventDescription.setValue(fse.cleartextPath().substring(indexFileName + 1));
|
||||
if (revealService != null) {
|
||||
addAction("Show decrypted file", () -> reveal(revealService, convertVaultPathToSystemPath(fse.cleartextPath())));
|
||||
addAction("Show encrypted Path", () -> reveal(revealService, fse.ciphertextPath()));
|
||||
} else {
|
||||
addAction("Copy decrypted Path", () -> copyToClipboard(convertVaultPathToSystemPath(fse.cleartextPath()).toString()));
|
||||
addAction("Copy encrypted Path", () -> copyToClipboard(fse.ciphertextPath().toString()));
|
||||
}
|
||||
addAction("Ignore in use status ", fse.ignoreMethod());
|
||||
}
|
||||
|
||||
|
||||
private void adjustToBrokenFileNodeEvent(BrokenFileNodeEvent bfe) {
|
||||
eventIcon.setValue(FontAwesome5Icon.TIMES);
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenFileNode.message"));
|
||||
eventDescription.setValue(bfe.ciphertextPath().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, bfe.ciphertextPath()));
|
||||
addLocalizedAction("eventView.entry.brokenFileNode.showEncrypted", () -> reveal(revealService, bfe.ciphertextPath()));
|
||||
} else {
|
||||
addAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(bfe.ciphertextPath().toString()));
|
||||
addLocalizedAction("eventView.entry.brokenFileNode.copyEncrypted", () -> copyToClipboard(bfe.ciphertextPath().toString()));
|
||||
}
|
||||
addAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
|
||||
addLocalizedAction("eventView.entry.brokenFileNode.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(bfe.cleartextPath()).toString()));
|
||||
}
|
||||
|
||||
private void adjustToConflictResolvedEvent(ConflictResolvedEvent cre) {
|
||||
@@ -145,9 +162,9 @@ public class EventListCellController implements FxController {
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.conflictResolved.message"));
|
||||
eventDescription.setValue(cre.resolvedCiphertextPath().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.conflictResolved.showDecrypted", () -> reveal(revealService, convertVaultPathToSystemPath(cre.resolvedCleartextPath())));
|
||||
addLocalizedAction("eventView.entry.conflictResolved.showDecrypted", () -> reveal(revealService, convertVaultPathToSystemPath(cre.resolvedCleartextPath())));
|
||||
} else {
|
||||
addAction("eventView.entry.conflictResolved.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(cre.resolvedCleartextPath()).toString()));
|
||||
addLocalizedAction("eventView.entry.conflictResolved.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(cre.resolvedCleartextPath()).toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,11 +173,11 @@ public class EventListCellController implements FxController {
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.conflict.message"));
|
||||
eventDescription.setValue(cfe.conflictingCiphertextPath().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.conflict.showDecrypted", () -> reveal(revealService, convertVaultPathToSystemPath(cfe.canonicalCleartextPath())));
|
||||
addAction("eventView.entry.conflict.showEncrypted", () -> reveal(revealService, cfe.conflictingCiphertextPath()));
|
||||
addLocalizedAction("eventView.entry.conflict.showDecrypted", () -> reveal(revealService, convertVaultPathToSystemPath(cfe.canonicalCleartextPath())));
|
||||
addLocalizedAction("eventView.entry.conflict.showEncrypted", () -> reveal(revealService, cfe.conflictingCiphertextPath()));
|
||||
} else {
|
||||
addAction("eventView.entry.conflict.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(cfe.canonicalCleartextPath()).toString()));
|
||||
addAction("eventView.entry.conflict.copyEncrypted", () -> copyToClipboard(cfe.conflictingCiphertextPath().toString()));
|
||||
addLocalizedAction("eventView.entry.conflict.copyDecrypted", () -> copyToClipboard(convertVaultPathToSystemPath(cfe.canonicalCleartextPath()).toString()));
|
||||
addLocalizedAction("eventView.entry.conflict.copyEncrypted", () -> copyToClipboard(cfe.conflictingCiphertextPath().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,9 +186,9 @@ public class EventListCellController implements FxController {
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.decryptionFailed.message"));
|
||||
eventDescription.setValue(dfe.ciphertextPath().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.decryptionFailed.showEncrypted", () -> reveal(revealService, dfe.ciphertextPath()));
|
||||
addLocalizedAction("eventView.entry.decryptionFailed.showEncrypted", () -> reveal(revealService, dfe.ciphertextPath()));
|
||||
} else {
|
||||
addAction("eventView.entry.decryptionFailed.copyEncrypted", () -> copyToClipboard(dfe.ciphertextPath().toString()));
|
||||
addLocalizedAction("eventView.entry.decryptionFailed.copyEncrypted", () -> copyToClipboard(dfe.ciphertextPath().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,14 +197,19 @@ public class EventListCellController implements FxController {
|
||||
eventMessage.setValue(resourceBundle.getString("eventView.entry.brokenDirFile.message"));
|
||||
eventDescription.setValue(bde.ciphertextPath().getParent().getFileName().toString());
|
||||
if (revealService != null) {
|
||||
addAction("eventView.entry.brokenDirFile.showEncrypted", () -> reveal(revealService, bde.ciphertextPath()));
|
||||
addLocalizedAction("eventView.entry.brokenDirFile.showEncrypted", () -> reveal(revealService, bde.ciphertextPath()));
|
||||
} else {
|
||||
addAction("eventView.entry.brokenDirFile.copyEncrypted", () -> copyToClipboard(bde.ciphertextPath().toString()));
|
||||
addLocalizedAction("eventView.entry.brokenDirFile.copyEncrypted", () -> copyToClipboard(bde.ciphertextPath().toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void addAction(String localizationKey, Runnable action) {
|
||||
var entry = new MenuItem(resourceBundle.getString(localizationKey));
|
||||
private void addLocalizedAction(String localizationKey, Runnable action) {
|
||||
var entryText = resourceBundle.getString(localizationKey);
|
||||
addAction(entryText, action);
|
||||
}
|
||||
|
||||
private void addAction(String entryText, Runnable action) {
|
||||
var entry = new MenuItem(entryText);
|
||||
entry.getStyleClass().addLast("dropdown-button-context-menu-item");
|
||||
entry.setOnAction(_ -> action.run());
|
||||
eventActionsMenu.getItems().addLast(entry);
|
||||
@@ -234,18 +256,14 @@ public class EventListCellController implements FxController {
|
||||
}
|
||||
}
|
||||
|
||||
private Path convertVaultPathToSystemPath(Path p) {
|
||||
if (!(p instanceof CryptoPath)) {
|
||||
throw new IllegalArgumentException("Path " + p + " is not a vault path");
|
||||
}
|
||||
private Path convertVaultPathToSystemPath(String vaultInternalPath) {
|
||||
var v = eventEntry.getValue().getKey().vault();
|
||||
if (!v.isUnlocked()) {
|
||||
return Path.of(System.getProperty("user.home"));
|
||||
}
|
||||
|
||||
var mountUri = v.getMountPoint().uri();
|
||||
var internalPath = p.toString().substring(1);
|
||||
return Path.of(mountUri.getPath().concat(internalPath).substring(1));
|
||||
return Path.of(mountUri.getPath().concat(vaultInternalPath.substring(1)).substring(1));
|
||||
}
|
||||
|
||||
private void reveal(RevealPathService s, Path p) {
|
||||
|
||||
@@ -63,8 +63,8 @@ abstract class HealthCheckModule {
|
||||
@Provides
|
||||
@HealthCheckWindow
|
||||
@HealthCheckScoped
|
||||
static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Builder compBuilder, @HealthCheckWindow Vault vault, @Named("unlockWindow") Stage window ) {
|
||||
return compBuilder.vault(vault).window(window).build().keyloadingStrategy();
|
||||
static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Factory compFactory, @HealthCheckWindow Vault vault, @Named("unlockWindow") Stage window ) {
|
||||
return compFactory.create(vault, window).keyloadingStrategy();
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -3,11 +3,8 @@ package org.cryptomator.ui.keyloading;
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Subcomponent;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptolib.api.MasterkeyLoader;
|
||||
|
||||
import javafx.stage.Stage;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@KeyLoadingScoped
|
||||
@Subcomponent(modules = {KeyLoadingModule.class})
|
||||
@@ -16,16 +13,10 @@ public interface KeyLoadingComponent {
|
||||
@KeyLoading
|
||||
KeyLoadingStrategy keyloadingStrategy();
|
||||
|
||||
@Subcomponent.Builder
|
||||
interface Builder {
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
|
||||
@BindsInstance
|
||||
Builder vault(@KeyLoading Vault vault);
|
||||
|
||||
@BindsInstance
|
||||
Builder window(@KeyLoading Stage window);
|
||||
|
||||
KeyLoadingComponent build();
|
||||
KeyLoadingComponent create(@BindsInstance @KeyLoading Vault vault, @KeyLoading @BindsInstance Stage window);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,6 +66,13 @@ public abstract class HubKeyLoadingModule {
|
||||
return new AtomicReference<>();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("userName")
|
||||
@KeyLoadingScoped
|
||||
static AtomicReference<String> provideUserNameRef() {
|
||||
return new AtomicReference<>();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@KeyLoadingScoped
|
||||
static CompletableFuture<ReceivedKey> provideResult() {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.cryptomator.ui.keyloading.hub;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.FilsystemOwnerSupplier;
|
||||
import org.cryptomator.common.keychain.KeychainManager;
|
||||
import org.cryptomator.common.keychain.NoKeychainAccessProviderException;
|
||||
import org.cryptomator.common.settings.DeviceKey;
|
||||
@@ -23,25 +24,28 @@ import java.net.URI;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@KeyLoading
|
||||
public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
|
||||
public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilsystemOwnerSupplier {
|
||||
|
||||
private static final String SCHEME_PREFIX = "hub+";
|
||||
public static final String SCHEME_PREFIX = "hub+";
|
||||
public static final String SCHEME_HUB_HTTP = SCHEME_PREFIX + "http";
|
||||
public static final String SCHEME_HUB_HTTPS = SCHEME_PREFIX + "https";
|
||||
|
||||
private final Stage window;
|
||||
private final KeychainManager keychainManager;
|
||||
private final AtomicReference<String> userName;
|
||||
private final Lazy<Scene> authFlowScene;
|
||||
private final Lazy<Scene> noKeychainScene;
|
||||
private final CompletableFuture<ReceivedKey> result;
|
||||
private final DeviceKey deviceKey;
|
||||
|
||||
@Inject
|
||||
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, @FxmlScene(FxmlFile.HUB_NO_KEYCHAIN) Lazy<Scene> noKeychainScene, CompletableFuture<ReceivedKey> result, DeviceKey deviceKey, KeychainManager keychainManager, @Named("windowTitle") String windowTitle) {
|
||||
public HubKeyLoadingStrategy(@KeyLoading Stage window, @FxmlScene(FxmlFile.HUB_AUTH_FLOW) Lazy<Scene> authFlowScene, @FxmlScene(FxmlFile.HUB_NO_KEYCHAIN) Lazy<Scene> noKeychainScene, CompletableFuture<ReceivedKey> result, DeviceKey deviceKey, KeychainManager keychainManager, @Named("windowTitle") String windowTitle, @Named("userName") AtomicReference<String> userName) {
|
||||
this.window = window;
|
||||
this.keychainManager = keychainManager;
|
||||
this.userName = userName;
|
||||
window.setTitle(windowTitle);
|
||||
window.setOnCloseRequest(_ -> result.cancel(true));
|
||||
this.authFlowScene = authFlowScene;
|
||||
@@ -90,4 +94,13 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOwner() {
|
||||
var name = userName.get();
|
||||
if (name == null) {
|
||||
throw new IllegalStateException("Owner is not yet determined");
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class ReceiveKeyController implements FxController {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ReceiveKeyController.class);
|
||||
private static final String SCHEME_PREFIX = "hub+";
|
||||
private static final ObjectMapper JSON = new ObjectMapper().setDefaultLeniency(true);
|
||||
private static final Duration REQ_TIMEOUT = Duration.ofSeconds(10);
|
||||
|
||||
@@ -50,6 +49,7 @@ public class ReceiveKeyController implements FxController {
|
||||
private final String vaultId;
|
||||
private final String deviceId;
|
||||
private final String bearerToken;
|
||||
private final AtomicReference<String> userName;
|
||||
private final CompletableFuture<ReceivedKey> result;
|
||||
private final Lazy<Scene> registerDeviceScene;
|
||||
private final Lazy<Scene> legacyRegisterDeviceScene;
|
||||
@@ -59,12 +59,25 @@ public class ReceiveKeyController implements FxController {
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Inject
|
||||
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, HubConfig hubConfig, @Named("deviceId") String deviceId, @Named("bearerToken") AtomicReference<String> tokenRef, CompletableFuture<ReceivedKey> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_LEGACY_REGISTER_DEVICE) Lazy<Scene> legacyRegisterDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, @FxmlScene(FxmlFile.HUB_REQUIRE_ACCOUNT_INIT) Lazy<Scene> accountInitializationScene, @FxmlScene(FxmlFile.HUB_INVALID_LICENSE) Lazy<Scene> invalidLicenseScene) {
|
||||
public ReceiveKeyController(@KeyLoading Vault vault, //
|
||||
ExecutorService executor, //
|
||||
@KeyLoading Stage window, //
|
||||
HubConfig hubConfig, //
|
||||
@Named("deviceId") String deviceId, //
|
||||
@Named("bearerToken") AtomicReference<String> tokenRef, //
|
||||
@Named("userName") AtomicReference<String> userName, //
|
||||
CompletableFuture<ReceivedKey> result, //
|
||||
@FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, //
|
||||
@FxmlScene(FxmlFile.HUB_LEGACY_REGISTER_DEVICE) Lazy<Scene> legacyRegisterDeviceScene, //
|
||||
@FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, //
|
||||
@FxmlScene(FxmlFile.HUB_REQUIRE_ACCOUNT_INIT) Lazy<Scene> accountInitializationScene, //
|
||||
@FxmlScene(FxmlFile.HUB_INVALID_LICENSE) Lazy<Scene> invalidLicenseScene) {
|
||||
this.window = window;
|
||||
this.hubConfig = hubConfig;
|
||||
this.vaultId = extractVaultId(vault.getVaultConfigCache().getUnchecked().getKeyId()); // TODO: access vault config's JTI directly (requires changes in cryptofs)
|
||||
this.deviceId = deviceId;
|
||||
this.bearerToken = Objects.requireNonNull(tokenRef.get());
|
||||
this.userName = userName;
|
||||
this.result = result;
|
||||
this.registerDeviceScene = registerDeviceScene;
|
||||
this.legacyRegisterDeviceScene = legacyRegisterDeviceScene;
|
||||
@@ -81,7 +94,34 @@ public class ReceiveKeyController implements FxController {
|
||||
}
|
||||
|
||||
public void receiveKey() {
|
||||
requestApiConfig();
|
||||
requestUserData();
|
||||
}
|
||||
|
||||
private void requestUserData() {
|
||||
var userUri = hubConfig.URIs.API.resolve("users/me?withDevices=false");
|
||||
var request = HttpRequest.newBuilder(userUri) //
|
||||
.header("Authorization", "Bearer " + bearerToken) //
|
||||
.GET() //
|
||||
.timeout(REQ_TIMEOUT) //
|
||||
.build();
|
||||
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8)) //
|
||||
.thenAcceptAsync(this::receivedUserData) //
|
||||
.exceptionally(this::retrievalFailed);
|
||||
}
|
||||
|
||||
private void receivedUserData(HttpResponse<String> response) {
|
||||
LOG.debug("GET {} -> Status Code {}", response.request().uri(), response.statusCode());
|
||||
try {
|
||||
if (response.statusCode() == 200) {
|
||||
var user = JSON.reader().readValue(response.body(), UserDto.class);
|
||||
userName.set(user.name);
|
||||
requestApiConfig();
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected response " + response.statusCode());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,11 +329,14 @@ public class ReceiveKeyController implements FxController {
|
||||
}
|
||||
|
||||
private static String extractVaultId(URI vaultKeyUri) {
|
||||
assert vaultKeyUri.getScheme().startsWith(SCHEME_PREFIX);
|
||||
assert vaultKeyUri.getScheme().startsWith(HubKeyLoadingStrategy.SCHEME_PREFIX);
|
||||
var path = vaultKeyUri.getPath();
|
||||
return path.substring(path.lastIndexOf('/') + 1);
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private record UserDto(@JsonProperty(value = "name", required = true) String name) {}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private record DeviceDto(@JsonProperty(value = "userPrivateKey", required = true) String userPrivateKey) {}
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ abstract class UnlockModule {
|
||||
@Provides
|
||||
@UnlockWindow
|
||||
@UnlockScoped
|
||||
static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Builder compBuilder, @UnlockWindow Vault vault, @UnlockWindow Stage window) {
|
||||
return compBuilder.vault(vault).window(window).build().keyloadingStrategy();
|
||||
static KeyLoadingStrategy provideKeyLoadingStrategy(KeyLoadingComponent.Factory compFactory, @UnlockWindow Vault vault, @UnlockWindow Stage window) {
|
||||
return compFactory.create(vault, window).keyloadingStrategy();
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
Reference in New Issue
Block a user