Authlib 1.6.5__py2.py3-none-any.whl → 1.6.6__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
authlib/__init__.py CHANGED
@@ -1,4 +1,5 @@
1
- """authlib.
1
+ """
2
+ authlib
2
3
  ~~~~~~~
3
4
 
4
5
  The ultimate Python library in building OAuth 1.0, OAuth 2.0 and OpenID
authlib/consts.py CHANGED
@@ -1,5 +1,5 @@
1
1
  name = "Authlib"
2
- version = "1.6.5"
2
+ version = "1.6.6"
3
3
  author = "Hsiaoming Yang <me@lepture.com>"
4
4
  homepage = "https://authlib.org"
5
5
  default_user_agent = f"{name}/{version} (+{homepage})"
@@ -20,11 +20,9 @@ class FrameworkIntegration:
20
20
 
21
21
  def _clear_session_state(self, session):
22
22
  now = time.time()
23
+ prefix = f"_state_{self.name}"
23
24
  for key in dict(session):
24
- if "_authlib_" in key:
25
- # TODO: remove in future
26
- session.pop(key)
27
- elif key.startswith("_state_"):
25
+ if key.startswith(prefix):
28
26
  value = session[key]
29
27
  exp = value.get("exp")
30
28
  if not exp or exp < now:
@@ -32,29 +30,32 @@ class FrameworkIntegration:
32
30
 
33
31
  def get_state_data(self, session, state):
34
32
  key = f"_state_{self.name}_{state}"
33
+ session_data = session.get(key)
34
+ if not session_data:
35
+ return None
35
36
  if self.cache:
36
- value = self._get_cache_data(key)
37
+ cached_value = self._get_cache_data(key)
37
38
  else:
38
- value = session.get(key)
39
- if value:
40
- return value.get("data")
39
+ cached_value = session_data
40
+ if cached_value:
41
+ return cached_value.get("data")
41
42
  return None
42
43
 
43
44
  def set_state_data(self, session, state, data):
44
45
  key = f"_state_{self.name}_{state}"
46
+ now = time.time()
45
47
  if self.cache:
46
48
  self.cache.set(key, json.dumps({"data": data}), self.expires_in)
49
+ session[key] = {"exp": now + self.expires_in}
47
50
  else:
48
- now = time.time()
49
51
  session[key] = {"data": data, "exp": now + self.expires_in}
50
52
 
51
53
  def clear_state_data(self, session, state):
52
54
  key = f"_state_{self.name}_{state}"
53
55
  if self.cache:
54
56
  self.cache.delete(key)
55
- else:
56
- session.pop(key, None)
57
- self._clear_session_state(session)
57
+ session.pop(key, None)
58
+ self._clear_session_state(session)
58
59
 
59
60
  def update_token(self, token, refresh_token=None, access_token=None):
60
61
  raise NotImplementedError()
@@ -172,6 +172,8 @@ class ClientAuth:
172
172
 
173
173
  if CONTENT_TYPE_FORM_URLENCODED in content_type:
174
174
  headers["Content-Type"] = CONTENT_TYPE_FORM_URLENCODED
175
+ if isinstance(body, bytes):
176
+ body = body.decode()
175
177
  uri, headers, body = self.sign(method, uri, headers, body)
176
178
  elif self.force_include_body:
177
179
  # To allow custom clients to work on non form encoded bodies.
@@ -4,15 +4,26 @@ import time
4
4
  class OAuth2Token(dict):
5
5
  def __init__(self, params):
6
6
  if params.get("expires_at"):
7
- params["expires_at"] = int(params["expires_at"])
7
+ try:
8
+ params["expires_at"] = int(params["expires_at"])
9
+ except ValueError:
10
+ # If expires_at is not parseable, fall back to expires_in if available
11
+ # Otherwise leave expires_at untouched
12
+ if params.get("expires_in"):
13
+ params["expires_at"] = int(time.time()) + int(params["expires_in"])
14
+
8
15
  elif params.get("expires_in"):
9
16
  params["expires_at"] = int(time.time()) + int(params["expires_in"])
17
+
10
18
  super().__init__(params)
11
19
 
12
20
  def is_expired(self, leeway=60):
13
21
  expires_at = self.get("expires_at")
14
22
  if not expires_at:
15
23
  return None
24
+ # Only check expiration if expires_at is an integer
25
+ if not isinstance(expires_at, int):
26
+ return None
16
27
  # small timedelta to consider token as expired before it actually expires
17
28
  expiration_threshold = expires_at - leeway
18
29
  return expiration_threshold < time.time()
@@ -8,6 +8,7 @@ per `Section 3.1`_.
8
8
  """
9
9
 
10
10
  import logging
11
+ import warnings
11
12
 
12
13
  from authlib.oauth2.rfc6749 import OAuth2Request
13
14
 
@@ -20,7 +21,7 @@ log = logging.getLogger(__name__)
20
21
 
21
22
 
22
23
  class OpenIDToken:
23
- def get_jwt_config(self, grant): # pragma: no cover
24
+ def get_jwt_config(self, grant, client): # pragma: no cover
24
25
  """Get the JWT configuration for OpenIDCode extension. The JWT
25
26
  configuration will be used to generate ``id_token``.
26
27
  If ``alg`` is undefined, the ``id_token_signed_response_alg`` client
@@ -29,15 +30,16 @@ class OpenIDToken:
29
30
  will be used.
30
31
  Developers MUST implement this method in subclass, e.g.::
31
32
 
32
- def get_jwt_config(self, grant):
33
+ def get_jwt_config(self, grant, client):
33
34
  return {
34
35
  "key": read_private_key_file(key_path),
35
- "alg": "RS256",
36
+ "alg": client.id_token_signed_response_alg or "RS256",
36
37
  "iss": "issuer-identity",
37
38
  "exp": 3600,
38
39
  }
39
40
 
40
41
  :param grant: AuthorizationCodeGrant instance
42
+ :param client: OAuth2 client instance
41
43
  :return: dict
42
44
  """
43
45
  raise NotImplementedError()
@@ -78,7 +80,17 @@ class OpenIDToken:
78
80
  request: OAuth2Request = grant.request
79
81
  authorization_code = request.authorization_code
80
82
 
81
- config = self.get_jwt_config(grant)
83
+ try:
84
+ config = self.get_jwt_config(grant, request.client)
85
+ except TypeError:
86
+ warnings.warn(
87
+ "get_jwt_config(self, grant) is deprecated and will be removed in version 1.8. "
88
+ "Use get_jwt_config(self, grant, client) instead.",
89
+ DeprecationWarning,
90
+ stacklevel=2,
91
+ )
92
+ config = self.get_jwt_config(grant)
93
+
82
94
  config["aud"] = self.get_audiences(request)
83
95
 
84
96
  # Per OpenID Connect Registration 1.0 Section 2:
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import warnings
2
3
 
3
4
  from authlib.oauth2.rfc6749 import AccessDeniedError
4
5
  from authlib.oauth2.rfc6749 import ImplicitGrant
@@ -36,19 +37,20 @@ class OpenIDImplicitGrant(ImplicitGrant):
36
37
  """
37
38
  raise NotImplementedError()
38
39
 
39
- def get_jwt_config(self):
40
+ def get_jwt_config(self, client):
40
41
  """Get the JWT configuration for OpenIDImplicitGrant. The JWT
41
42
  configuration will be used to generate ``id_token``. Developers
42
43
  MUST implement this method in subclass, e.g.::
43
44
 
44
- def get_jwt_config(self):
45
+ def get_jwt_config(self, client):
45
46
  return {
46
47
  "key": read_private_key_file(key_path),
47
- "alg": "RS256",
48
+ "alg": client.id_token_signed_response_alg or "RS256",
48
49
  "iss": "issuer-identity",
49
50
  "exp": 3600,
50
51
  }
51
52
 
53
+ :param client: OAuth2 client instance
52
54
  :return: dict
53
55
  """
54
56
  raise NotImplementedError()
@@ -143,7 +145,17 @@ class OpenIDImplicitGrant(ImplicitGrant):
143
145
  return params
144
146
 
145
147
  def process_implicit_token(self, token, code=None):
146
- config = self.get_jwt_config()
148
+ try:
149
+ config = self.get_jwt_config(self.request.client)
150
+ except TypeError:
151
+ warnings.warn(
152
+ "get_jwt_config(self) is deprecated and will be removed in version 1.8. "
153
+ "Use get_jwt_config(self, client) instead.",
154
+ DeprecationWarning,
155
+ stacklevel=2,
156
+ )
157
+ config = self.get_jwt_config()
158
+
147
159
  config["aud"] = self.get_audiences(self.request)
148
160
  config["nonce"] = self.request.payload.data.get("nonce")
149
161
  if code is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Authlib
3
- Version: 1.6.5
3
+ Version: 1.6.6
4
4
  Summary: The ultimate Python library in building OAuth and OpenID Connect servers and clients.
5
5
  Author-email: Hsiaoming Yang <me@lepture.com>
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
- authlib/__init__.py,sha256=9F2r7k-nrTBFVDVWk0oghhIpLioCwQtt-35ppwRNfGU,487
2
- authlib/consts.py,sha256=9cqeotlkDe69rVuzp_CwFO01qxVvyzzzbB2UpHWEvDg,299
1
+ authlib/__init__.py,sha256=2k6VBNbFu1ErBoHhp9Rcv9sDYrC1jWLWvfSkyq-N2AY,487
2
+ authlib/consts.py,sha256=im8FcZYwqc9z8PZ0Car86-7IYmzKzBqPpEgqOa8JV1A,299
3
3
  authlib/deprecate.py,sha256=BaH7IdSK0WEmanyJAl7-Rpmvm6NJcez-Z03k0OYPXl0,506
4
4
  authlib/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  authlib/common/encoding.py,sha256=S80EkhVVJABStdEuZvQV1c47gQnu359fgLAFDmqLaP0,1544
@@ -11,7 +11,7 @@ authlib/integrations/base_client/__init__.py,sha256=0nRNGKgwojLqaTwnbDfXqLiEjNY9
11
11
  authlib/integrations/base_client/async_app.py,sha256=Pw3KIzxFtBG1ZXHg4hfV-D-hX0ubNU34s8bF9IHRm-g,5978
12
12
  authlib/integrations/base_client/async_openid.py,sha256=imBoGouxPu4hMwjmxCu8JMgDADZOMdpCbc_B-LSULl4,2982
13
13
  authlib/integrations/base_client/errors.py,sha256=Iniwp6d3XJ0Q3bYQcOB1tnCQhMKcYv8wLH7BAFHICAA,632
14
- authlib/integrations/base_client/framework_integration.py,sha256=LQFGmr0RyebVWAw1rU7cEwIYK_WiWKA00IVMxn_H5PQ,1871
14
+ authlib/integrations/base_client/framework_integration.py,sha256=jZ9rcYLUwRANorQoJNzi7CC0NoceujnKrKSicGsiptI,1945
15
15
  authlib/integrations/base_client/registry.py,sha256=GV0IJqZzPtsJHb-tl4t38K_Yvv3q4NPvp851V_UzDxY,4313
16
16
  authlib/integrations/base_client/sync_app.py,sha256=3dWAUHefD1-3qoaWUr9w-rOwVsnJ2jB8GiKLMoYTDp4,12791
17
17
  authlib/integrations/base_client/sync_openid.py,sha256=qtUXnzSqHZZATr3BejSBdTy51QkHg_r_i7GwWilvCHo,3165
@@ -99,7 +99,7 @@ authlib/oauth1/errors.py,sha256=pg0NaUgENjfTN_ba50_yQB9aSNe5Mte5MDlikFuypBY,46
99
99
  authlib/oauth1/rfc5849/__init__.py,sha256=Ta7spUuDIW4nBxQoDOZHUZYj42hjyl2h-T7lLq2xDeM,1136
100
100
  authlib/oauth1/rfc5849/authorization_server.py,sha256=y-vDQ79-CFjCl05V9kYqTDhFdCGCMZ9wY9S66mMjmBc,13924
101
101
  authlib/oauth1/rfc5849/base_server.py,sha256=BtBnisyOWP1epfzyp9A5zvMZu3rmCJazyHk9XEtpg8w,3972
102
- authlib/oauth1/rfc5849/client_auth.py,sha256=ovx0Hx5LfSX6hCezFPsHupIsiP0Lc0pfy80cPuwS-0k,7079
102
+ authlib/oauth1/rfc5849/client_auth.py,sha256=Bx0iNj4zDJ6731o6Mfpt5KX5sNhg218N_9PoTbzuAWA,7156
103
103
  authlib/oauth1/rfc5849/errors.py,sha256=iHVEoxrP0ieSjTJO2I9ThG2TvLs3XtRDssuCvu53OsY,2285
104
104
  authlib/oauth1/rfc5849/models.py,sha256=Pvh-7iKXU3zkMYq1nYbdAaxL3Vdg95cxmdaC5-KWxxg,3418
105
105
  authlib/oauth1/rfc5849/parameters.py,sha256=XpAcRz9MZjIUIs6IbthBK_fWzcL2Iy9jHUnFn3-W7zk,3532
@@ -123,7 +123,7 @@ authlib/oauth2/rfc6749/requests.py,sha256=8m2bVR9KrUGzqFRBI8aXp7h-Y3a8H6wLY5hLaj
123
123
  authlib/oauth2/rfc6749/resource_protector.py,sha256=OKXtwUVn0kgK55mIzc9mGNbfUpwoOWTxb105Td5iVPE,5404
124
124
  authlib/oauth2/rfc6749/token_endpoint.py,sha256=kxjK39EHBgeD7uvJLyoLF5DAr1ef4l31jpCt6C4gYJ0,1103
125
125
  authlib/oauth2/rfc6749/util.py,sha256=--0YfF2ZVHTVMPGKD10iPqj02WeiDhXuYttX4tRleVM,1174
126
- authlib/oauth2/rfc6749/wrappers.py,sha256=g59stDpzoJjE6koXlwBNdGZDMgi25SxBNeJtAmtyb4I,805
126
+ authlib/oauth2/rfc6749/wrappers.py,sha256=DEtFYwlpabfGYbkDW6iZfeXXgua_7EGMKBlRh47idNA,1262
127
127
  authlib/oauth2/rfc6749/grants/__init__.py,sha256=7WmResYhXjt0RfzHvrh5sHOQqZURr3FphSO-dmZc9FI,1292
128
128
  authlib/oauth2/rfc6749/grants/authorization_code.py,sha256=CXp1RTezTAYI2yxMUtyW22HeuZb4Q_E1X_c6SRKc3ag,15604
129
129
  authlib/oauth2/rfc6749/grants/base.py,sha256=59YgBIEvYDoUUbGkk0A7lgLXeRnqCir1imvUV_YZqWc,5283
@@ -190,17 +190,17 @@ authlib/oidc/core/models.py,sha256=KjBcQnNJkVYnLWYeQuwb-K_DWDst78MZRLJXjqhtMtw,1
190
190
  authlib/oidc/core/userinfo.py,sha256=8r3WBd6H1JM_5IDW4l1zOkxqrWg_YTyGqDijShKxeLE,4354
191
191
  authlib/oidc/core/util.py,sha256=ihuKYlhQAVmK5SIhwxn5k_PqVB1q0Lmwl1tuwRTQuf4,502
192
192
  authlib/oidc/core/grants/__init__.py,sha256=-SjelrkrD35bnb5rIZiBpbiLxgiJtwMXHJXHr8ovQyo,243
193
- authlib/oidc/core/grants/code.py,sha256=GelmhPA0jj4zK-ucXL7fAwIPfnn5Znol6wJlsJeVx1A,5681
193
+ authlib/oidc/core/grants/code.py,sha256=wnB-8XigZIpv-pgnLe2SL4R2U9XrZ3x99JIRNYOmVgI,6178
194
194
  authlib/oidc/core/grants/hybrid.py,sha256=pIWRAGFbT9d9o4OHcPE-RtjJqOuTGbaFU0lsBG5kgAw,3430
195
- authlib/oidc/core/grants/implicit.py,sha256=rSG0S2jrFzK1rE247DiRyabnpbGq4UE0S6nqJKrMzZo,6619
195
+ authlib/oidc/core/grants/implicit.py,sha256=soG8ohEJ5N9qcOAsivQ89wUgVCyOo8ssgPVJ9kc9cvM,7100
196
196
  authlib/oidc/core/grants/util.py,sha256=prMt5LqyPLbsI6MQACkxOgmMK_WlS_C0I73jhJWETj4,4539
197
197
  authlib/oidc/discovery/__init__.py,sha256=rapkktd4XN0t6LeHOWFPeeKEzlF6gBHvWsTK9JPLPY0,305
198
198
  authlib/oidc/discovery/models.py,sha256=yzdWYQn-VfC48gywoxswge4tgnKb8uQ-UkjhVTClk1E,12442
199
199
  authlib/oidc/discovery/well_known.py,sha256=ry1VHxCmwvjmlMxOFEbSC6FsE_ttijyRcn2xUpv2CaU,574
200
200
  authlib/oidc/registration/__init__.py,sha256=lV_Og-DMFKzWWYsdK04oF83xKUGTE2gQhikPPsOdW84,77
201
201
  authlib/oidc/registration/claims.py,sha256=K7Ft8GDXkVrjJrc53Ihkhn2SVN4pvEf3qiHOkzVOJ7g,17264
202
- authlib-1.6.5.dist-info/licenses/LICENSE,sha256=jhtIUY3pxs0Ay0jH_luAI_2Q1VUsoS6-c2Kg3zDdvkU,1514
203
- authlib-1.6.5.dist-info/METADATA,sha256=JSpi4anvkVQ9zL3GuZR4mvuto9yjFI39uhUnGfKGwdY,9845
204
- authlib-1.6.5.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
205
- authlib-1.6.5.dist-info/top_level.txt,sha256=Rj3mJn0jhRuCs6x7ysI6hYE2PePbuxey6y6jswadAEY,8
206
- authlib-1.6.5.dist-info/RECORD,,
202
+ authlib-1.6.6.dist-info/licenses/LICENSE,sha256=jhtIUY3pxs0Ay0jH_luAI_2Q1VUsoS6-c2Kg3zDdvkU,1514
203
+ authlib-1.6.6.dist-info/METADATA,sha256=BowJdc0kfuglE5GugcqnpLRBGd5zG36dgPQgMaxh8yw,9845
204
+ authlib-1.6.6.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
205
+ authlib-1.6.6.dist-info/top_level.txt,sha256=Rj3mJn0jhRuCs6x7ysI6hYE2PePbuxey6y6jswadAEY,8
206
+ authlib-1.6.6.dist-info/RECORD,,