From f4b154962bd1b63837ab70ef08c8915a4283c702 Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Tue, 19 Apr 2022 17:58:13 -0700 Subject: [PATCH 1/6] add ability to add custom hosts to TokenCredentialAuthProvider --- .../BaseAuthenticationProvider.java | 6 +++-- .../TokenCredentialAuthProvider.java | 26 ++++++++++++++++++- .../BaseAuthenticationProviderTest.java | 19 +++++++++++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index 78a596a31..3c640850b 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -3,9 +3,11 @@ import java.net.URL; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Provides basic common methods for all authentication providers @@ -18,10 +20,10 @@ public abstract class BaseAuthenticationProvider implements IAuthenticationProvi * @param requestUrl request URL that is about to be executed * @return whether a token should be attached to this request */ - protected boolean shouldAuthenticateRequestWithUrl(@Nonnull final URL requestUrl) { + protected boolean shouldAuthenticateRequestWithUrl(@Nonnull final URL requestUrl, @Nullable final List customHosts) { if (requestUrl == null || !requestUrl.getProtocol().toLowerCase(Locale.ROOT).equals("https")) return false; final String hostName = requestUrl.getHost().toLowerCase(Locale.ROOT); - return validGraphHostNames.contains(hostName); + return customHosts == null ? (validGraphHostNames.contains(hostName)) : (customHosts.contains(hostName)); } } diff --git a/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java b/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java index 555dc34b2..bbcd27437 100644 --- a/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java @@ -19,8 +19,11 @@ public class TokenCredentialAuthProvider extends BaseAuthenticationProvider { private final TokenCredential tokenCredential; /** Context options which can be optionally set by the user */ private final TokenRequestContext context; + /** Custom hosts which can be optionally set by the user */ + private List customHosts = null; /** Default scope to use when no scopes are provided */ private static final String DEFAULT_GRAPH_SCOPE = "https://graph.microsoft.com/.default"; + /** * Creates an Authentication provider using a passed in TokenCredential * @@ -45,6 +48,27 @@ public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull this.tokenCredential = Objects.requireNonNull(tokenCredential, "tokenCredential parameter cannot be null."); } + /** + * Creates an Authentication provider using a TokenCredential and a list of custom hosts + * @param tokenCredential Credential object inheriting the TokenCredential interface used to instantiate the Auth Provider. + * @param customHosts the user defined custom hosts. + */ + public TokenCredentialAuthProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final List customHosts){ + this(Collections.singletonList(DEFAULT_GRAPH_SCOPE), tokenCredential); + this.customHosts = customHosts; + } + + /** + * Creates an Authentication provider using a TokenCredential, a list of scopes, and a list of custom hosts. + * @param scopes Specified desired scopes of the Auth Provider + * @param tokenCredential Credential object inheriting the TokenCredential interface used to instantiate the Auth Provider + * @param customHosts the user defined custom hosts. + */ + public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull final TokenCredential tokenCredential, @Nonnull final List customHosts) { + this(scopes, tokenCredential); + this.customHosts = customHosts; + } + /** * Returns an AccessToken as a string * @@ -52,7 +76,7 @@ public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull */ @Nonnull public CompletableFuture getAuthorizationTokenAsync(@Nonnull final URL requestUrl) { - if(shouldAuthenticateRequestWithUrl(Objects.requireNonNull(requestUrl, "requestUrl parameter cannot be null"))) + if(shouldAuthenticateRequestWithUrl(Objects.requireNonNull(requestUrl, "requestUrl parameter cannot be null"), customHosts)) return this.tokenCredential .getToken(this.context) .toFuture() diff --git a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java index 47630890c..228930a09 100644 --- a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java +++ b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java @@ -28,7 +28,7 @@ public void providerAddsTokenOnAllNationalAndPublicClouds() throws MalformedURLE // Arrange final URL url = new URL("https://"+ hostName); // Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); // Assert assertTrue(result); @@ -40,7 +40,7 @@ public void providerDoesNotAddTokenOnInvalidDomains() throws MalformedURLExcepti final URL url = new URL("https://localhost"); //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); //Assert assertFalse(result); @@ -51,7 +51,7 @@ public void providerDoesNotAddTokenOnInvalidProtocols() throws MalformedURLExcep final URL url = new URL("http://graph.microsoft.com"); //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); //Assert assertFalse(result); @@ -62,9 +62,20 @@ public void providerDoesNotAddTokenOnNullUrls() throws MalformedURLException { final URL url = (URL)null; //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); //Assert assertFalse(result); } + @Test + public void providerAddsTokenToCustomHosts() throws MalformedURLException { + //Arrange + final URL url = new URL("https://localhost"); + + //Act + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, Arrays.asList("localhost")); + + //Assert + assertTrue(result); + } } From ae53946a6999161a9e66f327741fd1a2d4af5e51 Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Thu, 21 Apr 2022 16:04:03 -0700 Subject: [PATCH 2/6] add custom hosts to BaseAuthenticationProvider w/out breaking --- .../BaseAuthenticationProvider.java | 25 ++++++++++++++++--- .../TokenCredentialAuthProvider.java | 25 +------------------ .../BaseAuthenticationProviderTest.java | 13 +++++----- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index 3c640850b..c487b190c 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -3,24 +3,43 @@ import java.net.URL; import java.util.Arrays; import java.util.HashSet; -import java.util.List; import java.util.Locale; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * Provides basic common methods for all authentication providers */ public abstract class BaseAuthenticationProvider implements IAuthenticationProvider { private static final HashSet validGraphHostNames = new HashSet<>(Arrays.asList("graph.microsoft.com", "graph.microsoft.us", "dod-graph.microsoft.us", "graph.microsoft.de", "microsoftgraph.chinacloudapi.cn", "canary.graph.microsoft.com")); + private HashSet customHosts; + + /** + * Allow the user to add custom hosts by passing in Array + * @param customHosts custom hosts passed in by user. + */ + public void setCustomHosts(String[] customHosts) { + if(this.customHosts == null){ + this.customHosts = new HashSet(); + } + for(String host: customHosts){ + this.customHosts.add(host.toLowerCase(Locale.ROOT)); + } + } + /** + * Get the custom hosts set by user. + * @return the custom hosts set by user. + */ + public HashSet getCustomHosts(){ + return (HashSet) this.customHosts.clone(); + } /** * Determines whether a request should be authenticated or not based on it's url. * If you're implementing a custom provider, call that method first before getting the token * @param requestUrl request URL that is about to be executed * @return whether a token should be attached to this request */ - protected boolean shouldAuthenticateRequestWithUrl(@Nonnull final URL requestUrl, @Nullable final List customHosts) { + protected boolean shouldAuthenticateRequestWithUrl(@Nonnull final URL requestUrl) { if (requestUrl == null || !requestUrl.getProtocol().toLowerCase(Locale.ROOT).equals("https")) return false; final String hostName = requestUrl.getHost().toLowerCase(Locale.ROOT); diff --git a/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java b/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java index bbcd27437..de9a5d9b3 100644 --- a/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/TokenCredentialAuthProvider.java @@ -19,8 +19,6 @@ public class TokenCredentialAuthProvider extends BaseAuthenticationProvider { private final TokenCredential tokenCredential; /** Context options which can be optionally set by the user */ private final TokenRequestContext context; - /** Custom hosts which can be optionally set by the user */ - private List customHosts = null; /** Default scope to use when no scopes are provided */ private static final String DEFAULT_GRAPH_SCOPE = "https://graph.microsoft.com/.default"; @@ -48,27 +46,6 @@ public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull this.tokenCredential = Objects.requireNonNull(tokenCredential, "tokenCredential parameter cannot be null."); } - /** - * Creates an Authentication provider using a TokenCredential and a list of custom hosts - * @param tokenCredential Credential object inheriting the TokenCredential interface used to instantiate the Auth Provider. - * @param customHosts the user defined custom hosts. - */ - public TokenCredentialAuthProvider(@Nonnull final TokenCredential tokenCredential, @Nonnull final List customHosts){ - this(Collections.singletonList(DEFAULT_GRAPH_SCOPE), tokenCredential); - this.customHosts = customHosts; - } - - /** - * Creates an Authentication provider using a TokenCredential, a list of scopes, and a list of custom hosts. - * @param scopes Specified desired scopes of the Auth Provider - * @param tokenCredential Credential object inheriting the TokenCredential interface used to instantiate the Auth Provider - * @param customHosts the user defined custom hosts. - */ - public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull final TokenCredential tokenCredential, @Nonnull final List customHosts) { - this(scopes, tokenCredential); - this.customHosts = customHosts; - } - /** * Returns an AccessToken as a string * @@ -76,7 +53,7 @@ public TokenCredentialAuthProvider(@Nonnull final List scopes, @Nonnull */ @Nonnull public CompletableFuture getAuthorizationTokenAsync(@Nonnull final URL requestUrl) { - if(shouldAuthenticateRequestWithUrl(Objects.requireNonNull(requestUrl, "requestUrl parameter cannot be null"), customHosts)) + if(shouldAuthenticateRequestWithUrl(Objects.requireNonNull(requestUrl, "requestUrl parameter cannot be null"))) return this.tokenCredential .getToken(this.context) .toFuture() diff --git a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java index 228930a09..3c0de4841 100644 --- a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java +++ b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java @@ -28,7 +28,7 @@ public void providerAddsTokenOnAllNationalAndPublicClouds() throws MalformedURLE // Arrange final URL url = new URL("https://"+ hostName); // Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); // Assert assertTrue(result); @@ -40,7 +40,7 @@ public void providerDoesNotAddTokenOnInvalidDomains() throws MalformedURLExcepti final URL url = new URL("https://localhost"); //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); //Assert assertFalse(result); @@ -51,7 +51,7 @@ public void providerDoesNotAddTokenOnInvalidProtocols() throws MalformedURLExcep final URL url = new URL("http://graph.microsoft.com"); //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); //Assert assertFalse(result); @@ -62,7 +62,7 @@ public void providerDoesNotAddTokenOnNullUrls() throws MalformedURLException { final URL url = (URL)null; //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, null); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); //Assert assertFalse(result); @@ -70,10 +70,11 @@ public void providerDoesNotAddTokenOnNullUrls() throws MalformedURLException { @Test public void providerAddsTokenToCustomHosts() throws MalformedURLException { //Arrange - final URL url = new URL("https://localhost"); + final URL url = new URL("https://localhost.com"); + authProvider.setCustomHosts(new String[]{"localHost.com"}); //Act - final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url, Arrays.asList("localhost")); + final boolean result = authProvider.shouldAuthenticateRequestWithUrl(url); //Assert assertTrue(result); From fcb9eeae0a53d3a30cb435e67b184d46ea4c4153 Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Fri, 22 Apr 2022 09:28:53 -0700 Subject: [PATCH 3/6] explict nonNull-ability --- .../graph/authentication/BaseAuthenticationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index c487b190c..4a761bd05 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -18,7 +18,7 @@ public abstract class BaseAuthenticationProvider implements IAuthenticationProvi * Allow the user to add custom hosts by passing in Array * @param customHosts custom hosts passed in by user. */ - public void setCustomHosts(String[] customHosts) { + public void setCustomHosts(@Nonnull String[] customHosts) { if(this.customHosts == null){ this.customHosts = new HashSet(); } From 37afc3bb420e0214f84db41fffc43035a030dfe9 Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Fri, 22 Apr 2022 09:40:06 -0700 Subject: [PATCH 4/6] explict Null-ability --- .../graph/authentication/BaseAuthenticationProvider.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index 4a761bd05..8280e0f76 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -6,6 +6,7 @@ import java.util.Locale; import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Provides basic common methods for all authentication providers @@ -30,6 +31,7 @@ public void setCustomHosts(@Nonnull String[] customHosts) { * Get the custom hosts set by user. * @return the custom hosts set by user. */ + @Nullable public HashSet getCustomHosts(){ return (HashSet) this.customHosts.clone(); } From 425a89d7313a1559adefca17a6d82c71e29ecb10 Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Fri, 22 Apr 2022 09:47:53 -0700 Subject: [PATCH 5/6] Kotlin getter/setter compliance --- .../graph/authentication/BaseAuthenticationProvider.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index 8280e0f76..905656c30 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -32,8 +32,8 @@ public void setCustomHosts(@Nonnull String[] customHosts) { * @return the custom hosts set by user. */ @Nullable - public HashSet getCustomHosts(){ - return (HashSet) this.customHosts.clone(); + public String[] getCustomHosts(){ + return (String[]) this.customHosts.toArray(); } /** * Determines whether a request should be authenticated or not based on it's url. From 9d17a4986dfd41847391a87ea06dcf8891a6044b Mon Sep 17 00:00:00 2001 From: ramsessanchez Date: Fri, 22 Apr 2022 10:01:07 -0700 Subject: [PATCH 6/6] correctly return hashset as array --- .../graph/authentication/BaseAuthenticationProvider.java | 2 +- .../authentication/BaseAuthenticationProviderTest.java | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java index 905656c30..d2fb35a9f 100644 --- a/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java +++ b/src/main/java/com/microsoft/graph/authentication/BaseAuthenticationProvider.java @@ -33,7 +33,7 @@ public void setCustomHosts(@Nonnull String[] customHosts) { */ @Nullable public String[] getCustomHosts(){ - return (String[]) this.customHosts.toArray(); + return customHosts.toArray(new String[customHosts.size()]); } /** * Determines whether a request should be authenticated or not based on it's url. diff --git a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java index 3c0de4841..48f6f7d98 100644 --- a/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java +++ b/src/test/java/com/microsoft/graph/authentication/BaseAuthenticationProviderTest.java @@ -1,8 +1,5 @@ package com.microsoft.graph.authentication; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; @@ -11,6 +8,8 @@ import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + public class BaseAuthenticationProviderTest { final BaseAuthenticationProvider authProvider = new BaseAuthenticationProvider() { @@ -78,5 +77,7 @@ public void providerAddsTokenToCustomHosts() throws MalformedURLException { //Assert assertTrue(result); + assertEquals(authProvider.getCustomHosts().length, 1); + assertEquals(authProvider.getCustomHosts()[0], "localhost.com"); } }