Merge pull request #58 from IcyNet/bans

Bans
This commit is contained in:
Evert Prants 2017-12-28 12:20:23 +02:00 committed by GitHub
commit c31fb93218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 147 additions and 19 deletions

View File

@ -68,7 +68,14 @@ class Show(TimestampedModel):
upload_to = name_banner,
help_text="A banner used for the show's page.",
verbose_name="Banner"
)
)
class Meta:
permissions = (
('can_create_show_ban', 'Can ban an user from submitting to this show'),
('can_moderate_show', 'Can add episodes, seasons and unrestricted submissions'),
)
def __str__(self):
return '%s [%s]'%(self.name,self.abbr)

View File

@ -26,7 +26,7 @@ label {
width: 200px;
display: block;
}
input[type=text], input:not([type=submit]) {
input[type=text], input[type=email], input[type=password], input[type=number], input[type=url] {
padding: 5px;
font-size: 120%;
width: 280px;

View File

@ -21,6 +21,7 @@
<span class="logo">Episodes<span class="period">.</span>Community</span>
<div class="userdata">
{% if user.is_authenticated %}
{% if user.is_staff %}<a class="mod" href="/admin"><i class="fa fa-fw fa-shield"></a></i>{% endif %}
{{ user.display_name }}
{% else %}
<a href="/login">Log in</a>

View File

@ -1,5 +1,5 @@
from django import forms
from LandingPage.models import Submission, Season, Episode
from LandingPage.models import Submission, Season, Episode, Ban, User
class SubmissionForm(forms.ModelForm):
class Meta():
@ -19,3 +19,8 @@ class EpisodeForm(forms.ModelForm):
class Meta():
model = Episode
fields = ('episode','name','summary','airdate',)
class BanForm(forms.ModelForm):
class Meta():
model = Ban
fields = ('reason','expiration','permanent',)

View File

@ -0,0 +1,35 @@
{% extends "base.html" %}
{% block title %}
Ban an user from {{show.name}} - Episodes.Community
{% endblock %}
{% block content %}
<section class="show-details">
<div class="banner" style="background-image: url(/media/uploaded_resources/{{show.banner}});"></div>
<div class="banner-cover">
<div class="artwork">
<img src="/media/uploaded_resources/{{show.artwork}}">
</div>
<div class="details">
<h1>{{show.name}}</h1>
<p class="description">
{{show.description}}
</p>
</div>
</div>
</section>
<section class="submissions">
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i>&nbsp;Show Index</a>
<h1>Ban an User</h1>
{% if error %}
<div class="message error">{{error}}</div>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<p>Banning user <b>{{ target.display_name }}</b></p>
{{ form }}
<input type="submit" value="Ban" />
<input type="submit" name="delete" value="Ban and Delete all submissions" />
</form>
</div>
</section>
{% endblock %}

View File

@ -42,7 +42,7 @@
<section class="submissions">
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i>&nbsp;Show Index</a>
{% if user.is_authenticated %}
{% if "change_show" in show_perms %}
{% if "can_moderate_show" in show_perms %}
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button modbutton"><i class="fa fa-fw fa-plus"></i>&nbsp;Add New Link</a>
{% else %}
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button"><i class="fa fa-fw fa-plus"></i>&nbsp;Submit New Link</a>
@ -70,8 +70,15 @@
</form>
</div>
<div class="data">
<span class="timestamp">Submitted {{sbm.timestamp}} by {{sbm.user.display_name}}</span><span class="divider">&middot;</span>
{% if "change_show" in show_perms %}
{% get_obj_perms sbm.user for show as "publisher_perms" %}
<span class="timestamp">Submitted {{sbm.timestamp}} by
{% if sbm.user.is_staff or "can_moderate_show" in publisher_perms %}
<span class="mod"><i class="fa fa-fw fa-shield"></i></span>
{% endif %}
<span class="display_name">{{sbm.user.display_name}}</span>
</span>
<span class="divider">&middot;</span>
{% if "can_moderate_show" in show_perms %}
<a href="/show/{{show.abbr}}/submission/{{sbm.id}}/moderate" class="button modbutton"><i class="fa fa-fw fa-shield"></i>&nbsp;Change</a>
{% else %}
<a href="/report?url={{ request.get_full_path|urlencode }}&submission={{ sbm.id }}" class="report">Report Invalid or Spam</a>

View File

@ -38,13 +38,13 @@
</div>
</section>
<section class="seasons">
{% if "change_show" in show_perms %}
{% if "can_moderate_show" in show_perms %}
<a href="/show/{{show.abbr}}/season/new" class="button modbutton"><i class="fa fa-fw fa-plus"></i>&nbsp;Add a Season</a>
{% endif %}
<h1>Watch Now</h1>
{% for season in seasons %}
<div class="season" data-season="{{season.number}}">
{% if "change_show" in show_perms %}
{% if "can_moderate_show" in show_perms %}
<div class="actions">
<a href="/show/{{show.abbr}}/season/{{season.number}}/append" class="action"><i class="fa fa-fw fa-plus"></i></a>
</div>

View File

@ -27,6 +27,8 @@
</div>
</section>
<section class="submissions">
{% load guardian_tags %}
{% get_obj_perms request.user for show as "show_perms" %}
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i>&nbsp;Show Index</a>
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}-{{episode.name|slugify}}" class="button">Back to Episode</a>
<h1>Submission</h1>
@ -38,7 +40,9 @@
{{ form }}
<input type="submit" value="Edit" />
<input type="submit" name="delete" value="Delete" />
{% if "can_create_show_ban" in show_perms %}
<input type="submit" name="delete_ban" value="Delete and Ban User" />
{% endif %}
</form>
</div>
</section>

View File

@ -20,6 +20,7 @@ from . import views
urlpatterns = [
url(r'^$', views.IndexView.as_view()),
url(r'^create_ban$', views.BanFromShowForm),
url(r'^season/new$', views.SeasonSubmitForm),
url(r'^season/(?P<season>\d{1,4})/append$', views.EpisodeSubmitForm),
url(r'^submission/(?P<submission>\d{1,4})/moderate$', views.SubmissionModForm),

View File

@ -4,15 +4,13 @@ from django.views import View
from django.views.generic.base import TemplateView
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.http import Http404
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.db.models import Case, When, Value, IntegerField, Count, F
from django.http import Http404, HttpResponseForbidden, HttpResponse, HttpResponseRedirect
from django.db.models import Case, When, Value, IntegerField, Count, F, Q
from django.contrib.auth.mixins import LoginRequiredMixin
from guardian.decorators import permission_required_or_403
from LandingPage.models import User, Show, Season, Episode, Submission, SubmissionVote
from LandingPage.models import User, Show, Season, Episode, Submission, SubmissionVote, Ban
from . import forms
@ -87,6 +85,12 @@ def SubmissionForm(req, abbr, season, episode):
'episode': episode
}
# Get bans for this user regarding this show
bans = Ban.objects.filter(Q(scope=show) | Q(site_wide=True), Q(expiration__gte=datetime.datetime.now()) | Q(permanent=True), user=user)
if bans.count() > 0:
return HttpResponseForbidden('You are banned from submitting links to this show.<br>Reason: %s'%(bans.first().reason))
# Handle POST
if req.method == 'POST':
form = forms.SubmissionForm(req.POST)
@ -100,7 +104,7 @@ def SubmissionForm(req, abbr, season, episode):
ctx['error'] = 'This URL has already been submitted!'
return render(req, "submit.html", ctx)
if not user.has_perm('LandingPage.change_show'):
if not user.has_perm('LandingPage.can_moderate_show', show):
# Check if there has been a submission by this user for this episode within the last 24 hours
if Submission.objects.filter(user=user,episode=episode,timestamp__gte=datetime.datetime.now() - datetime.timedelta(hours=24)).count() > 0:
ctx['error'] = 'You can only submit one link for an episode in 24 hours!'
@ -118,7 +122,7 @@ def SubmissionForm(req, abbr, season, episode):
return render(req, "submit.html", ctx)
# Edit a submission - for moderators
@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
def SubmissionModForm(req, abbr, submission):
show = get_object_or_404(Show, abbr=abbr)
submission = get_object_or_404(Submission, pk=submission)
@ -136,14 +140,13 @@ def SubmissionModForm(req, abbr, submission):
# Handle POST
if req.method == 'POST':
if 'delete' in req.POST:
submission.delete()
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
if 'delete_ban' in req.POST:
submission.delete()
return HttpResponseRedirect('/ban?user=%d'%(submission.user.pk))
return HttpResponseRedirect('/show/%s/create_ban?user=%s'%(abbr,submission.user.username))
form = forms.SubmissionForm(req.POST, instance=submission)
ctx['form'] = form
@ -159,7 +162,7 @@ def SubmissionModForm(req, abbr, submission):
return render(req, "submit_mod.html", ctx)
# Season form GET and POST
@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
def SeasonSubmitForm(req, abbr):
show = get_object_or_404(Show, abbr=abbr)
user = req.user
@ -196,7 +199,7 @@ def SeasonSubmitForm(req, abbr):
return render(req, "season_add.html", ctx)
# Episode form GET and POST
@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True)
def EpisodeSubmitForm(req, abbr, season):
show = get_object_or_404(Show, abbr=abbr)
season = get_object_or_404(Season, show=show,number=season)
@ -251,6 +254,14 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View):
if submission.user == user:
return HttpResponse('<h1>Error</h1><p>You cannot vote for your own submission.</p>', status=400)
show = submission.episode.show
# Get bans for this user regarding this show
bans = Ban.objects.filter(Q(scope=show) | Q(site_wide=True), Q(expiration__gte=datetime.datetime.now()) | Q(permanent=True), user=user)
if bans.count() > 0:
return HttpResponseForbidden('You are banned from voting on this show.<br>Reason: %s'%(bans.first().reason))
# Allow changing a vote from positive to negative or vice-versa. Delete vote if its a re-vote
vote = submission.votes.filter(user=user,submission__id=submission.id).first()
if vote:
@ -269,3 +280,60 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View):
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, submission.episode.season.number, submission.episode.episode))
# Episode form GET and POST
@permission_required_or_403('LandingPage.can_create_show_ban', (Show, 'abbr', 'abbr'), accept_global_perms=True)
def BanFromShowForm(req, abbr):
show = get_object_or_404(Show, abbr=abbr)
user = req.user
banTarget = get_object_or_404(User, username=req.GET.get('user', None))
if banTarget == user:
return HttpResponseForbidden('You cannot ban yourself!')
if banTarget.is_staff:
return HttpResponseForbidden('You cannot ban a staff member!')
if banTarget.has_perm('LandingPage.can_moderate_show', show):
return HttpResponseForbidden('You cannot ban another moderator!')
form = forms.BanForm()
# Request context
ctx = {
'form': form,
'show': show,
'target': banTarget
}
# Handle POST
if req.method == 'POST':
form = forms.BanForm(req.POST)
ctx['form'] = form
if form.is_valid():
form_data = form.cleaned_data
# Save
new_ban = form.save(commit=False)
if form_data['permanent']:
new_ban.expiration = datetime.datetime.now()
new_ban.site_wide = False
new_ban.user = banTarget
new_ban.admin = user
new_ban.save()
# Add show to scope
new_ban.scope.add(show)
# Delete all of the user's submissions for this show
if 'delete' in req.POST:
Submission.objects.filter(episode__show=show,user=banTarget).delete()
return HttpResponseRedirect('/show/%s'%(abbr))
else:
ctx['error'] = 'Invalid fields!'
return render(req, "create_ban.html", ctx)