Skip to content

Commit

Permalink
Allow Authorization Code flow without a client_secret - Initial commi…
Browse files Browse the repository at this point in the history
…t with Patch & testcases (#1276)

* Initial commit with Patch & testcases

* reference the RFC where empty client secret is allowed

---------

Co-authored-by: Alan Crosswell <alan@crosswell.us>
  • Loading branch information
bull500 and n2ygk committed May 31, 2023
1 parent 016c6c3 commit 64faa9e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Contributors

Abhishek Patel
Adam Johnson
Adheeth P Praveen
Alan Crosswell
Alejandro Mantecon Guillen
Aleksander Vaskevich
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* #1218 Confim support for Python 3.11.
* #1222 Remove expired ID tokens alongside access tokens in `cleartokens` management command
* #1270 Fix RP-initiated Logout with no available Django session
* #1092 Allow Authorization Code flow without a client_secret per [RFC 6749 2.3.1](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.3.1)

## [2.2.0] 2022-10-18

Expand Down
2 changes: 1 addition & 1 deletion oauth2_provider/oauth2_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def _authenticate_request_body(self, request):
# TODO: check if oauthlib has already unquoted client_id and client_secret
try:
client_id = request.client_id
client_secret = request.client_secret
client_secret = getattr(request, "client_secret", "")
except AttributeError:
return False

Expand Down
24 changes: 24 additions & 0 deletions tests/test_oauth2_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
RefreshToken = get_refresh_token_model()

CLEARTEXT_SECRET = "1234567890abcdefghijklmnopqrstuvwxyz"
CLEARTEXT_BLANK_SECRET = ""


@contextlib.contextmanager
Expand Down Expand Up @@ -61,11 +62,25 @@ def setUp(self):
)
self.request.client = self.application

self.blank_secret_request = mock.MagicMock(wraps=Request)
self.blank_secret_request.user = self.user
self.blank_secret_request.grant_type = "not client"
self.blank_secret_application = Application.objects.create(
client_id="blank_secret_client_id",
client_secret=CLEARTEXT_BLANK_SECRET,
user=self.user,
client_type=Application.CLIENT_PUBLIC,
authorization_grant_type=Application.GRANT_PASSWORD,
)
self.blank_secret_request.client = self.blank_secret_application

def tearDown(self):
self.application.delete()

def test_authenticate_request_body(self):
self.request.client_id = "client_id"
self.assertFalse(self.validator._authenticate_request_body(self.request))

self.request.client_secret = ""
self.assertFalse(self.validator._authenticate_request_body(self.request))

Expand All @@ -75,6 +90,15 @@ def test_authenticate_request_body(self):
self.request.client_secret = CLEARTEXT_SECRET
self.assertTrue(self.validator._authenticate_request_body(self.request))

self.blank_secret_request.client_id = "blank_secret_client_id"
self.assertTrue(self.validator._authenticate_request_body(self.blank_secret_request))

self.blank_secret_request.client_secret = CLEARTEXT_BLANK_SECRET
self.assertTrue(self.validator._authenticate_request_body(self.blank_secret_request))

self.blank_secret_request.client_secret = "wrong_client_secret"
self.assertFalse(self.validator._authenticate_request_body(self.blank_secret_request))

def test_extract_basic_auth(self):
self.request.headers = {"HTTP_AUTHORIZATION": "Basic 123456"}
self.assertEqual(self.validator._extract_basic_auth(self.request), "123456")
Expand Down

0 comments on commit 64faa9e

Please sign in to comment.