From: Andrew Flegg Date: Tue, 8 Jun 2010 23:04:26 +0000 (+0100) Subject: Tidy up LinkedInApi so that it does authentication in conjunction with X-Git-Tag: 0.8.0~29^2~3 X-Git-Url: https://vcs.maemo.org/git/?p=hermes;a=commitdiff_plain;h=eccc132a8247f103ba6c14ee05b72ad333349b95 Tidy up LinkedInApi so that it does authentication in conjunction with the UI, and stores off the username (like Facebook does). --- diff --git a/package/src/org/maemo/hermes/engine/linkedin/api.py b/package/src/org/maemo/hermes/engine/linkedin/api.py index 0d9eb24..6eaf200 100644 --- a/package/src/org/maemo/hermes/engine/linkedin/api.py +++ b/package/src/org/maemo/hermes/engine/linkedin/api.py @@ -13,10 +13,12 @@ class LinkedInApi(): GCONF_API_KEY = '/apps/maemo/hermes/linkedin_key' GCONF_API_SECRET = '/apps/maemo/hermes/linkedin_secret' GCONF_ACCESS_TOKEN = '/apps/maemo/hermes/linkedin_access_token' + GCONF_USER = '/apps/maemo/hermes/linkedin_user' LI_SERVER = "api.linkedin.com" LI_API_URL = "https://api.linkedin.com" LI_CONN_API_URL = LI_API_URL + "/v1/people/~/connections" + LI_PROFILE_API_URL = LI_API_URL + "/v1/people/~" REQUEST_TOKEN_URL = LI_API_URL + "/uas/oauth/requestToken" AUTHORIZE_URL = LI_API_URL + "/uas/oauth/authorize" @@ -42,8 +44,6 @@ class LinkedInApi(): self.consumer = oauth.OAuthConsumer(api_key, secret_key) self.sig_method = oauth.OAuthSignatureMethod_HMAC_SHA1() - - self._verify_browser_command() # ----------------------------------------------------------------------- @@ -51,7 +51,7 @@ class LinkedInApi(): need_auth() token = self._get_request_token() url = self._get_authorize_url(token) - verifier = block_for_auth(True) + verifier = block_for_auth(url) self._verify_verifier(token, verifier) @@ -194,6 +194,10 @@ class LinkedInApi(): def _verify_verifier(self, request_token, verifier): try: self.access_token = self._get_access_token(request_token, verifier) + xml = self._make_api_request(self.LI_PROFILE_API_URL) + dom = parseString(xml) + friends = self._parse_dom(dom) + self._gc.set_string(LinkedInApi.GCONF_USER, friends[0].get_name()) except Exception, e: import traceback traceback.print_exc() @@ -201,15 +205,10 @@ class LinkedInApi(): # ----------------------------------------------------------------------- - def _verify_browser_command(self): - # -- Check the environment is going to work... - # FIXME: duplication - if (self._gc.get_string('/desktop/gnome/url-handlers/http/command') == 'epiphany %s'): - raise Exception('Browser in gconf invalid (see NB#136012). Installation error.') - - - # ----------------------------------------------------------------------- def _store_access_token_in_gconf(self, token_str): + if "oauth_problem" in token_str: + raise Exception("Authorization failure - access token reported OAuth problem") + self._gc.set_string(LinkedInApi.GCONF_ACCESS_TOKEN, token_str) @@ -220,9 +219,6 @@ class LinkedInApi(): token_str = self._gc.get_string(LinkedInApi.GCONF_ACCESS_TOKEN) if not token_str: return None - if "oauth_problem" in token_str: - self._store_access_token_in_gconf("") - raise Exception("Authorization failure - access token reported OAuth problem") return oauth.OAuthToken.from_string(token_str) @@ -230,4 +226,5 @@ class LinkedInApi(): def remove_access_token_from_gconf(self): """Remove the oauth.OAuthToken, if any.""" - self._gc.unset(LinkedInAPI.GCONF_ACCESS_TOKEN) + self._gc.unset(LinkedInApi.GCONF_ACCESS_TOKEN) + self._gc.unset(LinkedInApi.GCONF_USER) diff --git a/package/src/org/maemo/hermes/engine/linkedin/provider.py b/package/src/org/maemo/hermes/engine/linkedin/provider.py index f4f871a..a25db8b 100644 --- a/package/src/org/maemo/hermes/engine/linkedin/provider.py +++ b/package/src/org/maemo/hermes/engine/linkedin/provider.py @@ -1,6 +1,7 @@ import gnome.gconf import gobject, gtk, hildon import time, thread +import webbrowser import org.maemo.hermes.engine.provider import org.maemo.hermes.engine.linkedin.service from org.maemo.hermes.engine.linkedin.api import LinkedInApi @@ -27,6 +28,13 @@ class Provider(org.maemo.hermes.engine.provider.Provider): # ----------------------------------------------------------------------- + def get_account_detail(self): + """Return the name of the linked LinkedIn account.""" + + return self._gc.get_string(LinkedInApi.GCONF_USER) + + + # ----------------------------------------------------------------------- def has_preferences(self): """Whether or not this provider has any preferences. If it does not, open_preferences must NOT be called; as the behaviour is undetermined.""" @@ -38,20 +46,16 @@ class Provider(org.maemo.hermes.engine.provider.Provider): def open_preferences(self, parent): """Open the preferences for this provider as a child of the 'parent' widget.""" + self.main_window = parent api = LinkedInApi(gconf = self._gc) dialog = gtk.Dialog(self.get_name(), parent) dialog.add_button(_('Disable'), gtk.RESPONSE_NO) dialog.add_button(_('Enable'), gtk.RESPONSE_YES) - authenticated = api.get_access_token_from_gconf() is not None - title = authenticated and _("Clear authorisation") or _("Authorise") button = hildon.Button(gtk.HILDON_SIZE_FINGER_HEIGHT, - hildon.BUTTON_ARRANGEMENT_VERTICAL, - title = title) - if authenticated: - button.connect('clicked', lambda e: api.remove_access_token_from_gconf) - else: - button.connect('clicked', lambda e: api.authenticate(lambda: None, self.block_for_auth)) + hildon.BUTTON_ARRANGEMENT_VERTICAL) + self._handle_button(None, api, button) + button.connect('clicked', self._handle_button, api, button) dialog.vbox.add(gtk.Label("")) dialog.vbox.add(button) @@ -64,47 +68,44 @@ class Provider(org.maemo.hermes.engine.provider.Provider): return None return result == gtk.RESPONSE_YES - # FIXME: do auth: - # get request token - # get auth token - # open browser to have user allow data access - # user inputs the 5 char + + + # ----------------------------------------------------------------------- + def _handle_button(self, e, api, button): + """Ensure the button state is correct.""" + + authenticated = api.get_access_token_from_gconf() is not None + if e is not None: + if authenticated: + api.remove_access_token_from_gconf() + else: + api.authenticate(lambda: None, self.block_for_auth) + authenticated = api.get_access_token_from_gconf() is not None + + button.set_title(authenticated and _("Clear authorisation") or _("Authorise")) + # ----------------------------------------------------------------------- - def block_for_auth(self, prompt = True, main = False, lock = None): + def block_for_auth(self, url): """Part of the GUI callback API.""" - print "Get input:", prompt, main, lock - return "12345" -# if main: -# note = gtk.Dialog(_('Service authorisation'), self.main_window) -# note.add_button(_("Validate"), gtk.RESPONSE_OK) -# if prompt: -# input = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) -# input.set_property('is-focus', False) -# note.set_title(_("Verification code from web browser")) -# note.vbox.add(input) -# else: -# note.vbox.add(gtk.Label(_("\nPress 'Validate' once account has\nbeen authorised in web browser.\n"))) -# -# note.show_all() -# result = note.run() -# note.hide() -# lock.release() -# if prompt and result == gtk.RESPONSE_OK: -# print input.get_text() -# return input.get_text() -# else: -# return None -# -# else: -# time.sleep(2) -# lock = thread.allocate_lock() -# lock.acquire() -# gobject.idle_add(self.block_for_auth, prompt, True, lock) -# lock.acquire() -# lock.release() + webbrowser.open(url) + time.sleep(2) + note = gtk.Dialog(_('Service authorisation'), self.main_window) + note.add_button(_("Validate"), gtk.RESPONSE_OK) + input = hildon.Entry(gtk.HILDON_SIZE_FINGER_HEIGHT) + input.set_property('is-focus', False) + note.set_title(_("Verification code from web browser")) + note.vbox.add(input) + + note.show_all() + result = note.run() + note.hide() + if result == gtk.RESPONSE_OK: + return input.get_text() + else: + return None # -----------------------------------------------------------------------