Access url for interventions

* adds access_token as new attribute
* adds generating of access_token
* adds new form
* adds two new routes for sharing an intervention
* adds translation
* adds render_submit to BaseModalForm which triggers rendering the modal footer
This commit is contained in:
mipel
2021-07-30 13:30:42 +02:00
parent b7ab9f6f55
commit 2f33e5fba9
9 changed files with 345 additions and 169 deletions
+41
View File
@@ -13,6 +13,7 @@ from django.utils.timezone import now
from intervention.settings import INTERVENTION_IDENTIFIER_LENGTH, INTERVENTION_IDENTIFIER_TEMPLATE
from konova.models import BaseObject, Geometry, UuidModel
from konova.utils import generators
from konova.utils.generators import generate_random_string
from organisation.models import Organisation
from user.models import UserActionLogEntry
@@ -92,6 +93,12 @@ class Intervention(BaseObject):
# Users having access on this object
users = models.ManyToManyField(User)
access_token = models.CharField(
max_length=255,
null=True,
blank=True,
help_text="Used for sharing access",
)
def __str__(self):
return "{} ({})".format(self.identifier, self.title)
@@ -139,6 +146,40 @@ class Intervention(BaseObject):
_str = "{}{}{}".format(curr_month, curr_year, rand_str)
return INTERVENTION_IDENTIFIER_TEMPLATE.format(_str)
def generate_access_token(self, make_unique: bool = False, rec_depth: int = 5):
""" Creates a new access token for the intervention
Tokens are not used for identification of a table row. The share logic checks the intervention id as well
as the given token. Therefore two different interventions can hold the same access_token without problems.
For (possible) future changes to the share logic, the make_unique parameter may be used for checking whether
the access_token is already used in any intervention. If so, tokens will be generated as long as a free token
can be found.
Args:
make_unique (bool): Perform check on uniqueness over all intervention entries
rec_depth (int): How many tries for generating a free random token (only if make_unique)
Returns:
"""
# Make sure we won't end up in an infinite loop of trying to generate access_tokens
rec_depth = rec_depth - 1
if rec_depth < 0 and make_unique:
raise RuntimeError(
"Access token generating for {} does not seem to find a free random token! Aborted!".format(self.id)
)
# Create random token
token = generators.generate_random_string(15)
token_used_in = Intervention.objects.filter(access_token=token)
# Make sure the token is not used anywhere as access_token, yet.
# Make use of QuerySet lazy method for checking if it exists or not.
if token_used_in and make_unique:
self.generate_access_token(make_unique, rec_depth)
else:
self.access_token = token
self.save()
def save(self, *args, **kwargs):
if self.identifier is None or len(self.identifier) == 0:
# Create new identifier