1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2025-07-04 14:52:13 +02:00

Compare commits

..

2 Commits

Author SHA1 Message Date
17be896a99 [permission] Add PermissionVar model 2022-10-10 19:37:51 +02:00
a69573ccdb Fix permission that allows users to create OAuth2 apps
Signed-off-by: Yohann D'ANELLO <ynerant@crans.org>
2022-08-29 11:21:45 +02:00
9 changed files with 98 additions and 52 deletions

View File

@ -1,5 +0,0 @@
from rest_framework.pagination import PageNumberPagination
class CustomPagination(PageNumberPagination):
page_size_query_param = 'page_size'

View File

@ -4,7 +4,7 @@
from django.contrib import admin from django.contrib import admin
from note_kfet.admin import admin_site from note_kfet.admin import admin_site
from .models import Permission, PermissionMask, Role from .models import Permission, PermissionVar, PermissionMask, Role
@admin.register(PermissionMask, site=admin_site) @admin.register(PermissionMask, site=admin_site)
@ -15,6 +15,14 @@ class PermissionMaskAdmin(admin.ModelAdmin):
list_display = ('description', 'rank', ) list_display = ('description', 'rank', )
@admin.register(PermissionVar, site=admin_site)
class PermissionVarAdmin(admin.ModelAdmin):
"""
Admin customisation for PermissionVar
"""
list_display = ('name', 'description',)
@admin.register(Permission, site=admin_site) @admin.register(Permission, site=admin_site)
class PermissionAdmin(admin.ModelAdmin): class PermissionAdmin(admin.ModelAdmin):
""" """

View File

@ -1967,7 +1967,7 @@
"note", "note",
"transaction" "transaction"
], ],
"query": "[\"AND\", [\"OR\", {\"source\": [\"club\", \"note\"]}, {\"destination\": [\"club\", \"note\"]}], [\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}]]", "query": "[\"AND\", [\"OR\", {\"source\": [\"club\", \"note\"]}, {\"destination\": [\"club\", \"note\"]}], [\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}]]",
"type": "change", "type": "change",
"mask": 2, "mask": 2,
"field": "valid", "field": "valid",
@ -2607,7 +2607,7 @@
"note", "note",
"transaction" "transaction"
], ],
"query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}]", "query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}]",
"type": "change", "type": "change",
"mask": 2, "mask": 2,
"field": "valid", "field": "valid",
@ -2623,7 +2623,7 @@
"note", "note",
"transaction" "transaction"
], ],
"query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}]", "query": "[\"OR\", {\"source__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": true}, {\"destination__balance__gte\": {\"F\": [\"SUB\", [\"MUL\", [\"F\", \"amount\"], [\"F\", \"quantity\"]], 5000]}, \"valid\": false}]",
"type": "change", "type": "change",
"mask": 2, "mask": 2,
"field": "invalidity_reason", "field": "invalidity_reason",
@ -2928,7 +2928,7 @@
"application" "application"
], ],
"query": "{\"user\": [\"user\"]}", "query": "{\"user\": [\"user\"]}",
"type": "create", "type": "add",
"mask": 1, "mask": 1,
"field": "", "field": "",
"permanent": true, "permanent": true,
@ -3114,10 +3114,10 @@
187, 187,
188, 188,
189, 189,
190, 190,
191, 191,
195, 195,
196 196
] ]
} }
}, },
@ -3159,8 +3159,8 @@
159, 159,
160, 160,
179, 179,
189, 189,
190 190
] ]
} }
}, },
@ -3310,10 +3310,10 @@
176, 176,
177, 177,
178, 178,
188, 188,
183, 183,
186, 186,
187 187
] ]
} }
}, },
@ -3508,13 +3508,13 @@
187, 187,
188, 188,
189, 189,
190, 190,
191, 191,
192, 192,
193, 193,
194, 194,
195, 195,
196 196
] ]
} }
}, },

View File

@ -0,0 +1,22 @@
# Generated by Django 2.2.28 on 2022-10-10 17:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('permission', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='PermissionVar',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.SlugField(unique=True, verbose_name='name')),
('query', models.TextField(verbose_name='query')),
('description', models.CharField(blank=True, max_length=255, verbose_name='description')),
],
),
]

View File

@ -118,6 +118,25 @@ class PermissionMask(models.Model):
verbose_name_plural = _("permission masks") verbose_name_plural = _("permission masks")
class PermissionVar(models.Model):
name = models.SlugField(
unique=True,
blank=False,
verbose_name=_("name"),
)
query = models.TextField(
verbose_name=_("query"),
)
description = models.CharField(
max_length=255,
blank=True,
verbose_name=_("description"),
)
class Permission(models.Model): class Permission(models.Model):
PERMISSION_TYPES = [ PERMISSION_TYPES = [
@ -139,6 +158,7 @@ class Permission(models.Model):
# query -> ["AND", query, …] AND multiple queries # query -> ["AND", query, …] AND multiple queries
# | ["OR", query, …] OR multiple queries # | ["OR", query, …] OR multiple queries
# | ["NOT", query] Opposite of query # | ["NOT", query] Opposite of query
# | ["VAR", query] A var name as defined in PermissionVar
# query -> {key: value, …} A list of fields and values of a Q object # query -> {key: value, …} A list of fields and values of a Q object
# key -> string A field name # key -> string A field name
# value -> int | string | bool | null Literal values # value -> int | string | bool | null Literal values
@ -150,6 +170,7 @@ class Permission(models.Model):
# | ["MUL", oper, …] Multiply F objects or literals # | ["MUL", oper, …] Multiply F objects or literals
# | int | string | bool | null Literal values # | int | string | bool | null Literal values
# | ["F", string] A field # | ["F", string] A field
# | ["VAR", string] A var name as defined in PermissionVar
# #
# Examples: # Examples:
# Q(is_superuser=True) := {"is_superuser": true} # Q(is_superuser=True) := {"is_superuser": true}
@ -215,6 +236,8 @@ class Permission(models.Model):
return functools.reduce(operator.mul, [Permission.compute_f(oper, **kwargs) for oper in oper[1:]]) return functools.reduce(operator.mul, [Permission.compute_f(oper, **kwargs) for oper in oper[1:]])
elif oper[0] == 'F': elif oper[0] == 'F':
return F(oper[1]) return F(oper[1])
elif oper[0] == 'VAR':
return compute_f(json.loads(PermissionVar.objects.get(name=oper[1]).query), **kwargs)
else: else:
field = kwargs[oper[0]] field = kwargs[oper[0]]
for i in range(1, len(oper)): for i in range(1, len(oper)):
@ -289,6 +312,8 @@ class Permission(models.Model):
return functools.reduce(operator.or_, [Permission._about(query, **kwargs) for query in query[1:]]) return functools.reduce(operator.or_, [Permission._about(query, **kwargs) for query in query[1:]])
elif query[0] == 'NOT': elif query[0] == 'NOT':
return ~Permission._about(query[1], **kwargs) return ~Permission._about(query[1], **kwargs)
elif query[0] == 'VAR':
return Permission._about(json.loads(PermissionVar.objects.get(name=query[1]).query), **kwargs)
else: else:
return Q(pk=F("pk")) if Permission.compute_param(query, **kwargs) else ~Q(pk=F("pk")) return Q(pk=F("pk")) if Permission.compute_param(query, **kwargs) else ~Q(pk=F("pk"))
elif isinstance(query, dict): elif isinstance(query, dict):

View File

@ -329,18 +329,17 @@ class SogeCredit(models.Model):
bde_qs = Membership.objects.filter(user=self.user, club=bde, date_start__gte=bde.membership_start) bde_qs = Membership.objects.filter(user=self.user, club=bde, date_start__gte=bde.membership_start)
kfet_qs = Membership.objects.filter(user=self.user, club=kfet, date_start__gte=kfet.membership_start) kfet_qs = Membership.objects.filter(user=self.user, club=kfet, date_start__gte=kfet.membership_start)
## Soge do not pay BDE and kfet memberships this year (2022-2023) if bde_qs.exists():
# if bde_qs.exists(): m = bde_qs.get()
# m = bde_qs.get() if MembershipTransaction.objects.filter(membership=m).exists(): # non-free membership
# if MembershipTransaction.objects.filter(membership=m).exists(): # non-free membership if m.transaction not in self.transactions.all():
# if m.transaction not in self.transactions.all(): self.transactions.add(m.transaction)
# self.transactions.add(m.transaction)
# if kfet_qs.exists():
# if kfet_qs.exists(): m = kfet_qs.get()
# m = kfet_qs.get() if MembershipTransaction.objects.filter(membership=m).exists(): # non-free membership
# if MembershipTransaction.objects.filter(membership=m).exists(): # non-free membership if m.transaction not in self.transactions.all():
# if m.transaction not in self.transactions.all(): self.transactions.add(m.transaction)
# self.transactions.add(m.transaction)
if 'wei' in settings.INSTALLED_APPS: if 'wei' in settings.INSTALLED_APPS:
from wei.models import WEIClub from wei.models import WEIClub

View File

@ -14,17 +14,14 @@ from .base import WEISurvey, WEISurveyInformation, WEISurveyAlgorithm, WEIBusInf
from ...models import WEIMembership from ...models import WEIMembership
WORDS = [ WORDS = [
'ABBA', 'After', 'Alcoolique anonyme', 'Ambiance festive', 'Années 2000', 'Apéro', 'Art', '13 organisé', '3ième mi temps', 'Années 2000', 'Apéro', 'BBQ', 'BP', 'Beauf', 'Binge drinking', 'Bon enfant',
'Baby foot billard biere pong', 'BBQ', 'Before', 'Bière pong', 'Bon enfant', 'Calme', 'Canapé', 'Cartouche', 'Catacombes', 'Chansons paillardes', 'Chansons populaires', 'Chanteur', 'Chartreuse', 'Chill',
'Chanson paillarde', 'Chanson populaire', 'Chartreuse', 'Cheerleader', 'Chill', 'Choré', 'Core', 'DJ', 'Dancefloor', 'Danse', 'David Guetta', 'Disco', 'Eau de vie', 'Électro', 'Escalade', 'Familial',
'Cinéma', 'Cocktail', 'Comédie musicle', 'Commercial', 'Copaing', 'Danse', 'Dancefloor', 'Fanfare', 'Fracassage', 'Féria', 'Hard rock', 'Hoeggarden', 'House', 'Huit-six', 'IPA', 'Inclusif', 'Inferno',
'Electro', 'Fanfare', 'Gin tonic', 'Inclusif', 'Jazz', "Jeux d'alcool", 'Jeux de carte', 'Introverti', 'Jager bomb', 'Jazz', 'Jeux d\'alcool', 'Jeux de rôles', 'Jeux vidéo', 'Jul', 'Jus de fruit',
'Jeux de rôle', 'Jeux de société', 'JUL', 'Jus de fruit', 'Kfet', 'Kleptomanie assurée', 'Karaoké', 'LGBTQI+', 'Lady Gaga', 'Loup garou', 'Morning beer', 'Métal', 'Nuit blanche', 'Ovalie', 'Psychedelic',
'LGBTQ+', 'Livre', 'Morning beer', 'Musique', 'NAPS', 'Paillettes', 'Pastis', 'Paté Hénaff', 'Pétanque', 'Rave', 'Reggae', 'Rhum', 'Ricard', 'Rock', 'Rosé', 'Rétro', 'Séducteur', 'Techno', 'Thérapie taxi',
'Peluche', 'Pena baiona', "Peu d'alcool", 'Pilier de bar', 'PMU', 'Poulpe', 'Punch', 'Rap', 'Théâtre', 'Trap', 'Turn up', 'Underground', 'Volley', 'Wati B', 'Zinédine Zidane',
'Réveil', 'Rock', 'Rugby', 'Sandwich', 'Serge', 'Shot', 'Sociable', 'Spectacle', 'Techno',
'Techno house', 'Thérapie Taxi', 'Tradition kchanaises', 'Troisième mi-temps', 'Turn up',
'Vodka', 'Vodka pomme', 'Volley', 'Vomi stratégique'
] ]

View File

@ -252,7 +252,7 @@ REST_FRAMEWORK = {
'rest_framework.authentication.TokenAuthentication', 'rest_framework.authentication.TokenAuthentication',
'oauth2_provider.contrib.rest_framework.OAuth2Authentication', 'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
], ],
'DEFAULT_PAGINATION_CLASS': 'apps.api.pagination.CustomPagination', 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20, 'PAGE_SIZE': 20,
} }

View File

@ -23,11 +23,11 @@ SPDX-License-Identifier: GPL-3.0-or-later
{% csrf_token %} {% csrf_token %}
{{ form|crispy }} {{ form|crispy }}
{{ profile_form|crispy }} {{ profile_form|crispy }}
{% comment "Soge not for membership (only WEI)" %} {{ soge_form|crispy }} {% endcomment %} {{ soge_form|crispy }}
<button class="btn btn-success" type="submit"> <button class="btn btn-success" type="submit">
{% trans "Sign up" %} {% trans "Sign up" %}
</button> </button>
</form> </form>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}