mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-18 10:41:26 +00:00
Add query to redirection to provide more context in the frontend (#1973)
Co-authored-by: Sebastian Stenzel <sebastian.stenzel@gmail.com>
This commit is contained in:
@@ -60,8 +60,8 @@ class AuthFlow implements AutoCloseable {
|
||||
* @return An authorization flow
|
||||
* @throws Exception In case of any problems starting the server
|
||||
*/
|
||||
public static AuthFlow init(HubConfig hubConfig) throws Exception {
|
||||
var receiver = AuthFlowReceiver.start(hubConfig);
|
||||
public static AuthFlow init(HubConfig hubConfig, AuthFlowContext authFlowContext) throws Exception {
|
||||
var receiver = AuthFlowReceiver.start(hubConfig, authFlowContext);
|
||||
return new AuthFlow(receiver, hubConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.cryptomator.ui.keyloading.hub;
|
||||
|
||||
record AuthFlowContext(String deviceId) {
|
||||
|
||||
}
|
||||
@@ -35,6 +35,7 @@ public class AuthFlowController implements FxController {
|
||||
private final Application application;
|
||||
private final Stage window;
|
||||
private final ExecutorService executor;
|
||||
private final String deviceId;
|
||||
private final HubConfig hubConfig;
|
||||
private final AtomicReference<String> tokenRef;
|
||||
private final UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result;
|
||||
@@ -45,10 +46,11 @@ public class AuthFlowController implements FxController {
|
||||
private AuthFlowTask task;
|
||||
|
||||
@Inject
|
||||
public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, HubConfig hubConfig, @Named("bearerToken") AtomicReference<String> tokenRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy<Scene> receiveKeyScene, ErrorComponent.Builder errorComponent) {
|
||||
public AuthFlowController(Application application, @KeyLoading Stage window, ExecutorService executor, @Named("deviceId") String deviceId, HubConfig hubConfig, @Named("bearerToken") AtomicReference<String> tokenRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_RECEIVE_KEY) Lazy<Scene> receiveKeyScene, ErrorComponent.Builder errorComponent) {
|
||||
this.application = application;
|
||||
this.window = window;
|
||||
this.executor = executor;
|
||||
this.deviceId = deviceId;
|
||||
this.hubConfig = hubConfig;
|
||||
this.tokenRef = tokenRef;
|
||||
this.result = result;
|
||||
@@ -62,7 +64,7 @@ public class AuthFlowController implements FxController {
|
||||
@FXML
|
||||
public void initialize() {
|
||||
assert task == null;
|
||||
task = new AuthFlowTask(hubConfig, this::setAuthUri);;
|
||||
task = new AuthFlowTask(hubConfig, new AuthFlowContext(deviceId), this::setAuthUri);;
|
||||
task.setOnFailed(this::authFailed);
|
||||
task.setOnSucceeded(this::authSucceeded);
|
||||
executor.submit(task);
|
||||
|
||||
@@ -30,20 +30,18 @@ class AuthFlowReceiver implements AutoCloseable {
|
||||
private final Server server;
|
||||
private final ServerConnector connector;
|
||||
private final CallbackServlet servlet;
|
||||
private final HubConfig hubConfig;
|
||||
|
||||
private AuthFlowReceiver(Server server, ServerConnector connector, CallbackServlet servlet, HubConfig hubConfig) {
|
||||
private AuthFlowReceiver(Server server, ServerConnector connector, CallbackServlet servlet) {
|
||||
this.server = server;
|
||||
this.connector = connector;
|
||||
this.servlet = servlet;
|
||||
this.hubConfig = hubConfig;
|
||||
}
|
||||
|
||||
public static AuthFlowReceiver start(HubConfig hubConfig) throws Exception {
|
||||
public static AuthFlowReceiver start(HubConfig hubConfig, AuthFlowContext authFlowContext) throws Exception {
|
||||
var server = new Server();
|
||||
var context = new ServletContextHandler();
|
||||
|
||||
var servlet = new CallbackServlet(hubConfig);
|
||||
var servlet = new CallbackServlet(hubConfig, authFlowContext);
|
||||
context.addServlet(new ServletHolder(servlet), CALLBACK_PATH);
|
||||
|
||||
var connector = new ServerConnector(server);
|
||||
@@ -52,7 +50,7 @@ class AuthFlowReceiver implements AutoCloseable {
|
||||
server.setConnectors(new Connector[]{connector});
|
||||
server.setHandler(context);
|
||||
server.start();
|
||||
return new AuthFlowReceiver(server, connector, servlet, hubConfig);
|
||||
return new AuthFlowReceiver(server, connector, servlet);
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
@@ -68,15 +66,19 @@ class AuthFlowReceiver implements AutoCloseable {
|
||||
server.stop();
|
||||
}
|
||||
|
||||
public static record Callback(String error, String code, String state){}
|
||||
public static record Callback(String error, String code, String state) {
|
||||
|
||||
}
|
||||
|
||||
private static class CallbackServlet extends HttpServlet {
|
||||
|
||||
private final BlockingQueue<Callback> callback = new LinkedBlockingQueue<>();
|
||||
private final HubConfig hubConfig;
|
||||
private final AuthFlowContext authFlowContext;
|
||||
|
||||
public CallbackServlet(HubConfig hubConfig) {
|
||||
public CallbackServlet(HubConfig hubConfig, AuthFlowContext authFlowContext) {
|
||||
this.hubConfig = hubConfig;
|
||||
this.authFlowContext = authFlowContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,9 +89,9 @@ class AuthFlowReceiver implements AutoCloseable {
|
||||
|
||||
res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
|
||||
if (error == null && code != null) {
|
||||
res.setHeader("Location", hubConfig.authSuccessUrl);
|
||||
res.setHeader("Location", hubConfig.authSuccessUrl + "&device=" + authFlowContext.deviceId());
|
||||
} else {
|
||||
res.setHeader("Location", hubConfig.authErrorUrl);
|
||||
res.setHeader("Location", hubConfig.authErrorUrl + "&device=" + authFlowContext.deviceId());
|
||||
}
|
||||
|
||||
callback.add(new Callback(error, code, state));
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.function.Consumer;
|
||||
|
||||
class AuthFlowTask extends Task<String> {
|
||||
|
||||
private final AuthFlowContext authFlowContext;
|
||||
private final Consumer<URI> redirectUriConsumer;
|
||||
|
||||
/**
|
||||
@@ -15,14 +16,15 @@ class AuthFlowTask extends Task<String> {
|
||||
* @param hubConfig Configuration object holding parameters required by {@link AuthFlow}
|
||||
* @param redirectUriConsumer A callback invoked with the redirectUri, as soon as the server has started
|
||||
*/
|
||||
public AuthFlowTask(HubConfig hubConfig, Consumer<URI> redirectUriConsumer) {
|
||||
public AuthFlowTask(HubConfig hubConfig, AuthFlowContext authFlowContext, Consumer<URI> redirectUriConsumer) {
|
||||
this.hubConfig = hubConfig;
|
||||
this.authFlowContext = authFlowContext;
|
||||
this.redirectUriConsumer = redirectUriConsumer;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String call() throws Exception {
|
||||
try (var authFlow = AuthFlow.init(hubConfig)) {
|
||||
try (var authFlow = AuthFlow.init(hubConfig, authFlowContext)) {
|
||||
return authFlow.run(uri -> Platform.runLater(() -> redirectUriConsumer.accept(uri)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package org.cryptomator.ui.keyloading.hub;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.nimbusds.jose.JWEObject;
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.multibindings.IntoMap;
|
||||
import dagger.multibindings.StringKey;
|
||||
import org.cryptomator.common.settings.DeviceKey;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptolib.common.MessageDigestSupplier;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxControllerKey;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
@@ -23,8 +26,7 @@ import javax.inject.Named;
|
||||
import javafx.scene.Scene;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.security.KeyPair;
|
||||
import java.util.Objects;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
@@ -47,6 +49,15 @@ public abstract class HubKeyLoadingModule {
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@KeyLoadingScoped
|
||||
@Named("deviceId")
|
||||
static String provideDeviceId(DeviceKey deviceKey) {
|
||||
var publicKey = Objects.requireNonNull(deviceKey.get()).getPublic().getEncoded();
|
||||
var hashedKey = MessageDigestSupplier.SHA256.get().digest(publicKey);
|
||||
return BaseEncoding.base16().encode(hashedKey);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("bearerToken")
|
||||
@KeyLoadingScoped
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package org.cryptomator.ui.keyloading.hub;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.nimbusds.jose.JWEObject;
|
||||
import dagger.Lazy;
|
||||
import org.cryptomator.common.settings.DeviceKey;
|
||||
import org.cryptomator.common.vaults.Vault;
|
||||
import org.cryptomator.cryptolib.common.MessageDigestSupplier;
|
||||
import org.cryptomator.cryptolib.common.P384KeyPair;
|
||||
import org.cryptomator.ui.common.ErrorComponent;
|
||||
import org.cryptomator.ui.common.FxController;
|
||||
import org.cryptomator.ui.common.FxmlFile;
|
||||
@@ -44,7 +40,7 @@ public class ReceiveKeyController implements FxController {
|
||||
private static final String SCHEME_PREFIX = "hub+";
|
||||
|
||||
private final Stage window;
|
||||
private final P384KeyPair keyPair;
|
||||
private final String deviceId;
|
||||
private final String bearerToken;
|
||||
private final AtomicReference<JWEObject> jweRef;
|
||||
private final UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result;
|
||||
@@ -55,9 +51,9 @@ public class ReceiveKeyController implements FxController {
|
||||
private final HttpClient httpClient;
|
||||
|
||||
@Inject
|
||||
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, DeviceKey deviceKey, @Named("bearerToken") AtomicReference<String> tokenRef, AtomicReference<JWEObject> jweRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, ErrorComponent.Builder errorComponent) {
|
||||
public ReceiveKeyController(@KeyLoading Vault vault, ExecutorService executor, @KeyLoading Stage window, @Named("deviceId") String deviceId, @Named("bearerToken") AtomicReference<String> tokenRef, AtomicReference<JWEObject> jweRef, UserInteractionLock<HubKeyLoadingModule.HubLoadingResult> result, @FxmlScene(FxmlFile.HUB_REGISTER_DEVICE) Lazy<Scene> registerDeviceScene, @FxmlScene(FxmlFile.HUB_UNAUTHORIZED_DEVICE) Lazy<Scene> unauthorizedScene, ErrorComponent.Builder errorComponent) {
|
||||
this.window = window;
|
||||
this.keyPair = Objects.requireNonNull(deviceKey.get());
|
||||
this.deviceId = deviceId;
|
||||
this.bearerToken = Objects.requireNonNull(tokenRef.get());
|
||||
this.jweRef = jweRef;
|
||||
this.result = result;
|
||||
@@ -71,9 +67,6 @@ public class ReceiveKeyController implements FxController {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
var deviceKey = keyPair.getPublic().getEncoded();
|
||||
var hashedKey = MessageDigestSupplier.SHA256.get().digest(deviceKey);
|
||||
var deviceId = BaseEncoding.base16().encode(hashedKey);
|
||||
var keyUri = appendPath(vaultBaseUri, "/keys/" + deviceId);
|
||||
var request = HttpRequest.newBuilder(keyUri) //
|
||||
.header("Authorization", "Bearer " + bearerToken) //
|
||||
|
||||
Reference in New Issue
Block a user