Revision 74796dd8
b/snf-astakos-app/astakos/im/auth_providers.py | ||
---|---|---|
151 | 151 |
def extra_actions(self): |
152 | 152 |
return [(_('Change password'), reverse('password_change')), ] |
153 | 153 |
|
154 |
|
|
154 | 155 |
class LDAPAuthProvider(AuthProvider): |
155 | 156 |
module = 'ldap' |
156 | 157 |
title = _('LDAP credentials') |
... | ... | |
188 | 189 |
class TwitterAuthProvider(AuthProvider): |
189 | 190 |
module = 'twitter' |
190 | 191 |
title = _('Twitter') |
191 |
description = _('Allows you to login to your account using your twitter '
|
|
192 |
'account')
|
|
192 |
description = _('Allows you to login to your account using your Twitter '
|
|
193 |
'credentials')
|
|
193 | 194 |
add_prompt = _('Connect with your Twitter account.') |
194 | 195 |
details_tpl = _('Twitter screen name: %(info_screen_name)s') |
195 | 196 |
user_title = _('Twitter (%(info_screen_name)s)') |
... | ... | |
201 | 202 |
login_template = 'im/auth/twitter_login.html' |
202 | 203 |
login_prompt_template = 'im/auth/twitter_login_prompt.html' |
203 | 204 |
|
205 |
|
|
206 |
class GoogleAuthProvider(AuthProvider): |
|
207 |
module = 'google' |
|
208 |
title = _('Google') |
|
209 |
description = _('Allows you to login to your account using your Google ' |
|
210 |
'credentials') |
|
211 |
add_prompt = _('Connect with your Google account.') |
|
212 |
details_tpl = _('Google account: %(info_email)s') |
|
213 |
user_title = _('Google (%(info_email)s)') |
|
214 |
|
|
215 |
@property |
|
216 |
def add_url(self): |
|
217 |
return reverse('astakos.im.target.google.login') |
|
218 |
|
|
219 |
login_template = 'im/auth/third_party_provider_generic_login.html' |
|
220 |
login_prompt_template = 'im/auth/third_party_provider_generic_login_prompt.html' |
|
221 |
|
|
222 |
|
|
223 |
class LinkedInAuthProvider(AuthProvider): |
|
224 |
module = 'linkedin' |
|
225 |
title = _('LinkedIn') |
|
226 |
description = _('Allows you to login to your account using your LinkedIn ' |
|
227 |
'credentials') |
|
228 |
add_prompt = _('Connect with your LinkedIn account.') |
|
229 |
details_tpl = _('LinkedIn account: %(info_emailAddress)s') |
|
230 |
user_title = _('LinkedIn (%(info_emailAddress)s)') |
|
231 |
|
|
232 |
@property |
|
233 |
def add_url(self): |
|
234 |
return reverse('astakos.im.target.linkedin.login') |
|
235 |
|
|
236 |
login_template = 'im/auth/third_party_provider_generic_login.html' |
|
237 |
login_prompt_template = 'im/auth/third_party_provider_generic_login_prompt.html' |
|
238 |
|
|
239 |
|
|
204 | 240 |
def get_provider(id, user_obj=None, default=None): |
205 | 241 |
""" |
206 | 242 |
Return a provider instance from the auth providers registry. |
b/snf-astakos-app/astakos/im/settings.py | ||
---|---|---|
10 | 10 |
TWITTER_AUTH_FORCE_LOGIN = getattr(settings, 'ASTAKOS_TWITTER_AUTH_FORCE_LOGIN', |
11 | 11 |
False) |
12 | 12 |
|
13 |
|
|
14 |
# OAuth2 Google credentials. |
|
15 |
GOOGLE_CLIENT_ID = getattr(settings, 'ASTAKOS_GOOGLE_CLIENT_ID', '') |
|
16 |
GOOGLE_SECRET = getattr(settings, 'ASTAKOS_GOOGLE_SECRET', '') |
|
17 |
|
|
18 |
# OAuth2 LinkedIn credentials. |
|
19 |
LINKEDIN_TOKEN = getattr(settings, 'ASTAKOS_LINKEDIN_TOKEN', '') |
|
20 |
LINKEDIN_SECRET = getattr(settings, 'ASTAKOS_LINKEDIN_SECRET', '') |
|
21 |
|
|
13 | 22 |
DEFAULT_USER_LEVEL = getattr(settings, 'ASTAKOS_DEFAULT_USER_LEVEL', 4) |
14 | 23 |
|
15 | 24 |
INVITATIONS_PER_LEVEL = getattr(settings, 'ASTAKOS_INVITATIONS_PER_LEVEL', { |
b/snf-astakos-app/astakos/im/target/google.py | ||
---|---|---|
1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
import json |
|
35 |
|
|
36 |
from django.http import HttpResponseBadRequest |
|
37 |
from django.utils.translation import ugettext as _ |
|
38 |
from django.contrib import messages |
|
39 |
from django.template import RequestContext |
|
40 |
from django.views.decorators.http import require_http_methods |
|
41 |
from django.http import HttpResponseRedirect |
|
42 |
from django.core.urlresolvers import reverse |
|
43 |
from django.core.exceptions import ImproperlyConfigured |
|
44 |
from django.shortcuts import get_object_or_404 |
|
45 |
|
|
46 |
from urlparse import urlunsplit, urlsplit |
|
47 |
|
|
48 |
from astakos.im.util import prepare_response, get_context |
|
49 |
from astakos.im.views import requires_anonymous, render_response, \ |
|
50 |
requires_auth_provider |
|
51 |
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL |
|
52 |
from astakos.im.models import AstakosUser, PendingThirdPartyUser |
|
53 |
from astakos.im.forms import LoginForm |
|
54 |
from astakos.im.activation_backends import get_backend, SimpleBackend |
|
55 |
from astakos.im import settings |
|
56 |
from astakos.im import auth_providers |
|
57 |
|
|
58 |
import logging |
|
59 |
import time |
|
60 |
import astakos.im.messages as astakos_messages |
|
61 |
import urlparse |
|
62 |
import urllib |
|
63 |
|
|
64 |
logger = logging.getLogger(__name__) |
|
65 |
|
|
66 |
import oauth2 as oauth |
|
67 |
import cgi |
|
68 |
|
|
69 |
signature_method = oauth.SignatureMethod_HMAC_SHA1() |
|
70 |
|
|
71 |
OAUTH_CONSUMER_KEY = settings.GOOGLE_CLIENT_ID |
|
72 |
OAUTH_CONSUMER_SECRET = settings.GOOGLE_SECRET |
|
73 |
|
|
74 |
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY, secret=OAUTH_CONSUMER_SECRET) |
|
75 |
client = oauth.Client(consumer) |
|
76 |
|
|
77 |
token_scope = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email' |
|
78 |
authenticate_url = 'https://accounts.google.com/o/oauth2/auth' |
|
79 |
access_token_url = 'https://www.googleapis.com/oauth2/v1/tokeninfo' |
|
80 |
request_token_url = 'https://accounts.google.com/o/oauth2/token' |
|
81 |
|
|
82 |
|
|
83 |
def get_redirect_uri(): |
|
84 |
return "%s%s" % (settings.BASEURL, |
|
85 |
reverse('astakos.im.target.google.authenticated')) |
|
86 |
|
|
87 |
@requires_auth_provider('google', login=True) |
|
88 |
@require_http_methods(["GET", "POST"]) |
|
89 |
def login(request): |
|
90 |
params = { |
|
91 |
'scope': token_scope, |
|
92 |
'response_type': 'code', |
|
93 |
'redirect_uri': get_redirect_uri(), |
|
94 |
'client_id': settings.GOOGLE_CLIENT_ID |
|
95 |
} |
|
96 |
url = "%s?%s" % (authenticate_url, urllib.urlencode(params)) |
|
97 |
return HttpResponseRedirect(url) |
|
98 |
|
|
99 |
|
|
100 |
@requires_auth_provider('google', login=True) |
|
101 |
@require_http_methods(["GET", "POST"]) |
|
102 |
def authenticated( |
|
103 |
request, |
|
104 |
template='im/third_party_check_local.html', |
|
105 |
extra_context={} |
|
106 |
): |
|
107 |
|
|
108 |
# TODO: Handle errors, e.g. error=access_denied |
|
109 |
try: |
|
110 |
code = request.GET.get('code', None) |
|
111 |
params = { |
|
112 |
'code': code, |
|
113 |
'client_id': settings.GOOGLE_CLIENT_ID, |
|
114 |
'client_secret': settings.GOOGLE_SECRET, |
|
115 |
'redirect_uri': get_redirect_uri(), |
|
116 |
'grant_type': 'authorization_code' |
|
117 |
} |
|
118 |
get_token_url = "%s" % (request_token_url,) |
|
119 |
resp, content = client.request(get_token_url, "POST", |
|
120 |
body=urllib.urlencode(params)) |
|
121 |
token = json.loads(content).get('access_token', None) |
|
122 |
|
|
123 |
resp, content = client.request("%s?access_token=%s" % (access_token_url, |
|
124 |
token) , "GET") |
|
125 |
access_token_data = json.loads(content) |
|
126 |
except Exception, e: |
|
127 |
messages.error(request, 'Invalid Google response. Please contact support') |
|
128 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
129 |
|
|
130 |
userid = access_token_data['user_id'] |
|
131 |
username = access_token_data.get('email', None) |
|
132 |
provider_info = access_token_data |
|
133 |
affiliation = 'Google.com' |
|
134 |
|
|
135 |
# an existing user accessed the view |
|
136 |
if request.user.is_authenticated(): |
|
137 |
if request.user.has_auth_provider('google', identifier=userid): |
|
138 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
139 |
|
|
140 |
# automatically add eppn provider to user |
|
141 |
user = request.user |
|
142 |
if not request.user.can_add_auth_provider('google', |
|
143 |
identifier=userid): |
|
144 |
messages.error(request, _(astakos_messages.AUTH_PROVIDER_ADD_FAILED) + |
|
145 |
u' ' + _(astakos_messages.AUTH_PROVIDER_ADD_EXISTS)) |
|
146 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
147 |
|
|
148 |
user.add_auth_provider('google', identifier=userid, |
|
149 |
affiliation=affiliation, |
|
150 |
provider_info=provider_info) |
|
151 |
messages.success(request, astakos_messages.AUTH_PROVIDER_ADDED) |
|
152 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
153 |
|
|
154 |
try: |
|
155 |
# astakos user exists ? |
|
156 |
user = AstakosUser.objects.get_auth_provider_user( |
|
157 |
'google', |
|
158 |
identifier=userid |
|
159 |
) |
|
160 |
if user.is_active: |
|
161 |
# authenticate user |
|
162 |
response = prepare_response(request, |
|
163 |
user, |
|
164 |
request.GET.get('next'), |
|
165 |
'renew' in request.GET) |
|
166 |
response.set_cookie('astakos_last_login_method', 'google') |
|
167 |
return response |
|
168 |
else: |
|
169 |
message = user.get_inactive_message() |
|
170 |
messages.error(request, message) |
|
171 |
return HttpResponseRedirect(reverse('login')) |
|
172 |
|
|
173 |
except AstakosUser.DoesNotExist, e: |
|
174 |
provider = auth_providers.get_provider('google') |
|
175 |
if not provider.is_available_for_create(): |
|
176 |
messages.error(request, |
|
177 |
_(astakos_messages.AUTH_PROVIDER_NOT_ACTIVE) % provider.get_title_display) |
|
178 |
return HttpResponseRedirect(reverse('login')) |
|
179 |
|
|
180 |
# eppn not stored in astakos models, create pending profile |
|
181 |
user, created = PendingThirdPartyUser.objects.get_or_create( |
|
182 |
third_party_identifier=userid, |
|
183 |
provider='google', |
|
184 |
) |
|
185 |
# update pending user |
|
186 |
user.affiliation = affiliation |
|
187 |
user.info = json.dumps(provider_info) |
|
188 |
user.generate_token() |
|
189 |
user.save() |
|
190 |
|
|
191 |
extra_context['provider'] = 'google' |
|
192 |
extra_context['provider_title'] = 'google' |
|
193 |
extra_context['token'] = user.token |
|
194 |
extra_context['signup_url'] = reverse('signup') + \ |
|
195 |
"?third_party_token=%s" % user.token |
|
196 |
|
|
197 |
return render_response( |
|
198 |
template, |
|
199 |
context_instance=get_context(request, extra_context) |
|
200 |
) |
|
201 |
|
|
202 |
|
b/snf-astakos-app/astakos/im/target/linkedin.py | ||
---|---|---|
1 |
# Copyright 2011-2012 GRNET S.A. All rights reserved. |
|
2 |
# |
|
3 |
# Redistribution and use in source and binary forms, with or |
|
4 |
# without modification, are permitted provided that the following |
|
5 |
# conditions are met: |
|
6 |
# |
|
7 |
# 1. Redistributions of source code must retain the above |
|
8 |
# copyright notice, this list of conditions and the following |
|
9 |
# disclaimer. |
|
10 |
# |
|
11 |
# 2. Redistributions in binary form must reproduce the above |
|
12 |
# copyright notice, this list of conditions and the following |
|
13 |
# disclaimer in the documentation and/or other materials |
|
14 |
# provided with the distribution. |
|
15 |
# |
|
16 |
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
# POSSIBILITY OF SUCH DAMAGE. |
|
28 |
# |
|
29 |
# The views and conclusions contained in the software and |
|
30 |
# documentation are those of the authors and should not be |
|
31 |
# interpreted as representing official policies, either expressed |
|
32 |
# or implied, of GRNET S.A. |
|
33 |
|
|
34 |
import json |
|
35 |
|
|
36 |
from django.http import HttpResponseBadRequest |
|
37 |
from django.utils.translation import ugettext as _ |
|
38 |
from django.contrib import messages |
|
39 |
from django.template import RequestContext |
|
40 |
from django.views.decorators.http import require_http_methods |
|
41 |
from django.http import HttpResponseRedirect |
|
42 |
from django.core.urlresolvers import reverse |
|
43 |
from django.core.exceptions import ImproperlyConfigured |
|
44 |
from django.shortcuts import get_object_or_404 |
|
45 |
|
|
46 |
from urlparse import urlunsplit, urlsplit |
|
47 |
|
|
48 |
from astakos.im.util import prepare_response, get_context |
|
49 |
from astakos.im.views import requires_anonymous, render_response, \ |
|
50 |
requires_auth_provider |
|
51 |
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL |
|
52 |
from astakos.im.models import AstakosUser, PendingThirdPartyUser |
|
53 |
from astakos.im.forms import LoginForm |
|
54 |
from astakos.im.activation_backends import get_backend, SimpleBackend |
|
55 |
from astakos.im import settings |
|
56 |
from astakos.im import auth_providers |
|
57 |
|
|
58 |
import astakos.im.messages as astakos_messages |
|
59 |
|
|
60 |
import logging |
|
61 |
|
|
62 |
logger = logging.getLogger(__name__) |
|
63 |
|
|
64 |
import oauth2 as oauth |
|
65 |
import cgi |
|
66 |
|
|
67 |
consumer = oauth.Consumer(settings.LINKEDIN_TOKEN, settings.LINKEDIN_SECRET) |
|
68 |
client = oauth.Client(consumer) |
|
69 |
|
|
70 |
request_token_url = 'https://api.linkedin.com/uas/oauth/requestToken?scope=r_basicprofile+r_emailaddress' |
|
71 |
access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken' |
|
72 |
authenticate_url = 'https://www.linkedin.com/uas/oauth/authorize' |
|
73 |
|
|
74 |
|
|
75 |
@requires_auth_provider('linkedin', login=True) |
|
76 |
@require_http_methods(["GET", "POST"]) |
|
77 |
def login(request): |
|
78 |
resp, content = client.request(request_token_url, "GET") |
|
79 |
if resp['status'] != '200': |
|
80 |
messages.error(request, 'Invalid linkedin response') |
|
81 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
82 |
|
|
83 |
print "111111111111", "RESP", "CONTENT", resp, content |
|
84 |
request_token = dict(cgi.parse_qsl(content)) |
|
85 |
print request_token |
|
86 |
request.session['request_token'] = request_token |
|
87 |
|
|
88 |
url = request_token.get('xoauth_request_auth_url') + "?oauth_token=%s" % request_token.get('oauth_token') |
|
89 |
|
|
90 |
return HttpResponseRedirect(url) |
|
91 |
|
|
92 |
|
|
93 |
@requires_auth_provider('linkedin', login=True) |
|
94 |
@require_http_methods(["GET", "POST"]) |
|
95 |
def authenticated( |
|
96 |
request, |
|
97 |
template='im/third_party_check_local.html', |
|
98 |
extra_context={} |
|
99 |
): |
|
100 |
|
|
101 |
if request.GET.get('denied'): |
|
102 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
103 |
|
|
104 |
if not 'request_token' in request.session: |
|
105 |
messages.error(request, 'linkedin handshake failed') |
|
106 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
107 |
|
|
108 |
token = oauth.Token(request.session['request_token']['oauth_token'], |
|
109 |
request.session['request_token']['oauth_token_secret']) |
|
110 |
token.set_verifier(request.GET.get('oauth_verifier')) |
|
111 |
client = oauth.Client(consumer, token) |
|
112 |
resp, content = client.request(access_token_url, "POST") |
|
113 |
if resp['status'] != '200': |
|
114 |
try: |
|
115 |
del request.session['request_token'] |
|
116 |
except: |
|
117 |
pass |
|
118 |
messages.error(request, 'Invalid linkedin token response') |
|
119 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
120 |
access_token = dict(cgi.parse_qsl(content)) |
|
121 |
print "ACCESS", access_token |
|
122 |
|
|
123 |
token = oauth.Token(access_token['oauth_token'], |
|
124 |
access_token['oauth_token_secret']) |
|
125 |
client = oauth.Client(consumer, token) |
|
126 |
resp, content = client.request("http://api.linkedin.com/v1/people/~:(id,first-name,last-name,industry,email-address)?format=json", "GET") |
|
127 |
if resp['status'] != '200': |
|
128 |
print resp, content |
|
129 |
try: |
|
130 |
del request.session['request_token'] |
|
131 |
except: |
|
132 |
pass |
|
133 |
messages.error(request, 'Invalid linkedin profile response') |
|
134 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
135 |
|
|
136 |
profile_data = json.loads(content) |
|
137 |
userid = profile_data['id'] |
|
138 |
username = profile_data.get('emailAddress', None) |
|
139 |
realname = profile_data.get('firstName', '') + ' ' + profile_data.get('lastName', '') |
|
140 |
provider_info = profile_data |
|
141 |
affiliation = 'linkedin.com' |
|
142 |
|
|
143 |
# an existing user accessed the view |
|
144 |
if request.user.is_authenticated(): |
|
145 |
if request.user.has_auth_provider('linkedin', identifier=userid): |
|
146 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
147 |
|
|
148 |
# automatically add eppn provider to user |
|
149 |
user = request.user |
|
150 |
if not request.user.can_add_auth_provider('linkedin', |
|
151 |
identifier=userid): |
|
152 |
messages.error(request, _(astakos_messages.AUTH_PROVIDER_ADD_FAILED) + |
|
153 |
u' ' + _(astakos_messages.AUTH_PROVIDER_ADD_EXISTS)) |
|
154 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
155 |
|
|
156 |
user.add_auth_provider('linkedin', identifier=userid, |
|
157 |
affiliation=affiliation, |
|
158 |
provider_info=provider_info) |
|
159 |
messages.success(request, astakos_messages.AUTH_PROVIDER_ADDED) |
|
160 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
161 |
|
|
162 |
try: |
|
163 |
# astakos user exists ? |
|
164 |
user = AstakosUser.objects.get_auth_provider_user( |
|
165 |
'linkedin', |
|
166 |
identifier=userid |
|
167 |
) |
|
168 |
if user.is_active: |
|
169 |
# authenticate user |
|
170 |
response = prepare_response(request, |
|
171 |
user, |
|
172 |
request.GET.get('next'), |
|
173 |
'renew' in request.GET) |
|
174 |
response.set_cookie('astakos_last_login_method', 'linkedin') |
|
175 |
return response |
|
176 |
else: |
|
177 |
message = user.get_inactive_message() |
|
178 |
messages.error(request, message) |
|
179 |
return HttpResponseRedirect(reverse('login')) |
|
180 |
|
|
181 |
except AstakosUser.DoesNotExist, e: |
|
182 |
provider = auth_providers.get_provider('linkedin') |
|
183 |
if not provider.is_available_for_create(): |
|
184 |
messages.error(request, |
|
185 |
_(astakos_messages.AUTH_PROVIDER_NOT_ACTIVE) % provider.get_title_display) |
|
186 |
return HttpResponseRedirect(reverse('login')) |
|
187 |
|
|
188 |
# eppn not stored in astakos models, create pending profile |
|
189 |
user, created = PendingThirdPartyUser.objects.get_or_create( |
|
190 |
third_party_identifier=userid, |
|
191 |
provider='linkedin', |
|
192 |
) |
|
193 |
# update pending user |
|
194 |
user.realname = realname |
|
195 |
user.affiliation = affiliation |
|
196 |
user.info = json.dumps(provider_info) |
|
197 |
user.generate_token() |
|
198 |
user.save() |
|
199 |
|
|
200 |
extra_context['provider'] = 'linkedin' |
|
201 |
extra_context['provider_title'] = 'linkedin' |
|
202 |
extra_context['token'] = user.token |
|
203 |
extra_context['signup_url'] = reverse('signup') + \ |
|
204 |
"?third_party_token=%s" % user.token |
|
205 |
|
|
206 |
return render_response( |
|
207 |
template, |
|
208 |
context_instance=get_context(request, extra_context) |
|
209 |
) |
|
210 |
|
|
211 |
|
|
212 |
|
b/snf-astakos-app/astakos/im/templates/im/auth/third_party_provider_generic_login.html | ||
---|---|---|
1 |
<h2><a href="{{ provider.add_url }}">{{ provider.get_login_prompt_display }} {{ provider.get_title_display }}</a></h2> |
b/snf-astakos-app/astakos/im/templates/im/auth/third_party_provider_generic_login_prompt.html | ||
---|---|---|
1 |
<br />{{ provider.get_login_prompt_display }} |
|
2 |
<a href="{{ provider.add_url }}?{% ifnotequal next "" %}&next={{ next|urlencode }}{% endifnotequal %}{% ifnotequal code ""%}{% if next != "" %}&{% else %}?{% endif %}code={{ code }}{% endifnotequal %}" |
|
3 |
alt="{{ provider.get_title_display }}">{{ provider.get_title_display }}</a> |
b/snf-astakos-app/astakos/im/urls.py | ||
---|---|---|
124 | 124 |
'twitter.authenticated'), |
125 | 125 |
) |
126 | 126 |
|
127 |
if 'google' in IM_MODULES: |
|
128 |
urlpatterns += patterns('astakos.im.target', |
|
129 |
url(r'^login/goggle/?$', 'google.login'), |
|
130 |
url(r'^login/google/authenticated/?$', |
|
131 |
'google.authenticated'), |
|
132 |
) |
|
133 |
if 'linkedin' in IM_MODULES: |
|
134 |
urlpatterns += patterns('astakos.im.target', |
|
135 |
url(r'^login/linkedin/?$', 'linkedin.login'), |
|
136 |
url(r'^login/linkedin/authenticated/?$', |
|
137 |
'linkedin.authenticated'), |
|
138 |
) |
|
139 |
|
|
127 | 140 |
urlpatterns += patterns('astakos.im.api', |
128 | 141 |
url(r'^get_services/?$', 'get_services'), |
129 | 142 |
url(r'^get_menu/?$', 'get_menu'), |
Also available in: Unified diff