diff options
Diffstat (limited to 'app/lib/flickr_api/auth.py.bak')
-rw-r--r-- | app/lib/flickr_api/auth.py.bak | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/app/lib/flickr_api/auth.py.bak b/app/lib/flickr_api/auth.py.bak new file mode 100644 index 0000000..6536cca --- /dev/null +++ b/app/lib/flickr_api/auth.py.bak @@ -0,0 +1,334 @@ +""" + Authentication capabilities for the Flickr API. + + It implements the new authentication specifications of Flickr + based on OAuth. + + The authentication process is in 3 steps. + + - Authorisation request: + >>> a = AuthHandler(call_back_url) + >>> a.get_authorization_url('write') + print ('http://www.flickr.com/services/oauth/' + 'authorize?oauth_token=xxxx&perms=write') + + - The user gives his authorization at the url given by + 'get_authorization_url' and is redirected to the 'call_back_url' with + the `oauth_verifier` encoded in the url. This value can then be given to + the `AuthHandler`: + + >>> a.set_verifier("66455xxxxx") + + - The authorization handler can then be set for the python session + and will be automatically used when needed. + + >>> flickr_api.set_auth_handler(a) + + The authorization handler can also be saved and loaded: + >>> a.write(filename) + >>> a = AuthHandler.load(filename) + + Date: 06/08/2011 + Author: Alexis Mignon <alexis.mignon@gmail.com> + Author: Christoffer Viken <christoffer@viken.me> + +""" + +try: # fixes a reported bug. Seems that oauth can be packed in different ways. + from oauth import oauth +except ImportError: + import oauth + +import time +import urlparse +import urllib2 +from . import keys + +TOKEN_REQUEST_URL = "https://www.flickr.com/services/oauth/request_token" +AUTHORIZE_URL = "https://www.flickr.com/services/oauth/authorize" +ACCESS_TOKEN_URL = "https://www.flickr.com/services/oauth/access_token" + +AUTH_HANDLER = None + + +class AuthHandlerError(Exception): + pass + + +class AuthHandler(object): + def __init__(self, key=None, secret=None, callback=None, + access_token_key=None, access_token_secret=None, + request_token_key=None, request_token_secret=None): + + self.key = key or keys.API_KEY + self.secret = secret or keys.API_SECRET + + if self.key is None or self.secret is None: + raise ValueError("API keys have not been set.") + + if callback is None: + callback = ("https://api.flickr.com/services/rest/" + "?method=flickr.test.echo&api_key=%s" % self.key) + + params = { + 'oauth_timestamp': str(int(time.time())), + 'oauth_signature_method': "HMAC-SHA1", + 'oauth_version': "1.0", + 'oauth_callback': callback, + 'oauth_nonce': oauth.generate_nonce(), + 'oauth_consumer_key': self.key + } + + self.consumer = oauth.OAuthConsumer(key=self.key, secret=self.secret) + if (access_token_key is None) and (request_token_key is None): + req = oauth.OAuthRequest(http_method="GET", + http_url=TOKEN_REQUEST_URL, + parameters=params) + req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), + self.consumer, None) + resp = urllib2.urlopen(req.to_url()) + request_token = dict(urlparse.parse_qsl(resp.read())) + self.request_token = oauth.OAuthToken( + request_token['oauth_token'], + request_token['oauth_token_secret'] + ) + self.access_token = None + elif request_token_key is not None: + self.access_token = None + self.request_token = oauth.OAuthToken( + request_token_key, + request_token_secret + ) + else: + self.request_token = None + self.access_token = oauth.OAuthToken( + access_token_key, + access_token_secret + ) + + def get_authorization_url(self, perms='read'): + if self.request_token is None: + raise AuthHandlerError( + ("Request token is not defined. This ususally means that the" + " access token has been loaded from a file.") + ) + return "%s?oauth_token=%s&perms=%s" % ( + AUTHORIZE_URL, self.request_token.key, perms + ) + + def set_verifier(self, oauth_verifier): + if self.request_token is None: + raise AuthHandlerError( + ("Request token is not defined. " + "This ususally means that the access token has been loaded " + "from a file.") + ) + self.request_token.set_verifier(oauth_verifier) + + access_token_parms = { + 'oauth_consumer_key': self.key, + 'oauth_nonce': oauth.generate_nonce(), + 'oauth_signature_method': "HMAC-SHA1", + 'oauth_timestamp': str(int(time.time())), + 'oauth_token': self.request_token.key, + 'oauth_verifier': self.request_token.verifier + } + + req = oauth.OAuthRequest(http_method="GET", http_url=ACCESS_TOKEN_URL, + parameters=access_token_parms) + req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), + self.consumer, self.request_token) + resp = urllib2.urlopen(req.to_url()) + access_token_resp = dict(urlparse.parse_qsl(resp.read())) + self.access_token = oauth.OAuthToken( + access_token_resp["oauth_token"], + access_token_resp["oauth_token_secret"] + ) + + def complete_parameters(self, url, params={}, exclude_signature=[]): + + defaults = { + 'oauth_timestamp': str(int(time.time())), + 'oauth_nonce': oauth.generate_nonce(), + 'signature_method': "HMAC-SHA1", + 'oauth_token': self.access_token.key, + 'oauth_consumer_key': self.consumer.key, + } + + excluded = {} + for e in exclude_signature: + excluded[e] = params.pop(e) + + defaults.update(params) + req = oauth.OAuthRequest(http_method="POST", http_url=url, + parameters=defaults) + req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), self.consumer, + self.access_token) + req.parameters.update(excluded) + + return req + + def tofile(self, filename, include_api_keys=False): + """ saves authentication information to a file. + + Parameters: + ---------- + filename: str + The name of the file to which we save the information. + + include_api_keys: bool, optional (default False) + Should we include the api keys in the file ? For security issues, it + is recommanded not to save the API keys information in several places + and the default behaviour is thus not to save the API keys. +""" + if self.access_token is None: + raise AuthHandlerError("Access token not set yet.") + with open(filename, "w") as f: + if include_api_keys: + f.write("\n".join([self.key, self.secret, + self.access_token.key, self.access_token.secret])) + else: + f.write("\n".join([self.access_token.key, + self.access_token.secret])) + + def save(self, filename, include_api_keys=False): + self.tofile(filename, include_api_keys) + + def write(self, filename, include_api_keys=False): + self.tofile(filename, include_api_keys) + + def todict(self, include_api_keys=False): + """ + Dumps the auth object to a dict, + Optional inclusion of API-keys, in case you are using multiple. + - include_api_keys: Whether API-keys should be included, False if you + have control of them. + """ + if self.access_token is not None: + dump = {'access_token_key': self.access_token.key, + 'access_token_secret': self.access_token.secret} + else: + dump = {'request_token_key': self.request_token.key, + 'request_token_secret': self.request_token.secret} + if include_api_keys: + dump['api_key'] = self.key + dump['api_secret'] = self.secret + return dump + + @staticmethod + def load(filename, set_api_keys=False): + """ Load authentication information from a file. + + Parameters + ---------- + filename: str + The file in which authentication information is stored. + + set_api_keys: bool, optional (default False) + If API keys are found in the file, should we use them to set the + API keys globally. + Default is False. The API keys should be stored separately from + authentication information. The recommanded way is to use a + `flickr_keys.py` file. Setting `set_api_keys=True` should be considered + as a conveniency only for single user settings. +""" + return AuthHandler.fromfile(filename, set_api_keys) + + @staticmethod + def fromfile(filename, set_api_keys=False): + """ Load authentication information from a file. + + Parameters + ---------- + filename: str + The file in which authentication information is stored. + + set_api_keys: bool, optional (default False) + If API keys are found in the file, should we use them to set the + API keys globally. + Default is False. The API keys should be stored separately from + authentication information. The recommanded way is to use a + `flickr_keys.py` file. Setting `set_api_keys=True` should be considered + as a conveniency only for single user settings. +""" + with open(filename, "r") as f: + keys_info = f.read().split("\n") + try: + key, secret, access_key, access_secret = keys_info + if set_api_keys: + keys.set_keys(api_key=key, api_secret=secret) + except ValueError: + access_key, access_secret = keys_info + key = keys.API_KEY + secret = keys.API_SECRET + return AuthHandler(key, secret, access_token_key=access_key, + access_token_secret=access_secret) + + @staticmethod + def fromdict(input_dict): + """ + Loads an auth object from a dict. + Structure identical to dict returned by todict + - input_dict: Dictionary to build from + """ + access_key, access_secret = None, None + request_token_key, request_token_secret = None, None + try: + if 'api_key' in input_dict: + key = input_dict['api_key'] + secret = input_dict['api_secret'] + else: + key = keys.API_KEY + secret = keys.API_SECRET + if 'access_token_key' in input_dict: + access_key = input_dict['access_token_key'] + access_secret = input_dict['access_token_secret'] + elif 'request_token_key' in input_dict: + request_token_key = input_dict['request_token_key'] + request_token_secret = input_dict['request_token_secret'] + except Exception: + raise AuthHandlerError("Error occurred while processing data") + + return AuthHandler(key, secret, access_token_key=access_key, + access_token_secret=access_secret, + request_token_key=request_token_key, + request_token_secret=request_token_secret) + + @staticmethod + def create(access_key, access_secret): + return AuthHandler(access_token_key=access_key, + access_token_secret=access_secret) + + +def token_factory(filename=None, token_key=None, token_secret=None): + if filename is None: + if (token_key is None) or (token_secret is None): + raise ValueError("token_secret and token_key cannot be None") + return AuthHandler.create(token_key, token_secret) + else: + return AuthHandler.load(filename) + + +def set_auth_handler(auth_handler, set_api_keys=False): + """ Set the authentication handler globally. + + Parameters + ---------- + auth_handler: AuthHandler object or str + If a string is given, it corresponds to the file in which + authentication information is stored. + + set_api_keys: bool, optional (default False) + If API keys are found in the file, should we use them to set the + API keys globally. + Default is False. The API keys should be stored separately from + authentication information. The recommanded way is to use a + `flickr_keys.py` file. Setting `set_api_keys=True` should be considered + as a conveniency only for single user settings. + """ + global AUTH_HANDLER + if isinstance(auth_handler, basestring): + ah = AuthHandler.load(auth_handler, set_api_keys) + set_auth_handler(ah) + else: + AUTH_HANDLER = auth_handler |