codekingpro/portable-devtools
114k
1import functools2from .framework_integration import FrameworkIntegration3 4__all__ = ['BaseOAuth']5 6 7OAUTH_CLIENT_PARAMS = (8 'client_id', 'client_secret',9 'request_token_url', 'request_token_params',10 'access_token_url', 'access_token_params',11 'refresh_token_url', 'refresh_token_params',12 'authorize_url', 'authorize_params',13 'api_base_url', 'client_kwargs',14 'server_metadata_url',15)16 17 18class BaseOAuth:19 """Registry for oauth clients.20 21 Create an instance for registry::22 23 oauth = OAuth()24 """25 oauth1_client_cls = None26 oauth2_client_cls = None27 framework_integration_cls = FrameworkIntegration28 29 def __init__(self, cache=None, fetch_token=None, update_token=None):30 self._registry = {}31 self._clients = {}32 self.cache = cache33 self.fetch_token = fetch_token34 self.update_token = update_token35 36 def create_client(self, name):37 """Create or get the given named OAuth client. For instance, the38 OAuth registry has ``.register`` a twitter client, developers may39 access the client with::40 41 client = oauth.create_client('twitter')42 43 :param: name: Name of the remote application44 :return: OAuth remote app45 """46 if name in self._clients:47 return self._clients[name]48 49 if name not in self._registry:50 return None51 52 overwrite, config = self._registry[name]53 client_cls = config.pop('client_cls', None)54 55 if client_cls and client_cls.OAUTH_APP_CONFIG:56 kwargs = client_cls.OAUTH_APP_CONFIG57 kwargs.update(config)58 else:59 kwargs = config60 61 kwargs = self.generate_client_kwargs(name, overwrite, **kwargs)62 framework = self.framework_integration_cls(name, self.cache)63 if client_cls:64 client = client_cls(framework, name, **kwargs)65 elif kwargs.get('request_token_url'):66 client = self.oauth1_client_cls(framework, name, **kwargs)67 else:68 client = self.oauth2_client_cls(framework, name, **kwargs)69 70 self._clients[name] = client71 return client72 73 def register(self, name, overwrite=False, **kwargs):74 """Registers a new remote application.75 76 :param name: Name of the remote application.77 :param overwrite: Overwrite existing config with framework settings.78 :param kwargs: Parameters for :class:`RemoteApp`.79 80 Find parameters for the given remote app class. When a remote app is81 registered, it can be accessed with *named* attribute::82 83 oauth.register('twitter', client_id='', ...)84 oauth.twitter.get('timeline')85 """86 self._registry[name] = (overwrite, kwargs)87 return self.create_client(name)88 89 def generate_client_kwargs(self, name, overwrite, **kwargs):90 fetch_token = kwargs.pop('fetch_token', None)91 update_token = kwargs.pop('update_token', None)92 93 config = self.load_config(name, OAUTH_CLIENT_PARAMS)94 if config:95 kwargs = _config_client(config, kwargs, overwrite)96 97 if not fetch_token and self.fetch_token:98 fetch_token = functools.partial(self.fetch_token, name)99 100 kwargs['fetch_token'] = fetch_token101 102 if not kwargs.get('request_token_url'):103 if not update_token and self.update_token:104 update_token = functools.partial(self.update_token, name)105 106 kwargs['update_token'] = update_token107 return kwargs108 109 def load_config(self, name, params):110 return self.framework_integration_cls.load_config(self, name, params)111 112 def __getattr__(self, key):113 try:114 return object.__getattribute__(self, key)115 except AttributeError:116 if key in self._registry:117 return self.create_client(key)118 raise AttributeError('No such client: %s' % key)119 120 121def _config_client(config, kwargs, overwrite):122 for k in OAUTH_CLIENT_PARAMS:123 v = config.get(k, None)124 if k not in kwargs:125 kwargs[k] = v126 elif overwrite and v:127 if isinstance(kwargs[k], dict):128 kwargs[k].update(v)129 else:130 kwargs[k] = v131 return kwargs132 