mirror of https://gitlab.crans.org/bde/nk20
Don't display a note that we can't see, fix CI, fix distinct fields on PostgresSQL DB
This commit is contained in:
parent
bac81cd13e
commit
751147f254
|
@ -139,7 +139,7 @@ class Entry(models.Model):
|
||||||
verbose_name = _("entry")
|
verbose_name = _("entry")
|
||||||
verbose_name_plural = _("entries")
|
verbose_name_plural = _("entries")
|
||||||
|
|
||||||
def save(self, *args,**kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
|
||||||
qs = Entry.objects.filter(~Q(pk=self.pk), activity=self.activity, note=self.note, guest=self.guest)
|
qs = Entry.objects.filter(~Q(pk=self.pk), activity=self.activity, note=self.note, guest=self.guest)
|
||||||
if qs.exists():
|
if qs.exists():
|
||||||
|
@ -153,7 +153,7 @@ class Entry(models.Model):
|
||||||
if self.note.balance < 0:
|
if self.note.balance < 0:
|
||||||
raise ValidationError(_("The balance is negative."))
|
raise ValidationError(_("The balance is negative."))
|
||||||
|
|
||||||
ret = super().save(*args,**kwargs)
|
ret = super().save(*args, **kwargs)
|
||||||
|
|
||||||
if insert and self.guest:
|
if insert and self.guest:
|
||||||
GuestTransaction.objects.create(
|
GuestTransaction.objects.create(
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import F, Q
|
from django.db.models import F, Q
|
||||||
|
@ -45,8 +46,8 @@ class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
|
||||||
context['title'] = _("Activities")
|
context['title'] = _("Activities")
|
||||||
|
|
||||||
upcoming_activities = Activity.objects.filter(date_end__gt=datetime.now())
|
upcoming_activities = Activity.objects.filter(date_end__gt=datetime.now())
|
||||||
context['upcoming'] = ActivityTable(data=upcoming_activities
|
context['upcoming'] = ActivityTable(data=upcoming_activities.filter(
|
||||||
.filter(PermissionBackend.filter_queryset(self.request.user, Activity, "view")))
|
PermissionBackend.filter_queryset(self.request.user, Activity, "view")))
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
@ -138,8 +139,14 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
|
||||||
| Q(note__noteuser__user__last_name__regex=pattern)
|
| Q(note__noteuser__user__last_name__regex=pattern)
|
||||||
| Q(name__regex=pattern)
|
| Q(name__regex=pattern)
|
||||||
| Q(normalized_name__regex=Alias.normalize(pattern)))) \
|
| Q(normalized_name__regex=Alias.normalize(pattern)))) \
|
||||||
.filter(PermissionBackend.filter_queryset(self.request.user, Alias, "view"))\
|
.filter(PermissionBackend.filter_queryset(self.request.user, Alias, "view"))
|
||||||
.distinct()[:20]
|
if settings.DATABASES[note_qs.db]["ENGINE"] == 'django.db.backends.postgresql_psycopg2':
|
||||||
|
note_qs = note_qs.distinct('note__pk')[:20]
|
||||||
|
else:
|
||||||
|
# SQLite doesn't support distinct fields. For compatibility reason (in dev mode), the note list will only
|
||||||
|
# have distinct aliases rather than distinct notes with a SQLite DB, but it can fill the result page.
|
||||||
|
# In production mode, please use PostgreSQL.
|
||||||
|
note_qs = note_qs.distinct()[:20]
|
||||||
for note in note_qs:
|
for note in note_qs:
|
||||||
note.type = "Adhérent"
|
note.type = "Adhérent"
|
||||||
note.activity = activity
|
note.activity = activity
|
||||||
|
@ -153,9 +160,9 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
|
||||||
context["title"] = _('Entry for activity "{}"').format(activity.name)
|
context["title"] = _('Entry for activity "{}"').format(activity.name)
|
||||||
context["noteuser_ctype"] = ContentType.objects.get_for_model(NoteUser).pk
|
context["noteuser_ctype"] = ContentType.objects.get_for_model(NoteUser).pk
|
||||||
context["notespecial_ctype"] = ContentType.objects.get_for_model(NoteSpecial).pk
|
context["notespecial_ctype"] = ContentType.objects.get_for_model(NoteSpecial).pk
|
||||||
|
|
||||||
context["activities_open"] = Activity.objects.filter(open=True).filter(
|
context["activities_open"] = Activity.objects.filter(open=True).filter(
|
||||||
PermissionBackend.filter_queryset(self.request.user, Activity, "view")).filter(
|
PermissionBackend.filter_queryset(self.request.user, Activity, "view")).filter(
|
||||||
PermissionBackend.filter_queryset(self.request.user, Activity, "change")).all()
|
PermissionBackend.filter_queryset(self.request.user, Activity, "change")).all()
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_polymorphic.serializers import PolymorphicSerializer
|
from rest_polymorphic.serializers import PolymorphicSerializer
|
||||||
|
from note_kfet.middlewares import get_current_authenticated_user
|
||||||
|
from permission.backends import PermissionBackend
|
||||||
|
|
||||||
from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
|
from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
|
||||||
from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
|
from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
|
||||||
|
@ -96,20 +98,24 @@ class NotePolymorphicSerializer(PolymorphicSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Note
|
model = Note
|
||||||
|
|
||||||
|
|
||||||
class ConsumerSerializer(serializers.ModelSerializer):
|
class ConsumerSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
REST API Nested Serializer for Consumers.
|
REST API Nested Serializer for Consumers.
|
||||||
return Alias, and the note Associated to it in
|
return Alias, and the note Associated to it in
|
||||||
"""
|
"""
|
||||||
note = NotePolymorphicSerializer()
|
note = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Alias
|
model = Alias
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
@staticmethod
|
def get_note(self, obj):
|
||||||
def setup_eager_loading(queryset):
|
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", obj.note):
|
||||||
queryset = queryset.select_related('note')
|
print(obj.pk)
|
||||||
|
return NotePolymorphicSerializer().to_representation(obj.note)
|
||||||
|
return dict(id=obj.id)
|
||||||
|
|
||||||
|
|
||||||
class TemplateCategorySerializer(serializers.ModelSerializer):
|
class TemplateCategorySerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -12,7 +12,7 @@ def register_note_urls(router, path):
|
||||||
router.register(path + '/note', NotePolymorphicViewSet)
|
router.register(path + '/note', NotePolymorphicViewSet)
|
||||||
router.register(path + '/alias', AliasViewSet)
|
router.register(path + '/alias', AliasViewSet)
|
||||||
router.register(path + '/consumer', ConsumerViewSet)
|
router.register(path + '/consumer', ConsumerViewSet)
|
||||||
|
|
||||||
router.register(path + '/transaction/category', TemplateCategoryViewSet)
|
router.register(path + '/transaction/category', TemplateCategoryViewSet)
|
||||||
router.register(path + '/transaction/transaction', TransactionViewSet)
|
router.register(path + '/transaction/transaction', TransactionViewSet)
|
||||||
router.register(path + '/transaction/template', TransactionTemplateViewSet)
|
router.register(path + '/transaction/template', TransactionTemplateViewSet)
|
||||||
|
|
|
@ -89,6 +89,7 @@ class AliasViewSet(ReadProtectedModelViewSet):
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||||
queryset = Alias.objects.all()
|
queryset = Alias.objects.all()
|
||||||
serializer_class = ConsumerSerializer
|
serializer_class = ConsumerSerializer
|
||||||
|
@ -111,7 +112,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
|
||||||
| Q(normalized_name__regex="^" + alias.lower()))
|
| Q(normalized_name__regex="^" + alias.lower()))
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class TemplateCategoryViewSet(ReadProtectedModelViewSet):
|
class TemplateCategoryViewSet(ReadProtectedModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.contrib.auth.models import User, AnonymousUser
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import Q, F
|
from django.db.models import Q, F
|
||||||
from note.models import Note, NoteUser, NoteClub, NoteSpecial
|
from note.models import Note, NoteUser, NoteClub, NoteSpecial
|
||||||
|
from note_kfet import settings
|
||||||
from note_kfet.middlewares import get_current_session
|
from note_kfet.middlewares import get_current_session
|
||||||
from member.models import Membership, Club
|
from member.models import Membership, Club
|
||||||
|
|
||||||
|
@ -36,14 +37,21 @@ class PermissionBackend(ModelBackend):
|
||||||
# Unauthenticated users have no permissions
|
# Unauthenticated users have no permissions
|
||||||
return Permission.objects.none()
|
return Permission.objects.none()
|
||||||
|
|
||||||
return Permission.objects.annotate(club=F("rolepermissions__role__membership__club")) \
|
perms = Permission.objects.annotate(club=F("rolepermissions__role__membership__club")) \
|
||||||
.filter(
|
.filter(
|
||||||
rolepermissions__role__membership__user=user,
|
rolepermissions__role__membership__user=user,
|
||||||
rolepermissions__role__membership__date_start__lte=datetime.date.today(),
|
rolepermissions__role__membership__date_start__lte=datetime.date.today(),
|
||||||
rolepermissions__role__membership__date_end__gte=datetime.date.today(),
|
rolepermissions__role__membership__date_end__gte=datetime.date.today(),
|
||||||
type=t,
|
type=t,
|
||||||
mask__rank__lte=get_current_session().get("permission_mask", 0),
|
mask__rank__lte=get_current_session().get("permission_mask", 42),
|
||||||
).distinct()
|
)
|
||||||
|
if settings.DATABASES[perms.db]["ENGINE"] == 'django.db.backends.postgresql_psycopg2':
|
||||||
|
# We want one permission per club, and per permission type.
|
||||||
|
# SQLite does not support this kind of filter, that's why we don't filter the permissions with this
|
||||||
|
# kind of DB. This only increases performances (we can check multiple times the same permission)
|
||||||
|
# but don't have any semantic influence.
|
||||||
|
perms = perms.distinct('club', 'pk')
|
||||||
|
return perms
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def permissions(user, model, type):
|
def permissions(user, model, type):
|
||||||
|
@ -95,7 +103,7 @@ class PermissionBackend(ModelBackend):
|
||||||
# Anonymous users can't do anything
|
# Anonymous users can't do anything
|
||||||
return Q(pk=-1)
|
return Q(pk=-1)
|
||||||
|
|
||||||
if user.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
if user.is_superuser and get_current_session().get("permission_mask", 42) >= 42:
|
||||||
# Superusers have all rights
|
# Superusers have all rights
|
||||||
return Q()
|
return Q()
|
||||||
|
|
||||||
|
@ -129,9 +137,9 @@ class PermissionBackend(ModelBackend):
|
||||||
|
|
||||||
sess = get_current_session()
|
sess = get_current_session()
|
||||||
if sess is not None and sess.session_key is None:
|
if sess is not None and sess.session_key is None:
|
||||||
return Permission.objects.none()
|
return False
|
||||||
|
|
||||||
if user_obj.is_superuser and get_current_session().get("permission_mask", 0) >= 42:
|
if user_obj.is_superuser and get_current_session().get("permission_mask", 42) >= 42:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if obj is None:
|
if obj is None:
|
||||||
|
|
|
@ -203,9 +203,9 @@ class RemittanceCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView)
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
context["table"] = RemittanceTable(data=Remittance.objects
|
context["table"] = RemittanceTable(
|
||||||
.filter(PermissionBackend.filter_queryset(self.request.user, Remittance, "view"))
|
data=Remittance.objects.filter(
|
||||||
.all())
|
PermissionBackend.filter_queryset(self.request.user, Remittance, "view")).all())
|
||||||
context["special_transactions"] = SpecialTransactionTable(data=SpecialTransaction.objects.none())
|
context["special_transactions"] = SpecialTransactionTable(data=SpecialTransaction.objects.none())
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
|
@ -119,7 +119,7 @@ function displayNote(note, alias, user_note_field=null, profile_pic_field=null)
|
||||||
note.display_image = '/media/pic/default.png';
|
note.display_image = '/media/pic/default.png';
|
||||||
}
|
}
|
||||||
let img = note.display_image;
|
let img = note.display_image;
|
||||||
if (alias !== note.name)
|
if (alias !== note.name && note.name)
|
||||||
alias += " (aka. " + note.name + ")";
|
alias += " (aka. " + note.name + ")";
|
||||||
if (user_note_field !== null)
|
if (user_note_field !== null)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue