Some refactoring and misc improvements

This commit is contained in:
Skia
2016-02-05 16:59:42 +01:00
parent ed080b76a2
commit a14d940db2
16 changed files with 199 additions and 74 deletions

View File

@ -1 +1 @@
[{"pk": 1, "model": "core.page", "fields": {"full_name": "guy2", "owner_group": 1, "parent": null, "edit_group": [], "name": "guy2", "view_group": []}}, {"pk": 2, "model": "core.page", "fields": {"full_name": "guy2/bibou", "owner_group": 1, "parent": 1, "edit_group": [], "name": "bibou", "view_group": []}}, {"pk": 3, "model": "core.page", "fields": {"full_name": "guy2/bibou/troll", "owner_group": 1, "parent": 2, "edit_group": [], "name": "troll", "view_group": []}}, {"pk": 4, "model": "core.page", "fields": {"full_name": "guy", "owner_group": 1, "parent": null, "edit_group": [1], "name": "guy", "view_group": [1]}}, {"pk": 5, "model": "core.page", "fields": {"full_name": "bibou", "owner_group": 3, "parent": null, "edit_group": [1], "name": "bibou", "view_group": []}}, {"pk": 6, "model": "core.page", "fields": {"full_name": "guy2/guy", "owner_group": 1, "parent": 1, "edit_group": [], "name": "guy", "view_group": []}}]
[{"pk": 1, "model": "core.page", "fields": {"full_name": "guy2", "owner_group": 1, "parent": null, "edit_groups": [], "name": "guy2", "view_groups": []}}, {"pk": 2, "model": "core.page", "fields": {"full_name": "guy2/bibou", "owner_group": 1, "parent": 1, "edit_group": [], "name": "bibou", "view_group": []}}, {"pk": 3, "model": "core.page", "fields": {"full_name": "guy2/bibou/troll", "owner_group": 1, "parent": 2, "edit_group": [], "name": "troll", "view_group": []}}, {"pk": 4, "model": "core.page", "fields": {"full_name": "guy", "owner_group": 1, "parent": null, "edit_group": [1], "name": "guy", "view_group": [1]}}, {"pk": 5, "model": "core.page", "fields": {"full_name": "bibou", "owner_group": 3, "parent": null, "edit_group": [1], "name": "bibou", "view_group": []}}, {"pk": 6, "model": "core.page", "fields": {"full_name": "guy2/guy", "owner_group": 1, "parent": 1, "edit_group": [], "name": "guy", "view_group": []}}]

View File

@ -16,9 +16,10 @@ class Command(BaseCommand):
parser.add_argument('--prod', action="store_true")
def handle(self, *args, **options):
root_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
try:
os.unlink(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), 'db.sqlite3'))
os.mkdir(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))+'/data')
os.unlink(os.path.join(root_path, 'db.sqlite3'))
os.mkdir(os.path.join(root_path)+'/data')
except Exception as e:
print(e)
call_command('migrate')
@ -37,37 +38,41 @@ class Command(BaseCommand):
# Here we add a lot of test datas, that are not necessary for the Sith, but that provide a basic development environment
if not options['prod']:
print("Dev mode, adding some test data")
# Adding user Skia
s = User(username='skia', last_name="Kia", first_name="S'",
email="skia@git.an",
date_of_birth="1942-06-12",
is_superuser=True, is_staff=True)
date_of_birth="1942-06-12")
s.set_password("plop")
s.save()
# Adding user Guy
u = User(username='guy', last_name="Carlier", first_name="Guy",
email="guy@git.an",
date_of_birth="1942-06-12",
is_superuser=False, is_staff=False)
u.set_password("plop")
u.save()
# Adding syntax help page
p = Page(name='Aide_sur_la_syntaxe')
p.set_lock(s)
p.save()
PageRev(page=p, title="Aide sur la syntaxe", author=s, content="""
Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site.
""").save()
# Accounting test values:
Customer(user=s, account_id="6568j").save()
p = ProductType(name="Bières bouteilles")
# Adding README
p = Page(name='README')
p.set_lock(s)
p.save()
Product(name="Barbar", code="BARB", product_type=p, purchase_price="1.50", selling_price="1.7",
special_selling_price="1.6").save()
GeneralJournal(start_date="2015-06-12", name="A15").save()
p.view_groups=[settings.AE_GROUPS['public']['id']]
p.set_lock(s)
p.save()
with open(os.path.join(root_path)+'/README.md', 'r') as rm:
PageRev(page=p, title="REAMDE", author=s, content=rm.read()).save()
# Subscription
Subscription(member=Subscriber.objects.filter(pk=s.pk).first(), subscription_type=list(settings.AE_SUBSCRIPTIONS.keys())[0],
payment_method=settings.AE_PAYMENT_METHOD[0]).save()
# Clubs
Club(name="Bibo'UT", unix_name="bibout",
address="46 de la Boustifaille", parent=ae).save()
guyut = Club(name="Guy'UT", unix_name="guyut",
@ -77,3 +82,12 @@ Cette page vise à documenter la syntaxe *Markdown* utilisée sur le site.
address="Woenzel", parent=guyut).save()
Club(name="BdF", unix_name="bdf",
address="Guyéuéyuéyuyé").save()
# Accounting test values:
Customer(user=s, account_id="6568j").save()
p = ProductType(name="Bières bouteilles")
p.save()
Product(name="Barbar", code="BARB", product_type=p, purchase_price="1.50", selling_price="1.7",
special_selling_price="1.6").save()
GeneralJournal(start_date="2015-06-12", name="A15").save()

View File

@ -54,10 +54,10 @@ class Migration(migrations.Migration):
('id', models.AutoField(serialize=False, auto_created=True, primary_key=True, verbose_name='ID')),
('name', models.CharField(max_length=30, verbose_name='page name')),
('_full_name', models.CharField(max_length=255, verbose_name='page name', blank=True)),
('edit_group', models.ManyToManyField(to='core.Group', related_name='editable_page', blank=True)),
('edit_groups', models.ManyToManyField(to='core.Group', related_name='editable_page', blank=True)),
('owner_group', models.ForeignKey(to='core.Group', related_name='owned_page', default=1)),
('parent', models.ForeignKey(to='core.Page', on_delete=django.db.models.deletion.SET_NULL, null=True, related_name='children', blank=True)),
('view_group', models.ManyToManyField(to='core.Group', related_name='viewable_page', blank=True)),
('view_groups', models.ManyToManyField(to='core.Group', related_name='viewable_page', blank=True)),
],
options={
'permissions': (('change_prop_page', "Can change the page's properties (groups, ...)"), ('view_page', 'Can view the page')),
@ -79,7 +79,7 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name='user',
name='edit_group',
name='edit_groups',
field=models.ManyToManyField(to='core.Group', related_name='editable_user', blank=True),
),
migrations.AddField(
@ -99,7 +99,7 @@ class Migration(migrations.Migration):
),
migrations.AddField(
model_name='user',
name='view_group',
name='view_groups',
field=models.ManyToManyField(to='core.Group', related_name='viewable_user', blank=True),
),
migrations.AlterUniqueTogether(

View File

@ -65,8 +65,8 @@ class User(AbstractBaseUser, PermissionsMixin):
date_joined = models.DateField(_('date joined'), auto_now_add=True)
owner_group = models.ForeignKey(Group, related_name="owned_user",
default=settings.AE_GROUPS['root']['id'])
edit_group = models.ManyToManyField(Group, related_name="editable_user", blank=True)
view_group = models.ManyToManyField(Group, related_name="viewable_user", blank=True)
edit_groups = models.ManyToManyField(Group, related_name="editable_user", blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_user", blank=True)
objects = UserManager()
@ -159,6 +159,8 @@ class User(AbstractBaseUser, PermissionsMixin):
self.has_perm(obj.__class__.__module__.split('.')[0]+".change_prop_"+obj.__class__.__name__.lower()) or
self.groups.filter(id=settings.AE_GROUPS['root']['id']).exists()):
return True
if hasattr(obj, "is_owned_by") and obj.is_owned_by(self):
return True
return False
def can_edit(self, obj):
@ -167,12 +169,14 @@ class User(AbstractBaseUser, PermissionsMixin):
"""
if self.is_owner(obj):
return True
if hasattr(obj, "edit_group"):
for g in obj.edit_group.all():
if hasattr(obj, "edit_groups"):
for g in obj.edit_groups.all():
if self.groups.filter(name=g.name).exists():
return True
if isinstance(obj, User) and obj == self:
return True
if hasattr(obj, "can_be_edited_by") and obj.can_be_edited_by(self):
return True
if self.has_perm(obj.__class__.__module__.split('.')[0]+".change_"+obj.__class__.__name__.lower()):
return True
return False
@ -183,10 +187,12 @@ class User(AbstractBaseUser, PermissionsMixin):
"""
if self.can_edit(obj):
return True
if hasattr(obj, "view_group"):
for g in obj.view_group.all():
if hasattr(obj, "view_groups"):
for g in obj.view_groups.all():
if self.groups.filter(name=g.name).exists():
return True
if hasattr(obj, "can_be_viewed_by") and obj.can_be_viewed_by(self):
return True
if self.has_perm(obj.__class__.__module__.split('.')[0]+".view_"+obj.__class__.__name__.lower()):
return True
return False
@ -202,7 +208,7 @@ class AnonymousUser(AuthAnonymousUser):
return False
def can_view(self, obj):
if obj.view_group.filter(pk=settings.AE_GROUPS['public']['id']).exists():
if obj.view_groups.filter(pk=settings.AE_GROUPS['public']['id']).exists():
return True
return False
@ -236,8 +242,8 @@ class Page(models.Model):
_full_name = models.CharField(_('page name'), max_length=255, blank=True)
owner_group = models.ForeignKey(Group, related_name="owned_page",
default=settings.AE_GROUPS['root']['id'])
edit_group = models.ManyToManyField(Group, related_name="editable_page", blank=True)
view_group = models.ManyToManyField(Group, related_name="viewable_page", blank=True)
edit_groups = models.ManyToManyField(Group, related_name="editable_page", blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_page", blank=True)
lock_mutex = {}
@ -397,10 +403,10 @@ class PageRev(models.Model):
def __getattribute__(self, attr):
if attr == "owner_group":
return self.page.owner_group
elif attr == "edit_group":
return self.page.edit_group
elif attr == "view_group":
return self.page.view_group
elif attr == "edit_groups":
return self.page.edit_groups
elif attr == "view_groups":
return self.page.view_groups
elif attr == "unset_lock":
return self.page.unset_lock
else:

View File

@ -12,6 +12,20 @@ def forbidden(request):
def not_found(request):
return render(request, "core/404.jinja")
def can_edit_prop(obj, user):
if obj is None or user.is_owner(obj):
return True
return False
def can_edit(obj, user):
if obj is None or user.can_edit(obj):
return True
return can_edit_prop(obj, user)
def can_view(obj, user):
if obj is None or user.can_view(obj):
return True
return can_edit(obj, user)
class CanEditPropMixin(View):
"""
@ -22,8 +36,11 @@ class CanEditPropMixin(View):
"""
def dispatch(self, request, *arg, **kwargs):
res = super(CanEditPropMixin, self).dispatch(request, *arg, **kwargs)
if ((hasattr(self, 'object') and (self.object is None or self.request.user.is_owner(self.object))) or
(hasattr(self, 'object_list') and (self.object_list is None or self.object_list is [] or self.request.user.is_owner(self.object_list[0])))):
if hasattr(self, 'object'):
obj = self.object
elif hasattr(self, 'object_list'):
obj = self.object_list[0] if self.object_list else None
if can_edit_prop(obj, self.request.user):
return res
try: # Always unlock when 403
self.object.unset_lock()
@ -32,35 +49,38 @@ class CanEditPropMixin(View):
class CanEditMixin(View):
"""
This view makes exactly the same this as its direct parent, but checks the group on the edit_group field of the
This view makes exactly the same this as its direct parent, but checks the group on the edit_groups field of the
object
"""
def dispatch(self, request, *arg, **kwargs):
# TODO: WIP: fix permissions with exceptions!
res = super(CanEditMixin, self).dispatch(request, *arg, **kwargs)
if ((hasattr(self, 'object') and (self.object is None or self.request.user.can_edit(self.object))) or
(hasattr(self, 'object_list') and (self.object_list is None or self.object_list is [] or self.request.user.can_edit(self.object_list[0])))):
if hasattr(self, 'object'):
obj = self.object
elif hasattr(self, 'object_list'):
obj = self.object_list[0] if self.object_list else None
if can_edit(obj, self.request.user):
return res
try: # Always unlock when 403
self.object.unset_lock()
except: pass
print("CanEditMixin 403")
raise PermissionDenied
class CanViewMixin(View):
"""
This view still makes exactly the same this as its direct parent, but checks the group on the view_group field of
This view still makes exactly the same this as its direct parent, but checks the group on the view_groups field of
the object
"""
def dispatch(self, request, *arg, **kwargs):
res = super(CanViewMixin, self).dispatch(request, *arg, **kwargs)
if ((hasattr(self, 'object') and (self.object is None or self.request.user.can_view(self.object))) or
(hasattr(self, 'object_list') and (self.object_list is None or self.object_list is [] or self.request.user.can_view(self.object_list[0])))):
if hasattr(self, 'object'):
obj = self.object
elif hasattr(self, 'object_list'):
obj = self.object_list[0] if self.object_list else None
if can_view(obj, self.request.user):
return res
try: # Always unlock when 403
self.object.unset_lock()
except: pass
print("CanViewMixin 403")
raise PermissionDenied
from .user import *

View File

@ -27,21 +27,21 @@ class UserPropForm(forms.ModelForm):
required_css_class = 'required'
class Meta:
model = User
fields = ['groups', 'edit_group', 'view_group']
fields = ['groups', 'edit_groups', 'view_groups']
labels = {
'edit_group': "Edit profile group",
'view_group': "View profile group",
'edit_groups': "Edit profile group",
'view_groups': "View profile group",
}
help_texts = {
'edit_group': "Groups that can edit this user's profile",
'view_group': "Groups that can view this user's profile",
'edit_groups': "Groups that can edit this user's profile",
'view_groups': "Groups that can view this user's profile",
'groups': "Which groups this user belongs to",
}
widgets = {
'groups': CheckboxSelectMultiple,
'user_permissions': CheckboxSelectMultiple,
'edit_group': CheckboxSelectMultiple,
'view_group': CheckboxSelectMultiple,
'edit_groups': CheckboxSelectMultiple,
'view_groups': CheckboxSelectMultiple,
}
class PagePropForm(forms.ModelForm):
@ -49,16 +49,16 @@ class PagePropForm(forms.ModelForm):
required_css_class = 'required'
class Meta:
model = Page
fields = ['parent', 'name', 'owner_group', 'edit_group', 'view_group', ]
fields = ['parent', 'name', 'owner_group', 'edit_groups', 'view_groups', ]
widgets = {
'edit_group': CheckboxSelectMultiple,
'view_group': CheckboxSelectMultiple,
'edit_groups': CheckboxSelectMultiple,
'view_groups': CheckboxSelectMultiple,
}
def __init__(self, *arg, **kwargs):
super(PagePropForm, self).__init__(*arg, **kwargs)
self.fields['edit_group'].required = False
self.fields['view_group'].required = False
self.fields['edit_groups'].required = False
self.fields['view_groups'].required = False
class GroupEditForm(forms.ModelForm):

View File

@ -9,7 +9,7 @@ from core.models import Page, PageRev, LockError
from core.views.forms import PagePropForm
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin
class PageListView(ListView):
class PageListView(CanViewMixin, ListView):
model = Page
template_name = 'core/page_list.jinja'