Commit 132ed6cd authored by Martin Juhás's avatar Martin Juhás
Browse files

Merge branch...

Merge branch '208-add-uploadedby-field-to-definitiontype-and-createdby-field-to-exercisetype' into 'main'

Resolve "Add 'uploadedBy' field to DefinitionType and 'createdBy' field to ExerciseType"

Closes #208

See merge request inject/backend!285
parents 95d572fe 9f8380df
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@ from django.contrib.auth.models import AnonymousUser
from rest_framework.exceptions import PermissionDenied, AuthenticationFailed
from rest_framework.request import Request

from user.models import User, UserInTeam, DefinitionAccess, InstructorOfExercise
from exercise.models import UserInTeam, InstructorOfExercise
from exercise_definition.models import DefinitionAccess
from user.models import User


def user_from_context(context: Request) -> User:
@@ -38,7 +40,7 @@ def exercise_access(context: Request, exercise_id: int):
        return

    condition = UserInTeam.objects.filter(
        user_id=user.id, user__teams__exercise_id=exercise_id
        user_id=user.id, team__exercise_id__in=[exercise_id]
    ).exists()  # Both trainees and instructors can be assigned in teams

    if not condition and user.group == User.AuthGroup.INSTRUCTOR:
+53 −8
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ from exercise.models import (
    TeamQuestionnaireState,
    TeamLearningObjective,
    TeamLearningActivity,
    InstructorOfExercise,
)
from exercise_definition.models import (
    Milestone,
@@ -44,13 +45,20 @@ from running_exercise.models import (
    CustomInjectDetails,
    QuestionnaireAnswer,
)
from user.models import User, Tag, InstructorOfExercise
from user.models import User, Tag


class RestrictedUser(DjangoObjectType):
    class Meta:
        model = User
        exclude = ("definitions", "exercises", "teams", "password")
        exclude = (
            "definitions",
            "exercises",
            "teams",
            "password",
            "uploaded_definitions",
            "created_exercises",
        )

    group = graphene.Field(GroupEnum)

@@ -86,10 +94,20 @@ class DefinitionType(DjangoObjectType):
        exclude = ["milestones"]

    tools = graphene.List(graphene.NonNull(ToolType), required=True)
    user_set = graphene.List(RestrictedUser)
    user_set = graphene.List(
        RestrictedUser, deprecation_reason="Use `maintainers` instead"
    )
    maintainers = graphene.List(graphene.NonNull(RestrictedUser), required=True)
    uploaded_by = graphene.Field(RestrictedUser)

    def resolve_user_set(self, info):
        return self.user_set.all()
        return self.maintainers.all()

    def resolve_maintainers(self, info):
        return self.maintainers.all()

    def resolve_tools(self, info):
        return self.tools.all()


class DefinitionRoleType(DjangoObjectType):
@@ -103,7 +121,11 @@ class ExerciseType(DjangoObjectType):

    # change the definition field type to hide some definition fields
    definition = graphene.Field(ExerciseDefinitionType)
    user_set = graphene.List(RestrictedUser)
    instructors = graphene.List(graphene.NonNull(RestrictedUser), required=True)
    user_set = graphene.List(
        RestrictedUser, deprecation_reason="Use `instructors` instead"
    )
    created_by = graphene.Field(RestrictedUser)

    def resolve_teams(self, info):
        user = info.context.user
@@ -122,19 +144,32 @@ class ExerciseType(DjangoObjectType):
    def resolve_user_set(self, info):
        if info.context.user.group == User.AuthGroup.TRAINEE:
            return User.objects.none()
        return self.user_set.all()
        return self.instructors.all()

    def resolve_instructors(self, info):
        if info.context.user.group == User.AuthGroup.TRAINEE:
            return User.objects.none()
        return self.instructors.all()


class TeamType(DjangoObjectType):
    class Meta:
        model = Team

    user_set = graphene.List(RestrictedUser)
    users = graphene.List(graphene.NonNull(RestrictedUser), required=True)
    user_set = graphene.List(
        RestrictedUser, deprecation_reason="Use `users` instead"
    )

    def resolve_user_set(self, info):
        if info.context.user.group == User.AuthGroup.TRAINEE:
            return User.objects.none()
        return self.user_set.all()
        return self.users.all()

    def resolve_users(self, info):
        if info.context.user.group == User.AuthGroup.TRAINEE:
            return User.objects.none()
        return self.users.all()


class ContentType(DjangoObjectType):
@@ -306,7 +341,11 @@ class GrapheneConfig(graphene.ObjectType):

class UserType(DjangoObjectType):
    definitions = graphene.List(ExerciseDefinitionType)
    uploaded_definitions = graphene.List(
        graphene.NonNull(ExerciseDefinitionType)
    )
    exercises = graphene.List(RestrictedExercise)
    created_exercises = graphene.List(graphene.NonNull(RestrictedExercise))
    teams = graphene.List(RestrictedTeam)
    group = graphene.Field(GroupEnum)

@@ -317,9 +356,15 @@ class UserType(DjangoObjectType):
    def resolve_definitions(self, info):
        return self.definitions.all()

    def resolve_uploaded_definitions(self, info):
        return self.uploaded_definitions.all()

    def resolve_exercises(self, info):
        return self.exercises.all()

    def resolve_created_exercises(self, info):
        return self.created_exercises.all()

    def resolve_teams(self, info):
        return self.teams.all()

+5 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ from exercise.models import (
    TeamQuestionnaireState,
    TeamLearningObjective,
    TeamLearningActivity,
    InstructorOfExercise,
)
from exercise_definition.models import (
    Milestone,
@@ -47,7 +48,7 @@ from running_exercise.models import (
    QuestionnaireAnswer,
    ThreadParticipant,
)
from user.models import InstructorOfExercise, User, Tag
from user.models import User, Tag


def select_by_group(user: User, all: Any, some: Any) -> Any:
@@ -94,7 +95,7 @@ class DefinitionType(DjangoObjectType):
    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)

    def resolve_user_set(self, info):
        return self.user_set.all()
        return self.users.all()


class ExerciseType(DjangoObjectType):
@@ -139,7 +140,7 @@ class ExerciseType(DjangoObjectType):

    def resolve_user_set(self, info):
        return select_by_group(
            info.context.user, self.user_set.all(), User.objects.none()
            info.context.user, self.users.all(), User.objects.none()
        )

    def resolve_threads(self, info):
@@ -165,7 +166,7 @@ class TeamType(DjangoObjectType):
    user_set = graphene.List(graphene.NonNull(Simple.UserType), required=True)

    def resolve_user_set(self, info):
        return self.user_set.all()
        return self.users.all()


class ContentType(DjangoObjectType):
+11 −3
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from exercise.lib.exercise_manager import ExerciseManager
from exercise.models import Team, MilestoneState, Exercise
from exercise_definition.lib import DefinitionUploader
from exercise_definition.models import Definition, Milestone
from user.models import User


def get_definition_id(status_code: int, content: bytes) -> int:
@@ -50,8 +51,11 @@ def internal_upload_definition(name: str) -> Definition:
        definition.getbuffer().nbytes,
        charset="utf-8",
    )

    return DefinitionUploader(def_file).upload(name)
    # ignoring whether the user was created or retrieved
    uploader, _ = User.objects.get_or_create(
        username="uploader@test.com", password="test_password"
    )
    return DefinitionUploader(def_file).upload(uploader, name)


def internal_create_exercise(
@@ -63,7 +67,11 @@ def internal_create_exercise(
        CreateExerciseInput, definition_id=definition_id, team_count=team_count
    )
    inp.config_override = config_override
    return ExerciseManager.create_exercise(inp)

    creator, _ = User.objects.get_or_create(
        username="uploader@test.com", password="test_password"
    )
    return ExerciseManager.create_exercise(creator, inp)


def reach_milestone(team: Team, milestone: Milestone, reached: bool):
+11 −4
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ from exercise_definition.models import (
    EnabledFeatures,
)
from running_exercise.models import TeamFile
from user.models import User

TMP_LOG_STORAGE = "./tmp_exercise_log/"

@@ -138,14 +139,19 @@ def _get_config(


def _create_exercise(
    definition: Definition, create_exercise_input: CreateExerciseInput
    definition: Definition,
    creator: User,
    create_exercise_input: CreateExerciseInput,
) -> Exercise:
    _check_inputs(definition, create_exercise_input)

    config, team_names = _get_config(definition.config, create_exercise_input)

    exercise = Exercise.objects.create(
        definition=definition, name=create_exercise_input.name, config=config
        definition=definition,
        name=create_exercise_input.name,
        config=config,
        created_by_id=creator.id,
    )
    if len(exercise.name) == 0:
        exercise.name = f"Exercise {exercise.id}"
@@ -339,17 +345,18 @@ def _create_email_participants(exercise: Exercise, definition: Definition):
class ExerciseManager:
    @staticmethod
    def create_exercise(
        creator: User,
        create_exercise_input: CreateExerciseInput,
        request: Optional[Request] = None,
    ) -> Exercise:
        definition = get_model(
            Definition, id=str(create_exercise_input.definition_id)
        )
        exercise = _create_exercise(definition, create_exercise_input)
        exercise = _create_exercise(definition, creator, create_exercise_input)
        logger.info(
            log_user_msg(
                request,
                request.user if request is not None else AnonymousUser(),
                creator,
            )
            + f"created exercise id: {exercise.id} using definition id: {definition.id}"
        )
Loading