1
0
mirror of https://gitlab.crans.org/mediatek/med.git synced 2025-07-09 07:30:19 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
48c056b210 Harden Django project configuration
Set session and CSRF cookies as secure for production.
Set HSTS header to let browser remember HTTPS for 1 year.
2022-03-09 12:30:18 +01:00
cf544dc596 Fix game research 2021-11-14 16:41:38 +01:00
c0521005ef Don't put current date as default value for memberships 2021-11-14 16:24:38 +01:00
09c61091d5 Put empty strings instead of None as default values 2021-11-14 16:16:17 +01:00
145806b5ce Merge branch 'note' into 'main'
Note Kfet integration

See merge request mediatek/med!7
2021-11-14 15:57:40 +01:00
49898143ce expires in may be not small 2021-11-14 15:51:45 +01:00
fe55a2a5ea Don't hardcode OAuth2 parameters 2021-11-14 15:22:11 +01:00
cdcb743b55 Fix membership filters 2021-11-14 15:09:04 +01:00
7 changed files with 82 additions and 57 deletions

View File

@ -26,6 +26,16 @@ SITE_ID = 1
ALLOWED_HOSTS = ['127.0.0.1'] ALLOWED_HOSTS = ['127.0.0.1']
# Use secure cookies in production
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG
# Remember HTTPS for 1 year
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
@ -167,22 +177,26 @@ PAGINATION_NUMBER = 25
AUTH_USER_MODEL = 'users.User' AUTH_USER_MODEL = 'users.User'
# AUTHLIB CLIENTS NOTE_KFET_URL = 'https://note.crans.org'
AUTHLIB_OAUTH_CLIENTS = { NOTE_KFET_CLIENT_ID = 'CHANGE_ME'
'notekfet': { NOTE_KFET_CLIENT_SECRET = 'CHANGE_ME'
'client_id': 'qtElmOUj67YNvSZjA5l70ITUMxd3NJ9kksBsK5e9', NOTE_KFET_SCOPES = '1_1 2_1 48_1'
'client_secret': 'SwF909sLIeU5GhruXsFzKfdBhFNgs8nvkVpFKgP4pIQ80BmLLlf3ZkMoNL7Cpox6Ke3MXNWGswTtbKkM8AiB9v6pys8PNfYH0MDFWAi3tnffjwaMQBzRFhjx20qb6S4W',
'access_token_url': 'https://note-dev.crans.org/o/token/',
'refresh_token_url': 'https://note-dev.crans.org/o/token/',
'authorize_url': 'https://note-dev.crans.org/o/authorize/',
'userinfo_endpoint': 'https://note-dev.crans.org/api/me/',
'client_kwargs': {
'scope': '1_1 2_1 48_1',
}
}
}
try: try:
from .settings_local import * from .settings_local import *
except ImportError: except ImportError:
pass pass
AUTHLIB_OAUTH_CLIENTS = {
'notekfet': {
'client_id': f'{NOTE_KFET_CLIENT_ID}',
'client_secret': f'{NOTE_KFET_CLIENT_SECRET}',
'access_token_url': f'{NOTE_KFET_URL}/o/token/',
'refresh_token_url': f'{NOTE_KFET_URL}/o/token/',
'authorize_url': f'{NOTE_KFET_URL}/o/authorize/',
'userinfo_endpoint': f'{NOTE_KFET_URL}/api/me/',
'client_kwargs': {
'scope': NOTE_KFET_SCOPES,
}
}
}

View File

@ -40,3 +40,8 @@ DATABASES = {
'PORT': '', 'PORT': '',
} }
} }
NOTE_KFET_URL = 'https://note.crans.org'
NOTE_KFET_CLIENT_ID = 'CHANGE_ME'
NOTE_KFET_CLIENT_SECRET = 'CHANGE_ME'
NOTE_KFET_SCOPES = '1_1 2_1 48_1'

View File

@ -142,8 +142,8 @@ class BorrowAdmin(VersionAdmin):
class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin): class GameAdmin(VersionAdmin, PolymorphicChildModelAdmin):
list_display = ('title', 'owner', 'duration', 'players_min', list_display = ('title', 'owner', 'duration', 'players_min',
'players_max', 'comment') 'players_max', 'comment', 'isbn')
search_fields = ('name', 'owner__username', 'duration', 'comment') search_fields = ('isbn', 'title', 'owner__username', 'duration', 'comment')
autocomplete_fields = ('owner',) autocomplete_fields = ('owner',)
show_in_index = True show_in_index = True

View File

@ -3,11 +3,9 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin from django.contrib import admin
from django.contrib import messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import PasswordResetForm from django.utils import timezone
from django.urls import reverse from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from med.admin import admin_site from med.admin import admin_site
@ -25,7 +23,12 @@ class IsMemberFilter(admin.SimpleListFilter):
) )
def queryset(self, request, queryset): def queryset(self, request, queryset):
# FIXME Replace with imported Note Kfet memberships if self.parameter_name in request.GET:
queryset = queryset.filter(
membership__date_start__lte=timezone.now(),
membership__date_end__gte=timezone.now(),
).distinct()
return queryset return queryset
@ -45,39 +48,21 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
list_filter = (IsMemberFilter, 'is_staff', 'is_superuser', 'is_active', list_filter = (IsMemberFilter, 'is_staff', 'is_superuser', 'is_active',
'groups') 'groups')
def save_model(self, request, obj, form, change): def has_add_permission(self, request):
""" # Only add users through Note Kfet login
On creation, send a password init mail return False
"""
super().save_model(request, obj, form, change)
if not change:
# Virtually fill the password reset form
password_reset = PasswordResetForm(data={'email': obj.email})
if password_reset.is_valid():
password_reset.save(request=request,
use_https=request.is_secure())
messages.success(request, _("An email to set the password"
" was sent."))
else:
messages.error(request, _("The email is invalid."))
def is_member(self, obj): def is_member(self, obj):
""" """
Get current membership year and check if user is there Get current membership year and check if user is there
""" """
# FIXME Use NK20 if obj.is_member:
is_member = True return mark_safe(
if is_member:
return format_html(
'<img src="/static/admin/img/icon-yes.svg" alt="True">' '<img src="/static/admin/img/icon-yes.svg" alt="True">'
) )
else: else:
return format_html( return mark_safe(
'<img src="/static/admin/img/icon-no.svg" alt="False"> ' '<img src="/static/admin/img/icon-no.svg" alt="False">'
'<a class="button" href="{}">{}</a>',
reverse('users:adherer', args=[obj.pk]),
_('Adhere')
) )
is_member.short_description = _('is member') is_member.short_description = _('is member')

View File

@ -17,7 +17,7 @@ class Migration(migrations.Migration):
fields=[ fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('access_token', models.CharField(max_length=32, verbose_name='access token')), ('access_token', models.CharField(max_length=32, verbose_name='access token')),
('expires_in', models.PositiveSmallIntegerField(verbose_name='expires in')), ('expires_in', models.PositiveIntegerField(verbose_name='expires in')),
('scopes', models.CharField(max_length=255, verbose_name='scopes')), ('scopes', models.CharField(max_length=255, verbose_name='scopes')),
('refresh_token', models.CharField(max_length=32, verbose_name='refresh token')), ('refresh_token', models.CharField(max_length=32, verbose_name='refresh token')),
('expires_at', models.DateTimeField(verbose_name='expires at')), ('expires_at', models.DateTimeField(verbose_name='expires at')),

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.24 on 2021-11-14 15:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0045_auto_20211114_1423'),
]
operations = [
migrations.AlterField(
model_name='membership',
name='date_end',
field=models.DateField(verbose_name='start date'),
),
migrations.AlterField(
model_name='membership',
name='date_start',
field=models.DateField(verbose_name='start date'),
),
]

View File

@ -59,12 +59,12 @@ class User(AbstractUser):
data : dict data : dict
Dictionary with user data to update. Dictionary with user data to update.
""" """
self.email = data['email'] self.email = data['email'] or ''
self.first_name = data['first_name'] self.first_name = data['first_name'] or ''
self.last_name = data['last_name'] self.last_name = data['last_name'] or ''
self.phone_number = data['profile']['phone_number'] self.phone_number = data['profile']['phone_number'] or ''
self.address = data['profile']['address'] self.address = data['profile']['address'] or ''
self.comment = data['profile']['section'] self.comment = data['profile']['section'] or ''
for membership_dict in data['memberships']: for membership_dict in data['memberships']:
if membership_dict['club'] != 22: # Med if membership_dict['club'] != 22: # Med
@ -88,12 +88,10 @@ class Membership(models.Model):
) )
date_start = models.DateField( date_start = models.DateField(
auto_now_add=True,
verbose_name=_('start date'), verbose_name=_('start date'),
) )
date_end = models.DateField( date_end = models.DateField(
auto_now_add=True,
verbose_name=_('start date'), verbose_name=_('start date'),
) )
@ -119,7 +117,7 @@ class AccessToken(models.Model):
verbose_name=_('access token'), verbose_name=_('access token'),
) )
expires_in = models.PositiveSmallIntegerField( expires_in = models.PositiveIntegerField(
verbose_name=_('expires in'), verbose_name=_('expires in'),
) )
@ -178,7 +176,7 @@ class AccessToken(models.Model):
Extract information about the Note Kfet API by using the current Extract information about the Note Kfet API by using the current
access token. access token.
""" """
data = requests.get('https://note-dev.crans.org/api/me/', data = requests.get(f'{settings.NOTE_KFET_URL}/api/me/',
headers=self.auth_header()).json() headers=self.auth_header()).json()
username = data['username'] username = data['username']
email = data['email'] email = data['email']