Sith/sas/api.py

78 lines
3.1 KiB
Python
Raw Normal View History

from django.conf import settings
2024-07-31 09:56:38 +00:00
from django.db.models import F
2024-07-18 18:23:30 +00:00
from ninja import Query
from ninja_extra import ControllerBase, api_controller, route
from ninja_extra.exceptions import PermissionDenied
from ninja_extra.permissions import IsAuthenticated
from pydantic import NonNegativeInt
2024-07-18 18:23:30 +00:00
from core.models import User
from sas.models import PeoplePictureRelation, Picture
2024-07-26 12:25:26 +00:00
from sas.schemas import PictureFilterSchema, PictureSchema
2024-07-18 18:23:30 +00:00
@api_controller("/sas/picture")
class PicturesController(ControllerBase):
2024-07-18 18:23:30 +00:00
@route.get(
"",
2024-07-18 18:23:30 +00:00
response=list[PictureSchema],
permissions=[IsAuthenticated],
url_name="pictures",
)
def fetch_pictures(self, filters: Query[PictureFilterSchema]):
"""Find pictures viewable by the user corresponding to the given filters.
A user with an active subscription can see any picture, as long
as it has been moderated and not asked for removal.
An unsubscribed user can see the pictures he has been identified on
2024-07-26 12:25:26 +00:00
(only the moderated ones, too).
2024-07-18 18:23:30 +00:00
Notes:
Trying to fetch the pictures of another user with this route
while being unsubscribed will just result in an empty response.
2024-07-26 12:25:26 +00:00
Notes:
Unsubscribed users who are identified is not a rare case.
They can be UTT students, faluchards from other schools,
or even Richard Stallman (that ain't no joke,
cf. https://ae.utbm.fr/user/32663/pictures/)
2024-07-18 18:23:30 +00:00
"""
user: User = self.context.request.user
if not user.is_subscribed and filters.users_identified != {user.id}:
# User can view any moderated picture if he/she is subscribed.
# If not, he/she can view only the one he/she has been identified on
raise PermissionDenied
2024-07-22 17:12:03 +00:00
pictures = list(
filters.filter(
Picture.objects.filter(is_moderated=True, asked_for_removal=False)
)
.distinct()
.order_by("-date")
2024-07-31 09:56:38 +00:00
.annotate(album=F("parent__name"))
2024-07-18 18:23:30 +00:00
)
for picture in pictures:
picture.full_size_url = picture.get_download_url()
picture.compressed_url = picture.get_download_compressed_url()
picture.thumb_url = picture.get_download_thumb_url()
return pictures
2024-07-26 12:25:26 +00:00
@api_controller("/sas/relation", tags="User identification on SAS pictures")
class UsersIdentifiedController(ControllerBase):
2024-07-26 12:25:26 +00:00
@route.delete("/{relation_id}", permissions=[IsAuthenticated])
def delete_relation(self, relation_id: NonNegativeInt):
2024-07-26 12:25:26 +00:00
"""Untag a user from a SAS picture.
Root and SAS admins can delete any picture identification.
All other users can delete their own identification.
"""
relation = self.get_object_or_exception(PeoplePictureRelation, pk=relation_id)
user: User = self.context.request.user
if (
relation.user_id != user.id
and not user.is_root
and not user.is_in_group(pk=settings.SITH_GROUP_SAS_ADMIN_ID)
):
raise PermissionDenied
relation.delete()