Permissions: change from list to key/value pairs in manifest #168

Merged
Oleg-Komarov merged 6 commits from permissions-dict into main 2024-06-04 17:34:33 +02:00
5 changed files with 46 additions and 14 deletions
Showing only changes of commit 1d3cd0ee83 - Show all commits

View File

@ -492,7 +492,9 @@ class VersionManager(models.Manager):
def update_or_create(self, *args, **kwargs):
# Stash the ManyToMany to be created after the Version has a valid ID already
licenses = kwargs.pop('licenses', [])
permissions = kwargs.pop('permissions', [])
permissions = kwargs.pop('permissions', {})
if permissions:
permissions = list(permissions.keys())
platforms = kwargs.pop('platforms', [])
tags = kwargs.pop('tags', [])

View File

@ -523,19 +523,19 @@ class ValidateManifestFields(TestCase):
**self.optional_fields,
}
data['permissions'] = ['files']
data['permissions'] = {'files': 'test files'}
ManifestValidator(data)
data.pop('permissions')
ManifestValidator(data)
data['permissions'] = ['non-supported-permission']
data['permissions'] = {'non-supported-permission': 'lalala'}
with self.assertRaises(ValidationError) as e:
ManifestValidator(data)
message_begin = "Manifest value error: <code>permissions</code> expects a list of"
message_begin = "Manifest value error: <code>permissions</code> expects key/value pairs of"
self.assertIn(message_begin, e.exception.messages[0])
self.assertIn('[\'files\', \'network\']', e.exception.messages[0])
self.assertIn('files, network', e.exception.messages[0])
# Check the permissions that will always be around.
message_end = e.exception.messages[0][len(message_begin) :]
@ -546,13 +546,13 @@ class ValidateManifestFields(TestCase):
for permission in VersionPermission.objects.all():
self.assertIn(permission.slug, message_end)
data['permissions'] = []
data['permissions'] = {}
with self.assertRaises(ValidationError) as e:
ManifestValidator(data)
self.assertEqual(1, len(e.exception.messages))
# Make sure permissions are only defined for add-ons, but fail for themes.
data['permissions'] = ['files']
data['permissions'] = {'files': 'test files'}
data['type'] = EXTENSION_TYPE_SLUGS_SINGULAR[EXTENSION_TYPE_CHOICES.THEME]
data['tags'] = []
with self.assertRaises(ValidationError) as e:
@ -693,7 +693,7 @@ class VersionPermissionsTest(CreateFileTest):
def test_version_permission_register(self):
"""Make sure permissions are saved"""
permissions = ['network']
permissions = {'network': 'talk to server'}
latest_version = self._test_version_permission(permissions)
self.assertEqual(latest_version.permissions.count(), 1)
self.assertEqual(latest_version.permissions.first().slug, 'network')

View File

@ -102,7 +102,9 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
# avoid triggering additional db queries, reuse the prefetched queryset
'maintainer': instance.team and instance.team.name or str(instance.authors.all()[0]),
'license': [license_iter.slug for license_iter in matching_version.licenses.all()],
'permissions': [permission.slug for permission in matching_version.permissions.all()],
'permissions': {
permission.slug: '-' for permission in matching_version.permissions.all()
},
'platforms': [platform.slug for platform in matching_version.platforms.all()],
# TODO: handle copyright
'tags': [str(tag) for tag in matching_version.tags.all()],

View File

@ -321,7 +321,10 @@ class TypeValidator:
class PermissionsValidator:
example = ['files', 'network']
example = {
'files': "Import/export FBX from/to disk",
'network': "Need to sync motion-capture data to server",
}
@classmethod
def validate(cls, *, name: str, value: str, manifest: dict) -> str:
@ -342,22 +345,47 @@ class PermissionsValidator:
if not is_bpy:
return
if (type(value) != list) or (not value):
if not isinstance(value, dict) or not value:
is_error = True
else:
for permission in value:
for permission, reason in value.items():
try:
VersionPermission.get_by_slug(permission)
except VersionPermission.DoesNotExist:
is_error = True
logger.info(f'Permission unavailable: {permission}')
if not isinstance(reason, str):
return mark_safe(
'Manifest value error: <code>permissions</code> reasons must be strings.'
)
if not reason:
return mark_safe(
f'Manifest value error: <code>permissions</code> {permission} reason '
'is empty.'
)
if reason[-1] in {'.', '!', '?'}:
return mark_safe(
'Manifest value error: <code>permissions</code> {permission} reason '
'cannot end with any punctuation (.!?).'
)
max_length = 64
if len(reason) > max_length:
return mark_safe(
f'Manifest value error: <code>permissions</code> {permission} reason is '
'too long ({len(value)}), '
f'max-length: {max_length} characters'
)
if not is_error:
return
error_message = (
f'Manifest value error: <code>permissions</code> expects a list of '
f'supported permissions. e.g.: {cls.example}. The supported permissions are: '
'Manifest value error: <code>permissions</code> expects key/value pairs of '
'supported permissions with the reasons why they are requred. '
'The supported permissions are: '
)
for permission_ob in VersionPermission.objects.all():