add device name to filesystemowner and display device name in notification

This commit is contained in:
Armin Schrenk
2025-12-17 16:55:42 +01:00
parent d836798361
commit eb20fd7278
6 changed files with 20 additions and 13 deletions

View File

@@ -13,5 +13,6 @@ public interface Constants {
String CRYPTOMATOR_FILENAME_GLOB = "*.cryptomator";
URI DEFAULT_KEY_ID = URI.create(MasterkeyFileLoadingStrategy.SCHEME + ":" + MASTERKEY_FILENAME);
byte[] PEPPER = new byte[0];
String HUB_USER_DEVICE_SEPARATOR = "&";
}

View File

@@ -67,9 +67,9 @@ public abstract class HubKeyLoadingModule {
}
@Provides
@Named("userName")
@Named("filesystemOwnerId")
@KeyLoadingScoped
static AtomicReference<String> provideUserNameRef() {
static AtomicReference<String> provideFilesystemOwnerIdRef() {
return new AtomicReference<>();
}

View File

@@ -35,17 +35,17 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilesystemOwne
private final Stage window;
private final KeychainManager keychainManager;
private final AtomicReference<String> userName;
private final AtomicReference<String> fsOwnerId;
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, @Named("userName") AtomicReference<String> userName) {
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("filesystemOwnerId") AtomicReference<String> fsOwnerId) {
this.window = window;
this.keychainManager = keychainManager;
this.userName = userName;
this.fsOwnerId = fsOwnerId;
window.setTitle(windowTitle);
window.setOnCloseRequest(_ -> result.cancel(true));
this.authFlowScene = authFlowScene;
@@ -96,7 +96,7 @@ public class HubKeyLoadingStrategy implements KeyLoadingStrategy, FilesystemOwne
@Override
public String getOwner() {
var name = userName.get();
var name = fsOwnerId.get();
if (name == null) {
throw new IllegalStateException("Owner is not yet determined");
}

View File

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.nimbusds.jose.JWEObject;
import dagger.Lazy;
import org.cryptomator.common.Constants;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxmlFile;
@@ -49,7 +50,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 AtomicReference<String> fsOwnerId;
private final CompletableFuture<ReceivedKey> result;
private final Lazy<Scene> registerDeviceScene;
private final Lazy<Scene> legacyRegisterDeviceScene;
@@ -65,7 +66,7 @@ public class ReceiveKeyController implements FxController {
HubConfig hubConfig, //
@Named("deviceId") String deviceId, //
@Named("bearerToken") AtomicReference<String> tokenRef, //
@Named("userName") AtomicReference<String> userName, //
@Named("filesystemOwnerId") AtomicReference<String> fsOwnerId, //
CompletableFuture<ReceivedKey> result, //
@FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, //
@FxmlScene(FxmlFile.HUB_LEGACY_REGISTER_DEVICE) Lazy<Scene> legacyRegisterDeviceScene, //
@@ -77,7 +78,7 @@ public class ReceiveKeyController implements FxController {
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.fsOwnerId = fsOwnerId;
this.result = result;
this.registerDeviceScene = registerDeviceScene;
this.legacyRegisterDeviceScene = legacyRegisterDeviceScene;
@@ -114,7 +115,7 @@ public class ReceiveKeyController implements FxController {
try {
if (response.statusCode() == 200) {
var user = JSON.reader().readValue(response.body(), UserDto.class);
userName.set(user.name);
fsOwnerId.set(user.name);
requestApiConfig();
} else {
throw new IllegalStateException("Unexpected response " + response.statusCode());
@@ -184,6 +185,7 @@ public class ReceiveKeyController implements FxController {
switch (response.statusCode()) {
case 200 -> {
var device = JSON.reader().readValue(response.body(), DeviceDto.class);
fsOwnerId.accumulateAndGet(device.name, (s1, s2) -> s1 + Constants.HUB_USER_DEVICE_SEPARATOR + s2);
requestVaultMasterkey(device.userPrivateKey);
}
case 404 -> Platform.runLater(this::needsDeviceRegistration);
@@ -338,7 +340,7 @@ public class ReceiveKeyController implements FxController {
private record UserDto(@JsonProperty(value = "name", required = true) String name) {}
@JsonIgnoreProperties(ignoreUnknown = true)
private record DeviceDto(@JsonProperty(value = "userPrivateKey", required = true) String userPrivateKey) {}
private record DeviceDto(@JsonProperty(value = "name", required = true) String name, @JsonProperty(value = "userPrivateKey", required = true) String userPrivateKey) {}
@JsonIgnoreProperties(ignoreUnknown = true)
private record ConfigDto(@JsonProperty(value = "apiLevel") int apiLevel) {}

View File

@@ -1,5 +1,6 @@
package org.cryptomator.ui.notification;
import org.cryptomator.common.Constants;
import org.cryptomator.cryptofs.event.FileIsInUseEvent;
import org.cryptomator.event.VaultEvent;
import org.cryptomator.ui.common.FxController;
@@ -84,7 +85,10 @@ public class NotificationController implements FxController {
switch (newEvent.actualEvent()) {
case FileIsInUseEvent fiiue -> {
message.set(resourceBundle.getString("notification.inUse.message"));
description.set(resourceBundle.getString("notification.inUse.description").formatted(fiiue.cleartextPath(), fiiue.owner()));
var userAndDevice = fiiue.owner().split(Constants.HUB_USER_DEVICE_SEPARATOR);
var user = userAndDevice[0];
var device = userAndDevice.length == 1? userAndDevice[0]:userAndDevice[1];
description.set(resourceBundle.getString("notification.inUse.description").formatted(fiiue.cleartextPath(), user, device));
actionText.set(resourceBundle.getString("notification.inUse.action"));
}
default -> {

View File

@@ -700,5 +700,5 @@ eventView.entry.brokenFileNode.copyDecrypted=Copy decrypted path
# Notifications
## FileIsInUse Notification
notification.inUse.message=File is locked
notification.inUse.description=File %s is opened by user %s. Ask the user to close the file. Otherwise, you can ignore the lock and open it anyway, but be aware of the data loss risk.
notification.inUse.description=File %s is opened by user %s (%s). Ask the user to close the file. Otherwise, you can ignore the lock and open it anyway, but be aware of the data loss risk.
notification.inUse.action=Ignore Lock