Skip to content
Snippets Groups Projects
Commit 271a2230 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

GMS client lib: fixed URL encoding issue in invited registration call

parent ae69e025
No related branches found
No related tags found
No related merge requests found
...@@ -22,7 +22,8 @@ public class AddInvitedRegistrationCall extends BaseGmsCall { ...@@ -22,7 +22,8 @@ public class AddInvitedRegistrationCall extends BaseGmsCall {
String endpoint = "invited-registration"; String endpoint = "invited-registration";
String bodyParams = "token_hash=" + tokenHash // plus symbol in token hash is encoded to %2B, otherwise it will be interpreted as space
String bodyParams = "token_hash=" + tokenHash.replace("+", "%2B")
+ "&email=" + email + "&groups=" + "&email=" + email + "&groups="
+ String.join("\n", groupsPermissions.entrySet() + String.join("\n", groupsPermissions.entrySet()
.stream().map(e -> e.getKey() + " " + e.getValue()) .stream().map(e -> e.getKey() + " " + e.getValue())
......
...@@ -7,14 +7,23 @@ import java.io.ByteArrayInputStream; ...@@ -7,14 +7,23 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublisher;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodySubscriber;
import java.net.http.HttpResponse.BodySubscribers;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Flow;
import java.util.concurrent.Flow.Subscriber;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.AdditionalMatchers;
import org.mockito.ArgumentMatcher; import org.mockito.ArgumentMatcher;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
...@@ -145,6 +154,72 @@ public class GmsClientTest { ...@@ -145,6 +154,72 @@ public class GmsClientTest {
verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "permission/LBT.INAF?user_id=user"), any()); verify(httpClient, times(1)).sendAsync(endpointEq("DELETE", "permission/LBT.INAF?user_id=user"), any());
} }
@Test
public void testInvitedRegistration() {
CompletableFuture response = CompletableFuture.completedFuture(getMockedResponse(201));
when(httpClient.sendAsync(any(), any())).thenReturn(response);
Map<String, Permission> permissionsMap = new HashMap<>();
permissionsMap.put("group1", Permission.MANAGE_MEMBERS);
permissionsMap.put("group2", Permission.MANAGE_MEMBERS);
client.addInvitedRegistration("bvjsgqu423", "email", permissionsMap);
// hash = AOyojiwaRR7BHPde6Tomg3+BMoQQggNM3wUHEarXuNQ=
verify(httpClient, times(1)).sendAsync(
AdditionalMatchers.and(
endpointEq("POST", "invited-registration"),
ArgumentMatchers.argThat(req -> {
String reqbody = req.bodyPublisher().map(p -> {
var bodySubscriber = BodySubscribers.ofString(StandardCharsets.UTF_8);
var flowSubscriber = new StringSubscriber(bodySubscriber);
p.subscribe(flowSubscriber);
return bodySubscriber.getBody().toCompletableFuture().join();
}).get();
// If the resulting hash contains a + symbol it has to be encoded to %2B,
// otherwise it will be interpreted as a space and wrong value will be
// stored into the database
String expectedBody = "token_hash=AOyojiwaRR7BHPde6Tomg3%2BBMoQQggNM3wUHEarXuNQ="
+ "&email=email&groups=group2 MANAGE_MEMBERS\n"
+ "group1 MANAGE_MEMBERS";
return reqbody.equals(expectedBody);
})), any());
}
/**
* Credit: https://stackoverflow.com/a/55816685/771431
*/
static final class StringSubscriber implements Flow.Subscriber<ByteBuffer> {
final BodySubscriber<String> wrapped;
StringSubscriber(BodySubscriber<String> wrapped) {
this.wrapped = wrapped;
}
@Override
public void onSubscribe(Flow.Subscription subscription) {
wrapped.onSubscribe(subscription);
}
@Override
public void onNext(ByteBuffer item) {
wrapped.onNext(List.of(item));
}
@Override
public void onError(Throwable throwable) {
wrapped.onError(throwable);
}
@Override
public void onComplete() {
wrapped.onComplete();
}
}
private HttpResponse getMockedResponse(int statusCode, String body) { private HttpResponse getMockedResponse(int statusCode, String body) {
HttpResponse response = getMockedResponse(statusCode); HttpResponse response = getMockedResponse(statusCode);
InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)); InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment