Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / target / linkedin.py @ 5bc77346

History | View | Annotate | Download (6.3 kB)

1 74796dd8 Kostas Papadimitriou
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 74796dd8 Kostas Papadimitriou
#
3 74796dd8 Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 74796dd8 Kostas Papadimitriou
# without modification, are permitted provided that the following
5 74796dd8 Kostas Papadimitriou
# conditions are met:
6 74796dd8 Kostas Papadimitriou
#
7 74796dd8 Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 74796dd8 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 74796dd8 Kostas Papadimitriou
#      disclaimer.
10 74796dd8 Kostas Papadimitriou
#
11 74796dd8 Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 74796dd8 Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 74796dd8 Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 74796dd8 Kostas Papadimitriou
#      provided with the distribution.
15 74796dd8 Kostas Papadimitriou
#
16 74796dd8 Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 74796dd8 Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 74796dd8 Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 74796dd8 Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 74796dd8 Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 74796dd8 Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 74796dd8 Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 74796dd8 Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 74796dd8 Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 74796dd8 Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 74796dd8 Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 74796dd8 Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 74796dd8 Kostas Papadimitriou
#
29 74796dd8 Kostas Papadimitriou
# The views and conclusions contained in the software and
30 74796dd8 Kostas Papadimitriou
# documentation are those of the authors and should not be
31 74796dd8 Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 74796dd8 Kostas Papadimitriou
# or implied, of GRNET S.A.
33 74796dd8 Kostas Papadimitriou
34 74796dd8 Kostas Papadimitriou
import json
35 3c5a2b21 Kostas Papadimitriou
import logging
36 3c5a2b21 Kostas Papadimitriou
import oauth2 as oauth
37 3c5a2b21 Kostas Papadimitriou
import cgi
38 74796dd8 Kostas Papadimitriou
39 74796dd8 Kostas Papadimitriou
from django.contrib import messages
40 74796dd8 Kostas Papadimitriou
from django.views.decorators.http import require_http_methods
41 74796dd8 Kostas Papadimitriou
from django.http import HttpResponseRedirect
42 74796dd8 Kostas Papadimitriou
from django.core.urlresolvers import reverse
43 3c5a2b21 Kostas Papadimitriou
from django.conf import settings as django_settings
44 74796dd8 Kostas Papadimitriou
45 3e0a032d Sofia Papagiannaki
from astakos.im.models import AstakosUser
46 74796dd8 Kostas Papadimitriou
from astakos.im import settings
47 3e0a032d Sofia Papagiannaki
from astakos.im.views.target import get_pending_key, \
48 3c5a2b21 Kostas Papadimitriou
    handle_third_party_signup, handle_third_party_login, \
49 3c5a2b21 Kostas Papadimitriou
    init_third_party_session
50 3e0a032d Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, \
51 70e11eaa Sofia Papagiannaki
    requires_auth_provider
52 74796dd8 Kostas Papadimitriou
53 74796dd8 Kostas Papadimitriou
logger = logging.getLogger(__name__)
54 74796dd8 Kostas Papadimitriou
55 74796dd8 Kostas Papadimitriou
56 3c5a2b21 Kostas Papadimitriou
def django_setting(key, default):
57 3c5a2b21 Kostas Papadimitriou
    return getattr(django_settings, 'GOOGLE_%s' % key.upper, default)
58 74796dd8 Kostas Papadimitriou
59 3c5a2b21 Kostas Papadimitriou
token_scope = 'r_basicprofile+r_emailaddress'
60 3c5a2b21 Kostas Papadimitriou
request_token_url = django_setting(
61 3c5a2b21 Kostas Papadimitriou
    'request_token_url',
62 3c5a2b21 Kostas Papadimitriou
    'https://api.linkedin.com/uas/oauth/requestToken?scope=' + token_scope)
63 3c5a2b21 Kostas Papadimitriou
access_token_url = django_setting(
64 3c5a2b21 Kostas Papadimitriou
    'access_token_url',
65 3c5a2b21 Kostas Papadimitriou
    'https://api.linkedin.com/uas/oauth/accessToken')
66 3c5a2b21 Kostas Papadimitriou
authenticate_url = django_setting(
67 3c5a2b21 Kostas Papadimitriou
    'authenticate_url',
68 3c5a2b21 Kostas Papadimitriou
    'https://www.linkedin.com/uas/oauth/authorize')
69 74796dd8 Kostas Papadimitriou
70 74796dd8 Kostas Papadimitriou
71 9d20fe23 Kostas Papadimitriou
@requires_auth_provider('linkedin')
72 74796dd8 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
73 222305b7 Sofia Papagiannaki
@cookie_fix
74 74796dd8 Kostas Papadimitriou
def login(request):
75 0e79735c Kostas Papadimitriou
    init_third_party_session(request)
76 93614ef0 Kostas Papadimitriou
    consumer = oauth.Consumer(settings.LINKEDIN_TOKEN,
77 93614ef0 Kostas Papadimitriou
                              settings.LINKEDIN_SECRET)
78 93614ef0 Kostas Papadimitriou
    client = oauth.Client(consumer)
79 74796dd8 Kostas Papadimitriou
    resp, content = client.request(request_token_url, "GET")
80 74796dd8 Kostas Papadimitriou
    if resp['status'] != '200':
81 74796dd8 Kostas Papadimitriou
        messages.error(request, 'Invalid linkedin response')
82 74796dd8 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
83 74796dd8 Kostas Papadimitriou
84 74796dd8 Kostas Papadimitriou
    request_token = dict(cgi.parse_qsl(content))
85 74796dd8 Kostas Papadimitriou
    request.session['request_token'] = request_token
86 74796dd8 Kostas Papadimitriou
87 93614ef0 Kostas Papadimitriou
    url = request_token.get('xoauth_request_auth_url') + \
88 93614ef0 Kostas Papadimitriou
        "?oauth_token=%s" % request_token.get('oauth_token')
89 74796dd8 Kostas Papadimitriou
90 dd5f8f4d Kostas Papadimitriou
    if request.GET.get('key', None):
91 dd5f8f4d Kostas Papadimitriou
        request.session['pending_key'] = request.GET.get('key')
92 dd5f8f4d Kostas Papadimitriou
93 64492c49 Kostas Papadimitriou
    if request.GET.get('next', None):
94 64492c49 Kostas Papadimitriou
        request.session['next_url'] = request.GET.get('next')
95 64492c49 Kostas Papadimitriou
96 74796dd8 Kostas Papadimitriou
    return HttpResponseRedirect(url)
97 74796dd8 Kostas Papadimitriou
98 74796dd8 Kostas Papadimitriou
99 74796dd8 Kostas Papadimitriou
@requires_auth_provider('linkedin', login=True)
100 74796dd8 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
101 222305b7 Sofia Papagiannaki
@cookie_fix
102 74796dd8 Kostas Papadimitriou
def authenticated(
103 74796dd8 Kostas Papadimitriou
    request,
104 74796dd8 Kostas Papadimitriou
    template='im/third_party_check_local.html',
105 7beef200 Kostas Papadimitriou
    extra_context=None
106 74796dd8 Kostas Papadimitriou
):
107 74796dd8 Kostas Papadimitriou
108 7beef200 Kostas Papadimitriou
    if extra_context is None:
109 7beef200 Kostas Papadimitriou
        extra_context = {}
110 7beef200 Kostas Papadimitriou
111 9d20fe23 Kostas Papadimitriou
    consumer = oauth.Consumer(settings.LINKEDIN_TOKEN,
112 9d20fe23 Kostas Papadimitriou
                              settings.LINKEDIN_SECRET)
113 9d20fe23 Kostas Papadimitriou
    client = oauth.Client(consumer)
114 9d20fe23 Kostas Papadimitriou
115 74796dd8 Kostas Papadimitriou
    if request.GET.get('denied'):
116 74796dd8 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
117 74796dd8 Kostas Papadimitriou
118 74796dd8 Kostas Papadimitriou
    if not 'request_token' in request.session:
119 74796dd8 Kostas Papadimitriou
        messages.error(request, 'linkedin handshake failed')
120 74796dd8 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
121 74796dd8 Kostas Papadimitriou
122 74796dd8 Kostas Papadimitriou
    token = oauth.Token(request.session['request_token']['oauth_token'],
123 8fb8d0cf Giorgos Korfiatis
                        request.session['request_token']['oauth_token_secret'])
124 74796dd8 Kostas Papadimitriou
    token.set_verifier(request.GET.get('oauth_verifier'))
125 74796dd8 Kostas Papadimitriou
    client = oauth.Client(consumer, token)
126 74796dd8 Kostas Papadimitriou
    resp, content = client.request(access_token_url, "POST")
127 74796dd8 Kostas Papadimitriou
    if resp['status'] != '200':
128 74796dd8 Kostas Papadimitriou
        try:
129 74796dd8 Kostas Papadimitriou
            del request.session['request_token']
130 74796dd8 Kostas Papadimitriou
        except:
131 74796dd8 Kostas Papadimitriou
            pass
132 74796dd8 Kostas Papadimitriou
        messages.error(request, 'Invalid linkedin token response')
133 74796dd8 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
134 74796dd8 Kostas Papadimitriou
    access_token = dict(cgi.parse_qsl(content))
135 74796dd8 Kostas Papadimitriou
136 74796dd8 Kostas Papadimitriou
    token = oauth.Token(access_token['oauth_token'],
137 8fb8d0cf Giorgos Korfiatis
                        access_token['oauth_token_secret'])
138 74796dd8 Kostas Papadimitriou
    client = oauth.Client(consumer, token)
139 8fb8d0cf Giorgos Korfiatis
    _url = ("http://api.linkedin.com/v1/people/~:(id,first-name,last-name,"
140 8fb8d0cf Giorgos Korfiatis
            "industry,email-address)?format=json")
141 8fb8d0cf Giorgos Korfiatis
    resp, content = client.request(_url, "GET")
142 74796dd8 Kostas Papadimitriou
    if resp['status'] != '200':
143 74796dd8 Kostas Papadimitriou
        try:
144 74796dd8 Kostas Papadimitriou
            del request.session['request_token']
145 74796dd8 Kostas Papadimitriou
        except:
146 74796dd8 Kostas Papadimitriou
            pass
147 74796dd8 Kostas Papadimitriou
        messages.error(request, 'Invalid linkedin profile response')
148 74796dd8 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
149 74796dd8 Kostas Papadimitriou
150 74796dd8 Kostas Papadimitriou
    profile_data = json.loads(content)
151 74796dd8 Kostas Papadimitriou
    userid = profile_data['id']
152 74796dd8 Kostas Papadimitriou
    username = profile_data.get('emailAddress', None)
153 8fb8d0cf Giorgos Korfiatis
    realname = profile_data.get('firstName', '') + ' ' + profile_data.get(
154 8fb8d0cf Giorgos Korfiatis
        'lastName', '')
155 74796dd8 Kostas Papadimitriou
    provider_info = profile_data
156 dd5f8f4d Kostas Papadimitriou
    affiliation = 'LinkedIn.com'
157 dd5f8f4d Kostas Papadimitriou
158 74796dd8 Kostas Papadimitriou
    try:
159 c8d89a3c Kostas Papadimitriou
        return handle_third_party_login(request, 'linkedin', userid,
160 c8d89a3c Kostas Papadimitriou
                                        provider_info, affiliation)
161 74796dd8 Kostas Papadimitriou
    except AstakosUser.DoesNotExist, e:
162 c8d89a3c Kostas Papadimitriou
        third_party_key = get_pending_key(request)
163 dd5f8f4d Kostas Papadimitriou
        user_info = {'affiliation': affiliation, 'realname': realname}
164 dd5f8f4d Kostas Papadimitriou
        return handle_third_party_signup(request, userid, 'linkedin',
165 dd5f8f4d Kostas Papadimitriou
                                         third_party_key,
166 dd5f8f4d Kostas Papadimitriou
                                         provider_info,
167 dd5f8f4d Kostas Papadimitriou
                                         user_info,
168 dd5f8f4d Kostas Papadimitriou
                                         template,
169 dd5f8f4d Kostas Papadimitriou
                                         extra_context)