Revision 9d20fe23 snf-astakos-app/astakos/im/views.py
b/snf-astakos-app/astakos/im/views.py | ||
---|---|---|
114 | 114 |
from astakos.im.api import get_services_dict |
115 | 115 |
from astakos.im import settings as astakos_settings |
116 | 116 |
from astakos.im.api.callpoint import AstakosCallpoint |
117 |
from astakos.im import auth_providers |
|
117 |
from astakos.im import auth_providers as auth
|
|
118 | 118 |
from astakos.im.project_xctx import project_transaction_context |
119 | 119 |
from astakos.im.retry_xctx import RetryException |
120 | 120 |
|
... | ... | |
142 | 142 |
def decorator(func, *args, **kwargs): |
143 | 143 |
@wraps(func) |
144 | 144 |
def wrapper(request, *args, **kwargs): |
145 |
provider = auth_providers.get_provider(provider_id)
|
|
145 |
provider = auth.get_provider(provider_id) |
|
146 | 146 |
|
147 | 147 |
if not provider or not provider.is_active(): |
148 | 148 |
raise PermissionDenied |
149 | 149 |
|
150 |
if provider: |
|
151 |
for pkey, value in perms.iteritems(): |
|
152 |
attr = 'is_available_for_%s' % pkey.lower() |
|
153 |
if getattr(provider, attr)() != value: |
|
154 |
#TODO: add session message |
|
155 |
return HttpResponseRedirect(reverse('login')) |
|
150 |
for pkey, value in perms.iteritems(): |
|
151 |
attr = 'get_%s_policy' % pkey.lower() |
|
152 |
if getattr(provider, attr) != value: |
|
153 |
#TODO: add session message |
|
154 |
return HttpResponseRedirect(reverse('login')) |
|
156 | 155 |
return func(request, *args) |
157 | 156 |
return wrapper |
158 | 157 |
return decorator |
... | ... | |
189 | 188 |
return wrapper |
190 | 189 |
|
191 | 190 |
|
192 |
def required_auth_methods_assigned(only_warn=False):
|
|
191 |
def required_auth_methods_assigned(allow_access=False):
|
|
193 | 192 |
""" |
194 | 193 |
Decorator that checks whether the request.user has all required auth providers |
195 | 194 |
assigned. |
196 | 195 |
""" |
197 |
required_providers = auth_providers.REQUIRED_PROVIDERS.keys() |
|
198 | 196 |
|
199 | 197 |
def decorator(func): |
200 |
if not required_providers: |
|
201 |
return func |
|
202 |
|
|
203 | 198 |
@wraps(func) |
204 | 199 |
def wrapper(request, *args, **kwargs): |
205 | 200 |
if request.user.is_authenticated(): |
206 |
for required in required_providers: |
|
207 |
if not request.user.has_auth_provider(required): |
|
208 |
provider = auth_providers.get_provider(required) |
|
209 |
if only_warn: |
|
210 |
messages.error(request, |
|
211 |
_(astakos_messages.AUTH_PROVIDER_REQUIRED % { |
|
212 |
'provider': provider.get_title_display})) |
|
213 |
else: |
|
214 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
201 |
missing = request.user.missing_required_providers() |
|
202 |
if missing: |
|
203 |
for provider in missing: |
|
204 |
messages.error(request, |
|
205 |
provider.get_required_msg) |
|
206 |
if not allow_access: |
|
207 |
return HttpResponseRedirect(reverse('edit_profile')) |
|
215 | 208 |
return func(request, *args, **kwargs) |
216 | 209 |
return wrapper |
217 | 210 |
return decorator |
... | ... | |
353 | 346 |
|
354 | 347 |
|
355 | 348 |
@require_http_methods(["GET", "POST"]) |
356 |
@required_auth_methods_assigned(only_warn=True)
|
|
349 |
@required_auth_methods_assigned(allow_access=True)
|
|
357 | 350 |
@login_required |
358 | 351 |
@signed_terms_required |
359 | 352 |
def edit_profile(request, template_name='im/profile.html', extra_context=None): |
... | ... | |
426 | 419 |
request.user.save() |
427 | 420 |
|
428 | 421 |
# existing providers |
429 |
user_providers = request.user.get_active_auth_providers() |
|
422 |
user_providers = request.user.get_enabled_auth_providers() |
|
423 |
user_disabled_providers = request.user.get_disabled_auth_providers() |
|
430 | 424 |
|
431 | 425 |
# providers that user can add |
432 | 426 |
user_available_providers = request.user.get_available_auth_providers() |
... | ... | |
435 | 429 |
return render_response(template_name, |
436 | 430 |
profile_form = form, |
437 | 431 |
user_providers = user_providers, |
432 |
user_disabled_providers = user_disabled_providers, |
|
438 | 433 |
user_available_providers = user_available_providers, |
439 | 434 |
context_instance = get_context(request, |
440 | 435 |
extra_context)) |
... | ... | |
480 | 475 |
return HttpResponseRedirect(reverse('edit_profile')) |
481 | 476 |
|
482 | 477 |
provider = get_query(request).get('provider', 'local') |
483 |
if not auth_providers.get_provider(provider).is_available_for_create():
|
|
478 |
if not auth.get_provider(provider).get_create_policy:
|
|
484 | 479 |
raise PermissionDenied |
485 | 480 |
|
486 | 481 |
id = get_query(request).get('id') |
... | ... | |
489 | 484 |
except AstakosUser.DoesNotExist: |
490 | 485 |
instance = None |
491 | 486 |
|
492 |
pending_user = None |
|
493 | 487 |
third_party_token = request.REQUEST.get('third_party_token', None) |
488 |
unverified = None |
|
494 | 489 |
if third_party_token: |
495 | 490 |
pending = get_object_or_404(PendingThirdPartyUser, |
496 | 491 |
token=third_party_token) |
492 |
|
|
497 | 493 |
provider = pending.provider |
498 | 494 |
instance = pending.get_user_instance() |
499 |
if pending.existing_user().count() > 0: |
|
500 |
pending_user = pending.existing_user().get() |
|
501 |
if request.method == "GET": |
|
502 |
messages.warning(request, pending_user.get_inactive_message()) |
|
503 |
|
|
504 |
|
|
505 |
extra_context['pending_user_exists'] = pending_user |
|
495 |
get_unverified = AstakosUserAuthProvider.objects.unverified |
|
496 |
unverified = get_unverified(pending.provider, |
|
497 |
identifier=pending.third_party_identifier) |
|
498 |
|
|
499 |
if unverified and request.method == 'GET': |
|
500 |
messages.warning(request, unverified.get_pending_registration_msg) |
|
501 |
if unverified.user.activation_sent: |
|
502 |
messages.warning(request, |
|
503 |
unverified.get_pending_resend_activation_msg) |
|
504 |
else: |
|
505 |
messages.warning(request, |
|
506 |
unverified.get_pending_moderation_msg) |
|
506 | 507 |
|
507 | 508 |
try: |
508 | 509 |
if not backend: |
... | ... | |
511 | 512 |
except Exception, e: |
512 | 513 |
form = SimpleBackend(request).get_signup_form(provider) |
513 | 514 |
messages.error(request, e) |
515 |
|
|
514 | 516 |
if request.method == 'POST': |
515 | 517 |
if form.is_valid(): |
516 | 518 |
user = form.save(commit=False) |
... | ... | |
520 | 522 |
AstakosUser.objects.get_by_identifier(user.email).delete() |
521 | 523 |
|
522 | 524 |
try: |
525 |
form.store_user(user, request) |
|
526 |
|
|
523 | 527 |
result = backend.handle_activation(user) |
524 | 528 |
status = messages.SUCCESS |
525 | 529 |
message = result.message |
526 | 530 |
|
527 |
form.store_user(user, request) |
|
528 |
|
|
529 | 531 |
if 'additional_email' in form.cleaned_data: |
530 | 532 |
additional_email = form.cleaned_data['additional_email'] |
531 | 533 |
if additional_email != user.email: |
... | ... | |
567 | 569 |
|
568 | 570 |
|
569 | 571 |
@require_http_methods(["GET", "POST"]) |
570 |
@required_auth_methods_assigned(only_warn=True)
|
|
572 |
@required_auth_methods_assigned(allow_access=True)
|
|
571 | 573 |
@login_required |
572 | 574 |
@signed_terms_required |
573 | 575 |
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None): |
... | ... | |
648 | 650 |
response['Location'] = LOGOUT_NEXT |
649 | 651 |
response.status_code = 301 |
650 | 652 |
else: |
651 |
message = _(astakos_messages.LOGOUT_SUCCESS) |
|
652 |
last_provider = request.COOKIES.get('astakos_last_login_method', None) |
|
653 |
if last_provider: |
|
654 |
provider = auth_providers.get_provider(last_provider) |
|
655 |
extra_message = provider.get_logout_message_display |
|
656 |
if extra_message: |
|
657 |
message += '<br />' + extra_message |
|
653 |
last_provider = request.COOKIES.get('astakos_last_login_method', 'local') |
|
654 |
provider = auth.get_provider(last_provider) |
|
655 |
message = provider.get_logout_success_msg |
|
656 |
extra = provider.get_logout_success_extra_msg |
|
657 |
if extra: |
|
658 |
message += "<br />" + extra |
|
658 | 659 |
messages.success(request, message) |
659 | 660 |
response['Location'] = reverse('index') |
660 | 661 |
response.status_code = 301 |
... | ... | |
807 | 808 |
form = EmailChangeForm(request.POST or None) |
808 | 809 |
if request.method == 'POST' and form.is_valid(): |
809 | 810 |
try: |
810 |
ec = form.save(email_template_name, request) |
|
811 |
ec = form.save(request, email_template_name, request)
|
|
811 | 812 |
except SendMailError, e: |
812 | 813 |
msg = e |
813 | 814 |
messages.error(request, msg) |
... | ... | |
834 | 835 |
if request.user.is_authenticated(): |
835 | 836 |
return HttpResponseRedirect(reverse('edit_profile')) |
836 | 837 |
|
837 |
# TODO: check if moderation is only enabled for local login |
|
838 |
if astakos_settings.MODERATION_ENABLED: |
|
839 |
raise PermissionDenied |
|
840 |
|
|
841 | 838 |
extra_context = extra_context or {} |
842 | 839 |
try: |
843 | 840 |
u = AstakosUser.objects.get(id=user_id) |
844 | 841 |
except AstakosUser.DoesNotExist: |
845 | 842 |
messages.error(request, _(astakos_messages.ACCOUNT_UNKNOWN)) |
846 | 843 |
else: |
844 |
if not u.activation_sent and astakos_settings.MODERATION_ENABLED: |
|
845 |
raise PermissionDenied |
|
847 | 846 |
try: |
848 | 847 |
send_activation_func(u) |
849 | 848 |
msg = _(astakos_messages.ACTIVATION_SENT) |
... | ... | |
906 | 905 |
|
907 | 906 |
# TODO: action only on POST and user should confirm the removal |
908 | 907 |
@require_http_methods(["GET", "POST"]) |
909 |
@login_required |
|
910 |
@signed_terms_required |
|
908 |
@valid_astakos_user_required |
|
911 | 909 |
def remove_auth_provider(request, pk): |
912 | 910 |
try: |
913 |
provider = request.user.auth_providers.get(pk=pk)
|
|
911 |
provider = request.user.auth_providers.get(pk=int(pk)).settings
|
|
914 | 912 |
except AstakosUserAuthProvider.DoesNotExist: |
915 | 913 |
raise Http404 |
916 | 914 |
|
917 |
if provider.can_remove(): |
|
918 |
provider.delete() |
|
919 |
message = astakos_messages.AUTH_PROVIDER_REMOVED % \ |
|
920 |
provider.settings.get_method_prompt_display |
|
921 |
user = request.user |
|
922 |
logger.info("%s deleted %s provider (%d): %r" % (user.log_display, |
|
923 |
provider.module, |
|
924 |
int(pk), |
|
925 |
provider.info)) |
|
926 |
messages.success(request, message) |
|
915 |
if provider.get_remove_policy: |
|
916 |
messages.success(request, provider.get_removed_msg) |
|
917 |
provider.remove_from_user() |
|
927 | 918 |
return HttpResponseRedirect(reverse('edit_profile')) |
928 | 919 |
else: |
929 | 920 |
raise PermissionDenied |
... | ... | |
1049 | 1040 |
return response |
1050 | 1041 |
|
1051 | 1042 |
@require_http_methods(["GET", "POST"]) |
1052 |
@signed_terms_required |
|
1053 |
@login_required |
|
1043 |
@valid_astakos_user_required |
|
1054 | 1044 |
def project_add(request): |
1055 | 1045 |
|
1056 | 1046 |
user = request.user |
... | ... | |
1109 | 1099 |
|
1110 | 1100 |
|
1111 | 1101 |
@require_http_methods(["GET"]) |
1112 |
@signed_terms_required |
|
1113 |
@login_required |
|
1102 |
@valid_astakos_user_required |
|
1114 | 1103 |
def project_list(request): |
1115 | 1104 |
projects = ProjectApplication.objects.user_accessible_projects(request.user).select_related() |
1116 | 1105 |
table = tables.UserProjectApplicationsTable(projects, user=request.user, |
... | ... | |
1128 | 1117 |
|
1129 | 1118 |
|
1130 | 1119 |
@require_http_methods(["GET", "POST"]) |
1131 |
@signed_terms_required |
|
1132 |
@login_required |
|
1120 |
@valid_astakos_user_required |
|
1133 | 1121 |
@project_transaction_context() |
1134 | 1122 |
def project_app_cancel(request, application_id, ctx=None): |
1135 | 1123 |
chain_id = None |
... | ... | |
1160 | 1148 |
|
1161 | 1149 |
|
1162 | 1150 |
@require_http_methods(["GET", "POST"]) |
1163 |
@signed_terms_required |
|
1164 |
@login_required |
|
1151 |
@valid_astakos_user_required |
|
1165 | 1152 |
def project_modify(request, application_id): |
1166 | 1153 |
|
1167 | 1154 |
try: |
... | ... | |
1216 | 1203 |
|
1217 | 1204 |
|
1218 | 1205 |
@require_http_methods(["GET", "POST"]) |
1219 |
@signed_terms_required |
|
1220 |
@login_required |
|
1206 |
@valid_astakos_user_required |
|
1221 | 1207 |
def project_app(request, application_id): |
1222 | 1208 |
return common_detail(request, application_id, project_view=False) |
1223 | 1209 |
|
1224 | 1210 |
@require_http_methods(["GET", "POST"]) |
1225 |
@signed_terms_required |
|
1226 |
@login_required |
|
1211 |
@valid_astakos_user_required |
|
1227 | 1212 |
def project_detail(request, chain_id): |
1228 | 1213 |
return common_detail(request, chain_id) |
1229 | 1214 |
|
... | ... | |
1321 | 1306 |
}) |
1322 | 1307 |
|
1323 | 1308 |
@require_http_methods(["GET", "POST"]) |
1324 |
@signed_terms_required |
|
1325 |
@login_required |
|
1309 |
@valid_astakos_user_required |
|
1326 | 1310 |
def project_search(request): |
1327 | 1311 |
q = request.GET.get('q', '') |
1328 | 1312 |
form = ProjectSearchForm() |
... | ... | |
1365 | 1349 |
}) |
1366 | 1350 |
|
1367 | 1351 |
@require_http_methods(["POST", "GET"]) |
1368 |
@signed_terms_required |
|
1369 |
@login_required |
|
1352 |
@valid_astakos_user_required |
|
1370 | 1353 |
@project_transaction_context(sync=True) |
1371 | 1354 |
def project_join(request, chain_id, ctx=None): |
1372 | 1355 |
next = request.GET.get('next') |
... | ... | |
1393 | 1376 |
return redirect(next) |
1394 | 1377 |
|
1395 | 1378 |
@require_http_methods(["POST", "GET"]) |
1396 |
@signed_terms_required |
|
1397 |
@login_required |
|
1379 |
@valid_astakos_user_required |
|
1398 | 1380 |
@project_transaction_context(sync=True) |
1399 | 1381 |
def project_leave(request, chain_id, ctx=None): |
1400 | 1382 |
next = request.GET.get('next') |
... | ... | |
1422 | 1404 |
return redirect(next) |
1423 | 1405 |
|
1424 | 1406 |
@require_http_methods(["POST"]) |
1425 |
@signed_terms_required |
|
1426 |
@login_required |
|
1407 |
@valid_astakos_user_required |
|
1427 | 1408 |
@project_transaction_context() |
1428 | 1409 |
def project_cancel(request, chain_id, ctx=None): |
1429 | 1410 |
next = request.GET.get('next') |
... | ... | |
1449 | 1430 |
return redirect(next) |
1450 | 1431 |
|
1451 | 1432 |
@require_http_methods(["POST"]) |
1452 |
@signed_terms_required |
|
1453 |
@login_required |
|
1433 |
@valid_astakos_user_required |
|
1454 | 1434 |
@project_transaction_context(sync=True) |
1455 | 1435 |
def project_accept_member(request, chain_id, user_id, ctx=None): |
1456 | 1436 |
try: |
... | ... | |
1473 | 1453 |
return redirect(reverse('project_detail', args=(chain_id,))) |
1474 | 1454 |
|
1475 | 1455 |
@require_http_methods(["POST"]) |
1476 |
@signed_terms_required |
|
1477 |
@login_required |
|
1456 |
@valid_astakos_user_required |
|
1478 | 1457 |
@project_transaction_context(sync=True) |
1479 | 1458 |
def project_remove_member(request, chain_id, user_id, ctx=None): |
1480 | 1459 |
try: |
... | ... | |
1497 | 1476 |
return redirect(reverse('project_detail', args=(chain_id,))) |
1498 | 1477 |
|
1499 | 1478 |
@require_http_methods(["POST"]) |
1500 |
@signed_terms_required |
|
1501 |
@login_required |
|
1479 |
@valid_astakos_user_required |
|
1502 | 1480 |
@project_transaction_context() |
1503 | 1481 |
def project_reject_member(request, chain_id, user_id, ctx=None): |
1504 | 1482 |
try: |
... | ... | |
1582 | 1560 |
next = reverse('project_list') |
1583 | 1561 |
return redirect(next) |
1584 | 1562 |
|
1585 |
|
|
1563 |
@require_http_methods(["GET"]) |
|
1564 |
@required_auth_methods_assigned(allow_access=True) |
|
1565 |
@login_required |
|
1566 |
@signed_terms_required |
|
1586 | 1567 |
def landing(request): |
1587 | 1568 |
return render_response( |
1588 | 1569 |
'im/landing.html', |
Also available in: Unified diff