Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metadata permissions #107

Open
wants to merge 15 commits into
base: integration
Choose a base branch
from
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
docker:
- image: circleci/python:3.9

- image: circleci/mysql:5.6.51-ram
- image: circleci/mysql:5.7.37-ram
environment:
MYSQL_ROOT_PASSWORD: MICrONS
MYSQL_DATABASE: microns
Expand Down
35 changes: 35 additions & 0 deletions django/bosscore/migrations/0010_auto_20221106_2226.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generated by Django 2.2.18 on 2022-11-06 22:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('bosscore', '0009_auto_20210517_2146'),
]

operations = [
migrations.AlterModelOptions(
name='channel',
options={'default_permissions': (), 'permissions': (('read', 'Can view resource'), ('update', 'Can update resource'), ('delete', 'Can delete resource'), ('add', 'Can add resources '), ('assign_group', 'Can assign groups permissions for the resource'), ('remove_group', 'Can remove groups permissions for the resource'), ('add_volumetric_data', 'Can add volumetric data for the channel'), ('read_volumetric_data', 'Can read volumetric data for the channel'), ('delete_volumetric_data', 'Can delete volumetric data for the channel'), ('add_metadata', 'Can add metadata for the channel'), ('read_metadata', 'Can read metadata for the channel'), ('update_metadata', 'Can read metadata for the channel'), ('delete_metadata', 'Can delete metadata for the channel'))},
),
migrations.AlterModelOptions(
name='collection',
options={'default_permissions': (), 'managed': True, 'permissions': (('read', 'Can view resource'), ('update', 'Can update resource'), ('delete', 'Can delete resource'), ('add', 'Can add resources '), ('assign_group', 'Can assign groups permissions for the resource'), ('remove_group', 'Can remove groups permissions for the resource'), ('add_metadata', 'Can add metadata for the channel'), ('read_metadata', 'Can read metadata for the channel'), ('update_metadata', 'Can read metadata for the channel'), ('delete_metadata', 'Can delete metadata for the channel'))},
),
migrations.AlterModelOptions(
name='experiment',
options={'default_permissions': (), 'permissions': (('read', 'Can view resource'), ('update', 'Can update resource'), ('delete', 'Can delete resource'), ('add', 'Can add resources '), ('assign_group', 'Can assign groups permissions for the resource'), ('remove_group', 'Can remove groups permissions for the resource'), ('add_metadata', 'Can add metadata for the channel'), ('read_metadata', 'Can read metadata for the channel'), ('update_metadata', 'Can read metadata for the channel'), ('delete_metadata', 'Can delete metadata for the channel'))},
),
migrations.AlterField(
model_name='channel',
name='cv_path',
field=models.CharField(blank=True, max_length=2000, null=True),
),
migrations.AlterField(
model_name='channel',
name='downsample_arn',
field=models.CharField(max_length=4096, null=True),
),
]
12 changes: 12 additions & 0 deletions django/bosscore/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class Meta:
('add', 'Can add resources '),
('assign_group', 'Can assign groups permissions for the resource'),
('remove_group', 'Can remove groups permissions for the resource'),
('add_metadata', 'Can add metadata for the channel'),
('read_metadata', 'Can read metadata for the channel'),
('update_metadata', 'Can update metadata for the channel'),
('delete_metadata', 'Can delete metadata for the channel')

)

Expand Down Expand Up @@ -226,6 +230,10 @@ class Meta:
('add', 'Can add resources '),
('assign_group', 'Can assign groups permissions for the resource'),
('remove_group', 'Can remove groups permissions for the resource'),
('add_metadata', 'Can add metadata for the channel'),
('read_metadata', 'Can read metadata for the channel'),
('update_metadata', 'Can update metadata for the channel'),
('delete_metadata', 'Can delete metadata for the channel')
)

def __str__(self):
Expand Down Expand Up @@ -333,6 +341,10 @@ class Meta:
('add_volumetric_data', 'Can add volumetric data for the channel'),
('read_volumetric_data', 'Can read volumetric data for the channel'),
('delete_volumetric_data', 'Can delete volumetric data for the channel'),
('add_metadata', 'Can add metadata for the channel'),
('read_metadata', 'Can read metadata for the channel'),
('update_metadata', 'Can update metadata for the channel'),
('delete_metadata', 'Can delete metadata for the channel'),
)

def add_source(self, source):
Expand Down
48 changes: 32 additions & 16 deletions django/bosscore/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ def add_permissions_primary_group(user, obj):
assign_perm('delete', user_primary_group, obj)
assign_perm('assign_group', user_primary_group, obj)
assign_perm('remove_group', user_primary_group, obj)

# Add metadata permissions for primary user
if ct.model != 'coordinateframe':
assign_perm('read_metadata', user_primary_group, obj)
assign_perm('add_metadata', user_primary_group, obj)
assign_perm('update_metadata', user_primary_group, obj)
assign_perm('delete_metadata', user_primary_group, obj)

if ct.model == 'channel':
assign_perm('add_volumetric_data', user_primary_group, obj)
assign_perm('read_volumetric_data', user_primary_group, obj)
Expand Down Expand Up @@ -182,6 +190,14 @@ def add_permissions_admin_group(obj):
assign_perm('delete', admin_group, obj)
assign_perm('assign_group', admin_group, obj)
assign_perm('remove_group', admin_group, obj)

# Add metadata permissions for admin user
if ct.model != 'coordinateframe':
assign_perm('read_metadata', admin_group, obj)
assign_perm('add_metadata', admin_group, obj)
assign_perm('update_metadata', admin_group, obj)
assign_perm('delete_metadata', admin_group, obj)

if ct.model == 'channel':
assign_perm('add_volumetric_data', admin_group, obj)
assign_perm('read_volumetric_data', admin_group, obj)
Expand All @@ -192,26 +208,24 @@ def add_permissions_admin_group(obj):
ErrorCodes.GROUP_NOT_FOUND)

@staticmethod
def check_resource_permissions(user, obj, method_type):
def check_data_permissions(user, obj, method_type):
"""
Check user permissions for a resource object
Check user permissions for a data
Args:
user: User name
obj: Obj
method_type: Method type specified in the request
obj: resource
method_type: Method type specified in the post

Returns:
bool. True if the user has the permission on the resource

"""
if method_type == 'GET':
permission = 'read'
elif method_type == 'POST':
permission = 'add'
elif method_type == 'PUT':
permission = 'update'
permission = 'read_volumetric_data'
elif method_type == 'POST' or method_type == 'PUT':
permission = 'add_volumetric_data'
elif method_type == 'DELETE':
permission = 'delete'
permission = 'delete_volumetric_data'
else:
raise BossError("Unable to get permissions for this request", ErrorCodes.INVALID_POST_ARGUMENT)

Expand All @@ -221,9 +235,9 @@ def check_resource_permissions(user, obj, method_type):
return False

@staticmethod
def check_data_permissions(user, obj, method_type):
def check_metadata_permissions(user, obj, method_type):
"""
Check user permissions for a data
Check user permissions for a metadata entry
Args:
user: User name
obj: resource
Expand All @@ -234,11 +248,13 @@ def check_data_permissions(user, obj, method_type):

"""
if method_type == 'GET':
permission = 'read_volumetric_data'
elif method_type == 'POST' or method_type == 'PUT':
permission = 'add_volumetric_data'
permission = 'read_metadata'
elif method_type == 'POST':
permission = 'add_metadata'
elif method_type == 'PUT':
permission = 'update_metadata'
elif method_type == 'DELETE':
permission = 'delete_volumetric_data'
permission = 'delete_metadata'
else:
raise BossError("Unable to get permissions for this request", ErrorCodes.INVALID_POST_ARGUMENT)

Expand Down
2 changes: 1 addition & 1 deletion django/bosscore/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,7 +808,7 @@ def check_permissions(self):
else:
raise BossError("Error encountered while checking permissions for this request",
ErrorCodes.UNABLE_TO_VALIDATE)
perm = BossPermissionManager.check_resource_permissions(self.user, obj, self.method)
perm = BossPermissionManager.check_metadata_permissions(self.user, obj, self.method)
elif self.service == 'reserve':
perm = BossPermissionManager.check_object_permissions(self.user, self.channel, self.method)

Expand Down
7 changes: 7 additions & 0 deletions django/bosscore/test/setup_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,13 @@ def add_permissions(group, obj):
assign_perm('delete', user_primary_group, obj)
assign_perm('assign_group', user_primary_group, obj)
assign_perm('remove_group', user_primary_group, obj)

if ct.model != 'coordinateframe':
assign_perm('read_metadata', user_primary_group, obj)
assign_perm('add_metadata', user_primary_group, obj)
assign_perm('update_metadata', user_primary_group, obj)
assign_perm('delete_metadata', user_primary_group, obj)

if ct.model == 'channel':
assign_perm('add_volumetric_data', user_primary_group, obj)
assign_perm('read_volumetric_data', user_primary_group, obj)
Expand Down
2 changes: 1 addition & 1 deletion django/mgmt/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def disable_non_admin_fields(self):
def PermField():
#perms = ['read', 'add', 'update', 'delete', 'assign_group', 'remove_group']
#return forms.MultipleChoiceField(choices=[(c,c) for c in perms])
perms = ['read', 'write', 'admin', 'admin+delete']
perms = ['read', 'read+addmeta', 'read+fullmeta', 'write', 'admin', 'admin+delete']
return forms.ChoiceField(choices=[(c,c) for c in perms])

class ResourcePermissionsForm(forms.Form):
Expand Down
60 changes: 47 additions & 13 deletions django/mgmt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,20 @@ def gen_key(ps):
add_v = [t,t,f]
del_v = [t,t,t]

def make_selection(p,is_chan):
# read_metadata, add_metadata, update_metadata, delete_metadata
read_m = [t, f, f, f]
add_m = [t, t, f, f]
del_m = [t, t, t, t]

def make_selection(p, is_chan):
"""Returns a permission group or raw permissions based on the raw
permissions from the requesting user's group.

Args:
p (list): list of raw permissions from the requestor's group
is_chan (bool): True if the requested resource is a channel
"""

chk = [
'read' in p,
'add' in p,
Expand All @@ -44,26 +57,41 @@ def make_selection(p,is_chan):
'delete_volumetric_data' in p,
]

chk_m = [
'read_metadata' in p,
'add_metadata' in p,
'update_metadata' in p,
'delete_metadata' in p
]

perm = None
if not is_chan:
if chk == read:
if chk == read and chk_m == read_m:
perm = "read"
elif chk == write:
elif chk == read and chk_m == add_m:
perm = "read+addmeta"
elif chk == read and chk_m == del_m:
perm = "read+fullmeta"
elif chk == write and chk_m == del_m:
perm = "write"
elif chk == admin:
elif chk == admin and chk_m == del_m:
perm = "admin"
elif chk == admin_d:
elif chk == admin_d and chk_m == del_m:
perm = "admin+delete"
else:
perm = "Raw: " + ", ".join(p)
else:
if chk == read and chk_v == read_v:
if chk == read and chk_m == read_m and chk_v == read_v:
perm = "read"
elif chk == write and chk_v == add_v:
elif chk == read and chk_m == add_m and chk_v == read_v:
perm = "read+addmeta"
elif chk == read and chk_m == del_m and chk_v == read_v:
perm = "read+fullmeta"
elif chk == write and chk_m == del_m and chk_v == add_v:
perm = "write"
elif chk == admin and chk_v == add_v: # make sure admin has proper permissions
elif chk == admin and chk_m == del_m and chk_v == add_v:
perm = "admin"
elif chk == admin_d and chk_v == del_v:
elif chk == admin_d and chk_m == del_m and chk_v == del_v:
perm = "admin+delete"
else:
perm = "Raw: " + ", ".join(p)
Expand Down Expand Up @@ -97,13 +125,19 @@ def set_perms(request, form, collection=None, experiment=None, channel=None, gro

perms = data['permissions']
if perms == "read":
perms = ['read']
perms = ['read', 'read_metadata']
elif perms == "read+addmeta":
perms = ['read', 'read_metadata', 'add_metadata']
elif perms == "read+fullmeta":
perms = ['read', 'read_metadata', 'update_metadata', 'add_metadata', 'delete_metadata']
elif perms == "write":
perms = ['read', 'add', 'update']
perms = ['read', 'add', 'update', 'read_metadata', 'update_metadata', 'add_metadata', 'delete_metadata']
elif perms == "admin":
perms = ['read', 'add', 'update', 'assign_group', 'remove_group']
perms = ['read', 'add', 'update', 'assign_group', 'remove_group',
'read_metadata', 'update_metadata', 'add_metadata', 'delete_metadata']
elif perms == "admin+delete":
perms = ['read', 'add', 'update', 'delete', 'assign_group', 'remove_group']
perms = ['read', 'add', 'update', 'delete', 'assign_group', 'remove_group',
'read_metadata', 'update_metadata', 'add_metadata', 'delete_metadata']
else:
raise Exception("Unknown permissions: " + perms)

Expand Down
4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ djangorestframework==3.11.2
drf-yasg==1.17.1
Markdown==3.3.4
mysqlclient==1.4.6
numpy==1.18.1
# Upgrade numpy to fix C-header issue
# https://stackoverflow.com/questions/66060487/valueerror-numpy-ndarray-size-changed-may-indicate-binary-incompatibility-exp
numpy==1.23.4
wheel==0.24.0
uWSGI==2.0.19.1

Expand Down