@@ -244,6 +244,86 @@ public void signRequest_withOptionallySignedHeader()
244244 }
245245 }
246246
247+ // Reload the classes so PowerMockito can inject the static mocks.
248+ @ PrepareForTest ({LoggerFactory .class , Serializer .class , RequestSignerImpl .class })
249+ @ Test
250+ public void signRequest_WhenXDateHeaderSkipDateHeaderFromSignature ()
251+ throws IllegalAccessException , NoSuchFieldException {
252+ final Map <String , List <String >> headers = new HashMap <>();
253+ headers .put (Constants .X_DATE ,Collections .singletonList ("Wed, 11 Oct 2023 12:23:17 GMT" ));
254+ headers .put (Constants .DATE ,Collections .singletonList ("Wed, 11 Oct 2023 12:23:17 GMT" ));
255+
256+ URI uri = URI .create ("https://test.us-phoenix-1.oraclecloud.com/20181016/paths" );
257+ String keyId = "keyId" ;
258+
259+ KeySupplier <RSAPrivateKey > keySupplier =
260+ (KeySupplier <RSAPrivateKey >) mock (KeySupplier .class );
261+
262+ RSAPrivateKey privateKey = mock (RSAPrivateKey .class );
263+ when (keySupplier .supplyKey (keyId )).thenReturn (Optional .of (privateKey ));
264+
265+ SignatureSigner signer = mock (SignatureSigner .class );
266+
267+ Field signerField = RequestSignerImpl .class .getDeclaredField ("SIGNER" );
268+ boolean wasAccessible = signerField .isAccessible ();
269+ signerField .setAccessible (true );
270+ signerField .set (null , signer );
271+ if (!wasAccessible ) {
272+ signerField .setAccessible (false );
273+ }
274+
275+ byte [] signature = new byte [] {1 , 2 , 3 , 4 , 5 };
276+ when (signer .sign (any (RSAPrivateKey .class ), any (byte [].class ), any (String .class )))
277+ .thenReturn (signature );
278+
279+ RequestSignerImpl .SigningConfiguration signingConfiguration =
280+ new RequestSignerImpl .SigningConfiguration (
281+ SigningStrategy .STANDARD .getHeadersToSign (),
282+ SigningStrategy .STANDARD .getOptionalHeadersToSign (),
283+ SigningStrategy .STANDARD .isSkipContentHeadersForStreamingPutRequests ());
284+ String verb = "get" ;
285+ Map <String , String > authHeaders =
286+ RequestSignerImpl .signRequest (
287+ Algorithm .RSAPSS256 ,
288+ uri ,
289+ verb ,
290+ headers ,
291+ null ,
292+ SignedRequestVersion .getLatestVersion ().getVersionName (),
293+ keyId ,
294+ keySupplier ,
295+ signingConfiguration );
296+
297+ String authorization = authHeaders .get (Constants .AUTHORIZATION_HEADER );
298+
299+ Pattern headersPattern = Pattern .compile ("headers=\" ([^\" ]*)\" " );
300+ Matcher matcher = headersPattern .matcher (authorization );
301+ assertTrue (matcher .find ());
302+ Set <String > authorizationHeaders =
303+ Collections .unmodifiableSet (
304+ new HashSet <>(Arrays .asList (matcher .group (1 ).split (" " ))));
305+ SigningStrategy .STANDARD .getHeadersToSign ().get (verb )
306+ .stream ()
307+ .filter (requiredHeader -> !Constants .DATE .equals (requiredHeader ))
308+ .forEach (requiredHeader -> {
309+ assertTrue (authorizationHeaders .contains (requiredHeader ));
310+ if (requiredHeader .equals (Constants .REQUEST_TARGET )) {
311+ // this is only signed, not passed as header
312+ assertFalse (authHeaders .containsKey (requiredHeader ));
313+ } else {
314+ assertTrue (authHeaders .containsKey (requiredHeader ));
315+ if (headers .containsKey (requiredHeader )) {
316+ // if it exists, it should have the same value
317+ assertEquals (
318+ headers .get (requiredHeader ).get (0 ), authHeaders .get (requiredHeader ));
319+ }
320+ }
321+ });
322+ assertTrue (authorizationHeaders .contains (Constants .X_DATE ));
323+ assertFalse (authorizationHeaders .contains (Constants .DATE ));
324+
325+ }
326+
247327 @ Test
248328 public void calculateMissingHeaders_postStringContentAsJson () throws IOException {
249329 calculateAndVerifyMissingHeaders (
@@ -415,32 +495,6 @@ public void calculateMissingHeaders_headInputStreamBodyWithExcludeBodySigningStr
415495 SigningStrategy .EXCLUDE_BODY );
416496 }
417497
418- @ Test
419- public void calculateMissingHeaders_whenGetRequestWithXDateHeader ()
420- throws IOException {
421- final URI uri = URI .create ("https://identity.us-phoenix-1.oraclecloud.com/20160918/users" );
422- final Map <String , List <String >> temp = new HashMap <>();
423- temp .put ("x-date" ,Collections .singletonList ("Wed, 11 Oct 2023 12:23:17 GMT" ));
424- final Map <String , List <String >> existingHeaders = Collections .unmodifiableMap (temp );
425- SigningStrategy signingStrategy = SigningStrategy .STANDARD ;
426- final RequestSignerImpl .SigningConfiguration signingConfiguration =
427- new RequestSignerImpl .SigningConfiguration (
428- signingStrategy .getHeadersToSign (),
429- signingStrategy .getOptionalHeadersToSign (),
430- signingStrategy .isSkipContentHeadersForStreamingPutRequests ());
431- final Map <String , String > missingHeaders =
432- RequestSignerImpl .calculateMissingHeaders (
433- "get" ,
434- uri ,
435- existingHeaders ,
436- null ,
437- Constants .ALL_HEADERS_LIST ,
438- signingConfiguration );
439- assertNotNull (missingHeaders );
440- assertEquals (1 , missingHeaders .size ());
441- assertFalse (missingHeaders .containsKey ("date" ));
442- }
443-
444498 private void calculateAndVerifyMissingHeaders (
445499 final String httpMethod ,
446500 final String contentType ,
0 commit comments