Skip to content

Commit

Permalink
Merge pull request #1130 from joakibj/fix/default-scope
Browse files Browse the repository at this point in the history
Fix UnsupportedOperationException when not providing scopes to AzureIdentityAccessTokenProvider
  • Loading branch information
baywet authored Mar 20, 2024
2 parents c4e2406 + a961572 commit 59a86b0
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

## [1.1.1] - 2024-03-20

### Changed

- Fixed a bug where not providing scopes to `AzureIdentityAccessTokenProvider` failed with `UnsupportedOperationException` when attempting to fetch the token. [microsoftgraph/msgraph-sdk-java#1882](https://github.com/microsoftgraph/msgraph-sdk-java/issues/1882)

## [1.1.0] - 2024-02-14

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public AzureIdentityAccessTokenProvider(
if (scopes == null) {
_scopes = new ArrayList<String>();
} else {
_scopes = Arrays.asList(scopes);
_scopes = new ArrayList<>(Arrays.asList(scopes));
}
if (allowedHosts == null || allowedHosts.length == 0) {
_hostValidator = new AllowedHostsValidator();
Expand Down Expand Up @@ -128,13 +128,18 @@ public AzureIdentityAccessTokenProvider(
"com.microsoft.kiota.authentication.additional_claims_provided",
decodedClaim != null && !decodedClaim.isEmpty());

final TokenRequestContext context = new TokenRequestContext();
if (_scopes.isEmpty()) {
_scopes.add(uri.getScheme() + "://" + uri.getHost() + "/.default");
List<String> scopes;
if (!_scopes.isEmpty()) {
scopes = new ArrayList<>(_scopes);
} else {
scopes = new ArrayList<>();
scopes.add(uri.getScheme() + "://" + uri.getHost() + "/.default");
}
context.setScopes(_scopes);

final TokenRequestContext context = new TokenRequestContext();
context.setScopes(scopes);
span.setAttribute(
"com.microsoft.kiota.authentication.scopes", String.join("|", _scopes));
"com.microsoft.kiota.authentication.scopes", String.join("|", scopes));
if (decodedClaim != null && !decodedClaim.isEmpty()) {
context.setClaims(decodedClaim);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
package com.microsoft.kiota.authentication;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertLinesMatch;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.azure.core.credential.AccessToken;
import com.azure.core.credential.TokenCredential;
import com.azure.core.credential.TokenRequestContext;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.NullAndEmptySource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.ArgumentCaptor;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

public class AzureIdentityAccessTokenProviderTest {

Expand Down Expand Up @@ -41,4 +49,57 @@ void testNonLocalhostHttpUrlIsInvalid(String urlString) {
accessTokenProvider.getAuthorizationToken(
new URI(urlString), new HashMap<>()));
}

@Test
void testKeepUserProvidedScopes() throws URISyntaxException {
var tokenCredential = mock(TokenCredential.class);
String[] userProvidedScopes = {
"https://graph.microsoft.com/User.Read", "https://graph.microsoft.com/Application.Read"
};
var accessTokenProvider =
new AzureIdentityAccessTokenProvider(
tokenCredential, new String[] {}, userProvidedScopes);
assertScopes(tokenCredential, accessTokenProvider, userProvidedScopes);
}

@Test
void testConfigureDefaultScopeWhenScopesNotProvided() throws URISyntaxException {
var tokenCredential = mock(TokenCredential.class);
var accessTokenProvider =
new AzureIdentityAccessTokenProvider(tokenCredential, new String[] {});
assertScopes(
tokenCredential,
accessTokenProvider,
new String[] {"https://graph.microsoft.com/.default"});
}

@ParameterizedTest
@NullAndEmptySource
void testConfigureDefaultScopeWhenScopesNullOrEmpty(String[] nullOrEmptyUserProvidedScopes)
throws URISyntaxException {
var tokenCredential = mock(TokenCredential.class);
var accessTokenProvider =
new AzureIdentityAccessTokenProvider(
tokenCredential, new String[] {}, nullOrEmptyUserProvidedScopes);
assertScopes(
tokenCredential,
accessTokenProvider,
new String[] {"https://graph.microsoft.com/.default"});
}

private static void assertScopes(
TokenCredential tokenCredential,
AzureIdentityAccessTokenProvider accessTokenProvider,
String[] expectedScopes)
throws URISyntaxException {
var tokenRequestContextArgumentCaptor = ArgumentCaptor.forClass(TokenRequestContext.class);
when(tokenCredential.getTokenSync(tokenRequestContextArgumentCaptor.capture()))
.thenReturn(mock(AccessToken.class));

accessTokenProvider.getAuthorizationToken(
new URI("https://graph.microsoft.com"), new HashMap<>());

List<String> actualScopes = tokenRequestContextArgumentCaptor.getValue().getScopes();
assertLinesMatch(Arrays.asList(expectedScopes), actualScopes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public UserAgentHandlerOption() {}

private boolean enabled = true;
@Nonnull private String productName = "kiota-java";
@Nonnull private String productVersion = "1.0.6";
@Nonnull private String productVersion = "1.1.1";

/**
* Gets the product name to be used in the user agent header
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ org.gradle.caching=true
mavenGroupId = com.microsoft.kiota
mavenMajorVersion = 1
mavenMinorVersion = 1
mavenPatchVersion = 0
mavenPatchVersion = 1
mavenArtifactSuffix =

#These values are used to run functional tests
Expand Down

0 comments on commit 59a86b0

Please sign in to comment.