Skip to content

Commit

Permalink
[#1078] Fix AMQP username of AzSaslRequestSigning.
Browse files Browse the repository at this point in the history
Signed-off-by: Yufei Cai <yufei.cai@bosch.io>
  • Loading branch information
yufei-cai committed Jun 3, 2021
1 parent 6cbc2fd commit f89eea0
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
Expand Up @@ -33,6 +33,8 @@ public final class AzSaslRequestSigning implements RequestSigning {

private static final String AUTH_SCHEME = "SharedAccessSignature";

private static final String AMQP_USERNAME_TRIM_PATTERN = "\\.azure-devices\\.net$";

private final String sharedKeyName;
private final ByteString sharedKey;
private final Duration ttl;
Expand Down Expand Up @@ -82,7 +84,7 @@ public Source<HttpRequest, NotUsed> sign(final HttpRequest request, final Instan
* @return The "username".
*/
public String getAmqpUsername() {
return sharedKeyName + "@sas.root." + endpoint;
return sharedKeyName + "@sas.root." + endpoint.replaceAll(AMQP_USERNAME_TRIM_PATTERN, "");
}

/**
Expand Down
Expand Up @@ -14,18 +14,19 @@

import static org.apache.qpid.jms.provider.failover.FailoverProviderFactory.FAILOVER_OPTION_PREFIX;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.time.Duration;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.eclipse.ditto.base.service.UriEncoding;
import org.eclipse.ditto.connectivity.model.Connection;
import org.eclipse.ditto.connectivity.model.UserPasswordCredentials;
import org.eclipse.ditto.connectivity.service.config.Amqp10Config;

/**
Expand Down Expand Up @@ -71,13 +72,14 @@ public static AmqpSpecificConfig withDefault(final String clientId, final Connec
final Map<String, String> defaultConfig,
final PlainCredentialsSupplier plainCredentialsSupplier) {
final var amqpParameters = new LinkedHashMap<>(filterForAmqpParameters(defaultConfig));
addSaslMechanisms(amqpParameters, connection);
final Optional<UserPasswordCredentials> credentialsOptional = plainCredentialsSupplier.get(connection);
addSaslMechanisms(amqpParameters, credentialsOptional.isPresent());
addTransportParameters(amqpParameters, connection);
addSpecificConfigParameters(amqpParameters, connection, AmqpSpecificConfig::isPermittedAmqpConfig);

final var jmsParameters = new LinkedHashMap<>(filterForJmsParameters(defaultConfig));
addParameter(jmsParameters, CLIENT_ID, clientId);
addCredentials(jmsParameters, connection, plainCredentialsSupplier);
credentialsOptional.ifPresent(credentials -> addCredentials(jmsParameters, credentials));
addFailoverParameters(jmsParameters, connection);
addSpecificConfigParameters(jmsParameters, connection, AmqpSpecificConfig::isPermittedJmsConfig);

Expand Down Expand Up @@ -141,21 +143,19 @@ private static void addSpecificConfigParameters(final LinkedHashMap<String, Stri
});
}

private static void addSaslMechanisms(final LinkedHashMap<String, String> parameters, final Connection connection) {
if (connection.getUsername().isPresent() && connection.getPassword().isPresent()) {
private static void addSaslMechanisms(final LinkedHashMap<String, String> parameters,
final boolean hasPlainCredentials) {
if (hasPlainCredentials) {
addParameter(parameters, SASL_MECHANISMS, "PLAIN");
} else {
addParameter(parameters, SASL_MECHANISMS, "ANONYMOUS");
}
}

private static void addCredentials(final LinkedHashMap<String, String> parameters, final Connection connection,
final PlainCredentialsSupplier plainCredentialsSupplier) {
final var credentialsOptional = plainCredentialsSupplier.get(connection);
credentialsOptional.ifPresent(credentials -> {
addParameter(parameters, USERNAME, credentials.getUsername());
addParameter(parameters, PASSWORD, credentials.getPassword());
});
private static void addCredentials(final LinkedHashMap<String, String> parameters,
final UserPasswordCredentials credentials) {
addParameter(parameters, USERNAME, credentials.getUsername());
addParameter(parameters, PASSWORD, credentials.getPassword());
}

private static void addTransportParameters(final LinkedHashMap<String, String> parameters,
Expand All @@ -173,7 +173,7 @@ private static void addParameter(final LinkedHashMap<String, String> parameters,
}

private static String encode(final String string) {
return URLEncoder.encode(string, StandardCharsets.UTF_8);
return UriEncoding.encodeAllButUnreserved(string);
}

private static boolean isSecuredConnection(final Connection connection) {
Expand Down
Expand Up @@ -57,6 +57,14 @@ public void testToken() {
assertThat(underTest.getAmqpPassword(timestamp)).isEqualTo("SharedAccessSignature " + expectedToken);
}

@Test
public void testAmqpUsernameTrimming() {
final String sharedKey = Base64.getEncoder().encodeToString("my-awesome-shared-key".getBytes());
final String resource = "resource-name.hostname.domain.azure-devices.net";
final var underTest = AzSaslRequestSigning.of("keyName", sharedKey, Duration.ZERO, resource);
assertThat(underTest.getAmqpUsername()).isEqualTo("keyName@sas.root.resource-name.hostname.domain");
}

@Test
public void testRequestSigning() {
final HttpRequest request = HttpRequest.POST("https://resource-name.hostname.domain")
Expand Down

0 comments on commit f89eea0

Please sign in to comment.