import graphene from graphene import relay from api.types import FailureNode, Success from api.utils import get_object from books.models import Module from books.models.snapshot import Snapshot from books.schema.nodes import SnapshotNode, ModuleNode from users.models import SchoolClass class NotOwner(graphene.ObjectType): class Meta: interfaces = (FailureNode,) NotOwnerFailure = NotOwner(reason="Not the owner") DeleteSnapshotSuccess = Success(message="Snapshot deleted successfully") class UpdateSnapshotResult(graphene.Union): class Meta: types = ( SnapshotNode, NotOwner, ) class DeleteSnapshotResult(graphene.Union): class Meta: types = ( Success, NotOwner, ) class CreateSnapshot(relay.ClientIDMutation): class Input: module = graphene.String(required=True) selected_class = graphene.ID(required=True) snapshot = graphene.Field(SnapshotNode) success = graphene.Boolean() @classmethod def mutate_and_get_payload(cls, root, info, **args): module_slug = args.get("module") module = Module.objects.get(slug=module_slug) user = info.context.user # todo: check user # raise NotImplementedError('Permissions') selected_class_id = args.get("selected_class") selected_class = get_object(SchoolClass, selected_class_id) snapshot = Snapshot.objects.create_snapshot(module, selected_class, user) return cls(snapshot=snapshot, success=True) class UpdateSnapshot(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) title = graphene.String() snapshot = graphene.Field(UpdateSnapshotResult) @classmethod def mutate_and_get_payload(cls, root, info, **args): id = args.get("id") title = args.get("title") user = info.context.user snapshot = get_object(Snapshot, id) if snapshot.creator != user: return cls(snapshot=NotOwnerFailure) if title is not None: snapshot.title = title snapshot.save() return cls(snapshot=snapshot) class DeleteSnapshot(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) result = graphene.Field(DeleteSnapshotResult) @classmethod def mutate_and_get_payload(cls, root, info, **args): id = args.get("id") user = info.context.user snapshot = get_object(Snapshot, id) if snapshot.creator != user: return cls(result=NotOwnerFailure) snapshot.delete() return cls(result=DeleteSnapshotSuccess) class ApplySnapshot(relay.ClientIDMutation): class Input: snapshot = graphene.ID(required=True) selected_class = graphene.ID(required=True) success = graphene.Boolean() module = graphene.Field(ModuleNode) @classmethod def mutate_and_get_payload(cls, root, info, **args): snapshot_id = args.get("snapshot") snapshot = get_object(Snapshot, snapshot_id) user = info.context.user selected_class_id = args.get("selected_class") selected_class = get_object(SchoolClass, selected_class_id) # permission check if ( not selected_class.users.filter(username=user.username).exists() or not user.is_teacher() ): raise PermissionError("Not allowed") # reset everything snapshot.reset(user, selected_class) # apply snapshot snapshot.apply(user, selected_class) return cls(success=True, module=snapshot.module) class ShareSnapshot(relay.ClientIDMutation): class Input: snapshot = graphene.ID(required=True) shared = graphene.Boolean(required=True) success = graphene.Boolean(required=True) snapshot = graphene.Field(SnapshotNode) @classmethod def mutate_and_get_payload(cls, root, info, **args): snapshot_id = args.get("snapshot") shared = args.get("shared") user = info.context.user snapshot = get_object(Snapshot, snapshot_id) if snapshot.creator != user: raise PermissionError("Not permitted") snapshot.shared = shared snapshot.save() return cls(success=True, snapshot=snapshot)