def authorize(self): """Full application authorizaton process. This executes the four steps necessary for an application to authorize itself for odesk.com API access. The True or False is returned to indicate success or failure to authorize this process. """ if self.api_token: assert self.app_authorized return True debug, error, iam = log.debug, log.error, func() frob, api_token = self.frob, self.api_token api_sig = self.get_signature(caller=iam) if self.mode != 'web': # desktop (non-web) application # 1. login # This is the second login. First is near bottom of __init__. # Authorization fails without this second login. if not self.api_login(): return False # 2. get frob frob = self.get_api_frob(api_sig) if not frob: return False # 3. authorize if not self._authorize(frob): return False # 4. get token self.get_api_token(frob) return self.app_authorized else: raise AppAPIUnimplementedError("web authentication") url = get_auth_URL('auth') +\ self.get_api_keys_uri(api_sig, caller=iam) webbrowser.open(url)
def login(self, user, password): params = [('login',user), ('password',password), ('action','login')] url = get_auth_URL('login') + self.merge_params_to_uri(None, params, False) data = self.send_request(url, 'post', caller=func()) self.user_authorized = self.request_ok(data) if self.user_authorized: log.info("Logged in as {0:s}".format(user)) self.set_user_and_password(user, password) return self.user_authorized
def install_opener(self, user=None, passwd=None): """Install (add) an opener which handles authentication and cookies.""" if not (user and passwd): (user, passwd) = self.get_user_and_password() pm = urllib2.HTTPPasswordMgrWithDefaultRealm() pm.add_password(None, get_auth_URL('login'), user, passwd) self.cookie_jar = cookielib.LWPCookieJar() try: self.set_cookie_file(self.cookie_file) except OpenerError, e: e += "Unable to open cookie file" log.warn("{0:s}".format(str(e)))
def _authorize(self, frob): """Authorize this application for use with oDesk deveroper's API. If successfull an application signature is generated which must be used with all communication with the server requiring authentication. """ iam = func() assert frob api_sig = self.get_signature([('frob', frob)], caller=iam) url = get_auth_URL('auth') +\ self.merge_params_to_uri(self.get_api_keys_uri(api_sig, iam), [('do','agree'), ('frob', frob)]) data = self.send_request(url, 'post', caller=iam) self.app_authorized = self.request_ok(data) return self.app_authorized
def install_opener(cookie_file, user=None, passwd=None): """Install (add) an opener which handles authentication and cookies.""" if not (user and passwd): auth_file = path.join(path.expanduser('~'),'.auth/odesk/odesk_user') (user, passwd) = user_auth_from_file(auth_file) pm = urllib2.HTTPPasswordMgrWithDefaultRealm() pm.add_password(None, get_auth_URL('login'), user, passwd) cookie_jar = cookielib.LWPCookieJar() if cookie_file is None: cookie_file = 'cookies.txt' try: set_cookie_file(cookie_file) except OpenerError, e: e += "Unable to open cookie file" log.warn("{0:s}".format(str(e)))
def check_api_token(self): """Check if a token needs renewing or has enough permissions. Returns the token previously obtained with self.get_api_token(). """ iam = func() data = self.get_request(get_auth_URL('token'), caller=iam) if self.request_ok(data): api_token = xml_get_tag(data['ret'], 'token') if not api_token: stderr("warning- failed to get token- using old.\n", iam) else: self.api_token = api_token else: self.api_token = None # Otherwise we get back old (expired) token self.get_api_token(self.frob)
def get_api_frob(self, api_sig): """Retrieve the 'frob' token from the odesk server. This token lives 600s. """ iam = func() assert self.user_authorized assert api_sig if self.frob: return frob url = get_auth_URL('frobs') + self.get_api_keys_uri(api_sig, iam) log.debug('{0:s}: frob URI: {1:s}'.format(iam,url)) data = self.send_request(url, 'post', caller=iam) if not self.request_ok(data): return None frob = xml_get_tag(data['ret'], 'frob', unicode=False) log.debug("frob: {0:s}".format(frob)) if not frob: log.error("Failed to parse 'frob' from server response") else: self.frob = frob return frob
def auth_check(frob): uauthfile = path.join(path.expanduser('~'),'.auth/odesk/odesk_user') (user, passwd) = user_auth_from_file(uauthfile) aauthfile = path.join(path.expanduser('~'),'.auth/odesk/nonweb') cred = Credentials(uauthfile, aauthfile) (key, secret) = cred.get_consumer_cred() params = [('frob', frob)] api_sig = get_signature(key, secret, params) stdout("api_sig: {0:s}\n".format(api_sig)) api_keys_str = get_api_keys_uri(key, api_sig) stdout("api_keys_str: {0:s}\n".format(api_keys_str)) merged_params = merge_params_to_uri(api_keys_str, params) stdout("merged_params: {0:s}\n".format(merged_params)) url = get_auth_URL('tokens') + merged_params stdout("url: {0:s}\n".format(url))
def get_api_token(self, frob): """Retrieve the API token needed for odesk.com server communication. This is the token appended to all server requests. The 'frob' token must be available to aquire this token from the server. """ iam = func() self.api_token = self.get_token() if self.api_token: return self.api_token assert frob is not None params = [('frob', self.frob)] api_sig = self.get_signature(params, caller=iam) url = get_auth_URL('tokens') + \ self.merge_params_to_uri(self.get_api_keys_uri(api_sig, iam), params) log.debug("get_api_token(): url: {0:s}".format(url)) data = self.send_request(url, 'get', caller=iam) if self.request_ok(data): self.api_token = xml_get_tag(data['ret'], 'token') else: log.error("Unable to get API token.") if not self.api_token: raise AppAPITokenError("Unable to get API token.") return self.api_token
Example consumer. This is not recommended for production. Instead, you'll want to create your own subclass of Client or find one that works with your web framework. """ import httplib import time import odapi.oauth2 as oauth from odapi import app_auth_from_file from odapi.urls import get_auth_URL # settings for the local test consumer SERVER = "https://www.odesk.com" PORT = 8080 REQUEST_TOKEN_URL = get_auth_URL("request") ACCESS_TOKEN_URL = get_auth_URL("access") AUTHORIZATION_URL = get_auth_URL("auth") CALLBACK_URL = "http://printer.example.com/request_token_ready" RESOURCE_URL = "http://photos.example.net/photos" # key and secret granted by the service provider for this consumer application - same as the MockOAuthDataStore CONSUMER_KEY, CONSUMER_SECRET = app_auth_from_file("/home/tsinclair/.auth/odesk/nonweb") # example client using httplib with headers class SimpleClient(oauth.Client): def __init__(self, server, port=8083, request_token_url="", access_token_url="", authorization_url=""): self.server = server self.port = port self.request_token_url = request_token_url
def revoke_api_token(self): """Terminates a session.""" data = self.delete_request(get_auth_URL('token'), caller=func())