Skip to content

Commit

Permalink
Merge pull request #16792 from iterate-ch/feature/16791
Browse files Browse the repository at this point in the history
Allow OAuth configuration in connection profiles using WebDAV.
  • Loading branch information
dkocher authored Jan 21, 2025
2 parents f767721 + 5ab1dc1 commit ca26b13
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import ch.cyberduck.core.dav.DAVSession;
import ch.cyberduck.core.dav.DAVTouchFeature;
import ch.cyberduck.core.exception.BackgroundException;
import ch.cyberduck.core.exception.ConnectionCanceledException;
import ch.cyberduck.core.features.AttributesFinder;
import ch.cyberduck.core.features.Delete;
import ch.cyberduck.core.features.Directory;
Expand All @@ -41,18 +40,13 @@
import ch.cyberduck.core.features.Upload;
import ch.cyberduck.core.features.Versioning;
import ch.cyberduck.core.features.Write;
import ch.cyberduck.core.http.CustomServiceUnavailableRetryStrategy;
import ch.cyberduck.core.http.DefaultHttpResponseExceptionMappingService;
import ch.cyberduck.core.http.ExecutionCountServiceUnavailableRetryStrategy;
import ch.cyberduck.core.http.HttpUploadFeature;
import ch.cyberduck.core.nextcloud.NextcloudDeleteFeature;
import ch.cyberduck.core.nextcloud.NextcloudListService;
import ch.cyberduck.core.nextcloud.NextcloudShareFeature;
import ch.cyberduck.core.nextcloud.NextcloudUrlProvider;
import ch.cyberduck.core.nextcloud.NextcloudWriteFeature;
import ch.cyberduck.core.oauth.OAuth2AuthorizationService;
import ch.cyberduck.core.oauth.OAuth2ErrorResponseInterceptor;
import ch.cyberduck.core.oauth.OAuth2RequestInterceptor;
import ch.cyberduck.core.ocs.OcsCapabilities;
import ch.cyberduck.core.ocs.OcsCapabilitiesRequest;
import ch.cyberduck.core.ocs.OcsCapabilitiesResponseHandler;
Expand All @@ -70,7 +64,6 @@
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpResponseException;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand All @@ -84,8 +77,6 @@
public class OwncloudSession extends DAVSession {
private static final Logger log = LogManager.getLogger(OwncloudSession.class);

private OAuth2RequestInterceptor authorizationService;

protected final TusCapabilities tus = new TusCapabilities();
protected final OcsCapabilities ocs = new OcsCapabilities();

Expand All @@ -110,26 +101,11 @@ protected DAVClient connect(final ProxyFinder proxy, final HostKeyCallback key,
return client;
}

@Override
protected HttpClientBuilder getConfiguration(final ProxyFinder proxy, final LoginCallback prompt) throws ConnectionCanceledException {
final HttpClientBuilder configuration = super.getConfiguration(proxy, prompt);
if(host.getProtocol().isOAuthConfigurable()) {
authorizationService = new OAuth2RequestInterceptor(configuration.build(), host, prompt)
.withRedirectUri(host.getProtocol().getOAuthRedirectUrl());
if(host.getProtocol().getAuthorization() != null) {
authorizationService.withFlowType(OAuth2AuthorizationService.FlowType.valueOf(host.getProtocol().getAuthorization()));
}
configuration.addInterceptorLast(authorizationService);
configuration.setServiceUnavailableRetryStrategy(new CustomServiceUnavailableRetryStrategy(host,
new ExecutionCountServiceUnavailableRetryStrategy(new OAuth2ErrorResponseInterceptor(host, authorizationService))));
}
return configuration;
}

@Override
public void login(final LoginCallback prompt, final CancelCallback cancel) throws BackgroundException {
super.login(prompt, cancel);
if(host.getProtocol().isOAuthConfigurable()) {
final Credentials credentials = authorizationService.validate();
final Credentials credentials = host.getCredentials();
final OAuthTokens oauth = credentials.getOauth();
try {
final String username = JWT.decode(oauth.getIdToken()).getClaim("preferred_username").asString();
Expand All @@ -141,7 +117,6 @@ public void login(final LoginCallback prompt, final CancelCallback cancel) throw
log.warn("Failure {} decoding JWT {}", e, oauth.getIdToken());
}
}
super.login(prompt, cancel);
try {
client.execute(new OcsCapabilitiesRequest(host), new OcsCapabilitiesResponseHandler(ocs));
}
Expand Down
5 changes: 5 additions & 0 deletions webdav/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ch.cyberduck</groupId>
<artifactId>oauth</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ch.cyberduck</groupId>
<artifactId>test</artifactId>
Expand Down
23 changes: 21 additions & 2 deletions webdav/src/main/java/ch/cyberduck/core/dav/DAVSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,20 @@
import ch.cyberduck.core.exception.ListCanceledException;
import ch.cyberduck.core.exception.LoginCanceledException;
import ch.cyberduck.core.features.*;
import ch.cyberduck.core.http.CustomServiceUnavailableRetryStrategy;
import ch.cyberduck.core.http.ExecutionCountServiceUnavailableRetryStrategy;
import ch.cyberduck.core.http.HttpExceptionMappingService;
import ch.cyberduck.core.http.HttpSession;
import ch.cyberduck.core.http.PreferencesRedirectCallback;
import ch.cyberduck.core.http.RedirectCallback;
import ch.cyberduck.core.oauth.OAuth2AuthorizationService;
import ch.cyberduck.core.oauth.OAuth2ErrorResponseInterceptor;
import ch.cyberduck.core.oauth.OAuth2RequestInterceptor;
import ch.cyberduck.core.preferences.HostPreferences;
import ch.cyberduck.core.preferences.PreferencesReader;
import ch.cyberduck.core.proxy.ProxyFinder;
import ch.cyberduck.core.shared.DefaultPathHomeFeature;
import ch.cyberduck.core.shared.DelegatingHomeFeature;
import ch.cyberduck.core.shared.WorkdirHomeFeature;
import ch.cyberduck.core.ssl.X509KeyManager;
import ch.cyberduck.core.ssl.X509TrustManager;
import ch.cyberduck.core.threading.CancelCallback;
Expand Down Expand Up @@ -90,6 +94,8 @@ public class DAVSession extends HttpSession<DAVClient> {
private final PreferencesReader preferences = new HostPreferences(host);
private final HttpCapabilities capabilities = new HttpCapabilities(preferences);

private OAuth2RequestInterceptor authorizationService;

public DAVSession(final Host host, final X509TrustManager trust, final X509KeyManager key) {
this(host, trust, key, new PreferencesRedirectCallback());
}
Expand All @@ -107,6 +113,16 @@ protected DAVClient connect(final ProxyFinder proxy, final HostKeyCallback key,

protected HttpClientBuilder getConfiguration(final ProxyFinder proxy, final LoginCallback prompt) throws ConnectionCanceledException {
final HttpClientBuilder configuration = builder.build(proxy, this, prompt);
if(host.getProtocol().isOAuthConfigurable()) {
authorizationService = new OAuth2RequestInterceptor(configuration.build(), host, prompt)
.withRedirectUri(host.getProtocol().getOAuthRedirectUrl());
if(host.getProtocol().getAuthorization() != null) {
authorizationService.withFlowType(OAuth2AuthorizationService.FlowType.valueOf(host.getProtocol().getAuthorization()));
}
configuration.addInterceptorLast(authorizationService);
configuration.setServiceUnavailableRetryStrategy(new CustomServiceUnavailableRetryStrategy(host,
new ExecutionCountServiceUnavailableRetryStrategy(new OAuth2ErrorResponseInterceptor(host, authorizationService))));
}
configuration.setRedirectStrategy(new DAVRedirectStrategy(redirect));
configuration.addInterceptorLast(new MicrosoftIISPersistentAuthResponseInterceptor());
return configuration;
Expand All @@ -124,8 +140,11 @@ protected void logout() throws BackgroundException {

@Override
public void login(final LoginCallback prompt, final CancelCallback cancel) throws BackgroundException {
final Credentials credentials = host.getCredentials();
if(host.getProtocol().isOAuthConfigurable()) {
authorizationService.validate();
}
if(host.getProtocol().isPasswordConfigurable()) {
final Credentials credentials = host.getCredentials();
final String domain, username;
if(credentials.getUsername().contains("\\")) {
domain = StringUtils.substringBefore(credentials.getUsername(), "\\");
Expand Down

0 comments on commit ca26b13

Please sign in to comment.