Don't display a note that we can't see, fix CI, fix distinct fields on PostgresSQL DB

This commit is contained in:
Yohann D'ANELLO 2020-04-10 00:02:22 +02:00
parent bac81cd13e
commit 751147f254
8 changed files with 48 additions and 26 deletions

View File

@ -139,7 +139,7 @@ class Entry(models.Model):
verbose_name = _("entry")
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)
if qs.exists():
@ -153,7 +153,7 @@ class Entry(models.Model):
if self.note.balance < 0:
raise ValidationError(_("The balance is negative."))
ret = super().save(*args,**kwargs)
ret = super().save(*args, **kwargs)
if insert and self.guest:
GuestTransaction.objects.create(

View File

@ -3,6 +3,7 @@
from datetime import datetime, timezone
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.db.models import F, Q
@ -45,8 +46,8 @@ class ActivityListView(ProtectQuerysetMixin, LoginRequiredMixin, SingleTableView
context['title'] = _("Activities")
upcoming_activities = Activity.objects.filter(date_end__gt=datetime.now())
context['upcoming'] = ActivityTable(data=upcoming_activities
.filter(PermissionBackend.filter_queryset(self.request.user, Activity, "view")))
context['upcoming'] = ActivityTable(data=upcoming_activities.filter(
PermissionBackend.filter_queryset(self.request.user, Activity, "view")))
return context
@ -138,8 +139,14 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
| Q(note__noteuser__user__last_name__regex=pattern)
| Q(name__regex=pattern)
| Q(normalized_name__regex=Alias.normalize(pattern)))) \
.filter(PermissionBackend.filter_queryset(self.request.user, Alias, "view"))\
.distinct()[:20]
.filter(PermissionBackend.filter_queryset(self.request.user, Alias, "view"))
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:
note.type = "Adhérent"
note.activity = activity
@ -153,9 +160,9 @@ class ActivityEntryView(LoginRequiredMixin, TemplateView):
context["title"] = _('Entry for activity "{}"').format(activity.name)
context["noteuser_ctype"] = ContentType.objects.get_for_model(NoteUser).pk
context["notespecial_ctype"] = ContentType.objects.get_for_model(NoteSpecial).pk
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, "change")).all()
return context
return context

View File

@ -3,6 +3,8 @@
from rest_framework import serializers
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.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
@ -96,20 +98,24 @@ class NotePolymorphicSerializer(PolymorphicSerializer):
class Meta:
model = Note
class ConsumerSerializer(serializers.ModelSerializer):
"""
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:
model = Alias
fields = '__all__'
@staticmethod
def setup_eager_loading(queryset):
queryset = queryset.select_related('note')
def get_note(self, obj):
if PermissionBackend.check_perm(get_current_authenticated_user(), "note.view_note", obj.note):
print(obj.pk)
return NotePolymorphicSerializer().to_representation(obj.note)
return dict(id=obj.id)
class TemplateCategorySerializer(serializers.ModelSerializer):
"""

View File

@ -12,7 +12,7 @@ def register_note_urls(router, path):
router.register(path + '/note', NotePolymorphicViewSet)
router.register(path + '/alias', AliasViewSet)
router.register(path + '/consumer', ConsumerViewSet)
router.register(path + '/transaction/category', TemplateCategoryViewSet)
router.register(path + '/transaction/transaction', TransactionViewSet)
router.register(path + '/transaction/template', TransactionTemplateViewSet)

View File

@ -89,6 +89,7 @@ class AliasViewSet(ReadProtectedModelViewSet):
return queryset
class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
queryset = Alias.objects.all()
serializer_class = ConsumerSerializer
@ -111,7 +112,7 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet):
| Q(normalized_name__regex="^" + alias.lower()))
return queryset
class TemplateCategoryViewSet(ReadProtectedModelViewSet):
"""

View File

@ -8,6 +8,7 @@ from django.contrib.auth.models import User, AnonymousUser
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q, F
from note.models import Note, NoteUser, NoteClub, NoteSpecial
from note_kfet import settings
from note_kfet.middlewares import get_current_session
from member.models import Membership, Club
@ -36,14 +37,21 @@ class PermissionBackend(ModelBackend):
# Unauthenticated users have no permissions
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(
rolepermissions__role__membership__user=user,
rolepermissions__role__membership__date_start__lte=datetime.date.today(),
rolepermissions__role__membership__date_end__gte=datetime.date.today(),
type=t,
mask__rank__lte=get_current_session().get("permission_mask", 0),
).distinct()
mask__rank__lte=get_current_session().get("permission_mask", 42),
)
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
def permissions(user, model, type):
@ -95,7 +103,7 @@ class PermissionBackend(ModelBackend):
# Anonymous users can't do anything
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
return Q()
@ -129,9 +137,9 @@ class PermissionBackend(ModelBackend):
sess = get_current_session()
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
if obj is None:

View File

@ -203,9 +203,9 @@ class RemittanceCreateView(ProtectQuerysetMixin, LoginRequiredMixin, CreateView)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["table"] = RemittanceTable(data=Remittance.objects
.filter(PermissionBackend.filter_queryset(self.request.user, Remittance, "view"))
.all())
context["table"] = RemittanceTable(
data=Remittance.objects.filter(
PermissionBackend.filter_queryset(self.request.user, Remittance, "view")).all())
context["special_transactions"] = SpecialTransactionTable(data=SpecialTransaction.objects.none())
return context

View File

@ -119,7 +119,7 @@ function displayNote(note, alias, user_note_field=null, profile_pic_field=null)
note.display_image = '/media/pic/default.png';
}
let img = note.display_image;
if (alias !== note.name)
if (alias !== note.name && note.name)
alias += " (aka. " + note.name + ")";
if (user_note_field !== null)