From 174907ba304ef23613ad39cf4eb9d5e6c0b17adc Mon Sep 17 00:00:00 2001 From: Mikko Nieminen Date: Thu, 5 Sep 2024 13:56:29 +0200 Subject: [PATCH] add ProjectInvite.reset_date_expire() helper (#1486) --- CHANGELOG.rst | 2 ++ .../management/commands/batchupdateroles.py | 3 +-- projectroles/models.py | 25 +++++++++++++++++++ projectroles/serializers.py | 4 +-- projectroles/tests/test_models.py | 20 +++++++-------- projectroles/utils.py | 11 -------- projectroles/views.py | 5 ++-- 7 files changed, 41 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 83ead18c..b0bdd5d5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,7 @@ Added - **Projectroles** - ``get_user_by_uuid()`` common template tag (#1478) - ``ProjectInvite.get_url()`` helper (#1485) + - ``ProjectInvite.refresh_date_expire()`` helper (#1486) Changed ------- @@ -41,6 +42,7 @@ Removed - **Projectroles** - ``build_invite_url()`` utility method (#1485) + - ``get_expiry_date()`` utility method (#1486) v1.0.1 (2024-08-08) diff --git a/projectroles/management/commands/batchupdateroles.py b/projectroles/management/commands/batchupdateroles.py index b16ec99c..7838b604 100644 --- a/projectroles/management/commands/batchupdateroles.py +++ b/projectroles/management/commands/batchupdateroles.py @@ -18,7 +18,7 @@ SODAR_CONSTANTS, ) from projectroles.views import RoleAssignmentModifyMixin, ProjectInviteMixin -from projectroles.utils import get_expiry_date, build_secret +from projectroles.utils import build_secret logger = ManagementCommandLogger(__name__) @@ -116,7 +116,6 @@ def _invite_user(self, email, project, role): project=project, role=role, issuer=self.issuer, - date_expire=get_expiry_date(), secret=build_secret(), ) self.handle_invite(invite, self.request, add_message=False) diff --git a/projectroles/models.py b/projectroles/models.py index 08a17a49..e96e0acd 100644 --- a/projectroles/models.py +++ b/projectroles/models.py @@ -11,6 +11,7 @@ from django.db import models from django.db.models import Q from django.urls import reverse +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from djangoplugins.models import Plugin @@ -1101,6 +1102,22 @@ def __repr__(self): values = (self.project.title, self.email, self.role.name, self.active) return 'ProjectInvite({})'.format(', '.join(repr(v) for v in values)) + @classmethod + def _get_date_expire(cls): + """ + Return expiry date based on current date + INVITE_EXPIRY_DAYS + + :return: DateTime object + """ + return timezone.now() + timezone.timedelta( + days=settings.PROJECTROLES_INVITE_EXPIRY_DAYS + ) + + def save(self, *args, **kwargs): + if not self.pk and not self.date_expire: # Set date_expire on create + self.date_expire = self._get_date_expire() + super().save(*args, **kwargs) + # Custom row-level functions def is_ldap(self): @@ -1139,6 +1156,14 @@ def get_url(self, request): ) ) + def reset_date_expire(self): + """ + Reset date_expire to current date plus defined expiry days. Saves the + object. + """ + self.date_expire = self._get_date_expire() + self.save() + # RemoteSite ------------------------------------------------------------------- diff --git a/projectroles/serializers.py b/projectroles/serializers.py index b459cfe1..b8ee6263 100644 --- a/projectroles/serializers.py +++ b/projectroles/serializers.py @@ -21,7 +21,7 @@ CAT_DELIMITER_ERROR_MSG, ROLE_PROJECT_TYPE_ERROR_MSG, ) -from projectroles.utils import build_secret, get_expiry_date +from projectroles.utils import build_secret from projectroles.views import ( ProjectModifyMixin, RoleAssignmentModifyMixin, @@ -349,7 +349,7 @@ def validate(self, attrs): def create(self, validated_data): validated_data['issuer'] = self.context['request'].user - validated_data['date_expire'] = get_expiry_date() + # validated_data['date_expire'] = get_expiry_date() validated_data['secret'] = build_secret() return super().create(validated_data) diff --git a/projectroles/tests/test_models.py b/projectroles/tests/test_models.py index 7347f0ef..4efac30c 100644 --- a/projectroles/tests/test_models.py +++ b/projectroles/tests/test_models.py @@ -2,7 +2,6 @@ import uuid -from django.conf import settings from django.contrib.auth.models import Group from django.core.exceptions import ValidationError from django.forms.models import model_to_dict @@ -149,16 +148,7 @@ def make_invite( 'role': role, 'issuer': issuer, 'message': message, - 'date_expire': ( - date_expire - if date_expire - else ( - timezone.now() - + timezone.timedelta( - days=settings.PROJECTROLES_INVITE_EXPIRY_DAYS - ) - ) - ), + 'date_expire': date_expire, 'secret': secret or SECRET, 'active': True, } @@ -1016,6 +1006,14 @@ def test_get_url(self): self.invite.get_url(request), request.build_absolute_uri() ) + def test_reset_date_expire(self): + """Test reset_date_expire()""" + old_date = self.invite.date_expire + self.assertIsNotNone(old_date) + self.invite.reset_date_expire() + self.assertNotEqual(self.invite.date_expire, old_date) + self.assertTrue(self.invite.date_expire > old_date) + @override_settings( ENABLE_LDAP=True, AUTH_LDAP_USERNAME_DOMAIN='xyz', diff --git a/projectroles/utils.py b/projectroles/utils.py index 70837d5d..907f3a16 100644 --- a/projectroles/utils.py +++ b/projectroles/utils.py @@ -3,14 +3,12 @@ from django.conf import settings from django.urls import reverse -from django.utils import timezone from projectroles.plugins import get_active_plugins from projectroles.models import SODAR_CONSTANTS # Settings SECRET_LENGTH = getattr(settings, 'PROJECTROLES_SECRET_LENGTH', 32) -INVITE_EXPIRY_DAYS = settings.PROJECTROLES_INVITE_EXPIRY_DAYS # SODAR constants PROJECT_TYPE_PROJECT = SODAR_CONSTANTS['PROJECT_TYPE_PROJECT'] @@ -77,15 +75,6 @@ def build_secret(length=SECRET_LENGTH): ) -def get_expiry_date(): - """ - Return expiry date based on current date + INVITE_EXPIRY_DAYS - - :return: DateTime object - """ - return timezone.now() + timezone.timedelta(days=INVITE_EXPIRY_DAYS) - - def get_app_names(): """Return list of names for locally installed non-django apps""" ret = [] diff --git a/projectroles/views.py b/projectroles/views.py index 7bea9e9e..a1ece660 100644 --- a/projectroles/views.py +++ b/projectroles/views.py @@ -58,7 +58,7 @@ get_backend_api, ) from projectroles.remote_projects import RemoteProjectAPI -from projectroles.utils import get_expiry_date, get_display_name +from projectroles.utils import get_display_name app_settings = AppSettingAPI() @@ -2935,8 +2935,7 @@ def get(self, *args, **kwargs): ) ) # Reset invite expiration date - invite.date_expire = get_expiry_date() - invite.save() + invite.reset_date_expire() # Resend mail and add to timeline self.handle_invite(invite=invite, request=self.request, resend=True) return redirect(