Revision d2633501 snf-astakos-app/astakos/im/target/shibboleth.py
b/snf-astakos-app/astakos/im/target/shibboleth.py | ||
---|---|---|
40 | 40 |
from django.core.exceptions import ValidationError |
41 | 41 |
from django.http import HttpResponseRedirect |
42 | 42 |
from django.core.urlresolvers import reverse |
43 |
from urlparse import urlunsplit, urlsplit |
|
44 | 43 |
from django.utils.http import urlencode |
44 |
from django.shortcuts import get_object_or_404 |
|
45 |
|
|
46 |
from urlparse import urlunsplit, urlsplit |
|
45 | 47 |
|
46 | 48 |
from astakos.im.util import prepare_response, get_context, get_invitation |
47 |
from astakos.im.views import requires_anonymous, render_response |
|
49 |
from astakos.im.views import requires_anonymous, render_response, \ |
|
50 |
requires_auth_provider |
|
48 | 51 |
from astakos.im.settings import ENABLE_LOCAL_ACCOUNT_MIGRATION, BASEURL |
49 | 52 |
|
50 | 53 |
from astakos.im.models import AstakosUser, PendingThirdPartyUser |
51 | 54 |
from astakos.im.forms import LoginForm |
52 | 55 |
from astakos.im.activation_backends import get_backend, SimpleBackend |
56 |
from astakos.im import settings |
|
53 | 57 |
|
54 | 58 |
import logging |
55 | 59 |
|
... | ... | |
66 | 70 |
SHIB_SESSION_ID = "HTTP_SHIB_SESSION_ID" |
67 | 71 |
SHIB_MAIL = "HTTP_SHIB_MAIL" |
68 | 72 |
|
73 |
@requires_auth_provider('local', login=True) |
|
69 | 74 |
@require_http_methods(["GET", "POST"]) |
70 |
@requires_anonymous |
|
71 | 75 |
def login( |
72 | 76 |
request, |
73 |
login_template='im/login.html', |
|
74 |
signup_template='im/third_party_check_local.html', |
|
77 |
template='im/third_party_check_local.html', |
|
75 | 78 |
extra_context=None |
76 | 79 |
): |
77 | 80 |
extra_context = extra_context or {} |
78 | 81 |
|
79 | 82 |
tokens = request.META |
80 |
|
|
83 |
|
|
81 | 84 |
try: |
82 | 85 |
eppn = tokens.get(Tokens.SHIB_EPPN) |
83 | 86 |
if not eppn: |
84 |
raise KeyError(_('Missing unique token in request'))
|
|
87 |
raise KeyError(_('Missing provider token'))
|
|
85 | 88 |
if Tokens.SHIB_DISPLAYNAME in tokens: |
86 | 89 |
realname = tokens[Tokens.SHIB_DISPLAYNAME] |
87 | 90 |
elif Tokens.SHIB_CN in tokens: |
... | ... | |
89 | 92 |
elif Tokens.SHIB_NAME in tokens and Tokens.SHIB_SURNAME in tokens: |
90 | 93 |
realname = tokens[Tokens.SHIB_NAME] + ' ' + tokens[Tokens.SHIB_SURNAME] |
91 | 94 |
else: |
92 |
raise KeyError(_('Missing user name in request'))
|
|
95 |
raise KeyError(_('Missing provider user information'))
|
|
93 | 96 |
except KeyError, e: |
94 |
extra_context['login_form'] = LoginForm(request=request)
|
|
97 |
# invalid shibboleth headers, redirect to login, display message
|
|
95 | 98 |
messages.error(request, e) |
96 |
return render_response( |
|
97 |
login_template, |
|
98 |
context_instance=get_context(request, extra_context) |
|
99 |
) |
|
100 |
|
|
99 |
return HttpResponseRedirect(reverse('login')) |
|
100 |
|
|
101 | 101 |
affiliation = tokens.get(Tokens.SHIB_EP_AFFILIATION, '') |
102 | 102 |
email = tokens.get(Tokens.SHIB_MAIL, '') |
103 |
|
|
103 |
|
|
104 |
# an existing user accessed the view |
|
105 |
if request.user.is_authenticated(): |
|
106 |
if request.user.has_auth_provider('shibboleth', identifier=eppn): |
|
107 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
108 |
|
|
109 |
# automatically add eppn provider to user |
|
110 |
user = request.user |
|
111 |
user.add_provider('shibboleth', identifier=eppn) |
|
112 |
return HttpResponseRedirect('edit_profile') |
|
113 |
|
|
104 | 114 |
try: |
105 |
user = AstakosUser.objects.get( |
|
106 |
provider='shibboleth', |
|
107 |
third_party_identifier=eppn |
|
115 |
# astakos user exists ? |
|
116 |
user = AstakosUser.objects.get_auth_provider_user( |
|
117 |
'shibboleth', |
|
118 |
identifier=eppn |
|
108 | 119 |
) |
109 | 120 |
if user.is_active: |
121 |
# authenticate user |
|
110 | 122 |
return prepare_response(request, |
111 | 123 |
user, |
112 | 124 |
request.GET.get('next'), |
113 | 125 |
'renew' in request.GET) |
114 | 126 |
elif not user.activation_sent: |
115 | 127 |
message = _('Your request is pending activation') |
128 |
if not settings.MODERATION_ENABLED: |
|
129 |
url = user.get_resend_activation_url() |
|
130 |
msg_extra = _('<a href="%s">Resend activation email?</a>') % url |
|
131 |
message = message + u' ' + msg_extra |
|
132 |
|
|
116 | 133 |
messages.error(request, message) |
134 |
return HttpResponseRedirect(reverse('login')) |
|
135 |
|
|
117 | 136 |
else: |
118 |
urls = {} |
|
119 |
urls['send_activation'] = reverse( |
|
120 |
'send_activation', |
|
121 |
kwargs={'user_id':user.id} |
|
122 |
) |
|
123 |
urls['signup'] = reverse( |
|
124 |
'shibboleth_signup', |
|
125 |
args= [user.username] |
|
126 |
) |
|
127 |
message = _( |
|
128 |
'You have not followed the activation link. \ |
|
129 |
<a href="%(send_activation)s">Resend activation email?</a> or \ |
|
130 |
<a href="%(signup)s">Provide new email?</a>' % urls |
|
131 |
) |
|
137 |
message = _(u'Account disabled. Please contact support') |
|
132 | 138 |
messages.error(request, message) |
133 |
return render_response(login_template, |
|
134 |
login_form = LoginForm(request=request), |
|
135 |
context_instance=RequestContext(request)) |
|
139 |
return HttpResponseRedirect(reverse('login')) |
|
140 |
|
|
136 | 141 |
except AstakosUser.DoesNotExist, e: |
137 |
# First time |
|
138 |
try: |
|
139 |
user, created = PendingThirdPartyUser.objects.get_or_create( |
|
140 |
third_party_identifier=eppn, |
|
141 |
provider='shibboleth', |
|
142 |
defaults=dict( |
|
143 |
realname=realname, |
|
144 |
affiliation=affiliation, |
|
145 |
email=email |
|
146 |
) |
|
147 |
) |
|
148 |
user.save() |
|
149 |
except BaseException, e: |
|
150 |
logger.exception(e) |
|
151 |
template = login_template |
|
152 |
extra_context['login_form'] = LoginForm(request=request) |
|
153 |
messages.error(request, _('Something went wrong.')) |
|
154 |
else: |
|
155 |
if not ENABLE_LOCAL_ACCOUNT_MIGRATION: |
|
156 |
url = reverse( |
|
157 |
'shibboleth_signup', |
|
158 |
args= [user.username] |
|
159 |
) |
|
160 |
return HttpResponseRedirect(url) |
|
161 |
else: |
|
162 |
template = signup_template |
|
163 |
extra_context['username'] = user.username |
|
164 |
|
|
165 |
extra_context['provider']='shibboleth' |
|
142 |
# eppn not stored in astakos models, create pending profile |
|
143 |
user, created = PendingThirdPartyUser.objects.get_or_create( |
|
144 |
third_party_identifier=eppn, |
|
145 |
provider='shibboleth', |
|
146 |
) |
|
147 |
# update pending user |
|
148 |
user.realname = realname |
|
149 |
user.affiliation = affiliation |
|
150 |
user.email = email |
|
151 |
user.generate_token() |
|
152 |
user.save() |
|
153 |
|
|
154 |
extra_context['provider'] = 'shibboleth' |
|
155 |
extra_context['token'] = user.token |
|
156 |
|
|
166 | 157 |
return render_response( |
167 | 158 |
template, |
168 | 159 |
context_instance=get_context(request, extra_context) |
169 | 160 |
) |
170 | 161 |
|
162 |
|
|
163 |
@requires_auth_provider('local', login=True, create=True) |
|
171 | 164 |
@require_http_methods(["GET"]) |
172 | 165 |
@requires_anonymous |
173 | 166 |
def signup( |
174 | 167 |
request, |
175 |
username,
|
|
168 |
token,
|
|
176 | 169 |
backend=None, |
177 | 170 |
on_creation_template='im/third_party_registration.html', |
178 |
extra_context=None |
|
179 |
): |
|
171 |
extra_context=None):
|
|
172 |
|
|
180 | 173 |
extra_context = extra_context or {} |
181 |
if not username:
|
|
174 |
if not token:
|
|
182 | 175 |
return HttpResponseBadRequest(_('Missing key parameter.')) |
183 |
try: |
|
184 |
pending = PendingThirdPartyUser.objects.get(username=username) |
|
185 |
except PendingThirdPartyUser.DoesNotExist: |
|
186 |
try: |
|
187 |
user = AstakosUser.objects.get(username=username) |
|
188 |
except AstakosUser.DoesNotExist: |
|
189 |
return HttpResponseBadRequest(_('Invalid key.')) |
|
190 |
else: |
|
191 |
d = pending.__dict__ |
|
192 |
d.pop('_state', None) |
|
193 |
d.pop('id', None) |
|
194 |
user = AstakosUser(**d) |
|
176 |
|
|
177 |
pending = get_object_or_404(PendingThirdPartyUser, token=token) |
|
178 |
d = pending.__dict__ |
|
179 |
d.pop('_state', None) |
|
180 |
d.pop('id', None) |
|
181 |
d.pop('token', None) |
|
182 |
d.pop('created', None) |
|
183 |
user = AstakosUser(**d) |
|
184 |
|
|
195 | 185 |
try: |
196 | 186 |
backend = backend or get_backend(request) |
197 | 187 |
except ImproperlyConfigured, e: |
... | ... | |
201 | 191 |
provider='shibboleth', |
202 | 192 |
instance=user |
203 | 193 |
) |
204 |
extra_context['provider']='shibboleth' |
|
194 |
|
|
195 |
extra_context['provider'] = 'shibboleth' |
|
196 |
extra_context['third_party_token'] = token |
|
205 | 197 |
return render_response( |
206 | 198 |
on_creation_template, |
207 | 199 |
context_instance=get_context(request, extra_context) |
208 |
) |
|
200 |
) |
|
201 |
|
Also available in: Unified diff