Revision 8fb8d0cf
b/snf-astakos-app/astakos/api/quotas.py | ||
---|---|---|
49 | 49 |
from .util import (json_response, is_integer, are_integer, |
50 | 50 |
user_from_token, component_from_token) |
51 | 51 |
|
52 |
|
|
52 | 53 |
@api.api_method(http_method='GET', token_required=True, user_required=False) |
53 | 54 |
@user_from_token |
54 | 55 |
def quotas(request): |
b/snf-astakos-app/astakos/im/activation_backends.py | ||
---|---|---|
387 | 387 |
if result.status == self.Result.PENDING_MODERATION: |
388 | 388 |
logger.info("Sending notifications for user" |
389 | 389 |
" verification: %s", user.log_display) |
390 |
functions.send_account_pending_moderation_notification(user, |
|
391 |
self.pending_moderation_template_name) |
|
390 |
functions.send_account_pending_moderation_notification( |
|
391 |
user, |
|
392 |
self.pending_moderation_template_name) |
|
392 | 393 |
# TODO: notify user |
393 | 394 |
|
394 | 395 |
if result.status == self.Result.ACCEPTED: |
395 | 396 |
logger.info("Sending notifications for user" |
396 | 397 |
" moderation: %s", user.log_display) |
397 |
functions.send_account_activated_notification(user, |
|
398 |
self.activated_email_template_name) |
|
398 |
functions.send_account_activated_notification( |
|
399 |
user, |
|
400 |
self.activated_email_template_name) |
|
399 | 401 |
functions.send_greeting(user, |
400 | 402 |
self.greeting_template_name) |
401 | 403 |
# TODO: notify admins |
b/snf-astakos-app/astakos/im/auth_backends.py | ||
---|---|---|
48 | 48 |
def authenticate(self, email=None, auth_token=None): |
49 | 49 |
try: |
50 | 50 |
user = AstakosUser.objects.get_by_identifier(email, is_active=True, |
51 |
auth_token=auth_token) |
|
51 |
auth_token=auth_token)
|
|
52 | 52 |
return user |
53 | 53 |
except AstakosUser.DoesNotExist: |
54 | 54 |
return None |
... | ... | |
65 | 65 |
|
66 | 66 |
class EmailBackend(ModelBackend): |
67 | 67 |
""" |
68 |
If the ``username`` parameter is actually an email uses email to authenticate
|
|
69 |
the user else tries the username. |
|
68 |
If the ``username`` parameter is actually an email uses email to |
|
69 |
authenticate the user else tries the username.
|
|
70 | 70 |
|
71 | 71 |
Used from ``astakos.im.forms.LoginForm`` to authenticate. |
72 | 72 |
""" |
... | ... | |
83 | 83 |
msg = 'Invalid password during authentication for %s' % username |
84 | 84 |
logger._log(settings.LOGGING_LEVEL, msg, []) |
85 | 85 |
|
86 |
|
|
87 | 86 |
def get_user(self, user_id): |
88 | 87 |
try: |
89 | 88 |
return AstakosUser.objects.get(pk=user_id) |
b/snf-astakos-app/astakos/im/auth_providers.py | ||
---|---|---|
286 | 286 |
self.provider_details['info'] = \ |
287 | 287 |
json.loads(self.provider_details['info']) |
288 | 288 |
for key, val in self.provider_details['info'].iteritems(): |
289 |
params['provider_info_%s' % key.lower()] = val |
|
289 |
params['provider_info_%s' % key.lower()] = val
|
|
290 | 290 |
|
291 | 291 |
# resolve username, handle unexisting defined username key |
292 | 292 |
if self.user and self.username_key in params: |
... | ... | |
440 | 440 |
}) |
441 | 441 |
if self.identifier and self._instance: |
442 | 442 |
urls.update({ |
443 |
'switch': reverse(self.login_view) + '?switch_from=%d' % \
|
|
444 |
self._instance.pk,
|
|
443 |
'switch': reverse(self.login_view) + '?switch_from=%d' % |
|
444 |
self._instance.pk, |
|
445 | 445 |
'remove': reverse('remove_auth_provider', |
446 | 446 |
kwargs={'pk': self._instance.pk}) |
447 | 447 |
}) |
b/snf-astakos-app/astakos/im/context_processors.py | ||
---|---|---|
49 | 49 |
def im_modules(request): |
50 | 50 |
return {'im_modules': settings.IM_MODULES} |
51 | 51 |
|
52 |
|
|
52 | 53 |
def auth_providers(request): |
53 | 54 |
active_auth_providers = [] |
54 | 55 |
for module in settings.IM_MODULES: |
... | ... | |
59 | 60 |
return {'auth_providers': active_auth_providers, |
60 | 61 |
'master_auth_provider': active_auth_providers[0]} |
61 | 62 |
|
63 |
|
|
62 | 64 |
def next(request): |
63 | 65 |
return {'next': get_query(request).get('next', '')} |
64 | 66 |
|
... | ... | |
66 | 68 |
def code(request): |
67 | 69 |
return {'code': request.GET.get('code', '')} |
68 | 70 |
|
71 |
|
|
69 | 72 |
def last_login_method(request): |
70 |
return {'last_login_method': request.COOKIES.get('astakos_last_login_method', None)} |
|
73 |
return {'last_login_method': |
|
74 |
request.COOKIES.get('astakos_last_login_method', None)} |
|
75 |
|
|
71 | 76 |
|
72 | 77 |
def invitations(request): |
73 | 78 |
return {'invitations_enabled': settings.INVITATIONS_ENABLED} |
... | ... | |
112 | 117 |
else: |
113 | 118 |
return {'menu': menu_items} |
114 | 119 |
|
120 |
|
|
115 | 121 |
def membership_policies(request): |
116 | 122 |
return {'join_policies': presentation.PROJECT_MEMBER_JOIN_POLICIES, |
117 | 123 |
'leave_policies': presentation.PROJECT_MEMBER_LEAVE_POLICIES} |
118 |
|
b/snf-astakos-app/astakos/im/cookie.py | ||
---|---|---|
67 | 67 |
|
68 | 68 |
@property |
69 | 69 |
def is_valid(self): |
70 |
cookie_attribute = 'uuid' if not settings.TRANSLATE_UUIDS else 'username' |
|
70 |
cookie_attribute = ('uuid' if not settings.TRANSLATE_UUIDS |
|
71 |
else 'username') |
|
71 | 72 |
return (self.uuid == getattr(self.user, cookie_attribute, '') and |
72 | 73 |
self.auth_token == getattr(self.user, 'auth_token', '')) |
73 | 74 |
|
... | ... | |
86 | 87 |
else: |
87 | 88 |
cookie_value = quote(user.uuid + '|' + user.auth_token) |
88 | 89 |
self.response.set_cookie( |
89 |
settings.COOKIE_NAME, value=cookie_value, expires=expire_fmt, path='/', |
|
90 |
settings.COOKIE_NAME, value=cookie_value, expires=expire_fmt, |
|
91 |
path='/', |
|
90 | 92 |
domain=settings.COOKIE_DOMAIN, secure=settings.COOKIE_SECURE |
91 | 93 |
) |
92 | 94 |
msg = str(('Cookie [expiring %(auth_token_expires)s]', |
b/snf-astakos-app/astakos/im/forms.py | ||
---|---|---|
323 | 323 |
self.fields[f].widget.attrs['readonly'] = True |
324 | 324 |
|
325 | 325 |
def save(self, commit=True): |
326 |
user = super(InvitedThirdPartyUserCreationForm, self).save(commit=False) |
|
326 |
user = super( |
|
327 |
InvitedThirdPartyUserCreationForm, self).save(commit=False) |
|
327 | 328 |
user.set_invitation_level() |
328 | 329 |
user.email_verified = True |
329 | 330 |
if commit: |
... | ... | |
340 | 341 |
# copy email value to additional_mail in case user will change it |
341 | 342 |
name = 'email' |
342 | 343 |
field = self.fields[name] |
343 |
self.initial['additional_email'] = self.initial.get(name, field.initial) |
|
344 |
self.initial['additional_email'] = self.initial.get( |
|
345 |
name, field.initial) |
|
344 | 346 |
self.initial['email'] = None |
345 | 347 |
|
346 | 348 |
|
... | ... | |
359 | 361 |
was_limited = kwargs.get('was_limited', False) |
360 | 362 |
request = kwargs.get('request', None) |
361 | 363 |
if request: |
362 |
self.ip = request.META.get('REMOTE_ADDR', |
|
363 |
request.META.get('HTTP_X_REAL_IP', None)) |
|
364 |
self.ip = request.META.get( |
|
365 |
'REMOTE_ADDR', |
|
366 |
request.META.get('HTTP_X_REAL_IP', None)) |
|
364 | 367 |
|
365 | 368 |
t = ('request', 'was_limited') |
366 | 369 |
for elem in t: |
... | ... | |
431 | 434 |
Most of the fields are readonly since the user is not allowed to change |
432 | 435 |
them. |
433 | 436 |
|
434 |
The class defines a save method which sets ``is_verified`` to True so as the
|
|
435 |
user during the next login will not to be redirected to profile page. |
|
437 |
The class defines a save method which sets ``is_verified`` to True so as |
|
438 |
the user during the next login will not to be redirected to profile page.
|
|
436 | 439 |
""" |
437 |
email = forms.EmailField(label='E-mail address', help_text='E-mail address') |
|
440 |
email = forms.EmailField(label='E-mail address', |
|
441 |
help_text='E-mail address') |
|
438 | 442 |
renew = forms.BooleanField(label='Renew token', required=False) |
439 | 443 |
|
440 | 444 |
class Meta: |
... | ... | |
466 | 470 |
return user |
467 | 471 |
|
468 | 472 |
|
469 |
|
|
470 | 473 |
class FeedbackForm(forms.Form): |
471 | 474 |
""" |
472 | 475 |
Form for writing feedback. |
... | ... | |
517 | 520 |
raise forms.ValidationError(_(astakos_messages.EMAIL_UNKNOWN)) |
518 | 521 |
return email |
519 | 522 |
|
520 |
def save( |
|
521 |
self, domain_override=None, email_template_name='registration/password_reset_email.html', |
|
522 |
use_https=False, token_generator=default_token_generator, request=None): |
|
523 |
def save(self, domain_override=None, |
|
524 |
email_template_name='registration/password_reset_email.html', |
|
525 |
use_https=False, token_generator=default_token_generator, |
|
526 |
request=None): |
|
523 | 527 |
""" |
524 |
Generates a one-use only link for resetting password and sends to the user. |
|
528 |
Generates a one-use only link for resetting password and sends to the |
|
529 |
user. |
|
525 | 530 |
""" |
526 | 531 |
for user in self.users_cache: |
527 | 532 |
url = user.astakosuser.get_password_reset_url(token_generator) |
... | ... | |
555 | 560 |
raise forms.ValidationError(_(astakos_messages.EMAIL_USED)) |
556 | 561 |
return addr |
557 | 562 |
|
558 |
def save(self, request, email_template_name='registration/email_change_email.txt', commit=True): |
|
563 |
def save(self, request, |
|
564 |
email_template_name='registration/email_change_email.txt', |
|
565 |
commit=True): |
|
559 | 566 |
ec = super(EmailChangeForm, self).save(commit=False) |
560 | 567 |
ec.user = request.user |
561 | 568 |
# delete pending email changes |
... | ... | |
607 | 614 |
username = self.cleaned_data['username'] |
608 | 615 |
try: |
609 | 616 |
Invitation.objects.get(username=username) |
610 |
raise forms.ValidationError(_(astakos_messages.INVITATION_EMAIL_EXISTS)) |
|
617 |
raise forms.ValidationError( |
|
618 |
_(astakos_messages.INVITATION_EMAIL_EXISTS)) |
|
611 | 619 |
except Invitation.DoesNotExist: |
612 | 620 |
pass |
613 | 621 |
return username |
... | ... | |
619 | 627 |
to optionally renew also the token. |
620 | 628 |
""" |
621 | 629 |
if not settings.NEWPASSWD_INVALIDATE_TOKEN: |
622 |
renew = forms.BooleanField(label='Renew token', required=False, |
|
623 |
initial=True, |
|
624 |
help_text='Unsetting this may result in security risk.') |
|
630 |
renew = forms.BooleanField( |
|
631 |
label='Renew token', required=False, |
|
632 |
initial=True, |
|
633 |
help_text='Unsetting this may result in security risk.') |
|
625 | 634 |
|
626 | 635 |
def __init__(self, user, *args, **kwargs): |
627 | 636 |
self.session_key = kwargs.pop('session_key', None) |
... | ... | |
638 | 647 |
pass |
639 | 648 |
return super(ExtendedPasswordChangeForm, self).save(commit=commit) |
640 | 649 |
|
650 |
|
|
641 | 651 |
class ExtendedSetPasswordForm(SetPasswordForm): |
642 | 652 |
""" |
643 | 653 |
Extends SetPasswordForm by enabling user |
... | ... | |
670 | 680 |
return super(ExtendedSetPasswordForm, self).save(commit=commit) |
671 | 681 |
|
672 | 682 |
|
673 |
|
|
674 |
|
|
675 |
app_name_label = "Project name" |
|
683 |
app_name_label = "Project name" |
|
676 | 684 |
app_name_placeholder = _("myproject.mylab.ntua.gr") |
677 |
app_name_validator = validators.RegexValidator(
|
|
678 |
DOMAIN_VALUE_REGEX,
|
|
679 |
_(astakos_messages.DOMAIN_VALUE_ERR),
|
|
680 |
'invalid')
|
|
681 |
app_name_help = _("""
|
|
685 |
app_name_validator = validators.RegexValidator(
|
|
686 |
DOMAIN_VALUE_REGEX, |
|
687 |
_(astakos_messages.DOMAIN_VALUE_ERR), |
|
688 |
'invalid') |
|
689 |
app_name_help = _("""
|
|
682 | 690 |
The project's name should be in a domain format. |
683 | 691 |
The domain shouldn't neccessarily exist in the real |
684 | 692 |
world but is helpful to imply a structure. |
685 | 693 |
e.g.: myproject.mylab.ntua.gr or |
686 | 694 |
myservice.myteam.myorganization""") |
687 |
app_name_widget = forms.TextInput(
|
|
688 |
attrs={'placeholder': app_name_placeholder})
|
|
695 |
app_name_widget = forms.TextInput(
|
|
696 |
attrs={'placeholder': app_name_placeholder}) |
|
689 | 697 |
|
690 | 698 |
|
691 |
app_home_label = "Homepage URL"
|
|
692 |
app_home_placeholder = 'myinstitution.org/myproject/'
|
|
693 |
app_home_help = _("""
|
|
699 |
app_home_label = "Homepage URL"
|
|
700 |
app_home_placeholder = 'myinstitution.org/myproject/' |
|
701 |
app_home_help = _("""
|
|
694 | 702 |
URL pointing at your project's site. |
695 | 703 |
e.g.: myinstitution.org/myproject/. |
696 | 704 |
Leave blank if there is no website.""") |
697 |
app_home_widget = forms.TextInput(
|
|
698 |
attrs={'placeholder': app_home_placeholder})
|
|
705 |
app_home_widget = forms.TextInput(
|
|
706 |
attrs={'placeholder': app_home_placeholder}) |
|
699 | 707 |
|
700 |
app_desc_label = _("Description")
|
|
701 |
app_desc_help = _("""
|
|
708 |
app_desc_label = _("Description")
|
|
709 |
app_desc_help = _("""
|
|
702 | 710 |
Please provide a short but descriptive abstract of your |
703 | 711 |
project, so that anyone searching can quickly understand |
704 | 712 |
what this project is about.""") |
705 | 713 |
|
706 |
app_comment_label = _("Comments for review (private)")
|
|
707 |
app_comment_help = _("""
|
|
714 |
app_comment_label = _("Comments for review (private)")
|
|
715 |
app_comment_help = _("""
|
|
708 | 716 |
Write down any comments you may have for the reviewer |
709 | 717 |
of this application (e.g. background and rationale to |
710 | 718 |
support your request). |
711 | 719 |
The comments are strictly for the review process |
712 | 720 |
and will not be made public.""") |
713 | 721 |
|
714 |
app_start_date_label = _("Start date")
|
|
715 |
app_start_date_help = _("""
|
|
722 |
app_start_date_label = _("Start date") |
|
723 |
app_start_date_help = _("""
|
|
716 | 724 |
Provide a date when your need your project to be created, |
717 | 725 |
and members to be able to join and get resources. |
718 | 726 |
This date is only a hint to help prioritize reviews.""") |
719 | 727 |
|
720 |
app_end_date_label = _("Termination date")
|
|
721 |
app_end_date_help = _("""
|
|
728 |
app_end_date_label = _("Termination date")
|
|
729 |
app_end_date_help = _("""
|
|
722 | 730 |
At this date, the project will be automatically terminated |
723 | 731 |
and its resource grants revoked from all members. If you are |
724 | 732 |
not certain, it is best to start with a conservative estimation. |
725 | 733 |
You can always re-apply for an extension, if you need.""") |
726 | 734 |
|
727 |
join_policy_label = _("Joining policy")
|
|
728 |
app_member_join_policy_help = _("""
|
|
735 |
join_policy_label = _("Joining policy")
|
|
736 |
app_member_join_policy_help = _("""
|
|
729 | 737 |
Select how new members are accepted into the project.""") |
730 |
leave_policy_label = _("Leaving policy")
|
|
731 |
app_member_leave_policy_help = _("""
|
|
738 |
leave_policy_label = _("Leaving policy")
|
|
739 |
app_member_leave_policy_help = _("""
|
|
732 | 740 |
Select how new members can leave the project.""") |
733 | 741 |
|
734 |
max_members_label = _("Maximum member count")
|
|
735 |
max_members_help = _("""
|
|
742 |
max_members_label = _("Maximum member count")
|
|
743 |
max_members_help = _("""
|
|
736 | 744 |
Specify the maximum number of members this project may have, |
737 | 745 |
including the owner. Beyond this number, no new members |
738 | 746 |
may join the project and be granted the project resources. |
... | ... | |
742 | 750 |
join_policies = presentation.PROJECT_MEMBER_JOIN_POLICIES.items() |
743 | 751 |
leave_policies = presentation.PROJECT_MEMBER_LEAVE_POLICIES.items() |
744 | 752 |
|
753 |
|
|
745 | 754 |
class ProjectApplicationForm(forms.ModelForm): |
746 | 755 |
|
747 | 756 |
name = forms.CharField( |
748 |
label = app_name_label,
|
|
749 |
help_text = app_name_help,
|
|
750 |
widget = app_name_widget,
|
|
751 |
validators = [app_name_validator])
|
|
757 |
label=app_name_label,
|
|
758 |
help_text=app_name_help,
|
|
759 |
widget=app_name_widget,
|
|
760 |
validators=[app_name_validator])
|
|
752 | 761 |
|
753 | 762 |
homepage = forms.URLField( |
754 |
label = app_home_label,
|
|
755 |
help_text = app_home_help,
|
|
756 |
widget = app_home_widget,
|
|
757 |
required = False)
|
|
763 |
label=app_home_label,
|
|
764 |
help_text=app_home_help,
|
|
765 |
widget=app_home_widget,
|
|
766 |
required=False)
|
|
758 | 767 |
|
759 | 768 |
description = forms.CharField( |
760 |
label = app_desc_label,
|
|
761 |
help_text = app_desc_help,
|
|
762 |
widget = forms.Textarea,
|
|
763 |
required = False)
|
|
769 |
label=app_desc_label,
|
|
770 |
help_text=app_desc_help,
|
|
771 |
widget=forms.Textarea,
|
|
772 |
required=False)
|
|
764 | 773 |
|
765 | 774 |
comments = forms.CharField( |
766 |
label = app_comment_label,
|
|
767 |
help_text = app_comment_help,
|
|
768 |
widget = forms.Textarea,
|
|
769 |
required = False)
|
|
775 |
label=app_comment_label,
|
|
776 |
help_text=app_comment_help,
|
|
777 |
widget=forms.Textarea,
|
|
778 |
required=False)
|
|
770 | 779 |
|
771 | 780 |
start_date = forms.DateTimeField( |
772 |
label = app_start_date_label,
|
|
773 |
help_text = app_start_date_help,
|
|
774 |
required = False)
|
|
781 |
label=app_start_date_label,
|
|
782 |
help_text=app_start_date_help,
|
|
783 |
required=False)
|
|
775 | 784 |
|
776 | 785 |
end_date = forms.DateTimeField( |
777 |
label = app_end_date_label,
|
|
778 |
help_text = app_end_date_help)
|
|
786 |
label=app_end_date_label,
|
|
787 |
help_text=app_end_date_help)
|
|
779 | 788 |
|
780 |
member_join_policy = forms.TypedChoiceField(
|
|
781 |
label = join_policy_label,
|
|
782 |
help_text = app_member_join_policy_help,
|
|
783 |
initial = 2,
|
|
784 |
coerce = int,
|
|
785 |
choices = join_policies)
|
|
789 |
member_join_policy = forms.TypedChoiceField( |
|
790 |
label=join_policy_label,
|
|
791 |
help_text=app_member_join_policy_help,
|
|
792 |
initial=2,
|
|
793 |
coerce=int,
|
|
794 |
choices=join_policies)
|
|
786 | 795 |
|
787 | 796 |
member_leave_policy = forms.TypedChoiceField( |
788 |
label = leave_policy_label,
|
|
789 |
help_text = app_member_leave_policy_help,
|
|
790 |
coerce = int,
|
|
791 |
choices = leave_policies)
|
|
797 |
label=leave_policy_label,
|
|
798 |
help_text=app_member_leave_policy_help,
|
|
799 |
coerce=int,
|
|
800 |
choices=leave_policies)
|
|
792 | 801 |
|
793 | 802 |
limit_on_members_number = forms.IntegerField( |
794 |
label = max_members_label,
|
|
795 |
help_text = max_members_help,
|
|
796 |
min_value = 0,
|
|
797 |
required = False)
|
|
803 |
label=max_members_label,
|
|
804 |
help_text=max_members_help,
|
|
805 |
min_value=0,
|
|
806 |
required=False)
|
|
798 | 807 |
|
799 | 808 |
class Meta: |
800 | 809 |
model = ProjectApplication |
801 |
fields = ( 'name', 'homepage', 'description',
|
|
802 |
'start_date', 'end_date', 'comments',
|
|
803 |
'member_join_policy', 'member_leave_policy',
|
|
804 |
'limit_on_members_number')
|
|
810 |
fields = ('name', 'homepage', 'description', |
|
811 |
'start_date', 'end_date', 'comments', |
|
812 |
'member_join_policy', 'member_leave_policy', |
|
813 |
'limit_on_members_number') |
|
805 | 814 |
|
806 | 815 |
def __init__(self, *args, **kwargs): |
807 | 816 |
instance = kwargs.get('instance') |
... | ... | |
820 | 829 |
today = datetime(today.year, today.month, today.day) |
821 | 830 |
if start_date and (start_date - today).days < 0: |
822 | 831 |
raise forms.ValidationError( |
823 |
_(astakos_messages.INVALID_PROJECT_START_DATE)) |
|
832 |
_(astakos_messages.INVALID_PROJECT_START_DATE))
|
|
824 | 833 |
return start_date |
825 | 834 |
|
826 | 835 |
def clean_end_date(self): |
... | ... | |
867 | 876 |
raise forms.ValidationError("Resource %s does not exist" % |
868 | 877 |
resource.name) |
869 | 878 |
# keep only resource limits for selected resource groups |
870 |
if self.data.get( |
|
871 |
'is_selected_%s' % resource.group, "0" |
|
872 |
) == "1": |
|
879 |
if self.data.get('is_selected_%s' % |
|
880 |
resource.group, "0") == "1": |
|
873 | 881 |
if not resource.allow_in_projects: |
874 | 882 |
raise forms.ValidationError("Invalid resource %s" % |
875 | 883 |
resource.name) |
... | ... | |
881 | 889 |
append(d) |
882 | 890 |
|
883 | 891 |
ordered_keys = presentation.RESOURCES['resources_order'] |
892 |
|
|
884 | 893 |
def resource_order(r): |
885 | 894 |
if r['str_repr'] in ordered_keys: |
886 | 895 |
return ordered_keys.index(r['str_repr']) |
... | ... | |
910 | 919 |
('issue_date', 'Sort by Issue date'), |
911 | 920 |
('start_date', 'Sort by Start Date'), |
912 | 921 |
('end_date', 'Sort by End Date'), |
913 |
# ('approved_members_num', 'Sort by Participants'),
|
|
922 |
# ('approved_members_num', 'Sort by Participants'),
|
|
914 | 923 |
('state', 'Sort by Status'), |
915 |
('member_join_policy__description', 'Sort by Member Join Policy'), |
|
916 |
('member_leave_policy__description', 'Sort by Member Leave Policy'), |
|
924 |
('member_join_policy__description', |
|
925 |
'Sort by Member Join Policy'), |
|
926 |
('member_leave_policy__description', |
|
927 |
'Sort by Member Leave Policy'), |
|
917 | 928 |
('-name', 'Sort by Name'), |
918 | 929 |
('-issue_date', 'Sort by Issue date'), |
919 | 930 |
('-start_date', 'Sort by Start Date'), |
920 | 931 |
('-end_date', 'Sort by End Date'), |
921 |
# ('-approved_members_num', 'Sort by Participants'),
|
|
932 |
# ('-approved_members_num', 'Sort by Participants'),
|
|
922 | 933 |
('-state', 'Sort by Status'), |
923 |
('-member_join_policy__description', 'Sort by Member Join Policy'), |
|
924 |
('-member_leave_policy__description', 'Sort by Member Leave Policy') |
|
925 |
), |
|
934 |
('-member_join_policy__description', |
|
935 |
'Sort by Member Join Policy'), |
|
936 |
('-member_leave_policy__description', |
|
937 |
'Sort by Member Leave Policy') |
|
938 |
), |
|
926 | 939 |
required=True |
927 | 940 |
) |
928 | 941 |
|
942 |
|
|
929 | 943 |
class AddProjectMembersForm(forms.Form): |
930 | 944 |
q = forms.CharField( |
931 |
widget=forms.Textarea(attrs={ |
|
932 |
'placeholder': astakos_messages.ADD_PROJECT_MEMBERS_Q_PLACEHOLDER} |
|
933 |
), |
|
945 |
widget=forms.Textarea( |
|
946 |
attrs={ |
|
947 |
'placeholder': |
|
948 |
astakos_messages.ADD_PROJECT_MEMBERS_Q_PLACEHOLDER}), |
|
934 | 949 |
label=_('Add members'), |
935 | 950 |
help_text=_(astakos_messages.ADD_PROJECT_MEMBERS_Q_HELP), |
936 | 951 |
required=True,) |
... | ... | |
966 | 981 |
except: |
967 | 982 |
return () |
968 | 983 |
|
984 |
|
|
969 | 985 |
class ProjectMembersSortForm(forms.Form): |
970 | 986 |
sorting = forms.ChoiceField( |
971 | 987 |
label='Sort by', |
972 | 988 |
choices=(('person__email', 'User Id'), |
973 | 989 |
('person__first_name', 'Name'), |
974 | 990 |
('acceptance_date', 'Acceptance date') |
975 |
), |
|
991 |
),
|
|
976 | 992 |
required=True |
977 | 993 |
) |
978 | 994 |
|
... | ... | |
1009 | 1025 |
def __init__(self, *args, **kwargs): |
1010 | 1026 |
session_key = kwargs.get('session_key', None) |
1011 | 1027 |
self.fields_list = [ |
1012 |
'email',
|
|
1013 |
'new_email_address',
|
|
1014 |
'first_name',
|
|
1015 |
'last_name',
|
|
1016 |
'old_password',
|
|
1017 |
'new_password1',
|
|
1018 |
'new_password2',
|
|
1019 |
'change_email',
|
|
1020 |
'change_password',
|
|
1028 |
'email', |
|
1029 |
'new_email_address', |
|
1030 |
'first_name', |
|
1031 |
'last_name', |
|
1032 |
'old_password', |
|
1033 |
'new_password1', |
|
1034 |
'new_password2', |
|
1035 |
'change_email', |
|
1036 |
'change_password', |
|
1021 | 1037 |
] |
1022 | 1038 |
|
1023 | 1039 |
super(ExtendedProfileForm, self).__init__(*args, **kwargs) |
... | ... | |
1043 | 1059 |
self.success_messages = [] |
1044 | 1060 |
self.fields.keyOrder = self.fields_list |
1045 | 1061 |
|
1046 |
|
|
1047 | 1062 |
def _init_extra_form_fields(self): |
1048 | 1063 |
if self.email_change: |
1049 | 1064 |
self.fields.update(self.email_change_form.fields) |
1050 | 1065 |
self.fields['new_email_address'].required = False |
1051 |
self.fields['email'].help_text = _('Change the email associated with ' |
|
1052 |
'your account. This email will ' |
|
1053 |
'remain active until you verify ' |
|
1054 |
'your new one.') |
|
1066 |
self.fields['email'].help_text = _( |
|
1067 |
'Change the email associated with ' |
|
1068 |
'your account. This email will ' |
|
1069 |
'remain active until you verify ' |
|
1070 |
'your new one.') |
|
1055 | 1071 |
|
1056 | 1072 |
if self.password_change: |
1057 | 1073 |
self.fields.update(self.password_change_form.fields) |
... | ... | |
1070 | 1086 |
|
1071 | 1087 |
def _init_extra_forms(self): |
1072 | 1088 |
self.email_change_form = EmailChangeForm(self.data) |
1073 |
self.password_change_form = ExtendedPasswordChangeForm(user=self.instance, |
|
1074 |
data=self.data, session_key=self.session_key) |
|
1089 |
self.password_change_form = ExtendedPasswordChangeForm( |
|
1090 |
user=self.instance, |
|
1091 |
data=self.data, session_key=self.session_key) |
|
1075 | 1092 |
self._init_extra_form_fields() |
1076 | 1093 |
|
1077 | 1094 |
def is_valid(self): |
... | ... | |
1099 | 1116 |
self.password_change_form.save(*args, **kwargs) |
1100 | 1117 |
self.password_changed = True |
1101 | 1118 |
return super(ExtendedProfileForm, self).save(*args, **kwargs) |
1102 |
|
b/snf-astakos-app/astakos/im/functions.py | ||
---|---|---|
218 | 218 |
|
219 | 219 |
|
220 | 220 |
def send_change_email( |
221 |
ec, request, email_template_name='registration/email_change_email.txt'): |
|
221 |
ec, request, email_template_name='registration/email_change_email.txt' |
|
222 |
): |
|
222 | 223 |
url = ec.get_url() |
223 | 224 |
url = request.build_absolute_uri(url) |
224 |
c = {'url': url, 'site_name': settings.SITENAME, 'support': settings.CONTACT_EMAIL, |
|
225 |
c = {'url': url, 'site_name': settings.SITENAME, |
|
226 |
'support': settings.CONTACT_EMAIL, |
|
225 | 227 |
'ec': ec} |
226 | 228 |
message = render_to_string(email_template_name, c) |
227 | 229 |
from_email = settings.SERVER_EMAIL |
... | ... | |
725 | 727 |
conflicting_project = Project.objects.get(q) |
726 | 728 |
if (conflicting_project != project): |
727 | 729 |
m = (_("cannot approve: project with name '%s' " |
728 |
"already exists (id: %s)") % (
|
|
729 |
new_project_name, conflicting_project.id))
|
|
730 |
raise PermissionDenied(m) # invalid argument |
|
730 |
"already exists (id: %s)") % |
|
731 |
(new_project_name, conflicting_project.id))
|
|
732 |
raise PermissionDenied(m) # invalid argument
|
|
731 | 733 |
except Project.DoesNotExist: |
732 | 734 |
pass |
733 | 735 |
|
b/snf-astakos-app/astakos/im/messages.py | ||
---|---|---|
35 | 35 |
import astakos.im.settings as astakos_settings |
36 | 36 |
|
37 | 37 |
|
38 |
LOGGED_IN_WARNING = 'It seems that you are already logged in.' |
|
39 |
ACCOUNT_ALREADY_VERIFIED = 'This account is already verified.' |
|
40 |
ACCOUNT_ALREADY_MODERATED = 'This account is already moderated.' |
|
41 |
ACCOUNT_ALREADY_ACTIVE = 'This account is already active.' |
|
42 |
ACCOUNT_REJECTED = 'This account has been rejected.' |
|
43 |
ACCOUNT_NOT_ACTIVE = 'User account is not active.' |
|
44 |
ACCOUNT_NOT_MODERATED = 'User account is not moderated.' |
|
45 |
ACCOUNT_NOT_VERIFIED = 'User account does not have a verified email address.' |
|
46 |
ACCOUNT_RESEND_ACTIVATION = 'It seems that an activation email has been sent to you, but you have not followed the activation link. <a href="%(send_activation_url)s">Resend activation email.</a>' |
|
47 |
INACTIVE_ACCOUNT_CHANGE_EMAIL = ''.join([ACCOUNT_RESEND_ACTIVATION, ' Or <a href="%(signup_url)s">Send activation to a new email.</a>']) |
|
38 |
LOGGED_IN_WARNING = 'It seems that you are already logged in.' |
|
39 |
ACCOUNT_ALREADY_VERIFIED = 'This account is already verified.' |
|
40 |
ACCOUNT_ALREADY_MODERATED = 'This account is already moderated.' |
|
41 |
ACCOUNT_ALREADY_ACTIVE = 'This account is already active.' |
|
42 |
ACCOUNT_REJECTED = 'This account has been rejected.' |
|
43 |
ACCOUNT_NOT_ACTIVE = 'User account is not active.' |
|
44 |
ACCOUNT_NOT_MODERATED = 'User account is not moderated.' |
|
45 |
ACCOUNT_NOT_VERIFIED = 'User account does not have a verified email address.' |
|
46 |
ACCOUNT_RESEND_ACTIVATION = ( |
|
47 |
'It seems that an activation email has been sent to you, but you have ' |
|
48 |
'not followed the activation link. ' |
|
49 |
'<a href="%(send_activation_url)s">Resend activation email.</a>') |
|
50 |
INACTIVE_ACCOUNT_CHANGE_EMAIL = ''.join( |
|
51 |
[ACCOUNT_RESEND_ACTIVATION, |
|
52 |
' Or <a href="%(signup_url)s">Send activation to a new email.</a>']) |
|
48 | 53 |
|
49 |
ACCOUNT_PENDING_ACTIVATION_HELP = 'An activation email has been sent to you. Make sure you check your spam folder, too.' |
|
54 |
ACCOUNT_PENDING_ACTIVATION_HELP = ( |
|
55 |
'An activation email has been sent to you. Make sure you check your ' |
|
56 |
'spam folder, too.') |
|
50 | 57 |
|
51 |
ACCOUNT_ACTIVATED = 'Congratulations. Your account has' + \ |
|
52 |
' been activated. You are now logged in.' |
|
53 |
ACCOUNT_DEACTIVATED = 'Your account is inactive' |
|
54 |
PASSWORD_RESET_DONE = 'An email with details on how to change your password has been sent. Please check your Inbox.' |
|
55 |
PASSWORD_RESET_CONFIRM_DONE = 'Your password has changed successfully. You can now login using your new password.' |
|
56 |
PASSWORD_CHANGED = 'Your new password was set successfully.' |
|
58 |
ACCOUNT_ACTIVATED = 'Congratulations. Your account has' + \ |
|
59 |
' been activated. You are now logged in.' |
|
60 |
ACCOUNT_DEACTIVATED = 'Your account is inactive' |
|
61 |
PASSWORD_RESET_DONE = ( |
|
62 |
'An email with details on how to change your password has been sent. ' |
|
63 |
'Please check your Inbox.') |
|
64 |
PASSWORD_RESET_CONFIRM_DONE = ( |
|
65 |
'Your password has changed successfully. You ' |
|
66 |
'can now login using your new password.') |
|
67 |
PASSWORD_CHANGED = 'Your new password was set successfully.' |
|
57 | 68 |
|
58 |
ACCOUNT_RESEND_ACTIVATION = 'Resend activation email'
|
|
59 |
ACCOUNT_USER_ACTIVATION_PENDING = 'You have not followed the activation link'
|
|
69 |
ACCOUNT_RESEND_ACTIVATION = 'Resend activation email'
|
|
70 |
ACCOUNT_USER_ACTIVATION_PENDING = 'You have not followed the activation link'
|
|
60 | 71 |
|
61 |
ACCOUNT_UNKNOWN = 'There is no such account.'
|
|
62 |
TOKEN_UNKNOWN = 'There is no user matching this authentication token.'
|
|
63 |
TOKEN_UPDATED = 'Your authentication token has been updated successfully.'
|
|
72 |
ACCOUNT_UNKNOWN = 'There is no such account.'
|
|
73 |
TOKEN_UNKNOWN = 'There is no user matching this authentication token.'
|
|
74 |
TOKEN_UPDATED = 'Your authentication token has been updated successfully.'
|
|
64 | 75 |
|
65 |
PROFILE_UPDATED = 'Your profile has been updated successfully.' |
|
66 |
FEEDBACK_SENT = 'Thank you for contacting us. We will process your message carefully and get back to you.' |
|
67 |
EMAIL_CHANGED = 'The email of your account changed successfully.' |
|
68 |
EMAIL_CHANGE_REGISTERED = 'Your request for changing your email has been registered successfully. \ |
|
69 |
A verification email will be sent to your new address.' |
|
76 |
PROFILE_UPDATED = 'Your profile has been updated successfully.' |
|
77 |
FEEDBACK_SENT = ( |
|
78 |
'Thank you for contacting us. We will process your message carefully ' |
|
79 |
'and get back to you.') |
|
80 |
EMAIL_CHANGED = 'The email of your account changed successfully.' |
|
81 |
EMAIL_CHANGE_REGISTERED = ( |
|
82 |
'Your request for changing your email has been registered successfully. ' |
|
83 |
'A verification email will be sent to your new address.') |
|
70 | 84 |
|
71 |
OBJECT_CREATED = 'The %(verbose_name)s was created successfully.' |
|
72 |
USER_MEMBERSHIP_REJECTED = 'Request by %s to join the project has been rejected.' |
|
73 |
BILLING_ERROR = 'Service response status: %(status)d' |
|
85 |
OBJECT_CREATED = 'The %(verbose_name)s was created successfully.' |
|
86 |
USER_MEMBERSHIP_REJECTED = ( |
|
87 |
'Request by %s to join the project has been rejected.') |
|
88 |
BILLING_ERROR = 'Service response status: %(status)d' |
|
74 | 89 |
|
75 |
GENERIC_ERROR = 'Hmm... It seems something bad has happened, and we don\'t know the details right now. \ |
|
76 |
Please contact the administrators by email for more details.' |
|
90 |
GENERIC_ERROR = ( |
|
91 |
'Hmm... It seems something bad has happened, and we don\'t know the ' |
|
92 |
'details right now. Please contact the administrators by email for ' |
|
93 |
'more details.') |
|
77 | 94 |
|
78 |
MAX_INVITATION_NUMBER_REACHED = 'You have reached the maximum amount of invitations for your account. No invitations left.' |
|
79 |
GROUP_MAX_PARTICIPANT_NUMBER_REACHED = 'This Group reached its maximum number of members. No other member can be added.' |
|
80 |
PROJECT_MAX_PARTICIPANT_NUMBER_REACHED = 'This Project reached its maximum number of members. No other member can be added.' |
|
81 |
NO_APPROVAL_TERMS = 'There are no terms of service to approve.' |
|
82 |
PENDING_EMAIL_CHANGE_REQUEST = 'It seems there is already a pending request for an email change. ' + \ |
|
83 |
'Submitting a new request to change your email will cancel all previous requests.' |
|
84 |
OBJECT_CREATED_FAILED = 'The %(verbose_name)s creation failed: %(reason)s.' |
|
85 |
GROUP_JOIN_FAILURE = 'Failed to join this Group.' |
|
86 |
PROJECT_JOIN_FAILURE = 'Failed to join this Project.' |
|
87 |
GROUPKIND_UNKNOWN = 'The kind of Project you specified does not exist.' |
|
88 |
NOT_MEMBER = 'User is not a member of the Project.' |
|
89 |
NOT_OWNER = 'User is not the Project\'s owner.' |
|
90 |
OWNER_CANNOT_LEAVE_GROUP = 'You are the owner of this Project. Owners can not leave their Projects.' |
|
95 |
MAX_INVITATION_NUMBER_REACHED = ( |
|
96 |
'You have reached the maximum amount of invitations for your account. ' |
|
97 |
'No invitations left.') |
|
98 |
GROUP_MAX_PARTICIPANT_NUMBER_REACHED = ( |
|
99 |
'This Group reached its maximum number of members. No other member can ' |
|
100 |
'be added.') |
|
101 |
PROJECT_MAX_PARTICIPANT_NUMBER_REACHED = ( |
|
102 |
'This Project reached its maximum number of members. No other member ' |
|
103 |
'can be added.') |
|
104 |
NO_APPROVAL_TERMS = 'There are no terms of service to approve.' |
|
105 |
PENDING_EMAIL_CHANGE_REQUEST = ( |
|
106 |
'It seems there is already a pending request for an email change. ' |
|
107 |
'Submitting a new request to change your email will cancel all previous ' |
|
108 |
'requests.') |
|
109 |
OBJECT_CREATED_FAILED = 'The %(verbose_name)s creation failed: %(reason)s.' |
|
110 |
GROUP_JOIN_FAILURE = 'Failed to join this Group.' |
|
111 |
PROJECT_JOIN_FAILURE = 'Failed to join this Project.' |
|
112 |
GROUPKIND_UNKNOWN = 'The kind of Project you specified does not exist.' |
|
113 |
NOT_MEMBER = 'User is not a member of the Project.' |
|
114 |
NOT_OWNER = 'User is not the Project\'s owner.' |
|
115 |
OWNER_CANNOT_LEAVE_GROUP = ( |
|
116 |
'You are the owner of this Project. Owners can not leave their Projects.') |
|
91 | 117 |
|
92 | 118 |
# Field validation fields |
93 |
REQUIRED_FIELD = 'This field is required.' |
|
94 |
EMAIL_USED = 'There is already an account with this email address.' |
|
95 |
SHIBBOLETH_EMAIL_USED = 'This email is already associated with another shibboleth account.' |
|
96 |
SHIBBOLETH_INACTIVE_ACC = 'This email is already associated with an account that is not yet activated. \ |
|
97 |
If that is your account, you need to activate it before being able to \ |
|
98 |
associate it with this shibboleth account.' |
|
99 |
SHIBBOLETH_MISSING_EPPN = 'Your request is missing a unique ' + \ |
|
100 |
'token. This means your academic ' + \ |
|
101 |
'institution does not yet allow its users to log ' + \ |
|
102 |
'into %(domain)s with their academic ' + \ |
|
103 |
'account. Please contact %(contact_email)s' + \ |
|
104 |
' for more information.' |
|
105 |
SHIBBOLETH_MISSING_NAME = 'This request is missing the user name.' |
|
119 |
REQUIRED_FIELD = 'This field is required.' |
|
120 |
EMAIL_USED = 'There is already an account with this email address.' |
|
121 |
SHIBBOLETH_EMAIL_USED = ( |
|
122 |
'This email is already associated with another shibboleth account.') |
|
123 |
SHIBBOLETH_INACTIVE_ACC = ( |
|
124 |
'This email is already associated with an account that is not ' |
|
125 |
'yet activated. ' |
|
126 |
'If that is your account, you need to activate it before being able to ' |
|
127 |
'associate it with this shibboleth account.') |
|
128 |
SHIBBOLETH_MISSING_EPPN = ( |
|
129 |
'Your request is missing a unique ' + |
|
130 |
'token. This means your academic ' + |
|
131 |
'institution does not yet allow its users to log ' + |
|
132 |
'into %(domain)s with their academic ' + |
|
133 |
'account. Please contact %(contact_email)s' + |
|
134 |
' for more information.') |
|
135 |
SHIBBOLETH_MISSING_NAME = 'This request is missing the user name.' |
|
106 | 136 |
|
107 |
SIGN_TERMS = 'Please, you need to \'Agree with the terms\' before proceeding.' |
|
108 |
CAPTCHA_VALIDATION_ERR = 'You have not entered the correct words. Please try again.' |
|
109 |
SUSPENDED_LOCAL_ACC = 'This account does not have a local password. \ |
|
110 |
Please try logging in using an external login provider (e.g.: twitter)' |
|
111 |
EMAIL_UNKNOWN = 'This email address doesn\'t have an associated user account. \ |
|
112 |
Please make sure you have registered, before proceeding.' |
|
113 |
INVITATION_EMAIL_EXISTS = 'An invitation has already been sent to this email.' |
|
114 |
INVITATION_CONSUMED_ERR = 'Invitation is used.' |
|
115 |
UNKNOWN_USERS = 'Unknown users: %s' |
|
116 |
UNIQUE_EMAIL_IS_ACTIVE_CONSTRAIN_ERR = 'More than one account with the same email & \'is_active\' field. Error.' |
|
117 |
INVALID_ACTIVATION_KEY = 'Invalid activation key.' |
|
118 |
NEW_EMAIL_ADDR_RESERVED = 'The new email address you requested is already used by another account. Please provide a different one.' |
|
119 |
EMAIL_RESERVED = 'Email: %(email)s is already reserved.' |
|
120 |
NO_LOCAL_AUTH = 'Only external login providers are enabled for this acccount. You can not login with a local password.' |
|
121 |
SWITCH_ACCOUNT_FAILURE = 'Account failed to switch. Invalid parameters.' |
|
122 |
SWITCH_ACCOUNT_SUCCESS_WITH_PROVIDER = 'Account failed to switch to %(provider)s.' |
|
123 |
SWITCH_ACCOUNT_SUCCESS = 'Account successfully switched to %(provider)s.' |
|
137 |
SIGN_TERMS = 'Please, you need to \'Agree with the terms\' before proceeding.' |
|
138 |
CAPTCHA_VALIDATION_ERR = ( |
|
139 |
'You have not entered the correct words. Please try again.') |
|
140 |
SUSPENDED_LOCAL_ACC = ( |
|
141 |
'This account does not have a local password. ' |
|
142 |
'Please try logging in using an external login provider (e.g.: twitter)') |
|
143 |
EMAIL_UNKNOWN = ( |
|
144 |
'This email address doesn\'t have an associated user account. ' |
|
145 |
'Please make sure you have registered, before proceeding.') |
|
146 |
INVITATION_EMAIL_EXISTS = 'An invitation has already been sent to this email.' |
|
147 |
INVITATION_CONSUMED_ERR = 'Invitation is used.' |
|
148 |
UNKNOWN_USERS = 'Unknown users: %s' |
|
149 |
UNIQUE_EMAIL_IS_ACTIVE_CONSTRAIN_ERR = ( |
|
150 |
'More than one account with the same email & \'is_active\' field. Error.') |
|
151 |
INVALID_ACTIVATION_KEY = 'Invalid activation key.' |
|
152 |
NEW_EMAIL_ADDR_RESERVED = ( |
|
153 |
'The new email address you requested is already used by another account. ' |
|
154 |
'Please provide a different one.') |
|
155 |
EMAIL_RESERVED = 'Email: %(email)s is already reserved.' |
|
156 |
NO_LOCAL_AUTH = ( |
|
157 |
'Only external login providers are enabled for this account. ' |
|
158 |
'You can not login with a local password.') |
|
159 |
SWITCH_ACCOUNT_FAILURE = 'Account failed to switch. Invalid parameters.' |
|
160 |
SWITCH_ACCOUNT_SUCCESS_WITH_PROVIDER = ( |
|
161 |
'Account failed to switch to %(provider)s.') |
|
162 |
SWITCH_ACCOUNT_SUCCESS = 'Account successfully switched to %(provider)s.' |
|
124 | 163 |
|
125 | 164 |
# Field help text |
126 |
ADD_GROUP_MEMBERS_Q_HELP = 'Add a comma separated list of user emails, eg. user1@user.com, user2@user.com' |
|
127 |
ASTAKOSUSER_GROUPS_HELP = 'In addition to the permissions assigned manually, \ |
|
128 |
this user will also get all permissions coming from his/her groups.' |
|
165 |
ADD_GROUP_MEMBERS_Q_HELP = ( |
|
166 |
'Add a comma separated list of user emails, eg. user1@user.com, ' |
|
167 |
'user2@user.com') |
|
168 |
ASTAKOSUSER_GROUPS_HELP = ( |
|
169 |
'In addition to the permissions assigned manually, ' |
|
170 |
'this user will also get all permissions coming from his/her groups.') |
|
129 | 171 |
|
130 |
EMAIL_SEND_ERR = 'Failed to send %s.' |
|
131 |
ADMIN_NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'admin notification' |
|
132 |
VERIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'verification' |
|
133 |
INVITATION_SEND_ERR = EMAIL_SEND_ERR % 'invitation' |
|
134 |
GREETING_SEND_ERR = EMAIL_SEND_ERR % 'greeting' |
|
135 |
FEEDBACK_SEND_ERR = EMAIL_SEND_ERR % 'feedback' |
|
136 |
CHANGE_EMAIL_SEND_ERR = EMAIL_SEND_ERR % 'email change' |
|
137 |
NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'notification' |
|
138 |
DETAILED_NOTIFICATION_SEND_ERR = 'Failed to send %(subject)s notification to %(recipients)s.' |
|
172 |
EMAIL_SEND_ERR = 'Failed to send %s.' |
|
173 |
ADMIN_NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'admin notification' |
|
174 |
VERIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'verification' |
|
175 |
INVITATION_SEND_ERR = EMAIL_SEND_ERR % 'invitation' |
|
176 |
GREETING_SEND_ERR = EMAIL_SEND_ERR % 'greeting' |
|
177 |
FEEDBACK_SEND_ERR = EMAIL_SEND_ERR % 'feedback' |
|
178 |
CHANGE_EMAIL_SEND_ERR = EMAIL_SEND_ERR % 'email change' |
|
179 |
NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'notification' |
|
180 |
DETAILED_NOTIFICATION_SEND_ERR = ( |
|
181 |
'Failed to send %(subject)s notification to %(recipients)s.') |
|
139 | 182 |
|
140 |
MISSING_NEXT_PARAMETER = 'The next parameter is missing.'
|
|
183 |
MISSING_NEXT_PARAMETER = 'The next parameter is missing.'
|
|
141 | 184 |
|
142 |
INVITATION_SENT = 'Invitation sent to %(email)s.' |
|
143 |
VERIFICATION_SENT = 'Your information has been submitted successfully. A verification email, with an activation link \ |
|
144 |
has been sent to the email address you provided. Please follow the activation link on this \ |
|
145 |
email to complete the registration process.' |
|
146 |
VERIFICATION_FAILED = 'Email verification process failed.' |
|
147 |
SWITCH_ACCOUNT_LINK_SENT = 'This email is already associated with a local account, and a verification email has been sent \ |
|
148 |
to %(email)s. To complete the association process, go back to your Inbox and follow the link \ |
|
149 |
inside the verification email.' |
|
150 |
NOTIFICATION_SENT = 'Your request for an account has been submitted successfully, and is now pending approval. \ |
|
151 |
You will be notified by email in the next few days. \ |
|
152 |
Thanks for your interest!' |
|
153 |
ACTIVATION_SENT = 'An email containing your activation link has been sent to your email address.' |
|
185 |
INVITATION_SENT = 'Invitation sent to %(email)s.' |
|
186 |
VERIFICATION_SENT = ( |
|
187 |
'Your information has been submitted successfully. A verification email, ' |
|
188 |
'with an activation link has been sent to the email address you provided. ' |
|
189 |
'Please follow the activation link on this email to complete the ' |
|
190 |
'registration process.') |
|
191 |
VERIFICATION_FAILED = 'Email verification process failed.' |
|
192 |
SWITCH_ACCOUNT_LINK_SENT = ( |
|
193 |
'This email is already associated with a local account, ' |
|
194 |
'and a verification email has been sent to %(email)s. To complete ' |
|
195 |
'the association process, go back to your Inbox and follow the link ' |
|
196 |
'inside the verification email.') |
|
197 |
NOTIFICATION_SENT = ( |
|
198 |
'Your request for an account has been submitted successfully, and is ' |
|
199 |
'now pending approval. You will be notified by email in the next few ' |
|
200 |
'days. Thanks for your interest!') |
|
201 |
ACTIVATION_SENT = ( |
|
202 |
'An email containing your activation link has been sent to your ' |
|
203 |
'email address.') |
|
154 | 204 |
|
155 |
REGISTRATION_COMPLETED = 'Your registration completed successfully. You can now login to your new account!' |
|
205 |
REGISTRATION_COMPLETED = ( |
|
206 |
'Your registration completed successfully. You can now login to your ' |
|
207 |
'new account!') |
|
156 | 208 |
|
157 |
NO_RESPONSE = 'There is no response.' |
|
158 |
NOT_ALLOWED_NEXT_PARAM = 'Not allowed next parameter.' |
|
159 |
MISSING_KEY_PARAMETER = 'Missing key parameter.' |
|
160 |
INVALID_KEY_PARAMETER = 'Invalid key.' |
|
161 |
DOMAIN_VALUE_ERR = 'Enter a valid domain.' |
|
162 |
QH_SYNC_ERROR = 'Failed to get synchronized with quotaholder.' |
|
163 |
UNIQUE_PROJECT_NAME_CONSTRAIN_ERR = 'The project name (as specified in its application\'s definition) must be unique among all active projects.' |
|
164 |
INVALID_PROJECT = 'Project %(id)s is invalid.' |
|
165 |
NOT_ALIVE_PROJECT = 'Project %(id)s is not alive.' |
|
166 |
NOT_SUSPENDED_PROJECT = 'Project %(id)s is not suspended.' |
|
167 |
NOT_ALLOWED = 'You do not have the permissions to perform this action.' |
|
168 |
MEMBER_NUMBER_LIMIT_REACHED = 'You have reached the maximum number of members for this Project.' |
|
169 |
MEMBER_JOIN_POLICY_CLOSED = 'The Project\'s member join policy is closed.' |
|
170 |
MEMBER_LEAVE_POLICY_CLOSED = 'The project\'s member leave policy is closed.' |
|
171 |
NOT_MEMBERSHIP_REQUEST = 'This is not a valid membership request.' |
|
172 |
NOT_ACCEPTED_MEMBERSHIP = 'This is not an accepted membership.' |
|
173 |
MEMBERSHIP_REQUEST_EXISTS = 'The membership request already exists.' |
|
174 |
NO_APPLICANT = 'Project application requires at least one applicant. None found.' |
|
175 |
INVALID_PROJECT_START_DATE = 'Project start date should be equal or greater than the current date.' |
|
176 |
INVALID_PROJECT_END_DATE = 'Project end date should be equal or greater than than the current date.' |
|
177 |
INCONSISTENT_PROJECT_DATES = 'Project end date should be greater than the project start date.' |
|
178 |
ADD_PROJECT_MEMBERS_Q_HELP = 'Add a comma separated list of user emails, eg. user1@user.com, user2@user.com' |
|
179 |
ADD_PROJECT_MEMBERS_Q_PLACEHOLDER = 'user1@user.com, user2@user.com' |
|
180 |
MISSING_IDENTIFIER = 'Missing identifier.' |
|
181 |
UNKNOWN_USER_ID = 'There is no user identified by %s.' |
|
182 |
UNKNOWN_PROJECT_APPLICATION_ID = 'There is no project application identified by %s.' |
|
183 |
UNKNOWN_PROJECT_ID = 'There is no project identified by %s.' |
|
184 |
UNKNOWN_IDENTIFIER = 'Unknown identifier.' |
|
185 |
PENDING_MEMBERSHIP_LEAVE = 'Your request is pending moderation by the Project owner.' |
|
186 |
USER_MEMBERSHIP_ACCEPTED = '%s has been accepted in the project.' |
|
187 |
USER_MEMBERSHIP_REMOVED = '%s has been removed from the project.' |
|
188 |
USER_LEFT_PROJECT = 'You have left the project.' |
|
189 |
USER_LEAVE_REQUEST_SUBMITTED = 'Your request to leave the project has been submitted successfully.' |
|
190 |
USER_JOIN_REQUEST_SUBMITTED = 'Your request to join the project has been submitted successfully.' |
|
191 |
USER_JOINED_PROJECT = 'You have joined the project.' |
|
192 |
USER_REQUEST_CANCELLED = 'Your request to join the project has been cancelled.' |
|
193 |
APPLICATION_CANNOT_APPROVE = "Cannot approve application %s in state '%s'" |
|
194 |
APPLICATION_CANNOT_DENY = "Cannot deny application %s in state '%s'" |
|
195 |
APPLICATION_CANNOT_DISMISS = "Cannot dismiss application %s in state '%s'" |
|
196 |
APPLICATION_CANNOT_CANCEL = "Cannot cancel application %s in state '%s'" |
|
197 |
APPLICATION_CANCELLED = "Your project application has been cancelled." |
|
209 |
NO_RESPONSE = 'There is no response.' |
|
210 |
NOT_ALLOWED_NEXT_PARAM = 'Not allowed next parameter.' |
|
211 |
MISSING_KEY_PARAMETER = 'Missing key parameter.' |
|
212 |
INVALID_KEY_PARAMETER = 'Invalid key.' |
|
213 |
DOMAIN_VALUE_ERR = 'Enter a valid domain.' |
|
214 |
QH_SYNC_ERROR = 'Failed to get synchronized with quotaholder.' |
|
215 |
UNIQUE_PROJECT_NAME_CONSTRAIN_ERR = ( |
|
216 |
'The project name (as specified in its application\'s definition) must ' |
|
217 |
'be unique among all active projects.') |
|
218 |
INVALID_PROJECT = 'Project %(id)s is invalid.' |
|
219 |
NOT_ALIVE_PROJECT = 'Project %(id)s is not alive.' |
|
220 |
NOT_SUSPENDED_PROJECT = 'Project %(id)s is not suspended.' |
|
221 |
NOT_ALLOWED = 'You do not have the permissions to perform this action.' |
|
222 |
MEMBER_NUMBER_LIMIT_REACHED = ( |
|
223 |
'You have reached the maximum number of members for this Project.') |
|
224 |
MEMBER_JOIN_POLICY_CLOSED = 'The Project\'s member join policy is closed.' |
|
225 |
MEMBER_LEAVE_POLICY_CLOSED = 'The project\'s member leave policy is closed.' |
|
226 |
NOT_MEMBERSHIP_REQUEST = 'This is not a valid membership request.' |
|
227 |
NOT_ACCEPTED_MEMBERSHIP = 'This is not an accepted membership.' |
|
228 |
MEMBERSHIP_REQUEST_EXISTS = 'The membership request already exists.' |
|
229 |
NO_APPLICANT = ( |
|
230 |
'Project application requires at least one applicant. None found.') |
|
231 |
INVALID_PROJECT_START_DATE = ( |
|
232 |
'Project start date should be equal or greater than the current date.') |
|
233 |
INVALID_PROJECT_END_DATE = ( |
|
234 |
'Project end date should be equal or greater than than the current date.') |
|
235 |
INCONSISTENT_PROJECT_DATES = ( |
|
236 |
'Project end date should be greater than the project start date.') |
|
237 |
ADD_PROJECT_MEMBERS_Q_HELP = ( |
|
238 |
'Add a comma separated list of user emails, eg. user1@user.com, ' |
|
239 |
'user2@user.com') |
|
240 |
ADD_PROJECT_MEMBERS_Q_PLACEHOLDER = 'user1@user.com, user2@user.com' |
|
241 |
MISSING_IDENTIFIER = 'Missing identifier.' |
|
242 |
UNKNOWN_USER_ID = 'There is no user identified by %s.' |
|
243 |
UNKNOWN_PROJECT_APPLICATION_ID = ( |
|
244 |
'There is no project application identified by %s.') |
|
245 |
UNKNOWN_PROJECT_ID = 'There is no project identified by %s.' |
|
246 |
UNKNOWN_IDENTIFIER = 'Unknown identifier.' |
|
247 |
PENDING_MEMBERSHIP_LEAVE = ( |
|
248 |
'Your request is pending moderation by the Project owner.') |
|
249 |
USER_MEMBERSHIP_ACCEPTED = '%s has been accepted in the project.' |
|
250 |
USER_MEMBERSHIP_REMOVED = '%s has been removed from the project.' |
|
251 |
USER_LEFT_PROJECT = 'You have left the project.' |
|
252 |
USER_LEAVE_REQUEST_SUBMITTED = ( |
|
253 |
'Your request to leave the project has been submitted successfully.') |
|
254 |
USER_JOIN_REQUEST_SUBMITTED = ( |
|
255 |
'Your request to join the project has been submitted successfully.') |
|
256 |
USER_JOINED_PROJECT = 'You have joined the project.' |
|
257 |
USER_REQUEST_CANCELLED = 'Your request to join the project has been cancelled.' |
|
258 |
APPLICATION_CANNOT_APPROVE = "Cannot approve application %s in state '%s'" |
|
259 |
APPLICATION_CANNOT_DENY = "Cannot deny application %s in state '%s'" |
|
260 |
APPLICATION_CANNOT_DISMISS = "Cannot dismiss application %s in state '%s'" |
|
261 |
APPLICATION_CANNOT_CANCEL = "Cannot cancel application %s in state '%s'" |
|
262 |
APPLICATION_CANCELLED = "Your project application has been cancelled." |
|
198 | 263 |
|
199 | 264 |
REACHED_PENDING_APPLICATION_LIMIT = ("You have reached the maximum number " |
200 | 265 |
"of pending project applications: %s.") |
... | ... | |
212 | 277 |
"Consider cancelling any unnecessary ones.") |
213 | 278 |
|
214 | 279 |
# Auth providers messages |
215 |
AUTH_PROVIDER_LOGIN_SUCCESS = "Logged in successfully, using {method_prompt}." |
|
216 |
AUTH_PROVIDER_LOGOUT_SUCCESS = "Logged out successfully." |
|
217 |
AUTH_PROVIDER_LOGOUT_SUCCESS_EXTRA = "You may still be logged in at {title} though. Consider logging out from there too." |
|
218 |
AUTH_PROVIDER_NOT_ACTIVE = "'{method_prompt}' is disabled." |
|
219 |
AUTH_PROVIDER_ADD_DISABLED = "{method_prompt} is disabled for your account." |
|
220 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_USER = "You cannot login using '{method_prompt}'." |
|
221 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_CREATE = "Sign up using '{method_prompt}' is disabled." |
|
222 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_ADD = "You cannot add {method_prompt}." |
|
223 |
AUTH_PROVIDER_ADDED = "{method_prompt} enabled for this account." |
|
224 |
AUTH_PROVIDER_SWITCHED = "{method_prompt} changed for this account." |
|
225 |
AUTH_PROVIDER_REMOVED = "{method_prompt} removed for this account." |
|
226 |
AUTH_PROVIDER_ADD_FAILED = "Failed to add {method_prompt}." |
|
227 |
AUTH_PROVIDER_ADD_EXISTS = "It seems that this '{method_prompt}' is already in use by another account." |
|
228 |
AUTH_PROVIDER_LOGIN_TO_ADD = "The new login method will be assigned once you login to your account." |
|
229 |
AUTH_PROVIDER_INVALID_LOGIN = "No account exists." |
|
230 |
AUTH_PROVIDER_REQUIRED = "{method_prompt} is required. Add one from your profile page." |
|
231 |
AUTH_PROVIDER_CANNOT_CHANGE_PASSWORD = "Changing password is not supported." |
|
232 |
AUTH_PROVIDER_SIGNUP_FROM_LOGIN = None |
|
233 |
AUTH_PROVIDER_UNUSABLE_PASSWORD = '{method_prompt} is not enabled' \ |
|
234 |
' for your account. You can access your account by logging in with' \ |
|
235 |
' {available_methods_links}.' |
|
236 |
AUTH_PROVIDER_LOGIN_DISABLED = AUTH_PROVIDER_UNUSABLE_PASSWORD |
|
237 |
AUTH_PROVIDER_SIGNUP_FROM_LOGIN = '' |
|
238 |
AUTH_PROVIDER_AUTHENTICATION_FAILED = 'Authentication with this account failed.' |
|
280 |
AUTH_PROVIDER_LOGIN_SUCCESS = "Logged in successfully, using {method_prompt}." |
|
281 |
AUTH_PROVIDER_LOGOUT_SUCCESS = "Logged out successfully." |
|
282 |
AUTH_PROVIDER_LOGOUT_SUCCESS_EXTRA = ( |
|
283 |
"You may still be logged in at {title} though. " |
|
284 |
"Consider logging out from there too.") |
|
285 |
AUTH_PROVIDER_NOT_ACTIVE = "'{method_prompt}' is disabled." |
|
286 |
AUTH_PROVIDER_ADD_DISABLED = "{method_prompt} is disabled for your account." |
|
287 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_USER = "You cannot login using '{method_prompt}'." |
|
288 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_CREATE = ( |
|
289 |
"Sign up using '{method_prompt}' is disabled.") |
|
290 |
AUTH_PROVIDER_NOT_ACTIVE_FOR_ADD = "You cannot add {method_prompt}." |
|
291 |
AUTH_PROVIDER_ADDED = "{method_prompt} enabled for this account." |
|
292 |
AUTH_PROVIDER_SWITCHED = "{method_prompt} changed for this account." |
|
293 |
AUTH_PROVIDER_REMOVED = "{method_prompt} removed for this account." |
|
294 |
AUTH_PROVIDER_ADD_FAILED = "Failed to add {method_prompt}." |
|
295 |
AUTH_PROVIDER_ADD_EXISTS = ( |
|
296 |
"It seems that this '{method_prompt}' is already in use by " |
|
297 |
"another account.") |
|
298 |
AUTH_PROVIDER_LOGIN_TO_ADD = ( |
|
299 |
"The new login method will be assigned once you login to your account.") |
|
300 |
AUTH_PROVIDER_INVALID_LOGIN = "No account exists." |
|
301 |
AUTH_PROVIDER_REQUIRED = ( |
|
302 |
"{method_prompt} is required. Add one from your profile page.") |
|
303 |
AUTH_PROVIDER_CANNOT_CHANGE_PASSWORD = "Changing password is not supported." |
|
304 |
AUTH_PROVIDER_SIGNUP_FROM_LOGIN = None |
|
305 |
AUTH_PROVIDER_UNUSABLE_PASSWORD = ( |
|
306 |
'{method_prompt} is not enabled' |
|
307 |
' for your account. You can access your account by logging in with' |
|
308 |
' {available_methods_links}.') |
|
309 |
AUTH_PROVIDER_LOGIN_DISABLED = AUTH_PROVIDER_UNUSABLE_PASSWORD |
|
310 |
AUTH_PROVIDER_SIGNUP_FROM_LOGIN = '' |
|
311 |
AUTH_PROVIDER_AUTHENTICATION_FAILED = ( |
|
312 |
'Authentication with this account failed.') |
|
239 | 313 |
|
240 | 314 |
|
241 |
AUTH_PROVIDER_PENDING_REGISTRATION = '''A pending registration exists for
|
|
315 |
AUTH_PROVIDER_PENDING_REGISTRATION = '''A pending registration exists for |
|
242 | 316 |
{title} account {username}. The email used for the registration is |
243 | 317 |
{user_email}. If you decide to procceed with the signup process once again, |
244 | 318 |
all pending registrations will be deleted.''' |
245 | 319 |
|
246 |
AUTH_PROVIDER_PENDING_RESEND_ACTIVATION = '<a href="{resend_activation_url}">Click here to resend activation email.</a>' |
|
247 |
AUTH_PROVIDER_PENDING_MODERATION = 'Your account request is pending moderation.' |
|
248 |
AUTH_PROVIDER_PENDING_ACTIVATION = 'Your account request is pending activation.' |
|
249 |
AUTH_PROVIDER_ACCOUNT_INACTIVE = 'Your account is disabled.' |
|
320 |
AUTH_PROVIDER_PENDING_RESEND_ACTIVATION = ( |
|
321 |
'<a href="{resend_activation_url}">Click here to resend activation ' |
|
322 |
'email.</a>') |
|
323 |
AUTH_PROVIDER_PENDING_MODERATION = ( |
|
324 |
'Your account request is pending moderation.') |
|
325 |
AUTH_PROVIDER_PENDING_ACTIVATION = ( |
|
326 |
'Your account request is pending activation.') |
|
327 |
AUTH_PROVIDER_ACCOUNT_INACTIVE = 'Your account is disabled.' |
|
250 | 328 |
|
251 |
AUTH_PROVIDER_ADD_TO_EXISTING_ACCOUNT = "You can add {method_prompt} to your existing account from your " \ |
|
252 |
" <a href='{profile_url}'>profile page</a>" |
|
329 |
AUTH_PROVIDER_ADD_TO_EXISTING_ACCOUNT = ( |
|
330 |
"You can add {method_prompt} to your existing account from your " |
|
331 |
" <a href='{profile_url}'>profile page</a>") |
|
253 | 332 |
|
254 | 333 |
# Email subjects |
255 | 334 |
_SITENAME = astakos_settings.SITENAME |
b/snf-astakos-app/astakos/im/models.py | ||
---|---|---|
148 | 148 |
else: |
149 | 149 |
metadata[component.name] = d |
150 | 150 |
|
151 |
|
|
152 | 151 |
def component_by_order(s): |
153 | 152 |
return s[1].get('order') |
154 | 153 |
|
... | ... | |
276 | 275 |
return '%ss' % self.display_name |
277 | 276 |
return self.display_name |
278 | 277 |
|
278 |
|
|
279 | 279 |
def get_resource_names(): |
280 | 280 |
_RESOURCE_NAMES = [] |
281 | 281 |
resources = Resource.objects.select_related('service').all() |
... | ... | |
320 | 320 |
Returns a uuid to username mapping for the uuids appearing in l. |
321 | 321 |
If l is None returns the mapping for all existing users. |
322 | 322 |
""" |
323 |
q = self.filter(uuid__in=l) if l != None else self
|
|
323 |
q = self.filter(uuid__in=l) if l is not None else self
|
|
324 | 324 |
return dict(q.values_list('uuid', 'username')) |
325 | 325 |
|
326 | 326 |
def displayname_catalog(self, l=None): |
... | ... | |
331 | 331 |
if l is not None: |
332 | 332 |
lmap = dict((x.lower(), x) for x in l) |
333 | 333 |
q = self.filter(username__in=lmap.keys()) |
334 |
values = ((lmap[n], u) for n, u in q.values_list('username', 'uuid')) |
|
334 |
values = ((lmap[n], u) |
|
335 |
for n, u in q.values_list('username', 'uuid')) |
|
335 | 336 |
else: |
336 | 337 |
q = self |
337 | 338 |
values = self.values_list('username', 'uuid') |
338 | 339 |
return dict(values) |
339 | 340 |
|
340 | 341 |
|
341 |
|
|
342 | 342 |
class AstakosUser(User): |
343 | 343 |
""" |
344 | 344 |
Extends ``django.contrib.auth.models.User`` by defining additional fields. |
345 | 345 |
""" |
346 |
affiliation = models.CharField(_('Affiliation'), max_length=255, blank=True,
|
|
347 |
null=True) |
|
346 |
affiliation = models.CharField(_('Affiliation'), max_length=255, |
|
347 |
blank=True, null=True)
|
|
348 | 348 |
|
349 | 349 |
#for invitations |
350 | 350 |
user_level = astakos_settings.DEFAULT_USER_LEVEL |
351 | 351 |
level = models.IntegerField(_('Inviter level'), default=user_level) |
352 | 352 |
invitations = models.IntegerField( |
353 |
_('Invitations left'), default=astakos_settings.INVITATIONS_PER_LEVEL.get(user_level, 0)) |
|
354 |
|
|
355 |
auth_token = models.CharField(_('Authentication Token'), |
|
356 |
max_length=64, |
|
357 |
unique=True, |
|
358 |
null=True, |
|
359 |
blank=True, |
|
360 |
help_text = _('Renew your authentication ' |
|
361 |
'token. Make sure to set the new ' |
|
362 |
'token in any client you may be ' |
|
363 |
'using, to preserve its ' |
|
364 |
'functionality.')) |
|
353 |
_('Invitations left'), |
|
354 |
default=astakos_settings.INVITATIONS_PER_LEVEL.get(user_level, 0)) |
|
355 |
|
|
356 |
auth_token = models.CharField( |
|
357 |
_('Authentication Token'), |
|
358 |
max_length=64, |
|
359 |
unique=True, |
|
360 |
null=True, |
|
361 |
blank=True, |
|
362 |
help_text=_('Renew your authentication ' |
|
363 |
'token. Make sure to set the new ' |
|
364 |
'token in any client you may be ' |
|
365 |
'using, to preserve its ' |
|
366 |
'functionality.')) |
|
365 | 367 |
auth_token_created = models.DateTimeField(_('Token creation date'), |
366 | 368 |
null=True) |
367 | 369 |
auth_token_expires = models.DateTimeField( |
... | ... | |
428 | 430 |
Resource, null=True, through='AstakosUserQuota') |
429 | 431 |
|
430 | 432 |
disturbed_quota = models.BooleanField(_('Needs quotaholder syncing'), |
431 |
default=False, db_index=True)
|
|
433 |
default=False, db_index=True) |
|
432 | 434 |
|
433 | 435 |
objects = AstakosUserManager() |
434 | 436 |
forupdate = ForUpdateManager() |
... | ... | |
463 | 465 |
if self.has_perm(pname): |
464 | 466 |
return |
465 | 467 |
p, created = Permission.objects.get_or_create( |
466 |
codename=pname,
|
|
467 |
name=pname.capitalize(),
|
|
468 |
content_type=get_content_type())
|
|
468 |
codename=pname, |
|
469 |
name=pname.capitalize(), |
|
470 |
content_type=get_content_type()) |
|
469 | 471 |
self.user_permissions.add(p) |
470 | 472 |
|
471 | 473 |
def remove_permission(self, pname): |
... | ... | |
545 | 547 |
self.auth_token = new_token |
546 | 548 |
self.auth_token_created = datetime.now() |
547 | 549 |
self.auth_token_expires = self.auth_token_created + \ |
548 |
timedelta(hours=astakos_settings.AUTH_TOKEN_DURATION)
|
|
550 |
timedelta(hours=astakos_settings.AUTH_TOKEN_DURATION) |
|
549 | 551 |
if flush_sessions: |
550 | 552 |
self.flush_sessions(current_key) |
551 | 553 |
msg = 'Token renewed for %s' % self.log_display |
... | ... | |
605 | 607 |
msg += " (manually accepted)" |
606 | 608 |
else: |
607 | 609 |
msg += " (accepted policy: %s)" % \ |
608 |
self.accepted_policy
|
|
610 |
self.accepted_policy |
|
609 | 611 |
return msg |
610 | 612 |
|
611 | 613 |
@property |
... | ... | |
730 | 732 |
|
731 | 733 |
def get_activation_url(self, nxt=False): |
732 | 734 |
url = "%s?auth=%s" % (reverse('astakos.im.views.activate'), |
733 |
quote(self.verification_code))
|
|
735 |
quote(self.verification_code)) |
|
734 | 736 |
if nxt: |
735 | 737 |
url += "&next=%s" % quote(nxt) |
736 | 738 |
return url |
737 | 739 |
|
738 | 740 |
def get_password_reset_url(self, token_generator=default_token_generator): |
739 | 741 |
return reverse('astakos.im.views.target.local.password_reset_confirm', |
740 |
kwargs={'uidb36':int_to_base36(self.id),
|
|
741 |
'token':token_generator.make_token(self)})
|
|
742 |
kwargs={'uidb36': int_to_base36(self.id),
|
|
743 |
'token': token_generator.make_token(self)})
|
|
742 | 744 |
|
743 | 745 |
def get_inactive_message(self, provider_module, identifier=None): |
744 | 746 |
provider = self.get_auth_provider(provider_module, identifier) |
... | ... | |
758 | 760 |
message = msg_pending |
759 | 761 |
url = self.get_resend_activation_url() |
760 | 762 |
msg_extra = msg_pending_help + \ |
761 |
u' ' + \
|
|
762 |
'<a href="%s">%s?</a>' % (url, msg_resend)
|
|
763 |
u' ' + \ |
|
764 |
'<a href="%s">%s?</a>' % (url, msg_resend) |
|
763 | 765 |
else: |
764 | 766 |
if not self.moderated: |
765 | 767 |
message = msg_pending_mod |
... | ... | |
930 | 932 |
""" |
931 | 933 |
Available user authentication methods. |
932 | 934 |
""" |
933 |
affiliation = models.CharField(_('Affiliation'), max_length=255, blank=True,
|
|
934 |
null=True, default=None) |
|
935 |
affiliation = models.CharField(_('Affiliation'), max_length=255, |
|
936 |
blank=True, null=True, default=None)
|
|
935 | 937 |
user = models.ForeignKey(AstakosUser, related_name='auth_providers') |
936 | 938 |
module = models.CharField(_('Provider'), max_length=255, blank=False, |
937 |
default='local')
|
|
939 |
default='local') |
|
938 | 940 |
identifier = models.CharField(_('Third-party identifier'), |
939 |
max_length=255, null=True,
|
|
940 |
blank=True)
|
|
941 |
max_length=255, null=True, |
|
942 |
blank=True) |
|
941 | 943 |
active = models.BooleanField(default=True) |
942 | 944 |
auth_backend = models.CharField(_('Backend'), max_length=255, blank=False, |
943 |
default='astakos') |
|
945 |
default='astakos')
|
|
944 | 946 |
info_data = models.TextField(default="", null=True, blank=True) |
945 | 947 |
created = models.DateTimeField('Creation date', auto_now_add=True) |
946 | 948 |
|
... | ... | |
959 | 961 |
except Exception, e: |
960 | 962 |
self.info = {} |
961 | 963 |
|
962 |
for key,value in self.info.iteritems(): |
|
964 |
for key, value in self.info.iteritems():
|
|
963 | 965 |
setattr(self, 'info_%s' % key, value) |
964 | 966 |
|
965 | 967 |
@property |
... | ... | |
977 | 979 |
|
978 | 980 |
extra_data['instance'] = self |
979 | 981 |
return auth.get_provider(self.module, self.user, |
980 |
self.identifier, **extra_data)
|
|
982 |
self.identifier, **extra_data) |
|
981 | 983 |
|
982 | 984 |
def __repr__(self): |
983 |
return '<AstakosUserAuthProvider %s:%s>' % (self.module, self.identifier) |
|
985 |
return '<AstakosUserAuthProvider %s:%s>' % ( |
|
986 |
self.module, self.identifier) |
|
984 | 987 |
|
985 | 988 |
def __unicode__(self): |
986 | 989 |
if self.identifier: |
... | ... | |
1055 | 1058 |
code = models.BigIntegerField(_('Invitation code'), db_index=True) |
1056 | 1059 |
is_consumed = models.BooleanField(_('Consumed?'), default=False) |
1057 | 1060 |
created = models.DateTimeField(_('Creation date'), auto_now_add=True) |
1058 |
consumed = models.DateTimeField(_('Consumption date'), null=True, blank=True) |
|
1061 |
consumed = models.DateTimeField(_('Consumption date'), |
|
1062 |
null=True, blank=True) |
|
1059 | 1063 |
|
1060 | 1064 |
def __init__(self, *args, **kwargs): |
1061 | 1065 |
super(Invitation, self).__init__(*args, **kwargs) |
... | ... | |
1099 | 1103 |
raise EmailChange.DoesNotExist |
1100 | 1104 |
# is there an active user with this address? |
1101 | 1105 |
try: |
1102 |
AstakosUser.objects.get(email__iexact=email_change.new_email_address) |
|
1106 |
AstakosUser.objects.get( |
|
1107 |
email__iexact=email_change.new_email_address) |
|
1103 | 1108 |
except AstakosUser.DoesNotExist: |
1104 | 1109 |
pass |
1105 | 1110 |
else: |
... | ... | |
1135 | 1140 |
|
1136 | 1141 |
def get_url(self): |
1137 | 1142 |
return reverse('email_change_confirm', |
1138 |
kwargs={'activation_key': self.activation_key}) |
|
1143 |
kwargs={'activation_key': self.activation_key})
|
|
1139 | 1144 |
|
1140 | 1145 |
def activation_key_expired(self): |
1141 |
expiration_date = timedelta(days=astakos_settings.EMAILCHANGE_ACTIVATION_DAYS) |
|
1146 |
expiration_date = timedelta( |
|
1147 |
days=astakos_settings.EMAILCHANGE_ACTIVATION_DAYS) |
|
1142 | 1148 |
return self.requested_at + expiration_date < datetime.now() |
1143 | 1149 |
|
1144 | 1150 |
|
... | ... | |
1173 | 1179 |
""" |
1174 | 1180 |
Model for registring successful third party user authentications |
1175 | 1181 |
""" |
1176 |
third_party_identifier = models.CharField(_('Third-party identifier'), max_length=255, null=True, blank=True) |
|
1182 |
third_party_identifier = models.CharField( |
|
1183 |
_('Third-party identifier'), max_length=255, null=True, blank=True) |
|
1177 | 1184 |
provider = models.CharField(_('Provider'), max_length=255, blank=True) |
1178 | 1185 |
email = models.EmailField(_('e-mail address'), blank=True, null=True) |
1179 | 1186 |
first_name = models.CharField(_('first name'), max_length=30, blank=True, |
... | ... | |
1182 | 1189 |
null=True) |
1183 | 1190 |
affiliation = models.CharField('Affiliation', max_length=255, blank=True, |
1184 | 1191 |
null=True) |
1185 |
username = models.CharField(_('username'), max_length=30, unique=True, |
|
1186 |
help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters")) |
|
1192 |
username = models.CharField( |
|
1193 |
_('username'), max_length=30, unique=True, |
|
1194 |
help_text=_("Required. 30 characters or fewer. " |
|
1195 |
"Letters, numbers and @/./+/-/_ characters")) |
|
1187 | 1196 |
token = models.CharField(_('Token'), max_length=255, null=True, blank=True) |
1188 | 1197 |
created = models.DateTimeField(auto_now_add=True, null=True, blank=True) |
1189 | 1198 |
info = models.TextField(default="", null=True, blank=True) |
... | ... | |
1211 | 1220 |
|
1212 | 1221 |
@property |
1213 | 1222 |
def realname(self): |
1214 |
return '%s %s' %(self.first_name, self.last_name) |
|
1223 |
return '%s %s' % (self.first_name, self.last_name)
|
|
1215 | 1224 |
|
1216 | 1225 |
@realname.setter |
1217 | 1226 |
def realname(self, value): |
... | ... | |
1226 | 1235 |
if not self.id: |
1227 | 1236 |
# set username |
1228 | 1237 |
while not self.username: |
1229 |
username = uuid.uuid4().hex[:30]
|
|
1238 |
username = uuid.uuid4().hex[:30] |
|
1230 | 1239 |
try: |
1231 |
AstakosUser.objects.get(username = username)
|
|
1240 |
AstakosUser.objects.get(username=username)
|
|
1232 | 1241 |
except AstakosUser.DoesNotExist, e: |
1233 | 1242 |
self.username = username |
1234 | 1243 |
super(PendingThirdPartyUser, self).save(**kwargs) |
... | ... | |
1239 | 1248 |
self.token = default_token_generator.make_token(self) |
1240 | 1249 |
|
1241 | 1250 |
def existing_user(self): |
1242 |
return AstakosUser.objects.filter(auth_providers__module=self.provider, |
|
1243 |
auth_providers__identifier=self.third_party_identifier) |
|
1251 |
return AstakosUser.objects.filter( |
|
1252 |
auth_providers__module=self.provider, |
|
1253 |
auth_providers__identifier=self.third_party_identifier) |
|
1244 | 1254 |
|
1245 | 1255 |
def get_provider(self, user): |
1246 | 1256 |
params = { |
... | ... | |
1250 | 1260 |
return auth.get_provider(self.provider, user, |
1251 | 1261 |
self.third_party_identifier, **params) |
1252 | 1262 |
|
1263 |
|
|
1253 | 1264 |
class SessionCatalog(models.Model): |
1254 | 1265 |
session_key = models.CharField(_('session key'), max_length=40) |
1255 | 1266 |
user = models.ForeignKey(AstakosUser, related_name='sessions', null=True) |
... | ... | |
1274 | 1285 |
def search_by_name(self, *search_strings): |
1275 | 1286 |
projects = Project.objects.search_by_name(*search_strings) |
1276 | 1287 |
chains = [p.id for p in projects] |
1277 |
apps = ProjectApplication.objects.search_by_name(*search_strings)
|
|
1288 |
apps = ProjectApplication.objects.search_by_name(*search_strings) |
|
1278 | 1289 |
apps = (app for app in apps if app.is_latest()) |
1279 | 1290 |
app_chains = [app.chain for app in apps if app.chain not in chains] |
1280 | 1291 |
return chains + app_chains |
... | ... | |
1309 | 1320 |
|
1310 | 1321 |
|
1311 | 1322 |
class Chain(models.Model): |
1312 |
chain = models.AutoField(primary_key=True)
|
|
1323 |
chain = models.AutoField(primary_key=True)
|
|
1313 | 1324 |
|
1314 | 1325 |
def __str__(self): |
1315 | 1326 |
return "%s" % (self.chain,) |
1316 | 1327 |
|
1317 | 1328 |
objects = ChainManager() |
1318 | 1329 |
|
1319 |
PENDING = 0
|
|
1320 |
DENIED = 3
|
|
1321 |
DISMISSED = 4
|
|
1322 |
CANCELLED = 5
|
|
1330 |
PENDING = 0 |
|
1331 |
DENIED = 3 |
|
1332 |
DISMISSED = 4 |
|
1333 |
CANCELLED = 5 |
|
1323 | 1334 |
|
1324 |
APPROVED = 10
|
|
1325 |
APPROVED_PENDING = 11
|
|
1326 |
SUSPENDED = 12
|
|
1327 |
SUSPENDED_PENDING = 13
|
|
1328 |
TERMINATED = 14
|
|
1335 |
APPROVED = 10 |
|
1336 |
APPROVED_PENDING = 11 |
|
1337 |
SUSPENDED = 12 |
|
1338 |
SUSPENDED_PENDING = 13 |
|
1339 |
TERMINATED = 14 |
|
1329 | 1340 |
TERMINATED_PENDING = 15 |
1330 | 1341 |
|
1331 | 1342 |
PENDING_STATES = [PENDING, |
... | ... | |
1353 | 1364 |
TERMINATED] |
1354 | 1365 |
|
1355 | 1366 |
STATE_DISPLAY = { |
1356 |
PENDING : _("Pending"), |
|
1357 |
DENIED : _("Denied"), |
|
1358 |
DISMISSED : _("Dismissed"), |
|
1359 |
CANCELLED : _("Cancelled"), |
|
1360 |
APPROVED : _("Active"), |
|
1361 |
APPROVED_PENDING : _("Active - Pending"), |
|
1362 |
SUSPENDED : _("Suspended"), |
|
1363 |
SUSPENDED_PENDING : _("Suspended - Pending"), |
|
1364 |
TERMINATED : _("Terminated"), |
|
1365 |
TERMINATED_PENDING : _("Terminated - Pending"), |
|
1366 |
} |
|
1367 |
|
Also available in: Unified diff