5454import io .fusionauth .http .HTTPValues .Headers ;
5555import io .fusionauth .http .server .HTTPRequest ;
5656import io .fusionauth .http .server .HTTPResponse ;
57+ import io .fusionauth .jwks .domain .JSONWebKey ;
58+ import io .fusionauth .jwt .Signer ;
5759import org .primeframework .mock .MockUserAgent ;
5860import org .primeframework .mvc .config .MVCConfiguration ;
5961import org .primeframework .mvc .http .FormBodyPublisher ;
@@ -94,6 +96,10 @@ public class RequestBuilder {
9496
9597 public boolean useTLS ;
9698
99+ private String bearerToken ;
100+
101+ private DPoPProofProvider dPoPProofProvider ;
102+
97103 private byte [] body ;
98104
99105 @ Inject (optional = true )
@@ -328,6 +334,12 @@ public RequestBuilder usingHTTPS() {
328334 throw new IllegalStateException ("This handling is not implemented yet" );
329335 }
330336
337+ public RequestBuilder withAuthorizationBearerToken (String encodedJWT ) {
338+ this .bearerToken = encodedJWT ;
339+ request .setHeader ("Authorization" , "Bearer " + encodedJWT );
340+ return this ;
341+ }
342+
331343 /**
332344 * Adds an Authorization header to the request using the specified value.
333345 * <p>Shorthand for calling
@@ -491,15 +503,9 @@ public RequestBuilder withCookie(String name, String value) throws Exception {
491503 return withCookie (name , value , false , false );
492504 }
493505
494- /**
495- * Encrypt the provided value and add a cookie with the encrypted value to the request
496- *
497- * @param name The name of the cookie.
498- * @param value The unencrypted value of the cookie.
499- * @return This.
500- */
501- public RequestBuilder withEncryptedCookie (String name , String value ) throws Exception {
502- return withCookie (name , value , false , true );
506+ public RequestBuilder withDPoPProofProvider (DPoPProofProvider dPoPProofProvider ) {
507+ this .dPoPProofProvider = dPoPProofProvider ;
508+ return this ;
503509 }
504510
505511 /**
@@ -526,6 +532,17 @@ public RequestBuilder withEncoding(Charset encoding) {
526532 return this ;
527533 }
528534
535+ /**
536+ * Encrypt the provided value and add a cookie with the encrypted value to the request
537+ *
538+ * @param name The name of the cookie.
539+ * @param value The unencrypted value of the cookie.
540+ * @return This.
541+ */
542+ public RequestBuilder withEncryptedCookie (String name , String value ) throws Exception {
543+ return withCookie (name , value , false , true );
544+ }
545+
529546 /**
530547 * Adds a file.
531548 *
@@ -825,6 +842,10 @@ HTTPResponseWrapper run() {
825842 request .setHost (requestURI .getHost ());
826843 request .setScheme (requestURI .getScheme ());
827844
845+ if (dPoPProofProvider != null ) {
846+ request .addHeader ("DPoP" , dPoPProofProvider .generateDPoPProof (request .getMethod (), requestURI .toString (), this .bearerToken ));
847+ }
848+
828849 // Now that the cookies are ready, if the CSRF token is enabled and the parameter isn't set, we set it to be consistent
829850 // since the [@control.form] would normally set that into the form and into the request.
830851 if (request .getMethod () == HTTPMethod .POST ) {
@@ -887,9 +908,12 @@ HTTPResponseWrapper run() {
887908 var requestBuilder = HttpRequest .newBuilder ()
888909 .method (request .getMethod ().name (), bodyPublisher );
889910
890- if (!locales .isEmpty ()) {
891- requestBuilder .setHeader ("Accept-Language" , locales .stream ().map (Locale ::toLanguageTag ).collect (Collectors .joining (", " )));
911+ if (locales .isEmpty ()) {
912+ // request.getLocale() returns a default locale if none are set by httpRequestConsumer but
913+ // we still want to set to the system's default, if none were explicitly set.
914+ locales = List .of (Locale .getDefault ());
892915 }
916+ requestBuilder .setHeader ("Accept-Language" , locales .stream ().map (Locale ::toLanguageTag ).collect (Collectors .joining (", " )));
893917
894918 if (contentType != null ) {
895919 requestBuilder .setHeader (Headers .ContentType , contentType + (characterEncoding != null ? "; charset=" + characterEncoding : "" ));
0 commit comments