Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google_auth_oauthlib/helpers.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

31 statements  

1# Copyright 2017 Google Inc. 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15"""Integration helpers. 

16 

17This module provides helpers for integrating with `requests-oauthlib`_. 

18Typically, you'll want to use the higher-level helpers in 

19:mod:`google_auth_oauthlib.flow`. 

20 

21.. _requests-oauthlib: http://requests-oauthlib.readthedocs.io/en/latest/ 

22""" 

23 

24import datetime 

25import json 

26 

27from google.auth import external_account_authorized_user 

28import google.oauth2.credentials 

29import requests_oauthlib 

30 

31_REQUIRED_CONFIG_KEYS = frozenset(("auth_uri", "token_uri", "client_id")) 

32 

33 

34def session_from_client_config(client_config, scopes, **kwargs): 

35 """Creates a :class:`requests_oauthlib.OAuth2Session` from client 

36 configuration loaded from a Google-format client secrets file. 

37 

38 Args: 

39 client_config (Mapping[str, Any]): The client 

40 configuration in the Google `client secrets`_ format. 

41 scopes (Sequence[str]): The list of scopes to request during the 

42 flow. 

43 kwargs: Any additional parameters passed to 

44 :class:`requests_oauthlib.OAuth2Session` 

45 

46 Raises: 

47 ValueError: If the client configuration is not in the correct 

48 format. 

49 

50 Returns: 

51 Tuple[requests_oauthlib.OAuth2Session, Mapping[str, Any]]: The new 

52 oauthlib session and the validated client configuration. 

53 

54 .. _client secrets: 

55 https://github.com/googleapis/google-api-python-client/blob/main/docs/client-secrets.md 

56 """ 

57 

58 if "web" in client_config: 

59 config = client_config["web"] 

60 elif "installed" in client_config: 

61 config = client_config["installed"] 

62 else: 

63 raise ValueError("Client secrets must be for a web or installed app.") 

64 

65 if not _REQUIRED_CONFIG_KEYS.issubset(config.keys()): 

66 raise ValueError("Client secrets is not in the correct format.") 

67 

68 session = requests_oauthlib.OAuth2Session( 

69 client_id=config["client_id"], scope=scopes, **kwargs 

70 ) 

71 

72 return session, client_config 

73 

74 

75def session_from_client_secrets_file(client_secrets_file, scopes, **kwargs): 

76 """Creates a :class:`requests_oauthlib.OAuth2Session` instance from a 

77 Google-format client secrets file. 

78 

79 Args: 

80 client_secrets_file (str): The path to the `client secrets`_ .json 

81 file. 

82 scopes (Sequence[str]): The list of scopes to request during the 

83 flow. 

84 kwargs: Any additional parameters passed to 

85 :class:`requests_oauthlib.OAuth2Session` 

86 

87 Returns: 

88 Tuple[requests_oauthlib.OAuth2Session, Mapping[str, Any]]: The new 

89 oauthlib session and the validated client configuration. 

90 

91 .. _client secrets: 

92 https://github.com/googleapis/google-api-python-client/blob/main/docs/client-secrets.md 

93 """ 

94 with open(client_secrets_file, "r") as json_file: 

95 client_config = json.load(json_file) 

96 

97 return session_from_client_config(client_config, scopes, **kwargs) 

98 

99 

100def credentials_from_session(session, client_config=None): 

101 """Creates :class:`google.oauth2.credentials.Credentials` from a 

102 :class:`requests_oauthlib.OAuth2Session`. 

103 

104 :meth:`fetch_token` must be called on the session before before calling 

105 this. This uses the session's auth token and the provided client 

106 configuration to create :class:`google.oauth2.credentials.Credentials`. 

107 This allows you to use the credentials from the session with Google 

108 API client libraries. 

109 

110 Args: 

111 session (requests_oauthlib.OAuth2Session): The OAuth 2.0 session. 

112 client_config (Mapping[str, Any]): The subset of the client 

113 configuration to use. For example, if you have a web client 

114 you would pass in `client_config['web']`. 

115 

116 Returns: 

117 google.oauth2.credentials.Credentials: The constructed credentials. 

118 

119 Raises: 

120 ValueError: If there is no access token in the session. 

121 """ 

122 client_config = client_config if client_config is not None else {} 

123 

124 if not session.token: 

125 raise ValueError( 

126 "There is no access token for this session, did you call " "fetch_token?" 

127 ) 

128 

129 if "3pi" in client_config: 

130 credentials = external_account_authorized_user.Credentials( 

131 token=session.token["access_token"], 

132 refresh_token=session.token.get("refresh_token"), 

133 token_url=client_config.get("token_uri"), 

134 client_id=client_config.get("client_id"), 

135 client_secret=client_config.get("client_secret"), 

136 token_info_url=client_config.get("token_info_url"), 

137 scopes=session.scope, 

138 ) 

139 else: 

140 credentials = google.oauth2.credentials.Credentials( 

141 session.token["access_token"], 

142 refresh_token=session.token.get("refresh_token"), 

143 id_token=session.token.get("id_token"), 

144 token_uri=client_config.get("token_uri"), 

145 client_id=client_config.get("client_id"), 

146 client_secret=client_config.get("client_secret"), 

147 scopes=session.scope, 

148 granted_scopes=session.token.get("scope"), 

149 ) 

150 credentials.expiry = datetime.datetime.utcfromtimestamp(session.token["expires_at"]) 

151 return credentials