|
3 | 3 |
|
4 | 4 | package com.azure.cosmos.implementation.directconnectivity; |
5 | 5 |
|
| 6 | +import com.azure.core.credential.AccessToken; |
| 7 | +import com.azure.core.credential.TokenCredential; |
| 8 | +import com.azure.core.credential.TokenRequestContext; |
6 | 9 | import com.azure.cosmos.implementation.AsyncDocumentClient; |
| 10 | +import com.azure.cosmos.implementation.AuthorizationTokenType; |
| 11 | +import com.azure.cosmos.implementation.Configs; |
7 | 12 | import com.azure.cosmos.implementation.Document; |
8 | 13 | import com.azure.cosmos.implementation.HttpConstants; |
9 | 14 | import com.azure.cosmos.implementation.IAuthorizationTokenProvider; |
|
12 | 17 | import com.azure.cosmos.implementation.RxDocumentClientImpl; |
13 | 18 | import com.azure.cosmos.implementation.RxDocumentServiceRequest; |
14 | 19 | import com.azure.cosmos.implementation.TestConfigurations; |
| 20 | +import com.azure.cosmos.implementation.Utils; |
15 | 21 | import com.azure.cosmos.implementation.routing.PartitionKeyRangeIdentity; |
16 | 22 | import org.testng.annotations.DataProvider; |
17 | 23 | import org.testng.annotations.Test; |
| 24 | +import reactor.core.publisher.Mono; |
18 | 25 |
|
| 26 | +import java.net.URI; |
| 27 | +import java.net.URISyntaxException; |
| 28 | +import java.time.OffsetDateTime; |
| 29 | +import java.time.ZonedDateTime; |
19 | 30 | import java.util.Map; |
20 | 31 | import java.util.UUID; |
21 | 32 |
|
@@ -143,6 +154,41 @@ public void barrierDocumentReadRidBasedRequest() { |
143 | 154 | assertThat(barrierRequest.getIsNameBased()).isEqualTo(false); |
144 | 155 | } |
145 | 156 |
|
| 157 | + @Test(groups = "direct") |
| 158 | + public void barrierWithAadAuthorizationTokenProviderType() throws URISyntaxException { |
| 159 | + |
| 160 | + TokenCredential tokenCredential = new AadSimpleTokenCredential(TestConfigurations.MASTER_KEY); |
| 161 | + |
| 162 | + IAuthorizationTokenProvider authTokenProvider = new RxDocumentClientImpl(new URI(TestConfigurations.HOST), |
| 163 | + null, |
| 164 | + null, |
| 165 | + null, |
| 166 | + null, |
| 167 | + new Configs(), |
| 168 | + null, |
| 169 | + null, |
| 170 | + tokenCredential, |
| 171 | + false, |
| 172 | + false, |
| 173 | + false, |
| 174 | + null); |
| 175 | + |
| 176 | + ResourceType resourceType = ResourceType.DocumentCollection; |
| 177 | + OperationType operationType = OperationType.Read; |
| 178 | + |
| 179 | + Document randomResource = new Document(); |
| 180 | + randomResource.setId(UUID.randomUUID().toString()); |
| 181 | + RxDocumentServiceRequest request = |
| 182 | + RxDocumentServiceRequest.create(mockDiagnosticsClientContext(), operationType, resourceType, "/dbs/7mVFAA==/colls/7mVFAP1jpeU=", randomResource, (Map<String, String>) null); |
| 183 | + |
| 184 | + RxDocumentServiceRequest barrierRequest = BarrierRequestHelper.createAsync(mockDiagnosticsClientContext(), request, authTokenProvider, 11l, 10l).block(); |
| 185 | + |
| 186 | + assertThat(authTokenProvider.getAuthorizationTokenType()).isEqualTo(AuthorizationTokenType.AadToken); |
| 187 | + assertThat(barrierRequest.authorizationTokenType).isEqualTo(AuthorizationTokenType.AadToken); |
| 188 | + assertThat(request.authorizationTokenType).isEqualTo(AuthorizationTokenType.PrimaryMasterKey); |
| 189 | + } |
| 190 | + |
| 191 | + |
146 | 192 | @DataProvider(name = "isCollectionHeadBarrierRequestArgProvider") |
147 | 193 | public Object[][] isCollectionHeadBarrierRequestArgProvider() { |
148 | 194 | return new Object[][]{ |
@@ -214,5 +260,36 @@ private Long getTargetLsn(RxDocumentServiceRequest req) { |
214 | 260 | private Long getTargetGlobalLsn(RxDocumentServiceRequest req) { |
215 | 261 | return Long.parseLong(getHeaderValue(req, HttpConstants.HttpHeaders.TARGET_GLOBAL_COMMITTED_LSN)); |
216 | 262 | } |
| 263 | + |
| 264 | + class AadSimpleTokenCredential implements TokenCredential { |
| 265 | + private final String keyEncoded; |
| 266 | + private final String AAD_HEADER_COSMOS_EMULATOR = "{\"typ\":\"JWT\",\"alg\":\"RS256\",\"x5t\":\"CosmosEmulatorPrimaryMaster\",\"kid\":\"CosmosEmulatorPrimaryMaster\"}"; |
| 267 | + private final String AAD_CLAIM_COSMOS_EMULATOR_FORMAT = "{\"aud\":\"https://localhost.localhost\",\"iss\":\"https://sts.fake-issuer.net/7b1999a1-dfd7-440e-8204-00170979b984\",\"iat\":%d,\"nbf\":%d,\"exp\":%d,\"aio\":\"\",\"appid\":\"localhost\",\"appidacr\":\"1\",\"idp\":\"https://localhost:8081/\",\"oid\":\"96313034-4739-43cb-93cd-74193adbe5b6\",\"rh\":\"\",\"sub\":\"localhost\",\"tid\":\"EmulatorFederation\",\"uti\":\"\",\"ver\":\"1.0\",\"scp\":\"user_impersonation\",\"groups\":[\"7ce1d003-4cb3-4879-b7c5-74062a35c66e\",\"e99ff30c-c229-4c67-ab29-30a6aebc3e58\",\"5549bb62-c77b-4305-bda9-9ec66b85d9e4\",\"c44fd685-5c58-452c-aaf7-13ce75184f65\",\"be895215-eab5-43b7-9536-9ef8fe130330\"]}"; |
| 268 | + |
| 269 | + public AadSimpleTokenCredential(String emulatorKey) { |
| 270 | + if (emulatorKey == null || emulatorKey.isEmpty()) { |
| 271 | + throw new IllegalArgumentException("emulatorKey"); |
| 272 | + } |
| 273 | + |
| 274 | + this.keyEncoded = Utils.encodeUrlBase64String(emulatorKey.getBytes()); |
| 275 | + } |
| 276 | + |
| 277 | + @Override |
| 278 | + public Mono<AccessToken> getToken(TokenRequestContext tokenRequestContext) { |
| 279 | + String aadToken = emulatorKey_based_AAD_String(); |
| 280 | + return Mono.just(new AccessToken(aadToken, OffsetDateTime.now().plusHours(2))); |
| 281 | + } |
| 282 | + |
| 283 | + String emulatorKey_based_AAD_String() { |
| 284 | + ZonedDateTime currentTime = ZonedDateTime.now(); |
| 285 | + String part1Encoded = Utils.encodeUrlBase64String(AAD_HEADER_COSMOS_EMULATOR.getBytes()); |
| 286 | + String part2 = String.format(AAD_CLAIM_COSMOS_EMULATOR_FORMAT, |
| 287 | + currentTime.toEpochSecond(), |
| 288 | + currentTime.toEpochSecond(), |
| 289 | + currentTime.plusHours(2).toEpochSecond()); |
| 290 | + String part2Encoded = Utils.encodeUrlBase64String(part2.getBytes()); |
| 291 | + return part1Encoded + "." + part2Encoded + "." + this.keyEncoded; |
| 292 | + } |
| 293 | + } |
217 | 294 | } |
218 | 295 |
|
0 commit comments