NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

refresher.py (3272B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\clientRefreshToken\refresher.py
      2 from __future__ import absolute_import
      3 import uthread2
      4 import requests
      5 import datetime
      6 import logging
      7 from .discovery_hacks import discover_refresh_parameters_from_user_token
      8 logger = logging.getLogger(__name__)
      9 
     10 class Refresher(object):
     11 
     12     def __init__(self, initial_user_token_payload, initial_refresh_token):
     13         client_id, token_endpoint = discover_refresh_parameters_from_user_token(initial_user_token_payload)
     14         self.client_id = client_id
     15         self.refresh_token = initial_refresh_token
     16         self.token_endpoint = token_endpoint
     17         self.access_token = None
     18         self.expires = None
     19         self.callbacks = []
     20         uthread2.StartTasklet(self._maintain_fresh_token)
     21 
     22     def _maintain_fresh_token(self):
     23         while True:
     24             try:
     25                 self._refresh()
     26                 self.broadcast(self.access_token)
     27                 uthread2.sleep(max(0, self.expires - 90))
     28             except requests.HTTPError as http_error:
     29                 response = http_error.response
     30                 if response is not None and 400 <= response.status_code < 500:
     31                     reportHTTPError(http_error, message='token refresh rejected, stopping refresher')
     32                     return
     33                 reportHTTPError(http_error, message='token refresh request failed')
     34                 uthread2.sleep(1)
     35             except (requests.ConnectionError, requests.Timeout) as e:
     36                 logger.warning('token refresh transient network error: %s', e)
     37                 uthread2.sleep(1)
     38             except Exception:
     39                 logger.exception('refreshing access token failed')
     40                 uthread2.sleep(1)
     41 
     42     def add_callback(self, callback):
     43         if not callable(callback):
     44             logger.warning('callback not callable: %s', callback)
     45             return
     46         self.callbacks.append(callback)
     47         callback(self.access_token)
     48 
     49     def broadcast(self, *args):
     50         for callback in self.callbacks:
     51             callback(*args)
     52 
     53     def _refresh(self):
     54         body = {'grant_type': 'refresh_token',
     55          'client_id': self.client_id,
     56          'refresh_token': self.refresh_token}
     57         response = requests.post(self.token_endpoint, data=body, timeout=(5, 15))
     58         response.raise_for_status()
     59         content = response.json()
     60         access_token = content['access_token']
     61         if not access_token:
     62             raise RuntimeError('access token empty on refresh')
     63         refresh_token = content['refresh_token']
     64         if not refresh_token:
     65             raise RuntimeError('refresh token empty on refresh')
     66         self.access_token = access_token
     67         self.refresh_token = refresh_token
     68         self.expires = content['expires_in']
     69         logger.debug('token refreshed, expires in %s', datetime.timedelta(seconds=self.expires))
     70 
     71 
     72 def reportHTTPError(http_error, message = ''):
     73     extra = dict()
     74     try:
     75         resp_data = http_error.response.json()
     76         extra.update(resp_data)
     77     except ValueError:
     78         extra['response_content'] = str(http_error.response.content)
     79 
     80     if not message:
     81         message = str(http_error)
     82     logger.exception(message, extra=extra)