diff --git a/src/c3nav/control/templates/control/user.html b/src/c3nav/control/templates/control/user.html
index c927a598..d55f36d5 100644
--- a/src/c3nav/control/templates/control/user.html
+++ b/src/c3nav/control/templates/control/user.html
@@ -46,7 +46,7 @@
{% if access_permission.expire_date %}{{ access_permission.expire_date }}{% else %}{% trans 'never' %}{% endif %} |
{% if access_permission.can_grant %}{% trans 'Yes' %}{% else %}{% trans 'No' %}{% endif %} |
- {{ access_permission. }}{% if access_permission.can_grant %}{% trans 'Yes' %}{% else %}{% trans 'No' %}{% endif %} |
+ {% if access_permission.unique_key %}{{ access_permission.unique_key }}{% endif %} |
{% if request.user_permissions.grant_all_access or request.user == access_permission.author %}
|
{% endif %}
diff --git a/src/c3nav/mapdata/migrations/0064_access_permission_unique_key.py b/src/c3nav/mapdata/migrations/0064_access_permission_unique_key.py
new file mode 100644
index 00000000..8c0b0267
--- /dev/null
+++ b/src/c3nav/mapdata/migrations/0064_access_permission_unique_key.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.7 on 2017-12-19 11:10
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('mapdata', '0063_descriptions_unique_together'),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name='accesspermissiontoken',
+ options={'verbose_name': 'Access Permission Token', 'verbose_name_plural': 'Access Permission Tokens'},
+ ),
+ migrations.AddField(
+ model_name='accesspermission',
+ name='unique_key',
+ field=models.CharField(max_length=32, null=True, verbose_name='unique key'),
+ ),
+ migrations.AddField(
+ model_name='accesspermissiontoken',
+ name='unique_key',
+ field=models.CharField(max_length=32, null=True, verbose_name='unique key'),
+ ),
+ migrations.AlterUniqueTogether(
+ name='accesspermission',
+ unique_together=set([('author', 'unique_key')]),
+ ),
+ ]
diff --git a/src/c3nav/mapdata/models/access.py b/src/c3nav/mapdata/models/access.py
index 815da566..05878a99 100644
--- a/src/c3nav/mapdata/models/access.py
+++ b/src/c3nav/mapdata/models/access.py
@@ -55,8 +55,14 @@ class AccessPermissionToken(models.Model):
unlimited = models.BooleanField(default=False, db_index=True, verbose_name=_('unlimited'))
redeemed = models.BooleanField(default=False, db_index=True, verbose_name=_('redeemed'))
can_grant = models.BooleanField(default=False, db_index=True, verbose_name=_('can grant'))
+ unique_key = models.CharField(max_length=32, null=True, verbose_name=_('unique key'))
data = models.BinaryField()
+ class Meta:
+ verbose_name = _('Access Permission Token')
+ verbose_name_plural = _('Access Permission Tokens')
+ default_related_name = 'accessrestriction_tokens'
+
@property
def restrictions(self) -> Sequence[AccessPermissionTokenItem]:
return pickle.loads(self.data)
@@ -76,15 +82,19 @@ class AccessPermissionToken(models.Model):
raise self.RedeemError('No longer valid.')
if user:
- for restriction in self.restrictions:
- AccessPermission.objects.create(
- user=user,
- access_restriction_id=restriction.pk,
- author_id=self.author_id,
- expire_date=restriction.expire_date,
- can_grant=self.can_grant,
- token=self if self.pk else None,
- )
+ with transaction.atomic():
+ if self.author_id and self.unique_key:
+ AccessPermission.objects.filter(author_id=self.author_id, unique_key=self.unique_key).delete()
+ for restriction in self.restrictions:
+ AccessPermission.objects.create(
+ user=user,
+ access_restriction_id=restriction.pk,
+ author_id=self.author_id,
+ expire_date=restriction.expire_date,
+ can_grant=self.can_grant,
+ unique_key=self.unique_key,
+ token=self if self.pk else None,
+ )
if self.pk and not self.unlimited:
self.redeemed = True
@@ -105,6 +115,7 @@ class AccessPermission(models.Model):
can_grant = models.BooleanField(default=False, verbose_name=_('can grant'))
author = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL,
related_name='authored_access_permissions', verbose_name=_('Author'))
+ unique_key = models.CharField(max_length=32, null=True, verbose_name=_('unique key'))
token = models.ForeignKey(AccessPermissionToken, null=True, on_delete=models.CASCADE,
verbose_name=_('Access permission token'))
@@ -112,6 +123,9 @@ class AccessPermission(models.Model):
verbose_name = _('Access Permission')
verbose_name_plural = _('Access Permissions')
default_related_name = 'accesspermissions'
+ unique_together = (
+ ('author', 'unique_key')
+ )
@staticmethod
def user_access_permission_key(user_id):