• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

oauthlib / oauthlib / 16526823736

25 Jul 2025 04:27PM UTC coverage: 92.909% (+0.06%) from 92.846%
16526823736

Pull #918

github

web-flow
Merge e3c8b4631 into 0667a391a
Pull Request #918: Add pre-commit to run linters, formatters, etc. on code changes

1018 of 1128 branches covered (90.25%)

Branch coverage included in aggregate %.

3109 of 3314 relevant lines covered (93.81%)

5.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.58
/oauthlib/oauth2/rfc8628/clients/device.py
1
"""
2
oauthlib.oauth2.rfc8628
3
~~~~~~~~~~~~~~~~~~~~~~~
4

5
This module is an implementation of various logic needed
6
for consuming and providing OAuth 2.0 Device Authorization RFC8628.
7
"""
8
from oauthlib.common import add_params_to_uri
6✔
9
from oauthlib.oauth2 import BackendApplicationClient, Client
6✔
10
from oauthlib.oauth2.rfc6749.errors import InsecureTransportError
6✔
11
from oauthlib.oauth2.rfc6749.parameters import prepare_token_request
6✔
12
from oauthlib.oauth2.rfc6749.utils import is_secure_transport, list_to_scope
6✔
13

14

15
class DeviceClient(Client):
6✔
16

17
    """A public client utilizing the device authorization workflow.
18

19
    The client can request an access token using a device code and
20
    a public client id associated with the device code as defined
21
    in RFC8628.
22

23
    The device authorization grant type can be used to obtain both
24
    access tokens and refresh tokens and is intended to be used in
25
    a scenario where the device being authorized does not have a
26
    user interface that is suitable for performing authentication.
27
    """
28

29
    grant_type = 'urn:ietf:params:oauth:grant-type:device_code'
6✔
30

31
    def __init__(self, client_id, **kwargs):
6✔
32
        super().__init__(client_id, **kwargs)
6✔
33
        self.client_secret = kwargs.get('client_secret')
6✔
34

35
    def prepare_request_uri(self, uri, scope=None, **kwargs):
6✔
36
        if not is_secure_transport(uri):
6!
37
            raise InsecureTransportError()
×
38

39
        scope = self.scope if scope is None else scope
6✔
40
        params = [(('client_id', self.client_id)), (('grant_type', self.grant_type))]
6✔
41

42
        if self.client_secret is not None:
6✔
43
            params.append(('client_secret', self.client_secret))
6✔
44

45
        if scope:
6✔
46
            params.append(('scope', list_to_scope(scope)))
6✔
47

48
        for k,v in kwargs.items():
6!
49
            if v:
×
50
                params.append((str(k), v))
×
51

52
        return add_params_to_uri(uri, params)
6✔
53

54
    def prepare_request_body(self, device_code, body='', scope=None,
6✔
55
                             include_client_id=False, **kwargs):
56
        """Add device_code to request body
57

58
        The client makes a request to the token endpoint by adding the
59
        device_code as a parameter using the
60
        "application/x-www-form-urlencoded" format to the HTTP request
61
        body.
62

63
        :param body: Existing request body (URL encoded string) to embed parameters
64
                     into. This may contain extra parameters. Default ''.
65
        :param scope:   The scope of the access request as described by
66
                        `Section 3.3`_.
67

68
        :param include_client_id: `True` to send the `client_id` in the
69
                                  body of the upstream request. This is required
70
                                  if the client is not authenticating with the
71
                                  authorization server as described in
72
                                  `Section 3.2.1`_. False otherwise (default).
73
        :type include_client_id: Boolean
74

75
        :param kwargs:  Extra credentials to include in the token request.
76

77
        The prepared body will include all provided device_code as well as
78
        the ``grant_type`` parameter set to
79
        ``urn:ietf:params:oauth:grant-type:device_code``::
80

81
            >>> from oauthlib.oauth2 import DeviceClient
82
            >>> client = DeviceClient('your_id', 'your_code')
83
            >>> client.prepare_request_body(scope=['hello', 'world'])
84
            'grant_type=urn:ietf:params:oauth:grant-type:device_code&scope=hello+world'
85

86
        .. _`Section 3.2.1`: https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1
87
        .. _`Section 3.3`: https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
88
        .. _`Section 3.4`: https://datatracker.ietf.org/doc/html/rfc8628#section-3.4
89
        """
90

91
        kwargs['client_id'] = self.client_id
6✔
92
        kwargs['include_client_id'] = include_client_id
6✔
93
        scope = self.scope if scope is None else scope
6✔
94
        return prepare_token_request(self.grant_type, body=body, device_code=device_code,
6✔
95
                                     scope=scope, **kwargs)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc