From 4df327d31e7fd9317990787ba79b8e64c793d725 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Thu, 13 Nov 2025 11:14:30 +0000 Subject: [PATCH 1/2] Add check that device code grants correct scopes. --- tests/test_device.py | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_device.py b/tests/test_device.py index 727c81002..4fc24befa 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -767,3 +767,50 @@ def test_device_is_expired_method_sets_status_to_expired_if_deadline_passed(self assert is_expired assert device.status == device.EXPIRED + + @mock.patch( + "oauthlib.oauth2.rfc8628.endpoints.device_authorization.generate_token", + lambda: "def", + ) + def test_device_flow_uses_requested_scope_not_default(self): + """ + Test that requested scope in device authorization is used in the token, + not DEFAULT_SCOPES. + """ + self.oauth2_settings.OAUTH_DEVICE_VERIFICATION_URI = "example.com/device" + self.oauth2_settings.OAUTH_DEVICE_USER_CODE_GENERATOR = lambda: "XYZ" + self.oauth2_settings.OAUTH_PRE_TOKEN_VALIDATION = [ + set_oauthlib_user_to_device_request_user + ] + + device_authorization_response = self.client.post( + reverse("oauth2_provider:device-authorization"), + data=urlencode({"client_id": self.application.client_id, "scope": "read"}), + content_type="application/x-www-form-urlencoded", + ) + assert device_authorization_response.status_code == 200 + + self.client.login(username="test_user", password="123456") + self.client.post(reverse("oauth2_provider:device"), data={"user_code": "XYZ"}) + self.client.post( + reverse( + "oauth2_provider:device-confirm", + kwargs={"user_code": "XYZ", "client_id": self.application.client_id}, + ), + data={"action": "accept"}, + ) + + token_response = self.client.post( + "/o/token/", + data=urlencode( + { + "device_code": "def", + "client_id": self.application.client_id, + "grant_type": "urn:ietf:params:oauth:grant-type:device_code", + } + ), + content_type="application/x-www-form-urlencoded", + ) + + assert token_response.status_code == 200 + assert token_response.json()["scope"] == "read" From 265268c11daf794109133741c1ac5e4c75ad8403 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Thu, 13 Nov 2025 11:32:14 +0000 Subject: [PATCH 2/2] Ensure that device code tokens have correct scopes --- oauth2_provider/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/oauth2_provider/utils.py b/oauth2_provider/utils.py index a009d8a0e..75dc1e793 100644 --- a/oauth2_provider/utils.py +++ b/oauth2_provider/utils.py @@ -100,3 +100,4 @@ def set_oauthlib_user_to_device_request_user(request: Request) -> None: device: DeviceGrant = get_device_grant_model().objects.get(device_code=request._params["device_code"]) request.user = device.user + request.scopes = device.scope.split() if device.scope else []