diff --git a/tubearchivist/api/views.py b/tubearchivist/api/views.py index a01a874..9d5eafa 100644 --- a/tubearchivist/api/views.py +++ b/tubearchivist/api/views.py @@ -2,6 +2,8 @@ from api.src.aggs import BiggestChannel, DownloadHist, Primary, WatchProgress from api.src.search_processor import SearchProcess +from django.contrib.auth.decorators import user_passes_test +from django.utils.decorators import method_decorator from home.src.download.queue import PendingInteract from home.src.download.subscriptions import ( ChannelSubscription, @@ -39,6 +41,11 @@ from rest_framework.response import Response from rest_framework.views import APIView +def check_admin(user): + """if user has access to restricted views""" + return user.is_staff or user.groups.filter(name="admin").exists() + + class ApiBaseView(APIView): """base view to inherit from""" @@ -109,6 +116,7 @@ class VideoApiView(ApiBaseView): self.get_document(video_id) return Response(self.response, status=self.status_code) + @method_decorator(user_passes_test(check_admin), name="dispatch") def delete(self, request, video_id): # pylint: disable=unused-argument """delete single video""" @@ -165,7 +173,6 @@ class VideoProgressView(ApiBaseView): message = {"position": position, "youtube_id": video_id} RedisArchivist().set_message(key, message) self.response = request.data - return Response(self.response) def delete(self, request, video_id): @@ -283,6 +290,7 @@ class ChannelApiView(ApiBaseView): self.get_document(channel_id) return Response(self.response, status=self.status_code) + @method_decorator(user_passes_test(check_admin), name="dispatch") def delete(self, request, channel_id): # pylint: disable=unused-argument """delete channel""" @@ -328,6 +336,7 @@ class ChannelApiListView(ApiBaseView): return Response(self.response) + @method_decorator(user_passes_test(check_admin), name="dispatch") def post(self, request): """subscribe/unsubscribe to list of channels""" data = request.data @@ -520,6 +529,7 @@ class DownloadApiView(ApiBaseView): self.get_document(video_id) return Response(self.response, status=self.status_code) + @method_decorator(user_passes_test(check_admin), name="dispatch") def post(self, request, video_id): """post to video to change status""" item_status = request.data.get("status") @@ -540,6 +550,7 @@ class DownloadApiView(ApiBaseView): return Response(request.data) + @method_decorator(user_passes_test(check_admin), name="dispatch") @staticmethod def delete(request, video_id): # pylint: disable=unused-argument @@ -585,6 +596,7 @@ class DownloadApiListView(ApiBaseView): self.get_document_list(request) return Response(self.response) + @method_decorator(user_passes_test(check_admin), name="dispatch") @staticmethod def post(request): """add list of videos to download queue""" @@ -610,6 +622,7 @@ class DownloadApiListView(ApiBaseView): return Response(data) + @method_decorator(user_passes_test(check_admin), name="dispatch") def delete(self, request): """delete download queue""" query_filter = request.GET.get("filter", False) @@ -661,6 +674,7 @@ class LoginApiView(ObtainAuthToken): return Response({"token": token.key, "user_id": user.pk}) +@method_decorator(user_passes_test(check_admin), name="dispatch") class SnapshotApiListView(ApiBaseView): """resolves to /api/snapshot/ GET: returns snapshot config plus list of existing snapshots @@ -684,6 +698,7 @@ class SnapshotApiListView(ApiBaseView): return Response(response) +@method_decorator(user_passes_test(check_admin), name="dispatch") class SnapshotApiView(ApiBaseView): """resolves to /api/snapshot// GET: return a single snapshot @@ -738,6 +753,7 @@ class TaskListView(ApiBaseView): return Response(all_results) +@method_decorator(user_passes_test(check_admin), name="dispatch") class TaskNameListView(ApiBaseView): """resolves to /api/task-name// GET: return a list of stored results of task @@ -776,6 +792,7 @@ class TaskNameListView(ApiBaseView): return Response({"message": message}) +@method_decorator(user_passes_test(check_admin), name="dispatch") class TaskIDView(ApiBaseView): """resolves to /api/task-id// GET: return details of task id @@ -827,6 +844,7 @@ class TaskIDView(ApiBaseView): return f"message:{task_conf.get('group')}:{task_id.split('-')[0]}" +@method_decorator(user_passes_test(check_admin), name="dispatch") class RefreshView(ApiBaseView): """resolves to /api/refresh/ GET: get refresh progress @@ -948,6 +966,7 @@ class SearchView(ApiBaseView): return Response(search_results) +@method_decorator(user_passes_test(check_admin), name="dispatch") class TokenView(ApiBaseView): """resolves to /api/token/ DELETE: revoke the token diff --git a/tubearchivist/home/templates/home/base.html b/tubearchivist/home/templates/home/base.html index 2adce0d..b7b998e 100644 --- a/tubearchivist/home/templates/home/base.html +++ b/tubearchivist/home/templates/home/base.html @@ -1,4 +1,5 @@ {% load static %} +{% load auth_extras %} @@ -57,9 +58,11 @@ + {% if request.user|has_group:"admin" or request.user.is_staff %} + {% endif %}