diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 842c2dca..922a6eaf 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -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() diff --git a/core/migrations/0005_auto_20161105_1035.py b/core/migrations/0005_auto_20161105_1035.py new file mode 100644 index 00000000..da6241d4 --- /dev/null +++ b/core/migrations/0005_auto_20161105_1035.py @@ -0,0 +1,25 @@ +# -*- 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'), + ), + ] diff --git a/core/models.py b/core/models.py index 97087e9c..656bf395 100644 --- a/core/models.py +++ b/core/models.py @@ -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): """ diff --git a/core/views/__init__.py b/core/views/__init__.py index 4e958e8f..66f27717 100644 --- a/core/views/__init__.py +++ b/core/views/__init__.py @@ -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): diff --git a/core/views/page.py b/core/views/page.py index 1e08ca18..60ce1bb8 100644 --- a/core/views/page.py +++ b/core/views/page.py @@ -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', ], diff --git a/sith/settings.py b/sith/settings.py index 7dc760ab..dac219e6 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -442,5 +442,6 @@ OLD_MYSQL_INFOS = { try: from .settings_custom import * + print("Custom settings imported") except: print("Custom settings failed")