Skip to content

Commit

Permalink
… (#1364)
Browse files Browse the repository at this point in the history
* A new model was created that allows to associate a user group to a release. The queries for the release and dataset views have been changed so that only records related to public releases or releases associated with the group that the user belongs to are returned.
An additional get_user_releases method was created for the User models, this method returns all the release ids that the user is allowed to access. Closed #1363

* minor fix
  • Loading branch information
glaubervila authored May 24, 2021
1 parent f396008 commit a745795
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 9 deletions.
11 changes: 8 additions & 3 deletions api/coadd/admin.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
from django.contrib import admin

from .models import Release, Tile, Tag, Dataset, Survey
from .models import Release, ReleaseGroupPermission, Tile, Tag, Dataset, Survey


class ReleaseAdmin(admin.ModelAdmin):
list_display = ('id', 'rls_name', 'rls_display_name', 'rls_version',
'rls_date', 'rls_description', 'rls_doc_url',
'rls_default', 'rls_disabled')
'rls_default', 'rls_disabled', 'rls_is_public')
list_display_links = ('id', 'rls_name', 'rls_display_name', 'rls_version',
'rls_date', 'rls_description', 'rls_doc_url',
'rls_default',)
search_fields = ('id', 'rls_name', 'rls_display_name',)
search_fields = ('id', 'rls_name', 'rls_display_name', )


class ReleaseGroupPermissionAdmin(admin.ModelAdmin):
list_display = ('id', 'rgp_release', 'rgp_user_group', )


class TileAdmin(admin.ModelAdmin):
Expand Down Expand Up @@ -51,6 +55,7 @@ class SurveyAdmin(admin.ModelAdmin):


admin.site.register(Release, ReleaseAdmin)
admin.site.register(ReleaseGroupPermission, ReleaseGroupPermissionAdmin)
admin.site.register(Tile, TileAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(Dataset, DatasetAdmin)
Expand Down
18 changes: 18 additions & 0 deletions api/coadd/migrations/0005_release_rls_is_public.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.17 on 2021-05-19 14:25

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('coadd', '0004_release_rls_disabled'),
]

operations = [
migrations.AddField(
model_name='release',
name='rls_is_public',
field=models.BooleanField(default=False, help_text='Mark the release as public so that it is available to all users. uncheck it to make it available only to groups that have permission.', verbose_name='Is Public'),
),
]
22 changes: 22 additions & 0 deletions api/coadd/migrations/0006_releasegrouppermission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 2.2.17 on 2021-05-20 18:29

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('coadd', '0005_release_rls_is_public'),
]

operations = [
migrations.CreateModel(
name='ReleaseGroupPermission',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('rgp_release', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='release_group_permission', to='coadd.Release', verbose_name='Release')),
('rgp_user_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='coadd.Release', verbose_name='User Group')),
],
),
]
19 changes: 19 additions & 0 deletions api/coadd/migrations/0007_auto_20210520_1849.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.2.17 on 2021-05-20 18:49

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('coadd', '0006_releasegrouppermission'),
]

operations = [
migrations.AlterField(
model_name='releasegrouppermission',
name='rgp_user_group',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group', verbose_name='User Group'),
),
]
62 changes: 61 additions & 1 deletion api/coadd/models.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import logging

from django.contrib.auth.models import Group, User
from django.db import models
from django.db.models import Q

logger = logging.getLogger(__name__)


# Create your models here.
class Release(models.Model):

rls_name = models.CharField(
max_length=60, verbose_name='Internal Name')
rls_display_name = models.CharField(
Expand All @@ -26,10 +28,29 @@ class Release(models.Model):
default=False, verbose_name='Disabled',
help_text='Mark this release as Disabled so that the interfaces cant select this release.')

rls_is_public = models.BooleanField(
default=False, verbose_name='Is Public',
help_text='Mark the release as public so that it is available to all users. uncheck it to make it available only to groups that have permission.')

def __str__(self):
return self.rls_display_name


class ReleaseGroupPermission(models.Model):
rgp_release = models.ForeignKey(
Release,
related_name='release_group_permission',
on_delete=models.CASCADE,
verbose_name='Release'
)

rgp_user_group = models.ForeignKey(
Group,
on_delete=models.CASCADE,
verbose_name='User Group'
)


class Tile(models.Model):
tli_tilename = models.CharField(
db_index=True, max_length=20, unique=True, verbose_name='Tilename')
Expand Down Expand Up @@ -165,3 +186,42 @@ class Survey(models.Model):

def __str__(self):
return str(self.srv_display_name)


def get_user_releases(self):
"""Esta função é adicionada ao model User,
ela retorna os ids de todos os releases que o usuario tem permisão de acessar.
1 - Se o usuario é um staff do admin, retorna todos os releases HABILITADOS (rls_disabled=False)
2 - Para os demais usuarios, retorna todos os releases publicos (rls_is_public=True) e OU filtra pelos grupos dos usuarios,
esses grupos devem estar associados aos releases no model ReleaseGroupPermission.
Returns:
[list]: Lista de ids dos releases que o usuario pode ter acesso.
"""

releases = list()
# Se for um usuario Admin do django retorna todos os releases Habilitados.
if self.is_staff:
releases = Release.objects.filter(rls_disabled=False)
else:
# IDs dos grupos que o usuario faz parte
a_groups = []
for group in self.groups.all():
a_groups.append(group.pk)

# Todos os Releases Publicos + os Releases relacionados aos grupos que o usuario pertence.
releases = Release.objects.filter(
Q(rls_disabled=False) & Q(
Q(rls_is_public=True) | Q(release_group_permission__rgp_user_group__in=a_groups))
)

ids = list()
for release in releases:
ids.append(release.pk)

return ids


User.add_to_class('get_user_releases', get_user_releases)
1 change: 1 addition & 0 deletions api/coadd/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class Meta:
'rls_description',
'rls_default',
'rls_disabled',
'rls_is_public',
'tags_count',
'tiles_count',
)
Expand Down
29 changes: 27 additions & 2 deletions api/coadd/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@
TileSerializer)

from common.desaccess import DesAccessApi
from django.db.models import Q


class ReleaseViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows releases to be viewed or edited
"""

queryset = Release.objects.filter(rls_disabled=False)
# queryset = Release.objects.filter(rls_disabled=False)

serializer_class = ReleaseSerializer

Expand All @@ -35,6 +36,20 @@ class ReleaseViewSet(viewsets.ModelViewSet):

ordering_fields = '__all__'

def get_queryset(self):

# Se o usuario for admin do Django retorna todos os releases Habilitados
if self.request.user.is_staff:
return Release.objects.filter(rls_disabled=False)
else:
# Retorna os IDs de todos os releases que o usuario tem permissão de acessar.
perm_releases = self.request.user.get_user_releases()

# Todos os Releases Publicos + os Releases relacionados aos grupos que o usuario pertence.
queryset = Release.objects.filter(pk__in=perm_releases)

return queryset


class TagViewSet(viewsets.ModelViewSet):
"""
Expand Down Expand Up @@ -165,7 +180,7 @@ def filter_inspected(self, queryset, name, value):


class DatasetViewSet(viewsets.ModelViewSet):
queryset = Dataset.objects.select_related().all().prefetch_related('comments').prefetch_related('inspected')
# queryset = Dataset.objects.select_related().all().prefetch_related('comments').prefetch_related('inspected')

serializer_class = DatasetSerializer

Expand All @@ -179,6 +194,16 @@ class DatasetViewSet(viewsets.ModelViewSet):

ordering = ('tile__tli_tilename',)

def get_queryset(self):

# Recuperar os releases que o usuario tem acesso
releases = self.request.user.get_user_releases()

# Filtra a tabela de datasets pelo id dos releases que o usuario tem acesso.
queryset = Dataset.objects.select_related().all().prefetch_related('comments').prefetch_related('inspected').filter(tag__tag_release__pk__in=releases)

return queryset

@action(detail=True)
def desaccess_tile_info(self, request, pk=None):
"""Search DESaccess for tilename and return a list of tile files already filtered by the dataset release.
Expand Down
2 changes: 1 addition & 1 deletion api/common/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Create your models here.
from django.db import models
from django.contrib.auth.models import User
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver

Expand Down
4 changes: 3 additions & 1 deletion api/common/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,6 @@ def get_ncsa_signup(request):
def teste(request):
if request.method == 'GET':

return Response(dict({'status': "success"}))
releases = request.user.get_user_releases()

return Response(dict({'status': "success", "releases": releases}))
2 changes: 1 addition & 1 deletion api/dri/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
router.register(r'logged', common_views.LoggedUserViewSet, basename='logged')
router.register(r'users_same_group', common_views.UsersInSameGroupViewSet, basename='users_same_group')

router.register(r'releases', coadd_views.ReleaseViewSet)
router.register(r'releases', coadd_views.ReleaseViewSet, basename='releases')
router.register(r'tags', coadd_views.TagViewSet)
router.register(r'tiles', coadd_views.TileViewSet)
router.register(r'dataset', coadd_views.DatasetViewSet, basename='dataset')
Expand Down

0 comments on commit a745795

Please sign in to comment.