finetune limited permission user

This commit is contained in:
Simon 2023-10-15 14:56:54 +07:00
parent e1fce06f97
commit 572b23169c
No known key found for this signature in database
GPG Key ID: 2C15AA5E89985DD4
7 changed files with 96 additions and 69 deletions

View File

@ -437,6 +437,7 @@ class PlaylistApiListView(ApiBaseView):
self.get_document_list(request) self.get_document_list(request)
return Response(self.response) return Response(self.response)
@method_decorator(user_passes_test(check_admin), name="dispatch")
def post(self, request): def post(self, request):
"""subscribe/unsubscribe to list of playlists""" """subscribe/unsubscribe to list of playlists"""
data = request.data data = request.data
@ -483,6 +484,7 @@ class PlaylistApiView(ApiBaseView):
self.get_document(playlist_id) self.get_document(playlist_id)
return Response(self.response, status=self.status_code) return Response(self.response, status=self.status_code)
@method_decorator(user_passes_test(check_admin), name="dispatch")
def delete(self, request, playlist_id): def delete(self, request, playlist_id):
"""delete playlist""" """delete playlist"""
print(f"{playlist_id}: delete playlist") print(f"{playlist_id}: delete playlist")
@ -513,6 +515,7 @@ class PlaylistApiVideoView(ApiBaseView):
return Response(self.response, status=self.status_code) return Response(self.response, status=self.status_code)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class DownloadApiView(ApiBaseView): class DownloadApiView(ApiBaseView):
"""resolves to /api/download/<video_id>/ """resolves to /api/download/<video_id>/
GET: returns metadata dict of an item in the download queue GET: returns metadata dict of an item in the download queue
@ -529,7 +532,6 @@ class DownloadApiView(ApiBaseView):
self.get_document(video_id) self.get_document(video_id)
return Response(self.response, status=self.status_code) return Response(self.response, status=self.status_code)
@method_decorator(user_passes_test(check_admin), name="dispatch")
def post(self, request, video_id): def post(self, request, video_id):
"""post to video to change status""" """post to video to change status"""
item_status = request.data.get("status") item_status = request.data.get("status")
@ -550,7 +552,6 @@ class DownloadApiView(ApiBaseView):
return Response(request.data) return Response(request.data)
@method_decorator(user_passes_test(check_admin), name="dispatch")
@staticmethod @staticmethod
def delete(request, video_id): def delete(request, video_id):
# pylint: disable=unused-argument # pylint: disable=unused-argument
@ -561,6 +562,7 @@ class DownloadApiView(ApiBaseView):
return Response({"success": True}) return Response({"success": True})
@method_decorator(user_passes_test(check_admin), name="dispatch")
class DownloadApiListView(ApiBaseView): class DownloadApiListView(ApiBaseView):
"""resolves to /api/download/ """resolves to /api/download/
GET: returns latest videos in the download queue GET: returns latest videos in the download queue
@ -596,7 +598,6 @@ class DownloadApiListView(ApiBaseView):
self.get_document_list(request) self.get_document_list(request)
return Response(self.response) return Response(self.response)
@method_decorator(user_passes_test(check_admin), name="dispatch")
@staticmethod @staticmethod
def post(request): def post(request):
"""add list of videos to download queue""" """add list of videos to download queue"""
@ -622,7 +623,6 @@ class DownloadApiListView(ApiBaseView):
return Response(data) return Response(data)
@method_decorator(user_passes_test(check_admin), name="dispatch")
def delete(self, request): def delete(self, request):
"""delete download queue""" """delete download queue"""
query_filter = request.GET.get("filter", False) query_filter = request.GET.get("filter", False)
@ -740,6 +740,7 @@ class SnapshotApiView(ApiBaseView):
return Response(response) return Response(response)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class TaskListView(ApiBaseView): class TaskListView(ApiBaseView):
"""resolves to /api/task-name/ """resolves to /api/task-name/
GET: return a list of all stored task results GET: return a list of all stored task results
@ -877,6 +878,7 @@ class RefreshView(ApiBaseView):
return Response(data) return Response(data)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class CookieView(ApiBaseView): class CookieView(ApiBaseView):
"""resolves to /api/cookie/ """resolves to /api/cookie/
GET: check if cookie is enabled GET: check if cookie is enabled

View File

@ -1,14 +1,17 @@
{# Base file for all of the settings pages to ensure a common menu #} {# Base file for all of the settings pages to ensure a common menu #}
{% extends "home/base.html" %} {% extends "home/base.html" %}
{% load static %} {% load static %}
{% load auth_extras %}
{% block content %} {% block content %}
<div class="boxed-content"> <div class="boxed-content">
<div class="info-box-item child-page-nav"> <div class="info-box-item child-page-nav">
<a href="{% url 'settings' %}"><h3>Dashboard</h3></a> <a href="{% url 'settings' %}"><h3>Dashboard</h3></a>
<a href="{% url 'settings_user' %}"><h3>User</h3></a> <a href="{% url 'settings_user' %}"><h3>User</h3></a>
<a href="{% url 'settings_application' %}"><h3>Application</h3></a> {% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'settings_scheduling' %}"><h3>Scheduling</h3></a> <a href="{% url 'settings_application' %}"><h3>Application</h3></a>
<a href="{% url 'settings_actions' %}"><h3>Actions</h3></a> <a href="{% url 'settings_scheduling' %}"><h3>Scheduling</h3></a>
<a href="{% url 'settings_actions' %}"><h3>Actions</h3></a>
{% endif %}
</div> </div>
<div id="notifications" data=""></div> <div id="notifications" data=""></div>
{% block settings_content %}{% endblock %} {% block settings_content %}{% endblock %}

View File

@ -21,7 +21,9 @@
{% endif %} {% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a> <a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %} {% if has_pending %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a> {% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %} {% endif %}
</div> </div>
<div id="notifications" data="channel reindex"></div> <div id="notifications" data="channel reindex"></div>

View File

@ -2,6 +2,7 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
{% load humanize %} {% load humanize %}
{% load auth_extras %}
<div class="boxed-content"> <div class="boxed-content">
<div class="channel-banner"> <div class="channel-banner">
<a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a> <a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a>
@ -19,7 +20,9 @@
{% endif %} {% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a> <a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %} {% if has_pending %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a> {% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %} {% endif %}
</div> </div>
<div id="notifications" data="channel reindex"></div> <div id="notifications" data="channel reindex"></div>
@ -56,19 +59,21 @@
{% elif channel_info.channel_views > 0 %} {% elif channel_info.channel_views > 0 %}
<p>Channel views: {{ channel_info.channel_views|intcomma }}</p> <p>Channel views: {{ channel_info.channel_views|intcomma }}</p>
{% endif %} {% endif %}
<div class="button-box"> {% if request.user|has_group:"admin" or request.user.is_staff %}
<button onclick="deleteConfirm()" id="delete-item">Delete Channel</button> <div class="button-box">
<div class="delete-confirm" id="delete-button"> <button onclick="deleteConfirm()" id="delete-item">Delete Channel</button>
<span>Delete {{ channel_info.channel_name }} including all videos? </span><button class="danger-button" onclick="deleteChannel(this)" data-id="{{ channel_info.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button> <div class="delete-confirm" id="delete-button">
</div> <span>Delete {{ channel_info.channel_name }} including all videos? </span><button class="danger-button" onclick="deleteChannel(this)" data-id="{{ channel_info.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button>
</div> </div>
{% if reindex %}
<p>Reindex scheduled</p>
{% else %}
<div id="reindex-button" class="button-box">
<button data-id="{{ channel_info.channel_id }}" data-type="channel" onclick="reindex(this)" title="Reindex Channel {{ channel_info.channel_name }}">Reindex</button>
<button data-id="{{ channel_info.channel_id }}" data-type="channel" data-extract-videos="true" onclick="reindex(this)" title="Reindex Videos of {{ channel_info.channel_name }}">Reindex Videos</button>
</div> </div>
{% if reindex %}
<p>Reindex scheduled</p>
{% else %}
<div id="reindex-button" class="button-box">
<button data-id="{{ channel_info.channel_id }}" data-type="channel" onclick="reindex(this)" title="Reindex Channel {{ channel_info.channel_name }}">Reindex</button>
<button data-id="{{ channel_info.channel_id }}" data-type="channel" data-extract-videos="true" onclick="reindex(this)" title="Reindex Videos of {{ channel_info.channel_name }}">Reindex Videos</button>
</div>
{% endif %}
{% endif %} {% endif %}
</div> </div>
</div> </div>
@ -90,53 +95,55 @@
</div> </div>
</div> </div>
{% endif %} {% endif %}
<div id="overwrite-form" class="info-box"> {% if request.user|has_group:"admin" or request.user.is_staff %}
<div class="info-box-item"> <div id="overwrite-form" class="info-box">
<h2>Customize {{ channel_info.channel_name }}</h2> <div class="info-box-item">
<form class="overwrite-form" action="/channel/{{ channel_info.channel_id }}/about/" method="POST"> <h2>Customize {{ channel_info.channel_name }}</h2>
{% csrf_token %} <form class="overwrite-form" action="/channel/{{ channel_info.channel_id }}/about/" method="POST">
<div class="overwrite-form-item"> {% csrf_token %}
<p>Download format: <span class="settings-current"> <div class="overwrite-form-item">
{% if channel_info.channel_overwrites.download_format %} <p>Download format: <span class="settings-current">
{{ channel_info.channel_overwrites.download_format }} {% if channel_info.channel_overwrites.download_format %}
{% else %} {{ channel_info.channel_overwrites.download_format }}
False {% else %}
{% endif %}</span></p> False
{{ channel_overwrite_form.download_format }}<br> {% endif %}</span></p>
</div> {{ channel_overwrite_form.download_format }}<br>
<div class="overwrite-form-item"> </div>
<p>Auto delete watched videos after x days: <span class="settings-current"> <div class="overwrite-form-item">
{% if channel_info.channel_overwrites.autodelete_days %} <p>Auto delete watched videos after x days: <span class="settings-current">
{{ channel_info.channel_overwrites.autodelete_days }} {% if channel_info.channel_overwrites.autodelete_days %}
{% else %} {{ channel_info.channel_overwrites.autodelete_days }}
False {% else %}
{% endif %}</span></p> False
{{ channel_overwrite_form.autodelete_days }}<br> {% endif %}</span></p>
</div> {{ channel_overwrite_form.autodelete_days }}<br>
<div class="overwrite-form-item"> </div>
<p>Index playlists: <span class="settings-current"> <div class="overwrite-form-item">
{% if channel_info.channel_overwrites.index_playlists %} <p>Index playlists: <span class="settings-current">
{{ channel_info.channel_overwrites.index_playlists }} {% if channel_info.channel_overwrites.index_playlists %}
{% else %} {{ channel_info.channel_overwrites.index_playlists }}
False {% else %}
{% endif %}</span></p> False
{{ channel_overwrite_form.index_playlists }}<br> {% endif %}</span></p>
</div> {{ channel_overwrite_form.index_playlists }}<br>
<div class="overwrite-form-item"> </div>
<p>Enable <a href="https://sponsor.ajay.app/" target="_blank">SponsorBlock</a>: <span class="settings-current"> <div class="overwrite-form-item">
{% if channel_info.channel_overwrites.integrate_sponsorblock %} <p>Enable <a href="https://sponsor.ajay.app/" target="_blank">SponsorBlock</a>: <span class="settings-current">
{{ channel_info.channel_overwrites.integrate_sponsorblock }} {% if channel_info.channel_overwrites.integrate_sponsorblock %}
{% elif channel_info.channel_overwrites.integrate_sponsorblock == False %} {{ channel_info.channel_overwrites.integrate_sponsorblock }}
Disabled {% elif channel_info.channel_overwrites.integrate_sponsorblock == False %}
{% else %} Disabled
False {% else %}
{% endif %}</span></p> False
{{ channel_overwrite_form.integrate_sponsorblock }}<br> {% endif %}</span></p>
</div> {{ channel_overwrite_form.integrate_sponsorblock }}<br>
<button type="submit">Save Channel Overwrites</button> </div>
</form> <button type="submit">Save Channel Overwrites</button>
</form>
</div>
</div> </div>
</div> {% endif %}
</div> </div>
<script type="text/javascript" src="{% static 'progress.js' %}"></script> <script type="text/javascript" src="{% static 'progress.js' %}"></script>
{% endblock content %} {% endblock content %}

View File

@ -2,6 +2,7 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
{% load humanize %} {% load humanize %}
{% load auth_extras %}
<div class="boxed-content"> <div class="boxed-content">
<div class="channel-banner"> <div class="channel-banner">
<a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a> <a href="{% url 'channel_id' channel_info.channel_id %}"><img src="{{ channel_info.channel_banner_url }}" alt="channel_banner"></a>
@ -19,7 +20,9 @@
{% endif %} {% endif %}
<a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a> <a href="{% url 'channel_id_about' channel_info.channel_id %}"><h3>About</h3></a>
{% if has_pending %} {% if has_pending %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a> {% if request.user|has_group:"admin" or request.user.is_staff %}
<a href="{% url 'downloads' %}?channel={{ channel_info.channel_id }}"><h3>Downloads</h3></a>
{% endif %}
{% endif %} {% endif %}
</div> </div>
<div id="notifications" data="channel reindex"></div> <div id="notifications" data="channel reindex"></div>

View File

@ -88,8 +88,8 @@
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if request.user|has_group:"admin" or request.user.is_staff %}
<a download="" href="{{ video.media_url }}"><button id="download-item">Download File</button></a> <a download="" href="{{ video.media_url }}"><button id="download-item">Download File</button></a>
{% if request.user|has_group:"admin" or request.user.is_staff %}
<button onclick="deleteConfirm()" id="delete-item">Delete Video</button> <button onclick="deleteConfirm()" id="delete-item">Delete Video</button>
<div class="delete-confirm" id="delete-button"> <div class="delete-confirm" id="delete-button">
<span>Are you sure? </span><button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-redirect = "{{ video.channel.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button> <span>Are you sure? </span><button class="danger-button" onclick="deleteVideo(this)" data-id="{{ video.youtube_id }}" data-redirect = "{{ video.channel.channel_id }}">Delete</button> <button onclick="cancelDelete()">Cancel</button>

View File

@ -9,11 +9,14 @@ import urllib.parse
from time import sleep from time import sleep
from api.src.search_processor import SearchProcess, process_aggs from api.src.search_processor import SearchProcess, process_aggs
from api.views import check_admin
from django.conf import settings from django.conf import settings
from django.contrib.auth import login from django.contrib.auth import login
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth.forms import AuthenticationForm
from django.http import Http404, JsonResponse from django.http import Http404, JsonResponse
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from home.src.download.queue import PendingInteract from home.src.download.queue import PendingInteract
from home.src.download.yt_dlp_base import CookieHandler from home.src.download.yt_dlp_base import CookieHandler
@ -317,6 +320,7 @@ class AboutView(MinView):
return render(request, "home/about.html", context) return render(request, "home/about.html", context)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class DownloadView(ArchivistResultsView): class DownloadView(ArchivistResultsView):
"""resolves to /download/ """resolves to /download/
handle the download queue handle the download queue
@ -597,6 +601,7 @@ class ChannelIdAboutView(ChannelIdBaseView):
return render(request, "home/channel_id_about.html", self.context) return render(request, "home/channel_id_about.html", self.context)
@method_decorator(user_passes_test(check_admin), name="dispatch")
@staticmethod @staticmethod
def post(request, channel_id): def post(request, channel_id):
"""handle post request""" """handle post request"""
@ -681,6 +686,7 @@ class ChannelView(ArchivistResultsView):
"term": {"channel_subscribed": {"value": True}} "term": {"channel_subscribed": {"value": True}}
} }
@method_decorator(user_passes_test(check_admin), name="dispatch")
@staticmethod @staticmethod
def post(request): def post(request):
"""handle http post requests""" """handle http post requests"""
@ -824,6 +830,7 @@ class PlaylistView(ArchivistResultsView):
} }
} }
@method_decorator(user_passes_test(check_admin), name="dispatch")
@staticmethod @staticmethod
def post(request): def post(request):
"""handle post from search form""" """handle post from search form"""
@ -986,6 +993,7 @@ class SettingsUserView(MinView):
return redirect("settings_user", permanent=True) return redirect("settings_user", permanent=True)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class SettingsApplicationView(MinView): class SettingsApplicationView(MinView):
"""resolves to /settings/application/ """resolves to /settings/application/
handle the settings sub-page for application configuration, handle the settings sub-page for application configuration,
@ -1075,6 +1083,7 @@ class SettingsApplicationView(MinView):
RedisArchivist().set_message(key, message=message, expire=True) RedisArchivist().set_message(key, message=message, expire=True)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class SettingsSchedulingView(MinView): class SettingsSchedulingView(MinView):
"""resolves to /settings/scheduling/ """resolves to /settings/scheduling/
handle the settings sub-page for scheduling settings, handle the settings sub-page for scheduling settings,
@ -1108,6 +1117,7 @@ class SettingsSchedulingView(MinView):
return redirect("settings_scheduling", permanent=True) return redirect("settings_scheduling", permanent=True)
@method_decorator(user_passes_test(check_admin), name="dispatch")
class SettingsActionsView(MinView): class SettingsActionsView(MinView):
"""resolves to /settings/actions/ """resolves to /settings/actions/
handle the settings actions sub-page handle the settings actions sub-page