Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/oauthlib/oauth2/rfc8628/clients/device.py: 38%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

29 statements  

1""" 

2oauthlib.oauth2.rfc8628 

3~~~~~~~~~~~~~~~~~~~~~~~ 

4 

5This module is an implementation of various logic needed 

6for consuming and providing OAuth 2.0 Device Authorization RFC8628. 

7""" 

8from oauthlib.common import add_params_to_uri 

9from oauthlib.oauth2 import BackendApplicationClient, Client 

10from oauthlib.oauth2.rfc6749.errors import InsecureTransportError 

11from oauthlib.oauth2.rfc6749.parameters import prepare_token_request 

12from oauthlib.oauth2.rfc6749.utils import is_secure_transport, list_to_scope 

13 

14 

15class DeviceClient(Client): 

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' 

30 

31 def __init__(self, client_id, **kwargs): 

32 super().__init__(client_id, **kwargs) 

33 self.client_secret = kwargs.get('client_secret') 

34 

35 def prepare_request_uri(self, uri, scope=None, **kwargs): 

36 if not is_secure_transport(uri): 

37 raise InsecureTransportError() 

38 

39 scope = self.scope if scope is None else scope 

40 params = [(('client_id', self.client_id)), (('grant_type', self.grant_type))] 

41 

42 if self.client_secret is not None: 

43 params.append(('client_secret', self.client_secret)) 

44 

45 if scope: 

46 params.append(('scope', list_to_scope(scope))) 

47 

48 for k,v in kwargs.items(): 

49 if v: 

50 params.append((str(k), v)) 

51 

52 return add_params_to_uri(uri, params) 

53 

54 def prepare_request_body(self, device_code, body='', scope=None, 

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 

92 kwargs['include_client_id'] = include_client_id 

93 scope = self.scope if scope is None else scope 

94 return prepare_token_request(self.grant_type, body=body, device_code=device_code, 

95 scope=scope, **kwargs)