-
Notifications
You must be signed in to change notification settings - Fork 217
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Augment requests with OAuth2 tokens; add togglable validation that th…
…e token endpoint protocol is HTTPS. Signed-off-by: Yufei Cai <yufei.cai@bosch.io>
- Loading branch information
Showing
16 changed files
with
413 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
80 changes: 80 additions & 0 deletions
80
...vice/src/main/java/org/eclipse/ditto/connectivity/service/config/DefaultOAuth2Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Copyright (c) 2020 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.connectivity.service.config; | ||
|
||
import java.time.Duration; | ||
import java.util.Objects; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
import org.eclipse.ditto.internal.utils.config.ConfigWithFallback; | ||
import org.eclipse.ditto.internal.utils.config.ScopedConfig; | ||
|
||
import com.typesafe.config.Config; | ||
|
||
/** | ||
* This class is the default implementation of {@link OAuth2Config}. | ||
*/ | ||
@Immutable | ||
final class DefaultOAuth2Config implements OAuth2Config { | ||
|
||
private static final String CONFIG_PATH = "oauth2"; | ||
|
||
private final Duration maxClockSkew; | ||
private final boolean enforceHttps; | ||
|
||
private DefaultOAuth2Config(final ScopedConfig config) { | ||
maxClockSkew = config.getDuration(ConfigValue.MAX_CLOCK_SKEW.getConfigPath()); | ||
enforceHttps = config.getBoolean(ConfigValue.ENFORCE_HTTPS.getConfigPath()); | ||
} | ||
|
||
static DefaultOAuth2Config of(final Config config) { | ||
return new DefaultOAuth2Config(ConfigWithFallback.newInstance(config, CONFIG_PATH, ConfigValue.values())); | ||
} | ||
|
||
@Override | ||
public Duration getMaxClockSkew() { | ||
return maxClockSkew; | ||
} | ||
|
||
@Override | ||
public boolean shouldEnforceHttps() { | ||
return enforceHttps; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final DefaultOAuth2Config that = (DefaultOAuth2Config) o; | ||
return Objects.equals(maxClockSkew, that.maxClockSkew) && enforceHttps == that.enforceHttps; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(enforceHttps, maxClockSkew); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return getClass().getSimpleName() + " [" + | ||
"requestTimeout=" + maxClockSkew + | ||
", httpProxyConfig=" + enforceHttps + | ||
"]"; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
82 changes: 82 additions & 0 deletions
82
...ity/service/src/main/java/org/eclipse/ditto/connectivity/service/config/OAuth2Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.connectivity.service.config; | ||
|
||
import java.time.Duration; | ||
|
||
import org.eclipse.ditto.internal.utils.config.KnownConfigValue; | ||
|
||
import com.typesafe.config.Config; | ||
|
||
/** | ||
* Provides configuration settings of the http-push connection for OAuth2. | ||
*/ | ||
public interface OAuth2Config { | ||
|
||
/** | ||
* Create an {@code OAuth2Config} object. | ||
* | ||
* @param config the HOCON. | ||
* @return the OAuth2Config object. | ||
*/ | ||
static OAuth2Config of(final Config config) { | ||
return DefaultOAuth2Config.of(config); | ||
} | ||
|
||
/** | ||
* @return Maximum expected clock skew. Tokens are renewed before they expire this much time into the future. | ||
*/ | ||
Duration getMaxClockSkew(); | ||
|
||
/** | ||
* @return Whether HTTPS is the required protocol of the token endpoint. Should be true in a production | ||
* environment to avoid transmitting client secret in plain text. | ||
*/ | ||
boolean shouldEnforceHttps(); | ||
|
||
/** | ||
* An enumeration of the known config path expressions and their associated default values for | ||
* {@code OAuthConfig}. | ||
*/ | ||
enum ConfigValue implements KnownConfigValue { | ||
|
||
/** | ||
* Maximum expected clock skew. | ||
*/ | ||
MAX_CLOCK_SKEW("max-clock-skew", Duration.ofMinutes(1L)), | ||
|
||
/** | ||
* Whether HTTPS is the required protocol of the token endpoint. | ||
*/ | ||
ENFORCE_HTTPS("enforce-https", true); | ||
|
||
private final String path; | ||
private final Object defaultValue; | ||
|
||
ConfigValue(final String thePath, final Object theDefaultValue) { | ||
path = thePath; | ||
defaultValue = theDefaultValue; | ||
} | ||
|
||
@Override | ||
public Object getDefaultValue() { | ||
return defaultValue; | ||
} | ||
|
||
@Override | ||
public String getConfigPath() { | ||
return path; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
...g/eclipse/ditto/connectivity/service/messaging/httppush/ClientCredentialsFlowVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (c) 2021 Contributors to the Eclipse Foundation | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information regarding copyright ownership. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.eclipse.ditto.connectivity.service.messaging.httppush; | ||
|
||
import org.eclipse.ditto.connectivity.model.ClientCertificateCredentials; | ||
import org.eclipse.ditto.connectivity.model.Connection; | ||
import org.eclipse.ditto.connectivity.model.CredentialsVisitor; | ||
import org.eclipse.ditto.connectivity.model.HmacCredentials; | ||
import org.eclipse.ditto.connectivity.model.OAuthClientCredentials; | ||
import org.eclipse.ditto.connectivity.model.SshPublicKeyCredentials; | ||
import org.eclipse.ditto.connectivity.model.UserPasswordCredentials; | ||
import org.eclipse.ditto.connectivity.service.config.HttpPushConfig; | ||
|
||
import akka.NotUsed; | ||
import akka.actor.ActorSystem; | ||
import akka.http.javadsl.Http; | ||
import akka.http.javadsl.model.HttpRequest; | ||
import akka.japi.Pair; | ||
import akka.stream.javadsl.Flow; | ||
|
||
/** | ||
* Visitor to create a flow that augment requests with bearer tokens. | ||
*/ | ||
final class ClientCredentialsFlowVisitor implements | ||
CredentialsVisitor<Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed>> { | ||
|
||
private final ActorSystem actorSystem; | ||
private final HttpPushConfig config; | ||
|
||
private ClientCredentialsFlowVisitor(final ActorSystem actorSystem, final HttpPushConfig config) { | ||
this.actorSystem = actorSystem; | ||
this.config = config; | ||
} | ||
|
||
static Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> eval( | ||
final ActorSystem actorSystem, final HttpPushConfig config, final Connection connection) { | ||
return connection.getCredentials() | ||
.map(credentials -> credentials.accept(new ClientCredentialsFlowVisitor(actorSystem, config))) | ||
.orElseGet(Flow::create); | ||
} | ||
|
||
@Override | ||
public Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> clientCertificate( | ||
final ClientCertificateCredentials credentials) { | ||
return Flow.create(); | ||
} | ||
|
||
@Override | ||
public Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> usernamePassword( | ||
final UserPasswordCredentials credentials) { | ||
return Flow.create(); | ||
} | ||
|
||
@Override | ||
public Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> | ||
sshPublicKeyAuthentication(final SshPublicKeyCredentials credentials) { | ||
return Flow.create(); | ||
} | ||
|
||
@Override | ||
public Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> hmac( | ||
final HmacCredentials credentials) { | ||
return Flow.create(); | ||
} | ||
|
||
@Override | ||
public Flow<Pair<HttpRequest, HttpPushContext>, Pair<HttpRequest, HttpPushContext>, NotUsed> oauthClientCredentials( | ||
final OAuthClientCredentials credentials) { | ||
return ClientCredentialsFlow.of(credentials, config).withToken(Http.get(actorSystem)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.