|
10 | 10 | import warnings |
11 | 11 | import time |
12 | 12 | import base64 |
| 13 | +import sys |
13 | 14 |
|
14 | 15 | import requests |
15 | 16 |
|
16 | 17 |
|
| 18 | +string_types = (str,) if sys.version_info[0] >= 3 else (basestring, ) |
| 19 | + |
17 | 20 |
|
18 | 21 | class BaseClient(object): |
19 | 22 | # This low-level interface works. Yet you'll find its sub-class |
@@ -163,13 +166,15 @@ def _obtain_token( # The verb "obtain" is influenced by OAUTH2 RFC 6749 |
163 | 166 | raise |
164 | 167 |
|
165 | 168 | def obtain_token_by_refresh_token(self, refresh_token, scope=None, **kwargs): |
| 169 | + # type: (str, Union[str, list, set, tuple]) -> dict |
166 | 170 | """Obtain an access token via a refresh token. |
167 | 171 |
|
168 | 172 | :param refresh_token: The refresh token issued to the client |
169 | 173 | :param scope: If omitted, is treated as equal to the scope originally |
170 | 174 | granted by the resource ownser, |
171 | 175 | according to https://tools.ietf.org/html/rfc6749#section-6 |
172 | 176 | """ |
| 177 | + assert isinstance(refresh_token, string_types) |
173 | 178 | data = kwargs.pop('data', {}) |
174 | 179 | data.update(refresh_token=refresh_token, scope=scope) |
175 | 180 | return self._obtain_token("refresh_token", data=data, **kwargs) |
@@ -380,14 +385,10 @@ def __init__(self, |
380 | 385 | self.on_removing_rt = on_removing_rt |
381 | 386 | self.on_updating_rt = on_updating_rt |
382 | 387 |
|
383 | | - def _obtain_token(self, grant_type, params=None, data=None, |
384 | | - rt_getter=lambda token_item: token_item["refresh_token"], |
385 | | - *args, **kwargs): |
| 388 | + def _obtain_token(self, grant_type, params=None, data=None, *args, **kwargs): |
386 | 389 | RT = "refresh_token" |
387 | 390 | _data = data.copy() # to prevent side effect |
388 | 391 | refresh_token = _data.get(RT) |
389 | | - if grant_type == RT and isinstance(refresh_token, dict): |
390 | | - _data[RT] = rt_getter(refresh_token) # Put raw RT in _data |
391 | 392 | resp = super(Client, self)._obtain_token( |
392 | 393 | grant_type, params, _data, *args, **kwargs) |
393 | 394 | if "error" not in resp: |
@@ -416,31 +417,31 @@ def obtain_token_by_refresh_token(self, token_item, scope=None, |
416 | 417 | on_removing_rt=None, |
417 | 418 | **kwargs): |
418 | 419 | # type: (Union[str, dict], Union[str, list, set, tuple], Callable) -> dict |
419 | | - """This is an "overload" which accepts a refresh token item as a dict, |
420 | | - therefore this method can relay refresh_token item to event listeners. |
| 420 | + """This is an overload which will trigger token storage callbacks. |
421 | 421 |
|
422 | 422 | :param token_item: |
423 | | - A refresh token item as a dict, came from the cache managed by this lib. |
| 423 | + A refresh token (RT) item, in flexible format. It can be a string, |
| 424 | + or a whatever data structure containing RT string and its metadata, |
| 425 | + in such case the `rt_getter` callable must be able to |
| 426 | + extract the RT string out from the token item data structure. |
| 427 | +
|
| 428 | + Either way, this token_item will be passed into other callbacks as-is. |
424 | 429 |
|
425 | | - Alternatively, you can still use a refresh token (RT) as a string, |
426 | | - supposedly came from a token cache managed by a different library, |
427 | | - then this library will store the new RT (if Authority Server issued one) |
428 | | - into this lib's cache. This is a way to migrate from other lib to us. |
429 | 430 | :param scope: If omitted, is treated as equal to the scope originally |
430 | 431 | granted by the resource ownser, |
431 | 432 | according to https://tools.ietf.org/html/rfc6749#section-6 |
432 | | - :param rt_getter: A callable used to extract the RT from token_item |
| 433 | + :param rt_getter: A callable to translate the token_item to a raw RT string |
433 | 434 | :param on_removing_rt: If absent, fall back to the one defined in initialization |
434 | 435 | """ |
435 | 436 | resp = super(Client, self).obtain_token_by_refresh_token( |
436 | | - token_item, scope=scope, |
437 | | - rt_getter=rt_getter, # Wire up this for _obtain_token() |
| 437 | + rt_getter(token_item) |
| 438 | + if not isinstance(token_item, string_types) else token_item, |
| 439 | + scope=scope, |
438 | 440 | **kwargs) |
439 | | - if isinstance(token_item, dict): |
440 | | - if resp.get('error') == 'invalid_grant': |
441 | | - (on_removing_rt or self.on_removing_rt)(token_item) # Discard old RT |
442 | | - if 'refresh_token' in resp: |
443 | | - self.on_updating_rt(token_item, resp['refresh_token']) |
| 441 | + if resp.get('error') == 'invalid_grant': |
| 442 | + (on_removing_rt or self.on_removing_rt)(token_item) # Discard old RT |
| 443 | + if 'refresh_token' in resp: |
| 444 | + self.on_updating_rt(token_item, resp['refresh_token']) |
444 | 445 | return resp |
445 | 446 |
|
446 | 447 | def obtain_token_by_assertion( |
|
0 commit comments