Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/oauthlib/openid/connect/core/endpoints/userinfo.py: 32%

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

40 statements  

1""" 

2oauthlib.openid.connect.core.endpoints.userinfo 

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

4 

5This module is an implementation of userinfo endpoint. 

6""" 

7import json 

8import logging 

9 

10from oauthlib.common import Request 

11from oauthlib.oauth2.rfc6749 import errors 

12from oauthlib.oauth2.rfc6749.endpoints.base import ( 

13 BaseEndpoint, catch_errors_and_unavailability, 

14) 

15from oauthlib.oauth2.rfc6749.tokens import BearerToken 

16 

17log = logging.getLogger(__name__) 

18 

19 

20class UserInfoEndpoint(BaseEndpoint): 

21 """Authorizes access to userinfo resource. 

22 """ 

23 def __init__(self, request_validator): 

24 self.bearer = BearerToken(request_validator, None, None, None) 

25 self.request_validator = request_validator 

26 BaseEndpoint.__init__(self) 

27 

28 @catch_errors_and_unavailability 

29 def create_userinfo_response(self, uri, http_method='GET', body=None, headers=None): 

30 """Validate BearerToken and return userinfo from RequestValidator 

31 

32 The UserInfo Endpoint MUST return a 

33 content-type header to indicate which format is being returned. The 

34 content-type of the HTTP response MUST be application/json if the 

35 response body is a text JSON object; the response body SHOULD be encoded 

36 using UTF-8. 

37 """ 

38 request = Request(uri, http_method, body, headers) 

39 request.scopes = ["openid"] 

40 self.validate_userinfo_request(request) 

41 

42 claims = self.request_validator.get_userinfo_claims(request) 

43 if claims is None: 

44 log.error('Userinfo MUST have claims for %r.', request) 

45 raise errors.ServerError(status_code=500) 

46 

47 if isinstance(claims, dict): 

48 resp_headers = { 

49 'Content-Type': 'application/json' 

50 } 

51 if "sub" not in claims: 

52 log.error('Userinfo MUST have "sub" for %r.', request) 

53 raise errors.ServerError(status_code=500) 

54 body = json.dumps(claims) 

55 elif isinstance(claims, str): 

56 resp_headers = { 

57 'Content-Type': 'application/jwt' 

58 } 

59 body = claims 

60 else: 

61 log.error('Userinfo return unknown response for %r.', request) 

62 raise errors.ServerError(status_code=500) 

63 log.debug('Userinfo access valid for %r.', request) 

64 return resp_headers, body, 200 

65 

66 def validate_userinfo_request(self, request): 

67 """Ensure the request is valid. 

68 

69 5.3.1. UserInfo Request 

70 The Client sends the UserInfo Request using either HTTP GET or HTTP 

71 POST. The Access Token obtained from an OpenID Connect Authentication 

72 Request MUST be sent as a Bearer Token, per `Section 2`_ of OAuth 2.0 

73 Bearer Token Usage [RFC6750]. 

74 

75 It is RECOMMENDED that the request use the HTTP GET method and the 

76 Access Token be sent using the Authorization header field. 

77 

78 The following is a non-normative example of a UserInfo Request: 

79 

80 .. code-block:: http 

81 

82 GET /userinfo HTTP/1.1 

83 Host: server.example.com 

84 Authorization: Bearer SlAV32hkKG 

85 

86 5.3.3. UserInfo Error Response 

87 When an error condition occurs, the UserInfo Endpoint returns an Error 

88 Response as defined in `Section 3`_ of OAuth 2.0 Bearer Token Usage 

89 [RFC6750]. (HTTP errors unrelated to RFC 6750 are returned to the User 

90 Agent using the appropriate HTTP status code.) 

91 

92 The following is a non-normative example of a UserInfo Error Response: 

93 

94 .. code-block:: http 

95 

96 HTTP/1.1 401 Unauthorized 

97 WWW-Authenticate: Bearer error="invalid_token", 

98 error_description="The Access Token expired" 

99 

100 .. _`Section 2`: https://datatracker.ietf.org/doc/html/rfc6750#section-2 

101 .. _`Section 3`: https://datatracker.ietf.org/doc/html/rfc6750#section-3 

102 """ 

103 if not self.bearer.validate_request(request): 

104 raise errors.InvalidTokenError() 

105 if "openid" not in request.scopes: 

106 raise errors.InsufficientScopeError()