From 561cff8157ebd5904d877eac7999088040b7cb0f Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 16 Feb 2021 13:31:33 +0100 Subject: [PATCH] SSO: support of parameter v2, which allows to have multiple values for same key Signed-off-by: tobiasKaminsky --- .../nextcloud/sso/InputStreamBinderTest.kt | 61 +++++++++++++++++++ .../android/sso/InputStreamBinder.java | 31 +++++++++- .../android/sso/aidl/NextcloudRequest.java | 31 ++++++++++ 3 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 src/androidTest/java/com/nextcloud/sso/InputStreamBinderTest.kt diff --git a/src/androidTest/java/com/nextcloud/sso/InputStreamBinderTest.kt b/src/androidTest/java/com/nextcloud/sso/InputStreamBinderTest.kt new file mode 100644 index 0000000000..27d5413b64 --- /dev/null +++ b/src/androidTest/java/com/nextcloud/sso/InputStreamBinderTest.kt @@ -0,0 +1,61 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2021 Tobias Kaminsky + * Copyright (C) 2021 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.nextcloud.sso + +import com.nextcloud.android.sso.InputStreamBinder +import junit.framework.Assert.assertEquals +import org.junit.Test + +class InputStreamBinderTest { + @Test + fun convertMapToNVP() { + val source = mutableMapOf() + source["quality"] = "1024p" + source["someOtherParameter"] = "parameterValue" + source["duplicate"] = "1" + source["duplicate"] = "2" // this overwrites previous parameter + + val output = InputStreamBinder.convertMapToNVP(source) + + assertEquals(source.size, output.size) + assertEquals("1024p", output[0].value) + assertEquals("parameterValue", output[1].value) + assertEquals("2", output[2].value) + } + + @Test + fun convertListToNVP() { + val source = mutableListOf>() + source.add(android.util.Pair("quality", "1024p")) + source.add(android.util.Pair("someOtherParameter", "parameterValue")) + source.add(android.util.Pair("duplicate", "1")) + source.add(android.util.Pair("duplicate", "2")) // here we can have same parameter multiple times + + val output = InputStreamBinder.convertListToNVP(source) + + assertEquals(source.size, output.size) + assertEquals("1024p", output[0].value) + assertEquals("parameterValue", output[1].value) + assertEquals("1", output[2].value) + assertEquals("2", output[3].value) + } +} diff --git a/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java b/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java index 2f83ac9706..6198785233 100644 --- a/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java +++ b/src/main/java/com/nextcloud/android/sso/InputStreamBinder.java @@ -32,6 +32,7 @@ import android.os.Binder; import android.os.ParcelFileDescriptor; import android.text.TextUtils; import android.util.Log; +import android.util.Pair; import com.nextcloud.android.sso.aidl.IInputStreamService; import com.nextcloud.android.sso.aidl.NextcloudRequest; @@ -70,9 +71,12 @@ import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.util.Collection; import java.util.List; import java.util.Map; +import androidx.annotation.VisibleForTesting; + import static com.nextcloud.android.sso.Constants.DELIMITER; import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_NOT_FOUND; import static com.nextcloud.android.sso.Constants.EXCEPTION_HTTP_REQUEST_FAILED; @@ -331,7 +335,11 @@ public class InputStreamBinder extends IInputStreamService.Stub { HttpMethodBase method = buildMethod(request, client.getBaseUri(), requestBodyInputStream); - method.setQueryString(convertMapToNVP(request.getParameter())); + if (!request.getParameterV2().isEmpty()) { + method.setQueryString(convertListToNVP(request.getParameterV2())); + } else { + method.setQueryString(convertMapToNVP(request.getParameter())); + } method.addRequestHeader("OCS-APIREQUEST", "true"); for (Map.Entry> header : request.getHeader().entrySet()) { @@ -394,7 +402,12 @@ public class InputStreamBinder extends IInputStreamService.Stub { HttpMethodBase method = buildMethod(request, client.getBaseUri(), requestBodyInputStream); - method.setQueryString(convertMapToNVP(request.getParameter())); + if (!request.getParameterV2().isEmpty()) { + method.setQueryString(convertListToNVP(request.getParameterV2())); + } else { + method.setQueryString(convertMapToNVP(request.getParameter())); + } + method.addRequestHeader("OCS-APIREQUEST", "true"); for (Map.Entry> header : request.getHeader().entrySet()) { @@ -482,7 +495,8 @@ public class InputStreamBinder extends IInputStreamService.Stub { } } - private static NameValuePair[] convertMapToNVP(Map map) { + @VisibleForTesting + public static NameValuePair[] convertMapToNVP(Map map) { NameValuePair[] nvp = new NameValuePair[map.size()]; int i = 0; for (String key : map.keySet()) { @@ -491,4 +505,15 @@ public class InputStreamBinder extends IInputStreamService.Stub { } return nvp; } + + @VisibleForTesting + public static NameValuePair[] convertListToNVP(Collection> list) { + NameValuePair[] nvp = new NameValuePair[list.size()]; + int i = 0; + for (Pair pair : list) { + nvp[i] = new NameValuePair(pair.first, pair.second); + i++; + } + return nvp; + } } diff --git a/src/main/java/com/nextcloud/android/sso/aidl/NextcloudRequest.java b/src/main/java/com/nextcloud/android/sso/aidl/NextcloudRequest.java index 467e875a33..a83ffe021e 100644 --- a/src/main/java/com/nextcloud/android/sso/aidl/NextcloudRequest.java +++ b/src/main/java/com/nextcloud/android/sso/aidl/NextcloudRequest.java @@ -1,3 +1,25 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2021 Tobias Kaminsky + * Copyright (C) 2021 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + /* * Nextcloud SingleSignOn * @@ -19,8 +41,12 @@ package com.nextcloud.android.sso.aidl; +import android.util.Pair; + import java.io.Serializable; +import java.util.Collection; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -31,6 +57,7 @@ public class NextcloudRequest implements Serializable { private String method; private Map> header = new HashMap<>(); private Map parameter = new HashMap<>(); + private final Collection> parameterV2 = new LinkedList<>(); private String requestBody; private String url; private String token; @@ -144,4 +171,8 @@ public class NextcloudRequest implements Serializable { public boolean isFollowRedirects() { return this.followRedirects; } + + public Collection> getParameterV2() { + return parameterV2; + } }