1
Fork 0
mirror of https://github.com/Steffo99/sophon.git synced 2024-12-22 14:54:22 +00:00

🔧 Dynamically create the serializer for users who can edit a notebook

This commit is contained in:
Steffo 2021-10-18 02:28:10 +02:00 committed by Stefano Pigozzi
parent 8bae344c68
commit b493a65e01
2 changed files with 41 additions and 2 deletions

View file

@ -1,5 +1,5 @@
from django.contrib.auth.models import User
from rest_framework.serializers import Serializer, ModelSerializer, CharField
from rest_framework.serializers import Serializer, ModelSerializer
class NoneSerializer(Serializer):
@ -29,3 +29,20 @@ class UserSerializer(ModelSerializer):
"last_name",
"email",
)
def dynamic_serializer(_model, _fields, _read_only_fields):
"""
:param _model: The model the serializer is for.
:param _fields: The fields to pass to the meta of the serializer class.
:param _read_only_fields: The read_only_fields to pass to the meta of the serializer class.
:return: a serializer class with the specified parameters.
"""
class DynamicSerializer(ModelSerializer):
class Meta:
model = _model
fields = _fields
read_only_fields = _read_only_fields
return DynamicSerializer

View file

@ -11,8 +11,10 @@ import docker.models.networks
import docker.models.volumes
from django.contrib.auth.models import User
from django.db import models
from rest_framework.serializers import ModelSerializer
from sophon.core.models import SophonGroupModel, ResearchGroup
from sophon.core.serializers import dynamic_serializer
from sophon.notebooks.apache import db as apache_db
from sophon.notebooks.apache import get_ephemeral_port, base_domain, http_protocol
from sophon.notebooks.docker import client as docker_client
@ -128,18 +130,27 @@ class Notebook(SophonGroupModel):
"legacy_notebook_url",
}
@classmethod
def get_member_fields(cls) -> set[str]:
"""
:return: The :class:`set` of field names (as :class:`str`) that will be added to the serializer for a member of the group the notebook belongs to.
"""
return {
"jupyter_token",
}
@classmethod
def get_editable_fields(cls) -> set[str]:
return {
"name",
"locked_by",
"container_image",
}
@classmethod
def get_administrable_fields(cls) -> set[str]:
return {
"project",
"container_image",
}
@classmethod
@ -151,6 +162,17 @@ class Notebook(SophonGroupModel):
"container_image",
}
def get_access_serializer(self, user: User) -> t.Type[ModelSerializer]:
access = super().get_access_serializer(user)
if self.can_edit(user):
# noinspection PyUnresolvedReferences
fields = tuple(set(access.Meta.fields).union(self.get_member_fields()))
# noinspection PyUnresolvedReferences
read_only_fields = tuple(set(access.Meta.read_only_fields).union(self.get_member_fields()))
return dynamic_serializer(_model=self.__class__, _fields=fields, _read_only_fields=read_only_fields)
else:
return access
@property
def container_name(self) -> str:
"""