diff --git a/flask_social/providers/linkedin.py b/flask_social/providers/linkedin.py new file mode 100644 index 0000000..7399431 --- /dev/null +++ b/flask_social/providers/linkedin.py @@ -0,0 +1,75 @@ +from __future__ import absolute_import + +from linkedin import linkedin +from linkedin.models import AccessToken + +config = { + 'id': 'linkedin', + 'name': 'LinkedIn', + 'install': 'pip install python-linkedin', + 'module': 'flask_social.providers.linkedin', + 'base_url': 'https://api.linkedin.com/', + 'request_token_url': None, + 'access_token_url': 'https://www.linkedin.com/uas/oauth2/accessToken', + 'authorize_url': 'https://www.linkedin.com/uas/oauth2/authorization', + 'access_token_params': { + 'grant_type': 'authorization_code' + }, + 'request_token_params': { + 'response_type': 'code', + 'scope': 'r_basicprofile r_emailaddress', + 'state': 'HSSRJKL02318akybgj857' + } +} + +selectors = 'id', 'first-name', 'last-name', 'email-address', 'site-standard-profile-request', 'picture-url' + + +def get_api(connection, **kwargs): + auth = linkedin.LinkedInAuthentication(kwargs.get('consumer_key'), + kwargs.get('consumer_secret'), + None, + linkedin.PERMISSIONS.enums.values()) + auth.token = AccessToken(getattr(connection, 'access_token'), getattr(connection, 'expires_in')) + api = linkedin.LinkedInApplication(auth) + return api + + +def get_provider_user_id(response, **kwargs): + if response: + auth = linkedin.LinkedInAuthentication(None, None, None, None) + auth.token = AccessToken(response['access_token'], response['expires_in']) + api = linkedin.LinkedInApplication(auth) + + profile = api.get_profile(selectors=selectors) + return profile['id'] + return None + + +def get_connection_values(response, **kwargs): + if not response: + return None + + access_token = response['access_token'] + + auth = linkedin.LinkedInAuthentication(None, None, None, None) + auth.token = AccessToken(response['access_token'], response['expires_in']) + api = linkedin.LinkedInApplication(auth) + profile = api.get_profile(selectors=selectors) + + profile_url = profile['siteStandardProfileRequest']['url'] + image_url = profile['pictureUrl'] + + + return dict( + provider_id=config['id'], + provider_user_id=profile['id'], + access_token=access_token, + secret=None, + display_name=profile['firstName'], + full_name = '%s %s' % (profile['firstName'], profile['lastName']), + profile_url=profile_url, + image_url=image_url + ) + + diff --git a/flask_social/utils.py b/flask_social/utils.py index 45c0609..cfb77b6 100644 --- a/flask_social/utils.py +++ b/flask_social/utils.py @@ -34,7 +34,9 @@ def get_authorize_callback(endpoint, provider_id): """ endpoint_prefix = config_value('BLUEPRINT_NAME') url = url_for(endpoint_prefix + '.' + endpoint, provider_id=provider_id) - return request.url_root[:-1] + url + #return request.url_root[:-1] + url + #when the application is running at http://domain.com/myapp above code redirects to http://domain.com/myapp/myapp... + return request.host_url[:-1] + url def get_connection_values_from_oauth_response(provider, oauth_response): diff --git a/flask_social/views.py b/flask_social/views.py index b8a58c2..05bf698 100644 --- a/flask_social/views.py +++ b/flask_social/views.py @@ -118,7 +118,14 @@ def connect_handler(cv, provider): :param provider_id: The provider ID the connection shoudl be made to """ cv.setdefault('user_id', current_user.get_id()) - connection = _datastore.find_connection(**cv) + #connection = _datastore.find_connection(**cv) + # As there are fields in the cv (like full_name) that are not in the connection document of the Mongo database, + # sending all the values in cv to create a query against the database fails + ctx = dict( + provider_id=cv["provider_id"], + provider_user_id=cv["provider_user_id"] + ) + connection = _datastore.find_connection(**ctx) if connection is None: after_this_request(_commit) @@ -163,7 +170,9 @@ def login_handler(response, provider, query): if connection: after_this_request(_commit) - user = connection.user + #user = connection.user + # Above code fails as the Mongoengine model definition of the 'Connection' class has 'user_id' as the ReferenceField to the 'User' class + user = connection.user_id login_user(user) key = _social.post_oauth_login_session_key redirect_url = session.pop(key, get_post_login_redirect())