Repository: auth0/auth0-python
Pull request #560 (2023-12-04 15:20:37)

[SDK-4138] Add support for Pushed Authorization Requests (PAR)
### Changes

Add support for the `/oauth/par` endpoint in the auth client

### References

Pushed Authorization Requests (PAR) https://www.rfc-editor.org/rfc/rfc9126.html



Patch:
diff --git a/auth0/authentication/pushed_authorization_requests.py b/auth0/authentication/pushed_authorization_requests.py
new file mode 100644
index 0000000..2b543fc
--- /dev/null
+++ b/auth0/authentication/pushed_authorization_requests.py
@@ -0,0 +1,30 @@
+from typing import Any
+
+from .base import AuthenticationBase
+
+
+class PushedAuthorizationRequests(AuthenticationBase):
+    """Pushed Authorization Request (PAR) endpoint"""
+
+    def pushed_authorization_request(
+        self, response_type: str, redirect_uri: str, **kwargs
+    ) -> Any:
+        """Send a Pushed Authorization Request (PAR).
+
+        Args:
+             response_type (str): Indicates to Auth0 which OAuth 2.0 flow you want to perform.
+             redirect_uri (str): The URL to which Auth0 will redirect the browser after authorization has been granted
+             by the user.
+             **kwargs: Other fields to send along with the PAR.
+
+        See: https://www.rfc-editor.org/rfc/rfc9126.html
+        """
+        return self.authenticated_post(
+            f"{self.protocol}://{self.domain}/oauth/par",
+            data={
+                "client_id": self.client_id,
+                "response_type": response_type,
+                "redirect_uri": redirect_uri,
+                **kwargs,
+            },
+        )


Test patch:
diff --git a/auth0/test/authentication/test_pushed_authorization_requests.py b/auth0/test/authentication/test_pushed_authorization_requests.py
new file mode 100644
index 0000000..8dee0b7
--- /dev/null
+++ b/auth0/test/authentication/test_pushed_authorization_requests.py
@@ -0,0 +1,47 @@
+import unittest
+from unittest import mock
+
+from ...authentication.pushed_authorization_requests import PushedAuthorizationRequests
+
+
+class TestRevokeToken(unittest.TestCase):
+    @mock.patch("auth0.rest.RestClient.post")
+    def test_par(self, mock_post):
+        a = PushedAuthorizationRequests("my.domain.com", "cid", client_secret="sh!")
+        a.pushed_authorization_request(
+            response_type="code", redirect_uri="https://example.com/callback"
+        )
+
+        args, kwargs = mock_post.call_args
+
+        self.assertEqual(args[0], "https://my.domain.com/oauth/par")
+        self.assertEqual(
+            kwargs["data"],
+            {
+                "client_id": "cid",
+                "client_secret": "sh!",
+                "response_type": "code",
+                "redirect_uri": "https://example.com/callback",
+            },
+        )
+
+    @mock.patch("auth0.rest.RestClient.post")
+    def test_par_custom_params(self, mock_post):
+        a = PushedAuthorizationRequests("my.domain.com", "cid", client_secret="sh!")
+        a.pushed_authorization_request(
+            response_type="code", redirect_uri="https://example.com/callback", foo="bar"
+        )
+
+        args, kwargs = mock_post.call_args
+
+        self.assertEqual(args[0], "https://my.domain.com/oauth/par")
+        self.assertEqual(
+            kwargs["data"],
+            {
+                "client_id": "cid",
+                "client_secret": "sh!",
+                "response_type": "code",
+                "redirect_uri": "https://example.com/callback",
+                "foo": "bar",
+            },
+        )