Merge pull request #5689 from FinnStutzenstein/fixManageSpeakerValidation
Add user_id validation for LOS and assignment candidates
This commit is contained in:
commit
01206cb7c6
@ -346,6 +346,9 @@ class ListOfSpeakersViewSet(
|
|||||||
raise ValidationError({"detail": "The list of speakers is closed."})
|
raise ValidationError({"detail": "The list of speakers is closed."})
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
else:
|
else:
|
||||||
|
if not isinstance(user_id, int):
|
||||||
|
raise ValidationError({"detail": "user_id has to be an int."})
|
||||||
|
|
||||||
point_of_order = False # not for someone else
|
point_of_order = False # not for someone else
|
||||||
# Add someone else.
|
# Add someone else.
|
||||||
if not has_perm(
|
if not has_perm(
|
||||||
@ -353,8 +356,8 @@ class ListOfSpeakersViewSet(
|
|||||||
):
|
):
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
try:
|
try:
|
||||||
user = get_user_model().objects.get(pk=int(user_id))
|
user = get_user_model().objects.get(pk=user_id)
|
||||||
except (ValueError, get_user_model().DoesNotExist):
|
except get_user_model().DoesNotExist:
|
||||||
raise ValidationError({"detail": "User does not exist."})
|
raise ValidationError({"detail": "User does not exist."})
|
||||||
|
|
||||||
# Try to add the user. This ensurse that a user is not twice in the
|
# Try to add the user. This ensurse that a user is not twice in the
|
||||||
|
@ -126,46 +126,29 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
assignment.remove_candidate(request.user)
|
assignment.remove_candidate(request.user)
|
||||||
return "You have withdrawn your candidature successfully."
|
return "You have withdrawn your candidature successfully."
|
||||||
|
|
||||||
def get_user_from_request_data(self, request):
|
|
||||||
"""
|
|
||||||
Helper method to get a specific user from request data (not the
|
|
||||||
request.user) so that the view self.candidature_other can play with it.
|
|
||||||
"""
|
|
||||||
if not isinstance(request.data, dict):
|
|
||||||
raise ValidationError(
|
|
||||||
{
|
|
||||||
"detail": "Invalid data. Expected dictionary, got {0}.",
|
|
||||||
"args": [type(request.data)],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
user_str = request.data.get("user", "")
|
|
||||||
try:
|
|
||||||
user_pk = int(user_str)
|
|
||||||
except ValueError:
|
|
||||||
raise ValidationError(
|
|
||||||
{"detail": 'Invalid data. Expected something like {"user": <id>}.'}
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
user = get_user_model().objects.get(pk=user_pk)
|
|
||||||
except get_user_model().DoesNotExist:
|
|
||||||
raise ValidationError(
|
|
||||||
{"detail": "Invalid data. User {0} does not exist.", "args": [user_pk]}
|
|
||||||
)
|
|
||||||
return user
|
|
||||||
|
|
||||||
@detail_route(methods=["post", "delete"])
|
@detail_route(methods=["post", "delete"])
|
||||||
def candidature_other(self, request, pk=None):
|
def candidature_other(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
View to nominate other users (POST) or delete their candidature
|
View to nominate other users (POST) or delete their candidature
|
||||||
status (DELETE). The client has to send {'user': <id>}.
|
status (DELETE). The client has to send {'user': <id>}.
|
||||||
"""
|
"""
|
||||||
user = self.get_user_from_request_data(request)
|
user_id = request.data.get("user")
|
||||||
|
if not isinstance(user_id, int):
|
||||||
|
raise ValidationError({"detail": "user_id must be an int."})
|
||||||
|
|
||||||
|
try:
|
||||||
|
user = get_user_model().objects.get(pk=user_id)
|
||||||
|
except get_user_model().DoesNotExist:
|
||||||
|
raise ValidationError(
|
||||||
|
{"detail": "Invalid data. User {0} does not exist.", "args": [user_id]}
|
||||||
|
)
|
||||||
|
|
||||||
assignment = self.get_object()
|
assignment = self.get_object()
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
return self.nominate_other(request, user, assignment)
|
return self.nominate_other(request, user, assignment)
|
||||||
else:
|
else:
|
||||||
# request.method == 'DELETE'
|
# request.method == 'DELETE'
|
||||||
return self.delete_other(request, user, assignment)
|
return self.withdraw_other(request, user, assignment)
|
||||||
|
|
||||||
def nominate_other(self, request, user, assignment):
|
def nominate_other(self, request, user, assignment):
|
||||||
if assignment.phase == assignment.PHASE_FINISHED:
|
if assignment.phase == assignment.PHASE_FINISHED:
|
||||||
@ -191,7 +174,7 @@ class AssignmentViewSet(ModelViewSet):
|
|||||||
{"detail": "User {0} was nominated successfully.", "args": [str(user)]}
|
{"detail": "User {0} was nominated successfully.", "args": [str(user)]}
|
||||||
)
|
)
|
||||||
|
|
||||||
def delete_other(self, request, user, assignment):
|
def withdraw_other(self, request, user, assignment):
|
||||||
# To delete candidature status you have to be a manager.
|
# To delete candidature status you have to be a manager.
|
||||||
if not has_perm(request.user, "assignments.can_manage"):
|
if not has_perm(request.user, "assignments.can_manage"):
|
||||||
self.permission_denied(request)
|
self.permission_denied(request)
|
||||||
|
@ -356,6 +356,13 @@ class ManageSpeaker(TestCase):
|
|||||||
).exists()
|
).exists()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_add_someone_else_no_id(self):
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("listofspeakers-manage-speaker", args=[self.list_of_speakers.pk]),
|
||||||
|
{"user": ["not valid"]},
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
||||||
def test_point_of_order_single(self):
|
def test_point_of_order_single(self):
|
||||||
config["agenda_enable_point_of_order_speakers"] = True
|
config["agenda_enable_point_of_order_speakers"] = True
|
||||||
self.assertEqual(Speaker.objects.all().count(), 0)
|
self.assertEqual(Speaker.objects.all().count(), 0)
|
||||||
|
@ -279,6 +279,14 @@ class CandidatureOther(TestCase):
|
|||||||
.exists()
|
.exists()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_nominate_other_invalid_id(self):
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("assignment-candidature-other", args=[self.assignment.pk]),
|
||||||
|
{"user": ["not valid"]},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
||||||
def test_nominate_other_twice(self):
|
def test_nominate_other_twice(self):
|
||||||
self.assignment.add_candidate(
|
self.assignment.add_candidate(
|
||||||
get_user_model().objects.get(username="test_user_eeheekai4Phue6cahtho")
|
get_user_model().objects.get(username="test_user_eeheekai4Phue6cahtho")
|
||||||
|
@ -46,7 +46,7 @@ class ListOfSpeakersViewSetManageSpeaker(TestCase):
|
|||||||
self.request.method = "POST"
|
self.request.method = "POST"
|
||||||
self.request.user = 1
|
self.request.user = 1
|
||||||
self.request.data = {
|
self.request.data = {
|
||||||
"user": "2"
|
"user": 2
|
||||||
} # It is assumed that the request user has pk!=2.
|
} # It is assumed that the request user has pk!=2.
|
||||||
mock_get_user_model.return_value = MockUser = MagicMock()
|
mock_get_user_model.return_value = MockUser = MagicMock()
|
||||||
MockUser.objects.get.return_value = mock_user = MagicMock()
|
MockUser.objects.get.return_value = mock_user = MagicMock()
|
||||||
|
Loading…
Reference in New Issue
Block a user