Add some better right management to forum

This commit is contained in:
Skia 2017-01-28 20:58:54 +01:00
parent 653d9d4707
commit 4cc57c183e
10 changed files with 123 additions and 16 deletions

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('forum', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='forum',
name='owner_group',
),
migrations.RemoveField(
model_name='forumtopic',
name='title',
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('club', '0006_auto_20161229_0040'),
('forum', '0002_auto_20170128_1958'),
]
operations = [
migrations.AddField(
model_name='forum',
name='owner_club',
field=models.ForeignKey(related_name='owned_forums', verbose_name='owner club', to='club.Club', default=1),
),
]

View File

@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse
from django.utils import timezone from django.utils import timezone
from core.models import User, MetaGroup, Group, SithFile from core.models import User, MetaGroup, Group, SithFile
from club.models import Club
class Forum(models.Model): class Forum(models.Model):
""" """
@ -17,13 +18,45 @@ class Forum(models.Model):
description = models.CharField(_('description'), max_length=256, default="") description = models.CharField(_('description'), max_length=256, default="")
is_category = models.BooleanField(_('is a category'), default=False) is_category = models.BooleanField(_('is a category'), default=False)
parent = models.ForeignKey('Forum', related_name='children', null=True, blank=True) parent = models.ForeignKey('Forum', related_name='children', null=True, blank=True)
owner_club = models.ForeignKey(Club, related_name="owned_forums", verbose_name=_("owner club"),
default=settings.SITH_MAIN_CLUB_ID)
edit_groups = models.ManyToManyField(Group, related_name="editable_forums", blank=True, edit_groups = models.ManyToManyField(Group, related_name="editable_forums", blank=True,
default=[settings.SITH_GROUP_OLD_SUBSCRIBERS_ID]) default=[settings.SITH_GROUP_OLD_SUBSCRIBERS_ID])
view_groups = models.ManyToManyField(Group, related_name="viewable_forums", blank=True, view_groups = models.ManyToManyField(Group, related_name="viewable_forums", blank=True,
default=[settings.SITH_GROUP_PUBLIC_ID]) default=[settings.SITH_GROUP_PUBLIC_ID])
def clean(self):
self.check_loop()
def save(self, *args, **kwargs):
copy_rights = False
if self.id is None:
copy_rights = True
super(Forum, self).save(*args, **kwargs)
if copy_rights:
self.copy_rights()
def apply_rights_recursively(self):
children = self.children.all()
for c in children:
c.copy_rights()
c.apply_rights_recursively()
def copy_rights(self):
"""Copy, if possible, the rights of the parent folder"""
if self.parent is not None:
self.owner_club = self.parent.owner_club
self.edit_groups = self.parent.edit_groups.all()
self.view_groups = self.parent.view_groups.all()
self.save()
def is_owned_by(self, user): def is_owned_by(self, user):
return user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) if user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID):
return True
m = self.owner_club.get_membership_for(user)
if m:
return m.role > settings.SITH_MAXIMUM_FREE_ROLE
return False
def check_loop(self): def check_loop(self):
"""Raise a validation error when a loop is found within the parent list""" """Raise a validation error when a loop is found within the parent list"""
@ -35,9 +68,6 @@ class Forum(models.Model):
objs.append(cur) objs.append(cur)
cur = cur.parent cur = cur.parent
def clean(self):
self.check_loop()
def __str__(self): def __str__(self):
return "%s" % (self.name) return "%s" % (self.name)
@ -73,7 +103,6 @@ class Forum(models.Model):
class ForumTopic(models.Model): class ForumTopic(models.Model):
forum = models.ForeignKey(Forum, related_name='topics') forum = models.ForeignKey(Forum, related_name='topics')
author = models.ForeignKey(User, related_name='forum_topics') author = models.ForeignKey(User, related_name='forum_topics')
title = models.CharField(_("title"), default="", max_length=64)
description = models.CharField(_('description'), max_length=256, default="") description = models.CharField(_('description'), max_length=256, default="")
class Meta: class Meta:
@ -94,6 +123,10 @@ class ForumTopic(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('forum:view_topic', kwargs={'topic_id': self.id}) return reverse('forum:view_topic', kwargs={'topic_id': self.id})
@property
def title(self):
return self.messages.order_by('date').first().title
class ForumMessage(models.Model): class ForumMessage(models.Model):
""" """
"A ForumMessage object represents a message in the forum" -- Cpt. Obvious "A ForumMessage object represents a message in the forum" -- Cpt. Obvious

View File

@ -11,9 +11,14 @@
> <a href="{{ forum.get_absolute_url() }}">{{ forum }}</a> > <a href="{{ forum.get_absolute_url() }}">{{ forum }}</a>
</div> </div>
<h3>{{ forum.name }}</h3> <h3>{{ forum.name }}</h3>
<a href="{{ url('forum:new_forum') }}?parent={{ forum.id }}">New forum</a> <p>
{% if user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
<a href="{{ url('forum:new_forum') }}?parent={{ forum.id }}">New forum</a> <br/>
{% endif %}
<a href="{{ url('forum:new_topic', forum_id=forum.id) }}">New topic</a>
</p>
{% for f in forum.children.all() %} {% for f in forum.children.all() %}
{{ display_forum(f) }} {{ display_forum(f, user) }}
{% endfor %} {% endfor %}
{% for t in topics %} {% for t in topics %}
<div class="topic"> <div class="topic">
@ -22,7 +27,7 @@
<h5>{{ t.title }}</h5> <h5>{{ t.title }}</h5>
<p>{{ t.description }}</p> <p>{{ t.description }}</p>
</a> </a>
{% if user.can_edit(t) %} {% if user.is_owner(t) %}
<div class="ib" style="text-align: center;"> <div class="ib" style="text-align: center;">
<a href="{{ url('forum:edit_topic', topic_id=t.id) }}">Edit</a> <a href="{{ url('forum:edit_topic', topic_id=t.id) }}">Edit</a>
</div> </div>
@ -45,7 +50,6 @@
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
<a href="{{ url('forum:new_topic', forum_id=forum.id) }}">New topic</a>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
{% macro display_forum(forum) %} {% macro display_forum(forum, user) %}
<div class="forum {% if forum.is_category %}category{% endif %}"> <div class="forum {% if forum.is_category %}category{% endif %}">
<div class="ib w_big"> <div class="ib w_big">
{% if not forum.is_category %} {% if not forum.is_category %}
@ -13,7 +13,10 @@
{% else %} {% else %}
</div> </div>
{% endif %} {% endif %}
{% if user.is_owner(forum) %}
<a class="ib" href="{{ url('forum:edit_forum', forum_id=forum.id) }}">Edit</a> <a class="ib" href="{{ url('forum:edit_forum', forum_id=forum.id) }}">Edit</a>
<a class="ib" href="{{ url('forum:delete_forum', forum_id=forum.id) }}">Delete</a>
{% endif %}
</div> </div>
{% if not forum.is_category %} {% if not forum.is_category %}
<div class="ib w_small"> <div class="ib w_small">

View File

@ -7,12 +7,16 @@
<a href="{{ url('forum:main') }}">Forum</a> > <a href="{{ url('forum:main') }}">Forum</a> >
</p> </p>
<h3>{% trans %}Forum{% endtrans %}</h3> <h3>{% trans %}Forum{% endtrans %}</h3>
<a href="{{ url('forum:new_forum') }}">New forum</a> <p>
{% if user.is_in_group(settings.SITH_GROUP_FORUM_ADMIN_ID) or user.is_in_group(settings.SITH_GROUP_COM_ADMIN_ID) %}
<a href="{{ url('forum:new_forum') }}">New forum</a>
{% endif %}
</p>
{% for f in forum_list %} {% for f in forum_list %}
<div style="padding: 4px; margin: 4px"> <div style="padding: 4px; margin: 4px">
{{ display_forum(f) }} {{ display_forum(f, user) }}
{% for c in f.children.all() %} {% for c in f.children.all() %}
{{ display_forum(c) }} {{ display_forum(c, user) }}
{% endfor %} {% endfor %}
</div> </div>
{% endfor %} {% endfor %}

View File

@ -7,6 +7,7 @@ urlpatterns = [
url(r'^new_forum$', ForumCreateView.as_view(), name='new_forum'), url(r'^new_forum$', ForumCreateView.as_view(), name='new_forum'),
url(r'^(?P<forum_id>[0-9]+)$', ForumDetailView.as_view(), name='view_forum'), url(r'^(?P<forum_id>[0-9]+)$', ForumDetailView.as_view(), name='view_forum'),
url(r'^(?P<forum_id>[0-9]+)/edit$', ForumEditView.as_view(), name='edit_forum'), url(r'^(?P<forum_id>[0-9]+)/edit$', ForumEditView.as_view(), name='edit_forum'),
url(r'^(?P<forum_id>[0-9]+)/delete$', ForumDeleteView.as_view(), name='delete_forum'),
url(r'^(?P<forum_id>[0-9]+)/new_topic$', ForumTopicCreateView.as_view(), name='new_topic'), url(r'^(?P<forum_id>[0-9]+)/new_topic$', ForumTopicCreateView.as_view(), name='new_topic'),
url(r'^topic/(?P<topic_id>[0-9]+)$', ForumTopicDetailView.as_view(), name='view_topic'), url(r'^topic/(?P<topic_id>[0-9]+)$', ForumTopicDetailView.as_view(), name='view_topic'),
url(r'^topic/(?P<topic_id>[0-9]+)/edit$', ForumTopicEditView.as_view(), name='edit_topic'), url(r'^topic/(?P<topic_id>[0-9]+)/edit$', ForumTopicEditView.as_view(), name='edit_topic'),

View File

@ -18,7 +18,7 @@ class ForumMainView(CanViewMixin, ListView):
class ForumCreateView(CanCreateMixin, CreateView): class ForumCreateView(CanCreateMixin, CreateView):
model = Forum model = Forum
fields = ['name', 'parent', 'is_category', 'edit_groups', 'view_groups'] fields = ['name', 'parent', 'owner_club', 'is_category', 'edit_groups', 'view_groups']
template_name = "core/create.jinja" template_name = "core/create.jinja"
def get_initial(self): def get_initial(self):
@ -26,16 +26,35 @@ class ForumCreateView(CanCreateMixin, CreateView):
try: try:
parent = Forum.objects.filter(id=self.request.GET['parent']).first() parent = Forum.objects.filter(id=self.request.GET['parent']).first()
init['parent'] = parent init['parent'] = parent
init['owner_club'] = parent.owner_club
except: pass except: pass
return init return init
class ForumEditForm(forms.ModelForm):
class Meta:
model = Forum
fields = ['name', 'parent', 'owner_club', 'is_category', 'edit_groups', 'view_groups']
recursive = forms.BooleanField(label=_("Apply rights and club owner recursively"), required=False)
class ForumEditView(CanEditPropMixin, UpdateView): class ForumEditView(CanEditPropMixin, UpdateView):
model = Forum model = Forum
pk_url_kwarg = "forum_id" pk_url_kwarg = "forum_id"
fields = ['name', 'parent', 'is_category', 'edit_groups', 'view_groups'] form_class = ForumEditForm
template_name = "core/edit.jinja" template_name = "core/edit.jinja"
success_url = reverse_lazy('forum:main') success_url = reverse_lazy('forum:main')
def form_valid(self, form):
ret = super(ForumEditView, self).form_valid(form)
if form.cleaned_data['recursive']:
self.object.apply_rights_recursively()
return ret
class ForumDeleteView(CanEditPropMixin, DeleteView):
model = Forum
pk_url_kwarg = "forum_id"
template_name = "core/delete_confirm.jinja"
success_url = reverse_lazy('forum:main')
class ForumDetailView(CanViewMixin, DetailView): class ForumDetailView(CanViewMixin, DetailView):
model = Forum model = Forum
template_name = "forum/forum.jinja" template_name = "forum/forum.jinja"

View File

@ -39,7 +39,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
<div> <div>
{% for a in album.children_albums.order_by('-id') %} {% for a in album.children_albums.order_by('-date') %}
<div style="display: inline-block;"> <div style="display: inline-block;">
{% if edit_mode %} {% if edit_mode %}
<input type="checkbox" name="file_list" value="{{ a.id }}"> <input type="checkbox" name="file_list" value="{{ a.id }}">

View File

@ -232,6 +232,7 @@ SITH_URL = "my.url.git.an"
SITH_NAME = "Sith website" SITH_NAME = "Sith website"
# AE configuration # AE configuration
SITH_MAIN_CLUB_ID = 1 # TODO: keep only that first setting, with the ID, and do the same for the other clubs
SITH_MAIN_CLUB = { SITH_MAIN_CLUB = {
'name': "AE", 'name': "AE",
'unix_name': "ae", 'unix_name': "ae",