Commit 59f5917b authored by Skia's avatar Skia

Fix Page locking

parent c0c8b295
Pipeline #343 failed with stage
in 3 minutes and 41 seconds
......@@ -167,15 +167,14 @@ Welcome to the wiki page!
r.save()
# Adding syntax help page
p = Page(name='Aide_sur_la_syntaxe')
p.save()
p.save(force_lock=True)
PageRev(page=p, title="Aide sur la syntaxe", author=skia, content="""
Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site.
""").save()
p = Page(name='Services')
p.save()
p.set_lock(skia)
p.save(force_lock=True)
p.view_groups=[settings.SITH_GROUPS['public']['id']]
p.save()
p.save(force_lock=True)
PageRev(page=p, title="Services", author=skia, content="""
| | | |
| :---: | :---: | :---: |
......@@ -185,10 +184,9 @@ Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site.
""").save()
# Adding README
p = Page(name='README')
p.save()
p.save(force_lock=True)
p.view_groups=[settings.SITH_GROUPS['public']['id']]
p.set_lock(skia)
p.save()
p.save(force_lock=True)
with open(os.path.join(root_path)+'/README.md', 'r') as rm:
PageRev(page=p, title="README", author=skia, content=rm.read()).save()
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('core', '0004_user_godfathers'),
]
operations = [
migrations.AddField(
model_name='page',
name='lock_timeout',
field=models.DateTimeField(verbose_name='lock_timeout', null=True, blank=True, default=None),
),
migrations.AddField(
model_name='page',
name='lock_user',
field=models.ForeignKey(verbose_name='lock user', default=None, blank=True, to=settings.AUTH_USER_MODEL, null=True, related_name='locked_pages'),
),
]
......@@ -630,7 +630,8 @@ class Page(models.Model):
default=settings.SITH_GROUPS['root']['id'])
edit_groups = models.ManyToManyField(Group, related_name="editable_page", verbose_name=_("edit group"), blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_page", verbose_name=_("view group"), blank=True)
lock_mutex = {}
lock_user = models.ForeignKey(User, related_name="locked_pages", verbose_name=_("lock user"), blank=True, null=True, default=None)
lock_timeout = models.DateTimeField(_('lock_timeout'), null=True, blank=True, default=None)
class Meta:
unique_together = ('name', 'parent')
......@@ -679,7 +680,9 @@ class Page(models.Model):
"""
Performs some needed actions before and after saving a page in database
"""
if not self.is_locked():
locked = kwargs.pop('force_lock', False)
if not locked: locked = self.is_locked()
if not locked:
raise NotLocked("The page is not locked and thus can not be saved")
self.full_clean()
# This reset the _full_name just before saving to maintain a coherent field quicker for queries than the
......@@ -697,23 +700,20 @@ class Page(models.Model):
This is where the timeout is handled, so a locked page for which the timeout is reach will be unlocked and this
function will return False
"""
if self.pk not in Page.lock_mutex.keys():
# print("Page mutex does not exists")
return False
if (timezone.now()-Page.lock_mutex[self.pk]['time']) > timedelta(minutes=5):
if self.lock_timeout and (timezone.now() - self.lock_timeout > timedelta(minutes=5)):
# print("Lock timed out")
self.unset_lock()
return False
return True
return self.lock_user and self.lock_timeout and (timezone.now() - self.lock_timeout < timedelta(minutes=5))
def set_lock(self, user):
"""
Sets a lock on the current page or raise an AlreadyLocked exception
"""
if self.is_locked() and self.get_lock()['user'] != user:
if self.is_locked() and self.get_lock() != user:
raise AlreadyLocked("The page is already locked by someone else")
Page.lock_mutex[self.pk] = {'user': user,
'time': timezone.now()}
self.lock_user = user
self.lock_timeout = timezone.now()
super(Page, self).save()
# print("Locking page")
def set_lock_recursive(self, user):
......@@ -726,16 +726,18 @@ class Page(models.Model):
def unset_lock(self):
"""Always try to unlock, even if there is no lock"""
Page.lock_mutex.pop(self.pk, None)
self.lock_user = None
self.lock_timeout = None
super(Page, self).save()
# print("Unlocking page")
def get_lock(self):
"""
Returns the page's mutex containing the time and the user in a dict
"""
if self.is_locked():
return Page.lock_mutex[self.pk]
raise NotLocked("The page is not locked and thus can not return its mutex")
if self.lock_user:
return self.lock_user
raise NotLocked("The page is not locked and thus can not return its user")
def get_absolute_url(self):
"""
......
......@@ -37,6 +37,12 @@ class CanCreateMixin(View):
This view is made to protect any child view that would create an object, and thus, that can not be protected by any
of the following mixin
"""
def dispatch(self, request, *arg, **kwargs):
res = super(CanCreateMixin, self).dispatch(request, *arg, **kwargs)
if not request.user.is_authenticated():
raise PermissionDenied
return res
def form_valid(self, form):
obj = form.instance
if can_edit_prop(obj, self.request.user):
......
......@@ -9,7 +9,7 @@ from django.forms import CheckboxSelectMultiple
from core.models import Page, PageRev, LockError
from core.views.forms import PagePropForm
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
class PageListView(CanViewMixin, ListView):
model = Page
......@@ -59,7 +59,7 @@ class PageRevView(CanViewMixin, DetailView):
context['new_page'] = self.kwargs['page_name']
return context
class PageCreateView(CanEditPropMixin, CreateView):
class PageCreateView(CanCreateMixin, CreateView):
model = Page
form_class = modelform_factory(Page,
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ],
......
......@@ -442,5 +442,6 @@ OLD_MYSQL_INFOS = {
try:
from .settings_custom import *
print("Custom settings imported")
except:
print("Custom settings failed")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment