From 0bd24cef784793af317df8d8425c2abd89204272 Mon Sep 17 00:00:00 2001 From: Mitch Robertson Date: Thu, 27 Jul 2017 14:45:35 -0400 Subject: [PATCH 1/4] prevent asymmetric facebook session management with flag --- .../java/com/parse/FacebookController.java | 4 +-- .../java/com/parse/ParseFacebookUtils.java | 5 +++- .../com/parse/FacebookControllerTest.java | 26 ++++++++++++++----- .../com/parse/ParseFacebookUtilsTest.java | 7 ++--- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/library/src/main/java/com/parse/FacebookController.java b/library/src/main/java/com/parse/FacebookController.java index 4a79ba7..6f7e475 100644 --- a/library/src/main/java/com/parse/FacebookController.java +++ b/library/src/main/java/com/parse/FacebookController.java @@ -139,9 +139,9 @@ public Map getAuthData(AccessToken accessToken) { return authData; } - public void setAuthData(Map authData) + public void setAuthData(Map authData, boolean isFacebookLoginScopeExternallyManaged) throws java.text.ParseException { - if (authData == null) { + if (authData == null && !isFacebookLoginScopeExternallyManaged) { facebookSdkDelegate.getLoginManager().logOut(); return; } diff --git a/library/src/main/java/com/parse/ParseFacebookUtils.java b/library/src/main/java/com/parse/ParseFacebookUtils.java index 77b2cb4..f424981 100644 --- a/library/src/main/java/com/parse/ParseFacebookUtils.java +++ b/library/src/main/java/com/parse/ParseFacebookUtils.java @@ -71,6 +71,7 @@ public final class ParseFacebookUtils { private static final Object lock = new Object(); /* package for tests */ static boolean isInitialized; + /* package for tests */ static boolean isFacebookLoginScopeExternallyManaged = false; /* package for tests */ static FacebookController controller; /* package for tests */ static ParseUserDelegate userDelegate = new ParseUserDelegateImpl(); @@ -111,7 +112,7 @@ public static void initialize(Context context, int callbackRequestCodeOffset) { @Override public boolean onRestore(Map authData) { try { - getController().setAuthData(authData); + getController().setAuthData(authData, isFacebookLoginScopeExternallyManaged); return true; } catch (Exception e) { return false; @@ -167,6 +168,7 @@ public static boolean onActivityResult(int requestCode, int resultCode, Intent d * @return A task that will be resolved when logging in is complete. */ public static Task logInInBackground(AccessToken accessToken) { + isFacebookLoginScopeExternallyManaged = true; checkInitialization(); return userDelegate.logInWithInBackground(AUTH_TYPE, getController().getAuthData(accessToken)); } @@ -180,6 +182,7 @@ public static Task logInInBackground(AccessToken accessToken) { * @return A task that will be resolved when logging in is complete. */ public static Task logInInBackground(AccessToken accessToken, LogInCallback callback) { + isFacebookLoginScopeExternallyManaged = true; return callbackOnMainThreadAsync(logInInBackground(accessToken), callback, true); } diff --git a/library/src/test/java/com/parse/FacebookControllerTest.java b/library/src/test/java/com/parse/FacebookControllerTest.java index f42d076..5110f60 100644 --- a/library/src/test/java/com/parse/FacebookControllerTest.java +++ b/library/src/test/java/com/parse/FacebookControllerTest.java @@ -102,20 +102,34 @@ public void testGetAuthData() { //region testSetAuthData @Test - public void testSetAuthDataWithNull() throws java.text.ParseException { + public void testSetAuthDataWithNullNotExternallyManaged() throws java.text.ParseException { FacebookController.FacebookSdkDelegate facebookSdk = mock(FacebookController.FacebookSdkDelegate.class); LoginManager loginManager = mock(LoginManager.class); when(facebookSdk.getLoginManager()).thenReturn(loginManager); FacebookController controller = new FacebookController(facebookSdk); - controller.setAuthData(null); + controller.setAuthData(null, true); verify(facebookSdk).getLoginManager(); verifyNoMoreInteractions(facebookSdk); verify(loginManager).logOut(); verifyNoMoreInteractions(loginManager); } + @Test + public void testSetAuthDataWithNullExternallyManaged() throws java.text.ParseException { + FacebookController.FacebookSdkDelegate facebookSdk = + mock(FacebookController.FacebookSdkDelegate.class); + LoginManager loginManager = mock(LoginManager.class); + when(facebookSdk.getLoginManager()).thenReturn(loginManager); + FacebookController controller = new FacebookController(facebookSdk); + + controller.setAuthData(null, false); + verify(facebookSdk).getLoginManager(); + verifyNoMoreInteractions(facebookSdk); + verifyNoMoreInteractions(loginManager); + } + @Test public void testSetAuthData() throws ParseException { Locale.setDefault(new Locale("ar")); // Mimic the device's locale @@ -130,7 +144,7 @@ public void testSetAuthData() throws ParseException { authData.put("id", "test_id"); authData.put("access_token", "test_token"); authData.put("expiration_date", "2015-07-03T07:00:00.000Z"); - controller.setAuthData(authData); + controller.setAuthData(authData, true); ArgumentCaptor accessTokenCapture = ArgumentCaptor.forClass(AccessToken.class); verify(facebookSdk).setCurrentAccessToken(accessTokenCapture.capture()); AccessToken accessToken = accessTokenCapture.getValue(); @@ -153,13 +167,13 @@ public void testSetAuthDataWithDifferentAccessToken() throws ParseException { authData.put("id", "new_id"); authData.put("access_token", "test_token"); authData.put("expiration_date", "2015-07-03T07:00:00.000Z"); - controller.setAuthData(authData); + controller.setAuthData(authData, true); verify(facebookSdk, times(1)).setCurrentAccessToken(any(AccessToken.class)); authData.put("id", "new_id"); authData.put("access_token", "new_token"); authData.put("expiration_date", "2015-07-03T07:00:00.000Z"); - controller.setAuthData(authData); + controller.setAuthData(authData, true); verify(facebookSdk, times(2)).setCurrentAccessToken(any(AccessToken.class)); } @@ -175,7 +189,7 @@ public void testSetAuthDataWithSameAccessToken() throws ParseException { authData.put("id", "test_id"); authData.put("access_token", "test_token"); authData.put("expiration_date", "2015-07-03T07:00:00.000Z"); - controller.setAuthData(authData); + controller.setAuthData(authData, true); verify(facebookSdk, never()).setCurrentAccessToken(any(AccessToken.class)); } diff --git a/library/src/test/java/com/parse/ParseFacebookUtilsTest.java b/library/src/test/java/com/parse/ParseFacebookUtilsTest.java index 6ed23ad..ff72b6a 100644 --- a/library/src/test/java/com/parse/ParseFacebookUtilsTest.java +++ b/library/src/test/java/com/parse/ParseFacebookUtilsTest.java @@ -34,6 +34,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyMapOf; @@ -102,7 +103,7 @@ public void testRestoreAuthentication() throws java.text.ParseException { Map authData = new HashMap<>(); assertTrue(callback.onRestore(authData)); - verify(controller).setAuthData(authData); + verify(controller).setAuthData(authData, true); } @Test @@ -115,10 +116,10 @@ public void testRestoreAuthenticationFailure() throws java.text.ParseException { Map authData = new HashMap<>(); doThrow(new RuntimeException()) .when(controller) - .setAuthData(anyMapOf(String.class, String.class)); + .setAuthData(anyMapOf(String.class, String.class), anyBoolean()); assertFalse(callback.onRestore(authData)); - verify(controller).setAuthData(authData); + verify(controller).setAuthData(authData, false); } //endregion From a5304dce9f1d42ca71d0021fd6b1d2a5fff18898 Mon Sep 17 00:00:00 2001 From: Mitch Robertson Date: Thu, 27 Jul 2017 15:13:14 -0400 Subject: [PATCH 2/4] fixed tests --- .../src/main/java/com/parse/FacebookController.java | 6 ++++-- .../test/java/com/parse/FacebookControllerTest.java | 10 +++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/parse/FacebookController.java b/library/src/main/java/com/parse/FacebookController.java index 6f7e475..fcff015 100644 --- a/library/src/main/java/com/parse/FacebookController.java +++ b/library/src/main/java/com/parse/FacebookController.java @@ -141,8 +141,10 @@ public Map getAuthData(AccessToken accessToken) { public void setAuthData(Map authData, boolean isFacebookLoginScopeExternallyManaged) throws java.text.ParseException { - if (authData == null && !isFacebookLoginScopeExternallyManaged) { - facebookSdkDelegate.getLoginManager().logOut(); + if (authData == null) { + if (!isFacebookLoginScopeExternallyManaged) { + facebookSdkDelegate.getLoginManager().logOut(); + } return; } diff --git a/library/src/test/java/com/parse/FacebookControllerTest.java b/library/src/test/java/com/parse/FacebookControllerTest.java index 5110f60..64ab7a3 100644 --- a/library/src/test/java/com/parse/FacebookControllerTest.java +++ b/library/src/test/java/com/parse/FacebookControllerTest.java @@ -104,12 +104,12 @@ public void testGetAuthData() { @Test public void testSetAuthDataWithNullNotExternallyManaged() throws java.text.ParseException { FacebookController.FacebookSdkDelegate facebookSdk = - mock(FacebookController.FacebookSdkDelegate.class); + mock(FacebookController.FacebookSdkDelegate.class); LoginManager loginManager = mock(LoginManager.class); when(facebookSdk.getLoginManager()).thenReturn(loginManager); FacebookController controller = new FacebookController(facebookSdk); - controller.setAuthData(null, true); + controller.setAuthData(null, false); verify(facebookSdk).getLoginManager(); verifyNoMoreInteractions(facebookSdk); verify(loginManager).logOut(); @@ -120,14 +120,10 @@ public void testSetAuthDataWithNullNotExternallyManaged() throws java.text.Parse public void testSetAuthDataWithNullExternallyManaged() throws java.text.ParseException { FacebookController.FacebookSdkDelegate facebookSdk = mock(FacebookController.FacebookSdkDelegate.class); - LoginManager loginManager = mock(LoginManager.class); - when(facebookSdk.getLoginManager()).thenReturn(loginManager); FacebookController controller = new FacebookController(facebookSdk); - controller.setAuthData(null, false); - verify(facebookSdk).getLoginManager(); + controller.setAuthData(null, true); verifyNoMoreInteractions(facebookSdk); - verifyNoMoreInteractions(loginManager); } @Test From 03810e84d1525220dc108a9efc35460064e90223 Mon Sep 17 00:00:00 2001 From: Mathieu Hartvick Date: Tue, 24 Oct 2017 16:06:07 -0400 Subject: [PATCH 3/4] Update to Support 26 and buildTools 3 --- build.gradle | 2 +- library/build.gradle | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index cdeb3ac..e6913d1 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.2' + classpath 'com.android.tools.build:gradle:3.0.0-rc2' } } diff --git a/library/build.gradle b/library/build.gradle index ebdac74..94e1810 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -23,12 +23,12 @@ buildscript { } android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion '26.0.2' defaultConfig { minSdkVersion 15 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 1 versionName project.version } From 460faed9b4003bf6bee7b8977adcf9c61af230ca Mon Sep 17 00:00:00 2001 From: Mathieu Hartvick Date: Wed, 25 Oct 2017 15:14:25 -0400 Subject: [PATCH 4/4] Update gradle to 3.0 stable --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e6913d1..28020ad 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-rc2' + classpath 'com.android.tools.build:gradle:3.0.0' } }