Revision f432088a
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
596 | 596 |
else: |
597 | 597 |
return auth_providers.get_provider(provider).is_available_for_login() |
598 | 598 |
|
599 |
def can_add_provider(self, provider, **kwargs): |
|
599 |
def can_add_auth_provider(self, provider, **kwargs):
|
|
600 | 600 |
provider_settings = auth_providers.get_provider(provider) |
601 | 601 |
if not provider_settings.is_available_for_login(): |
602 | 602 |
return False |
603 |
|
|
603 | 604 |
if self.has_auth_provider(provider) and \ |
604 | 605 |
provider_settings.one_per_user: |
605 | 606 |
return False |
607 |
|
|
608 |
if 'identifier' in kwargs: |
|
609 |
try: |
|
610 |
# provider with specified params already exist |
|
611 |
existing_user = AstakosUser.objects.get_auth_provider_user(provider, |
|
612 |
**kwargs) |
|
613 |
except AstakosUser.DoesNotExist: |
|
614 |
return True |
|
615 |
else: |
|
616 |
return False |
|
617 |
|
|
606 | 618 |
return True |
607 | 619 |
|
608 | 620 |
def can_remove_auth_provider(self, provider): |
... | ... | |
618 | 630 |
**kwargs).count()) |
619 | 631 |
|
620 | 632 |
def add_auth_provider(self, provider, **kwargs): |
621 |
self.auth_providers.create(module=provider, active=True, **kwargs) |
|
633 |
if self.can_add_auth_provider(provider, **kwargs): |
|
634 |
self.auth_providers.create(module=provider, active=True, **kwargs) |
|
635 |
else: |
|
636 |
raise Exception('Cannot add provider') |
|
622 | 637 |
|
623 | 638 |
def add_pending_auth_provider(self, pending): |
624 | 639 |
""" |
... | ... | |
665 | 680 |
""" |
666 | 681 |
providers = [] |
667 | 682 |
for module, provider_settings in auth_providers.PROVIDERS.iteritems(): |
668 |
if self.can_add_provider(module): |
|
683 |
if self.can_add_auth_provider(module):
|
|
669 | 684 |
providers.append(provider_settings(self)) |
670 | 685 |
|
671 | 686 |
return providers |
... | ... | |
722 | 737 |
self.user.save() |
723 | 738 |
return ret |
724 | 739 |
|
740 |
def __repr__(self): |
|
741 |
return '<AstakosUserAuthProvider %s:%s>' % (self.module, self.identifier) |
|
742 |
|
|
725 | 743 |
|
726 | 744 |
class Membership(models.Model): |
727 | 745 |
person = models.ForeignKey(AstakosUser) |
b/snf-astakos-app/astakos/im/target/local.py | ||
---|---|---|
44 | 44 |
from astakos.im.util import prepare_response, get_query |
45 | 45 |
from astakos.im.views import requires_anonymous, signed_terms_required |
46 | 46 |
from astakos.im.models import PendingThirdPartyUser |
47 |
from astakos.im.forms import LoginForm, ExtendedPasswordChangeForm |
|
47 |
from astakos.im.forms import LoginForm, ExtendedPasswordChangeForm, \ |
|
48 |
ExtendedSetPasswordForm |
|
48 | 49 |
from astakos.im.settings import (RATELIMIT_RETRIES_ALLOWED, |
49 | 50 |
ENABLE_LOCAL_ACCOUNT_MIGRATION) |
50 | 51 |
import astakos.im.messages as astakos_messages |
... | ... | |
156 | 157 |
return render_to_response(template_name, { |
157 | 158 |
'form': form, |
158 | 159 |
}, context_instance=RequestContext(request)) |
160 |
|
b/snf-astakos-app/astakos/im/target/shibboleth.py | ||
---|---|---|
71 | 71 |
|
72 | 72 |
@requires_auth_provider('local', login=True) |
73 | 73 |
@require_http_methods(["GET", "POST"]) |
74 |
@requires_anonymous |
|
75 | 74 |
def login( |
76 | 75 |
request, |
77 | 76 |
template='im/third_party_check_local.html', |
... | ... | |
108 | 107 |
|
109 | 108 |
# automatically add eppn provider to user |
110 | 109 |
user = request.user |
111 |
user.add_provider('shibboleth', identifier=eppn) |
|
112 |
return HttpResponseRedirect('edit_profile') |
|
110 |
if not request.user.can_add_auth_provider('shibboleth', |
|
111 |
identifier=eppn): |
|
112 |
messages.error(request, 'Account already exists.') |
|
113 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
114 |
|
|
115 |
user.add_auth_provider('shibboleth', identifier=eppn) |
|
116 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
113 | 117 |
|
114 | 118 |
try: |
115 | 119 |
# astakos user exists ? |
b/snf-astakos-app/astakos/im/tests.py | ||
---|---|---|
269 | 269 |
r = client.get("/im/login/shibboleth?", follow=True) |
270 | 270 |
self.assertFalse(r.context['request'].user.is_authenticated()) |
271 | 271 |
|
272 |
user2 = get_local_user('kpap@grnet.gr') |
|
272 |
# lets remove local password |
|
273 |
user = AstakosUser.objects.get(username="kpap@grnet.gr", |
|
274 |
email="kpap@grnet.gr") |
|
275 |
provider_pk = user.auth_providers.get(module='local').pk |
|
276 |
provider_shib_pk = user.auth_providers.get(module='shibboleth').pk |
|
277 |
client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn", cn="1") |
|
278 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
279 |
client.reset_tokens() |
|
280 |
r = client.get("/im/remove_auth_provider/%d" % provider_pk) |
|
281 |
self.assertEqual(user.auth_providers.count(), 1) |
|
282 |
r = client.get("/im/remove_auth_provider/%d" % provider_pk) |
|
283 |
self.assertEqual(r.status_code, 404) |
|
284 |
r = client.get("/im/remove_auth_provider/%d" % provider_shib_pk) |
|
285 |
self.assertEqual(r.status_code, 403) |
|
286 |
|
|
287 |
self.client.logout() |
|
288 |
post_data = {'password': 'password', |
|
289 |
'username': 'kpap@grnet.gr'} |
|
290 |
r = self.client.post('/im/local', post_data, follow=True) |
|
291 |
self.assertFalse(r.context['request'].user.is_authenticated()) |
|
292 |
|
|
293 |
r = client.get("/im/password_change", follow=True) |
|
294 |
r = client.post("/im/password_change", {'new_password1':'111', |
|
295 |
'new_password2': '111'}, |
|
296 |
follow=True) |
|
297 |
user = r.context['request'].user |
|
298 |
self.assertTrue(user.has_auth_provider('local')) |
|
299 |
self.assertTrue(user.has_auth_provider('shibboleth')) |
|
300 |
self.assertTrue(user.check_password('111')) |
|
301 |
self.assertTrue(user.has_usable_password()) |
|
302 |
self.client.logout() |
|
303 |
post_data = {'password': '111', |
|
304 |
'username': 'kpap@grnet.gr'} |
|
305 |
r = self.client.post('/im/local', post_data, follow=True) |
|
306 |
self.assertTrue(r.context['request'].user.is_authenticated()) |
|
307 |
|
|
308 |
client.set_tokens(mail="kpap@shibboleth.gr", eppn="kpapeppn", cn="1") |
|
309 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
310 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
311 |
user = AstakosUser.objects.get(username="kpap@grnet.gr", |
|
312 |
email="kpap@grnet.gr") |
|
313 |
|
|
314 |
user2 = get_local_user('another@grnet.gr') |
|
315 |
user2.add_auth_provider('shibboleth', identifier='existingeppn') |
|
316 |
|
|
317 |
self.assertEqual(user.auth_providers.count(), 2) # local and 1 shibboleth |
|
318 |
client.set_tokens(mail="kpap_second@shibboleth.gr", eppn="kpapeppn2", cn="1") |
|
319 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
320 |
self.assertEqual(user.auth_providers.count(), 3) # local and 2 shibboleth |
|
321 |
|
|
322 |
client.set_tokens(mail="kpap_second@shibboleth.gr", eppn="kpapeppn2", cn="1") |
|
323 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
324 |
|
|
325 |
client.set_tokens(mail="kpap_second@shibboleth.gr", eppn="existingeppn", cn="1") |
|
326 |
r = client.get("/im/login/shibboleth?", follow=True) |
|
327 |
self.assertContains(r, 'Account already exists') |
|
273 | 328 |
|
274 | 329 |
|
275 | 330 |
class LocalUserTests(TestCase): |
b/snf-astakos-app/astakos/im/views.py | ||
---|---|---|
65 | 65 |
|
66 | 66 |
from astakos.im.models import (AstakosUser, ApprovalTerms, AstakosGroup, |
67 | 67 |
EmailChange, GroupKind, Membership, |
68 |
RESOURCE_SEPARATOR) |
|
68 |
RESOURCE_SEPARATOR, AstakosUserAuthProvider)
|
|
69 | 69 |
from astakos.im.util import get_context, prepare_response, get_query, restrict_next |
70 | 70 |
from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm, |
71 | 71 |
FeedbackForm, SignApprovalTermsForm, |
... | ... | |
1406 | 1406 |
timeline_body=timeline_body) |
1407 | 1407 |
return data |
1408 | 1408 |
|
1409 |
# TODO: action only on POST and user should confirm the removal |
|
1409 | 1410 |
@require_http_methods(["GET", "POST"]) |
1410 | 1411 |
@login_required |
1411 | 1412 |
@signed_terms_required |
1412 | 1413 |
def remove_auth_provider(request, pk): |
1413 |
provider = request.user.auth_providers.get(pk=pk) |
|
1414 |
try: |
|
1415 |
provider = request.user.auth_providers.get(pk=pk) |
|
1416 |
except AstakosUserAuthProvider.DoesNotExist: |
|
1417 |
raise Http404 |
|
1418 |
|
|
1414 | 1419 |
if provider.can_remove(): |
1415 | 1420 |
provider.delete() |
1416 | 1421 |
return HttpResponseRedirect(reverse('edit_profile')) |
1417 | 1422 |
else: |
1418 |
messages.error(_('Authentication method cannot be removed')) |
|
1419 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
1423 |
raise PermissionDenied |
|
1424 |
|
Also available in: Unified diff