Describe the bug
When OAUTH2_PROVIDER_DEVICE_GRANT_MODEL points to a swapped DeviceGrant model, django-oauth-toolkit 3.2 device-code support is only partially compatible with that swap. Some code paths correctly use get_device_grant_model(), but important runtime paths still use the concrete oauth2_provider.DeviceGrant class directly.
This breaks the device flow because creation, lookup, and exception handling can target the wrong model/table or the wrong DoesNotExist exception class.
To Reproduce
- Define a custom model subclassing
oauth2_provider.models.AbstractDeviceGrant.
- Set
OAUTH2_PROVIDER_DEVICE_GRANT_MODEL to that swapped model.
- Enable and exercise the device authorization flow.
- Hit the device authorization endpoint so DOT creates a device grant.
- Poll the token endpoint with
grant_type=urn:ietf:params:oauth:grant-type:device_code.
- Optionally test the browser confirmation/status views using the generated user code.
Concrete problematic paths observed in DOT 3.2:
oauth2_provider.models.create_device_grant() uses DeviceGrant.objects.create(...)
oauth2_provider.views.base.TokenView.device_flow_token_response() uses DeviceGrant.objects.get(...)
oauth2_provider.views.device.DeviceGrantForm.clean_user_code() catches DeviceGrant.DoesNotExist instead of the swapped model's exception
oauth2_provider.views.device.DeviceConfirmView and DeviceGrantStatusView use the concrete DeviceGrant model in lookups/views
Expected behavior
All device-grant runtime paths should consistently use get_device_grant_model() so swapped models are fully supported anywhere DOT creates, loads, or catches exceptions for DeviceGrant instances.
Version
3.2.x
Additional context
I did a repo pass focused on DeviceGrant usages and found that some DOT code already handles swaps correctly, for example oauth2_provider.utils.set_oauthlib_user_to_device_request_user() and the objects.get(...) call in DeviceGrantForm. The bug appears to be incomplete migration to get_device_grant_model() rather than lack of swap support overall.
The likely fix is to replace concrete DeviceGrant usages in the affected runtime paths with get_device_grant_model() and add regression tests under swapped settings with a custom SampleDeviceGrant.
Describe the bug
When
OAUTH2_PROVIDER_DEVICE_GRANT_MODELpoints to a swappedDeviceGrantmodel, django-oauth-toolkit 3.2 device-code support is only partially compatible with that swap. Some code paths correctly useget_device_grant_model(), but important runtime paths still use the concreteoauth2_provider.DeviceGrantclass directly.This breaks the device flow because creation, lookup, and exception handling can target the wrong model/table or the wrong
DoesNotExistexception class.To Reproduce
oauth2_provider.models.AbstractDeviceGrant.OAUTH2_PROVIDER_DEVICE_GRANT_MODELto that swapped model.grant_type=urn:ietf:params:oauth:grant-type:device_code.Concrete problematic paths observed in DOT 3.2:
oauth2_provider.models.create_device_grant()usesDeviceGrant.objects.create(...)oauth2_provider.views.base.TokenView.device_flow_token_response()usesDeviceGrant.objects.get(...)oauth2_provider.views.device.DeviceGrantForm.clean_user_code()catchesDeviceGrant.DoesNotExistinstead of the swapped model's exceptionoauth2_provider.views.device.DeviceConfirmViewandDeviceGrantStatusViewuse the concreteDeviceGrantmodel in lookups/viewsExpected behavior
All device-grant runtime paths should consistently use
get_device_grant_model()so swapped models are fully supported anywhere DOT creates, loads, or catches exceptions forDeviceGrantinstances.Version
3.2.x
Additional context
I did a repo pass focused on
DeviceGrantusages and found that some DOT code already handles swaps correctly, for exampleoauth2_provider.utils.set_oauthlib_user_to_device_request_user()and theobjects.get(...)call inDeviceGrantForm. The bug appears to be incomplete migration toget_device_grant_model()rather than lack of swap support overall.The likely fix is to replace concrete
DeviceGrantusages in the affected runtime paths withget_device_grant_model()and add regression tests under swapped settings with a customSampleDeviceGrant.