From 089c2917a4e70233ec0c183073d8b438fe6d2bbc Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Mon, 28 May 2018 19:18:59 -0400 Subject: [PATCH 1/9] Upon creating AuthenticatedActivity, now checking if the user is blocked via api call and notifying the user if they are blocked via snackbar --- .../commons/auth/AuthenticatedActivity.java | 19 ++++++++++++++++++ .../free/nrw/commons/auth/LoginActivity.java | 1 + .../mwapi/ApacheHttpClientMediaWikiApi.java | 20 +++++++++++++++++++ .../free/nrw/commons/mwapi/MediaWikiApi.java | 2 ++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 43 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index e39528252..19fabf7d2 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -4,8 +4,13 @@ import android.os.Bundle; import javax.inject.Inject; +import fr.free.nrw.commons.R; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.utils.ViewUtil; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import static fr.free.nrw.commons.auth.AccountUtil.AUTH_COOKIE; @@ -34,6 +39,8 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { if (savedInstanceState != null) { authCookie = savedInstanceState.getString(AUTH_COOKIE); } + + showBlockStatus(); } @Override @@ -45,4 +52,16 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { protected abstract void onAuthCookieAcquired(String authCookie); protected abstract void onAuthFailure(); + + protected void showBlockStatus() + { + Observable.fromCallable(() -> mediaWikiApi.isUserBlocked()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .filter(result -> result) + .subscribe(result -> { + ViewUtil.showSnackbar(findViewById(android.R.id.content), R.string.block_notification); + } + ); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index d0fb628e3..5c3f86c24 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -162,6 +162,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { if (sessionManager.getCurrentAccount() != null && sessionManager.isUserLoggedIn() && sessionManager.getCachedAuthCookie() != null) { + sessionManager.revalidateAuthToken(); startMainActivity(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 6629d0933..679a6af20 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -615,6 +615,26 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { }); } + @Override + public boolean isUserBlocked() { + boolean userBlocked = false; + try { + ApiResult result = api.action("query") + .param("action", "query") + .param("format", "xml") + .param("meta", "userinfo") + .param("uiprop", "blockinfo") + .get(); + if(result != null) { + userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return userBlocked; + } + private Date parseMWDate(String mwDate) { SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC try { diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java index c0bd2fd87..6ba1f9158 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java @@ -75,6 +75,8 @@ public interface MediaWikiApi { @NonNull Single getUploadCount(String userName); + boolean isUserBlocked(); + interface ProgressListener { void onProgress(long transferred, long total); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6e30baa10..bd82e5c4d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -283,5 +283,6 @@ Share App Coordinates were not specified during image selection Error fetching nearby places. + You are blocked from editing commons From 39bf214c572cfbfb433c88ad5cf493a6498d09da Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 09:44:09 -0400 Subject: [PATCH 2/9] Added comments to isUserBlocked method and tests for the method --- .../mwapi/ApacheHttpClientMediaWikiApi.java | 5 ++ .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 679a6af20..d5f9a7fce 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -615,6 +615,10 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { }); } + /** + * Checks to see if a user is currently blocked + * @return whether or not the user is blocked + */ @Override public boolean isUserBlocked() { boolean userBlocked = false; @@ -626,6 +630,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { .param("uiprop", "blockinfo") .get(); if(result != null) { + // the blockexpiry field will only be present if the user is currently blocked userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); } } catch (Exception e) { diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt index 686a90ef2..6f630ce1a 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -223,6 +223,60 @@ class ApacheHttpClientMediaWikiApiTest { assertEquals(23, testObserver.values()[0]) } + @Test + fun isUserBlockedForInfinitelyBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertTrue(result) + } + + @Test + fun isUserBlockedForTimeBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertTrue(result) + } + + @Test + fun isUserBlockedForNotBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertFalse(result) + } + private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let { assertEquals("/", it.requestUrl.encodedPath()) assertEquals(method, it.method) From 47bffa1b21c26f4a83e096c2a01be287764e2938 Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 11:28:56 -0400 Subject: [PATCH 3/9] Updated isUserBlocked method to check the expiration time instead of just if an expiration time exists. Updated tests accordingly --- .../mwapi/ApacheHttpClientMediaWikiApi.java | 16 ++++++++-- .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 29 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index d5f9a7fce..6db6a4e5a 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -37,6 +37,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.TimeZone; import java.util.concurrent.Callable; import fr.free.nrw.commons.BuildConfig; @@ -630,8 +631,17 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { .param("uiprop", "blockinfo") .get(); if(result != null) { - // the blockexpiry field will only be present if the user is currently blocked - userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); + String blockEnd = result.getString("/api/query/userinfo/@blockexpiry"); + if(blockEnd.equals("infinite")) + { + userBlocked = true; + } + else if (!blockEnd.isEmpty()) { + Date endDate = parseMWDate(blockEnd); + Date current = new Date(); + userBlocked = endDate.after(current); + } + } } catch (Exception e) { e.printStackTrace(); @@ -642,10 +652,12 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { private Date parseMWDate(String mwDate) { SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC + isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { return isoFormat.parse(mwDate); } catch (ParseException e) { throw new RuntimeException(e); } } + } diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt index 6f630ce1a..eea86fd2f 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -18,6 +18,7 @@ import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config import java.net.URLDecoder +import java.text.SimpleDateFormat import java.util.* @RunWith(RobolectricTestRunner::class) @@ -243,7 +244,11 @@ class ApacheHttpClientMediaWikiApiTest { @Test fun isUserBlockedForTimeBlockedUser() { - server.enqueue(MockResponse().setBody("")) + val currentDate = Date() + val expiredDate = Date(currentDate.time + 10000) + val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) + server.enqueue(MockResponse().setBody("")) val result = testObject.isUserBlocked(); @@ -259,6 +264,28 @@ class ApacheHttpClientMediaWikiApiTest { assertTrue(result) } + @Test + fun isUserBlockedForExpiredBlockedUser() { + val currentDate = Date() + val expiredDate = Date(currentDate.time - 10000) + val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertFalse(result) + } + @Test fun isUserBlockedForNotBlockedUser() { server.enqueue(MockResponse().setBody("")) From db30e03cf2a6b96b598f4b91e7136f64eb46ea02 Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 13:37:55 -0400 Subject: [PATCH 4/9] Added javadoc comments to showBlockStatus method --- .../java/fr/free/nrw/commons/auth/AuthenticatedActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 19fabf7d2..f31f36c51 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -53,6 +53,10 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { protected abstract void onAuthFailure(); + /** + * Makes API call to check if user is blocked. If the user is blocked, a snackbar + * is created to notify the user + */ protected void showBlockStatus() { Observable.fromCallable(() -> mediaWikiApi.isUserBlocked()) From 39096cf30baafa78f925f61220bbcedd3ebbd62c Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Mon, 28 May 2018 19:18:59 -0400 Subject: [PATCH 5/9] Upon creating AuthenticatedActivity, now checking if the user is blocked via api call and notifying the user if they are blocked via snackbar --- .../commons/auth/AuthenticatedActivity.java | 19 ++++++++++++++++++ .../free/nrw/commons/auth/LoginActivity.java | 1 + .../mwapi/ApacheHttpClientMediaWikiApi.java | 20 +++++++++++++++++++ .../free/nrw/commons/mwapi/MediaWikiApi.java | 2 ++ app/src/main/res/values/strings.xml | 1 + 5 files changed, 43 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index e39528252..19fabf7d2 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -4,8 +4,13 @@ import android.os.Bundle; import javax.inject.Inject; +import fr.free.nrw.commons.R; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.theme.NavigationBaseActivity; +import fr.free.nrw.commons.utils.ViewUtil; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; import static fr.free.nrw.commons.auth.AccountUtil.AUTH_COOKIE; @@ -34,6 +39,8 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { if (savedInstanceState != null) { authCookie = savedInstanceState.getString(AUTH_COOKIE); } + + showBlockStatus(); } @Override @@ -45,4 +52,16 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { protected abstract void onAuthCookieAcquired(String authCookie); protected abstract void onAuthFailure(); + + protected void showBlockStatus() + { + Observable.fromCallable(() -> mediaWikiApi.isUserBlocked()) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .filter(result -> result) + .subscribe(result -> { + ViewUtil.showSnackbar(findViewById(android.R.id.content), R.string.block_notification); + } + ); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index b19d70a4e..339af96d7 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -162,6 +162,7 @@ public class LoginActivity extends AccountAuthenticatorActivity { if (sessionManager.getCurrentAccount() != null && sessionManager.isUserLoggedIn() && sessionManager.getCachedAuthCookie() != null) { + sessionManager.revalidateAuthToken(); startMainActivity(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index e962bdaf3..13eb77e83 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -615,6 +615,26 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { }); } + @Override + public boolean isUserBlocked() { + boolean userBlocked = false; + try { + ApiResult result = api.action("query") + .param("action", "query") + .param("format", "xml") + .param("meta", "userinfo") + .param("uiprop", "blockinfo") + .get(); + if(result != null) { + userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); + } + } catch (Exception e) { + e.printStackTrace(); + } + + return userBlocked; + } + private Date parseMWDate(String mwDate) { SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC try { diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java index c0bd2fd87..6ba1f9158 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java @@ -75,6 +75,8 @@ public interface MediaWikiApi { @NonNull Single getUploadCount(String userName); + boolean isUserBlocked(); + interface ProgressListener { void onProgress(long transferred, long total); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3e3902e5..6828af2c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -282,6 +282,7 @@ Share App Coordinates were not specified during image selection Error fetching nearby places. + You are blocked from editing commons Set wallpaper Wallpaper set successfully! From 01a3a233a90a33e6c74b41c3024852e9f89fbd22 Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 09:44:09 -0400 Subject: [PATCH 6/9] Added comments to isUserBlocked method and tests for the method --- .../mwapi/ApacheHttpClientMediaWikiApi.java | 5 ++ .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 13eb77e83..b78ad88ae 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -615,6 +615,10 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { }); } + /** + * Checks to see if a user is currently blocked + * @return whether or not the user is blocked + */ @Override public boolean isUserBlocked() { boolean userBlocked = false; @@ -626,6 +630,7 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { .param("uiprop", "blockinfo") .get(); if(result != null) { + // the blockexpiry field will only be present if the user is currently blocked userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); } } catch (Exception e) { diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt index 686a90ef2..6f630ce1a 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -223,6 +223,60 @@ class ApacheHttpClientMediaWikiApiTest { assertEquals(23, testObserver.values()[0]) } + @Test + fun isUserBlockedForInfinitelyBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertTrue(result) + } + + @Test + fun isUserBlockedForTimeBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertTrue(result) + } + + @Test + fun isUserBlockedForNotBlockedUser() { + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertFalse(result) + } + private fun assertBasicRequestParameters(server: MockWebServer, method: String): RecordedRequest = server.takeRequest().let { assertEquals("/", it.requestUrl.encodedPath()) assertEquals(method, it.method) From fcfae643c3478dfe2fdf31128af4feb8ef837063 Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 11:28:56 -0400 Subject: [PATCH 7/9] Updated isUserBlocked method to check the expiration time instead of just if an expiration time exists. Updated tests accordingly --- .../mwapi/ApacheHttpClientMediaWikiApi.java | 16 ++++++++-- .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 29 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index b78ad88ae..c24ee2f21 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -37,6 +37,7 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.TimeZone; import java.util.concurrent.Callable; import fr.free.nrw.commons.BuildConfig; @@ -630,8 +631,17 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { .param("uiprop", "blockinfo") .get(); if(result != null) { - // the blockexpiry field will only be present if the user is currently blocked - userBlocked = !result.getString("/api/query/userinfo/@blockexpiry").isEmpty(); + String blockEnd = result.getString("/api/query/userinfo/@blockexpiry"); + if(blockEnd.equals("infinite")) + { + userBlocked = true; + } + else if (!blockEnd.isEmpty()) { + Date endDate = parseMWDate(blockEnd); + Date current = new Date(); + userBlocked = endDate.after(current); + } + } } catch (Exception e) { e.printStackTrace(); @@ -642,10 +652,12 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { private Date parseMWDate(String mwDate) { SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC + isoFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { return isoFormat.parse(mwDate); } catch (ParseException e) { throw new RuntimeException(e); } } + } diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt index 6f630ce1a..eea86fd2f 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -18,6 +18,7 @@ import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config import java.net.URLDecoder +import java.text.SimpleDateFormat import java.util.* @RunWith(RobolectricTestRunner::class) @@ -243,7 +244,11 @@ class ApacheHttpClientMediaWikiApiTest { @Test fun isUserBlockedForTimeBlockedUser() { - server.enqueue(MockResponse().setBody("")) + val currentDate = Date() + val expiredDate = Date(currentDate.time + 10000) + val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) + server.enqueue(MockResponse().setBody("")) val result = testObject.isUserBlocked(); @@ -259,6 +264,28 @@ class ApacheHttpClientMediaWikiApiTest { assertTrue(result) } + @Test + fun isUserBlockedForExpiredBlockedUser() { + val currentDate = Date() + val expiredDate = Date(currentDate.time - 10000) + val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) + server.enqueue(MockResponse().setBody("")) + + val result = testObject.isUserBlocked(); + + assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> + parseQueryParams(userBlockedRequest).let { body -> + assertEquals("xml", body["format"]) + assertEquals("query", body["action"]) + assertEquals("userinfo", body["meta"]) + assertEquals("blockinfo", body["uiprop"]) + } + } + + assertFalse(result) + } + @Test fun isUserBlockedForNotBlockedUser() { server.enqueue(MockResponse().setBody("")) From 4aac81d6273182097d0c01e0910982985080dde8 Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Thu, 31 May 2018 13:37:55 -0400 Subject: [PATCH 8/9] Added javadoc comments to showBlockStatus method --- .../java/fr/free/nrw/commons/auth/AuthenticatedActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index 19fabf7d2..f31f36c51 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -53,6 +53,10 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { protected abstract void onAuthFailure(); + /** + * Makes API call to check if user is blocked. If the user is blocked, a snackbar + * is created to notify the user + */ protected void showBlockStatus() { Observable.fromCallable(() -> mediaWikiApi.isUserBlocked()) From 22a5178e04f70956d10d51ea0383b1be63c6be3b Mon Sep 17 00:00:00 2001 From: Sean Nemann Date: Mon, 11 Jun 2018 13:07:54 -0400 Subject: [PATCH 9/9] Updated comments and method headers to clarify that the block status being checked within AuthenticatedActivity refers to the Wikimedia Commons block status of the user --- .../nrw/commons/auth/AuthenticatedActivity.java | 4 ++-- .../mwapi/ApacheHttpClientMediaWikiApi.java | 6 +++--- .../fr/free/nrw/commons/mwapi/MediaWikiApi.java | 2 +- app/src/main/res/values/strings.xml | 2 +- .../mwapi/ApacheHttpClientMediaWikiApiTest.kt | 16 ++++++++-------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java index f31f36c51..611cb7975 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/AuthenticatedActivity.java @@ -54,12 +54,12 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity { protected abstract void onAuthFailure(); /** - * Makes API call to check if user is blocked. If the user is blocked, a snackbar + * Makes API call to check if user is blocked from Commons. If the user is blocked, a snackbar * is created to notify the user */ protected void showBlockStatus() { - Observable.fromCallable(() -> mediaWikiApi.isUserBlocked()) + Observable.fromCallable(() -> mediaWikiApi.isUserBlockedFromCommons()) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .filter(result -> result) diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index c24ee2f21..ab534b00f 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -617,11 +617,11 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi { } /** - * Checks to see if a user is currently blocked - * @return whether or not the user is blocked + * Checks to see if a user is currently blocked from Commons + * @return whether or not the user is blocked from Commons */ @Override - public boolean isUserBlocked() { + public boolean isUserBlockedFromCommons() { boolean userBlocked = false; try { ApiResult result = api.action("query") diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java index 6ba1f9158..21f45e127 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java @@ -75,7 +75,7 @@ public interface MediaWikiApi { @NonNull Single getUploadCount(String userName); - boolean isUserBlocked(); + boolean isUserBlockedFromCommons(); interface ProgressListener { void onProgress(long transferred, long total); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6828af2c3..eb040f458 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -282,7 +282,7 @@ Share App Coordinates were not specified during image selection Error fetching nearby places. - You are blocked from editing commons + You are blocked from editing Commons Set wallpaper Wallpaper set successfully! diff --git a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt index eea86fd2f..2d624ced8 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApiTest.kt @@ -225,10 +225,10 @@ class ApacheHttpClientMediaWikiApiTest { } @Test - fun isUserBlockedForInfinitelyBlockedUser() { + fun isUserBlockedFromCommonsForInfinitelyBlockedUser() { server.enqueue(MockResponse().setBody("")) - val result = testObject.isUserBlocked(); + val result = testObject.isUserBlockedFromCommons(); assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> parseQueryParams(userBlockedRequest).let { body -> @@ -243,14 +243,14 @@ class ApacheHttpClientMediaWikiApiTest { } @Test - fun isUserBlockedForTimeBlockedUser() { + fun isUserBlockedFromCommonsForTimeBlockedUser() { val currentDate = Date() val expiredDate = Date(currentDate.time + 10000) val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) server.enqueue(MockResponse().setBody("")) - val result = testObject.isUserBlocked(); + val result = testObject.isUserBlockedFromCommons(); assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> parseQueryParams(userBlockedRequest).let { body -> @@ -265,14 +265,14 @@ class ApacheHttpClientMediaWikiApiTest { } @Test - fun isUserBlockedForExpiredBlockedUser() { + fun isUserBlockedFromCommonsForExpiredBlockedUser() { val currentDate = Date() val expiredDate = Date(currentDate.time - 10000) val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")) server.enqueue(MockResponse().setBody("")) - val result = testObject.isUserBlocked(); + val result = testObject.isUserBlockedFromCommons(); assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> parseQueryParams(userBlockedRequest).let { body -> @@ -287,10 +287,10 @@ class ApacheHttpClientMediaWikiApiTest { } @Test - fun isUserBlockedForNotBlockedUser() { + fun isUserBlockedFromCommonsForNotBlockedUser() { server.enqueue(MockResponse().setBody("")) - val result = testObject.isUserBlocked(); + val result = testObject.isUserBlockedFromCommons(); assertBasicRequestParameters(server, "GET").let { userBlockedRequest -> parseQueryParams(userBlockedRequest).let { body ->