mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 09:12:11 +01:00 
			
		
		
		
	Compare commits
	
		
			26 Commits
		
	
	
		
			116451603c
			...
			faster_ci
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3eed93e346 | ||
| 
						 | 
					4da523a1ba | ||
| 
						 | 
					e74ff54468 | ||
| 
						 | 
					2e49c9ffbd | ||
| 
						 | 
					d20a1038a8 | ||
| 
						 | 
					f6b711bb1b | ||
| 
						 | 
					893d87a9e1 | ||
| 
						 | 
					9f3323c73e | ||
| 
						 | 
					c57f81b920 | ||
| 
						 | 
					0636d84286 | ||
| 
						 | 
					ed06901fae | ||
| 
						 | 
					28932f316b | ||
| 
						 | 
					9b50ba722c | ||
| 
						 | 
					3e3e61d23f | ||
| 
						 | 
					1129815ca3 | ||
| 
						 | 
					c13172d3ff | ||
| 
						 | 
					fcc4121225 | ||
| 
						 | 
					a06f355559 | ||
| 
						 | 
					08df5fcccd | ||
| 
						 | 
					b6c0f9758d | ||
| 
						 | 
					a23093851f | ||
| 
						 | 
					d803ab5ec2 | ||
| 
						 | 
					d7a537b6b5 | ||
| 
						 | 
					0941ee954d | ||
| 
						 | 
					fd11d96d95 | ||
| 
						 | 
					4bfc057454 | 
							
								
								
									
										3
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					skip_list:
 | 
				
			||||||
 | 
					  - command-instead-of-shell  # Use shell only when shell functionality is required
 | 
				
			||||||
 | 
					  - experimental  # all rules tagged as experimental
 | 
				
			||||||
@@ -10,50 +10,22 @@ variables:
 | 
				
			|||||||
# Debian Buster
 | 
					# Debian Buster
 | 
				
			||||||
py37-django22:
 | 
					py37-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: debian:buster-backports
 | 
					  image: otthorn/nk20_ci_37
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -t buster-backports -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py37-django22
 | 
					  script: tox -e py37-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Ubuntu 20.04
 | 
					# Ubuntu 20.04
 | 
				
			||||||
py38-django22:
 | 
					py38-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: ubuntu:20.04
 | 
					  image: otthorn/nk20_ci_38
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    # Fix tzdata prompt
 | 
					 | 
				
			||||||
    - ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py38-django22
 | 
					  script: tox -e py38-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Debian Bullseye
 | 
					# Debian Bullseye
 | 
				
			||||||
py39-django22:
 | 
					py39-django22:
 | 
				
			||||||
  stage: test
 | 
					  stage: test
 | 
				
			||||||
  image: debian:bullseye
 | 
					  image: otthorn/nk20_ci_39
 | 
				
			||||||
  before_script:
 | 
					 | 
				
			||||||
    - >
 | 
					 | 
				
			||||||
        apt-get update &&
 | 
					 | 
				
			||||||
        apt-get install --no-install-recommends -y
 | 
					 | 
				
			||||||
        python3-django python3-django-crispy-forms
 | 
					 | 
				
			||||||
        python3-django-extensions python3-django-filters python3-django-polymorphic
 | 
					 | 
				
			||||||
        python3-djangorestframework python3-django-oauth-toolkit python3-psycopg2 python3-pil
 | 
					 | 
				
			||||||
        python3-babel python3-lockfile python3-pip python3-phonenumbers python3-memcache
 | 
					 | 
				
			||||||
        python3-bs4 python3-setuptools tox texlive-xetex
 | 
					 | 
				
			||||||
  script: tox -e py39-django22
 | 
					  script: tox -e py39-django22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Tox linter
 | 
				
			||||||
linters:
 | 
					linters:
 | 
				
			||||||
  stage: quality-assurance
 | 
					  stage: quality-assurance
 | 
				
			||||||
  image: debian:buster-backports
 | 
					  image: debian:buster-backports
 | 
				
			||||||
@@ -64,6 +36,20 @@ linters:
 | 
				
			|||||||
  # Be nice to new contributors, but please use `tox`
 | 
					  # Be nice to new contributors, but please use `tox`
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ansible linter
 | 
				
			||||||
 | 
					ansible-linter:
 | 
				
			||||||
 | 
					  stage: quality-assurance
 | 
				
			||||||
 | 
					  image: otthorn/nk20_ci_ansiblelint
 | 
				
			||||||
 | 
					  script: ansible-lint ansible/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Docker linter
 | 
				
			||||||
 | 
					docker-linter:
 | 
				
			||||||
 | 
					  stage: quality-assurance
 | 
				
			||||||
 | 
					  image: hadolint/hadolint
 | 
				
			||||||
 | 
					  script:
 | 
				
			||||||
 | 
					    - hadolint -c .hadolint Dockerfile
 | 
				
			||||||
 | 
					    - hadolint -c .hadolint docker_ci/Dockerfile.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile documentation
 | 
					# Compile documentation
 | 
				
			||||||
documentation:
 | 
					documentation:
 | 
				
			||||||
  stage: docs
 | 
					  stage: docs
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								.hadolint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.hadolint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					ignored:
 | 
				
			||||||
 | 
					  - DL3008  # Do not force to pin version in apt (Debian)
 | 
				
			||||||
 | 
					  - DL3013  # Do not force to pin version in pip (PyPI)
 | 
				
			||||||
 | 
					  - DL3018  # Do not force to pin version in apk (Alpine)
 | 
				
			||||||
@@ -4,14 +4,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from django.contrib.contenttypes.models import ContentType
 | 
					from django.contrib.contenttypes.models import ContentType
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.utils import timezone
 | 
					from rest_framework.serializers import ModelSerializer
 | 
				
			||||||
from rest_framework import serializers
 | 
					 | 
				
			||||||
from member.api.serializers import ProfileSerializer, MembershipSerializer
 | 
					 | 
				
			||||||
from note.api.serializers import NoteSerializer
 | 
					 | 
				
			||||||
from note.models import Alias
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UserSerializer(serializers.ModelSerializer):
 | 
					class UserSerializer(ModelSerializer):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    REST API Serializer for Users.
 | 
					    REST API Serializer for Users.
 | 
				
			||||||
    The djangorestframework plugin will analyse the model `User` and parse all fields in the API.
 | 
					    The djangorestframework plugin will analyse the model `User` and parse all fields in the API.
 | 
				
			||||||
@@ -26,7 +22,7 @@ class UserSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ContentTypeSerializer(serializers.ModelSerializer):
 | 
					class ContentTypeSerializer(ModelSerializer):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    REST API Serializer for Users.
 | 
					    REST API Serializer for Users.
 | 
				
			||||||
    The djangorestframework plugin will analyse the model `User` and parse all fields in the API.
 | 
					    The djangorestframework plugin will analyse the model `User` and parse all fields in the API.
 | 
				
			||||||
@@ -35,42 +31,3 @@ class ContentTypeSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = ContentType
 | 
					        model = ContentType
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OAuthSerializer(serializers.ModelSerializer):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Informations that are transmitted by OAuth.
 | 
					 | 
				
			||||||
    For now, this includes user, profile and valid memberships.
 | 
					 | 
				
			||||||
    This should be better managed later.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    normalized_name = serializers.SerializerMethodField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    profile = ProfileSerializer()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    note = NoteSerializer()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    memberships = serializers.SerializerMethodField()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_normalized_name(self, obj):
 | 
					 | 
				
			||||||
        return Alias.normalize(obj.username)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_memberships(self, obj):
 | 
					 | 
				
			||||||
        return serializers.ListSerializer(child=MembershipSerializer()).to_representation(
 | 
					 | 
				
			||||||
            obj.memberships.filter(date_start__lte=timezone.now(), date_end__gte=timezone.now()))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class Meta:
 | 
					 | 
				
			||||||
        model = User
 | 
					 | 
				
			||||||
        fields = (
 | 
					 | 
				
			||||||
            'id',
 | 
					 | 
				
			||||||
            'username',
 | 
					 | 
				
			||||||
            'normalized_name',
 | 
					 | 
				
			||||||
            'first_name',
 | 
					 | 
				
			||||||
            'last_name',
 | 
					 | 
				
			||||||
            'email',
 | 
					 | 
				
			||||||
            'is_superuser',
 | 
					 | 
				
			||||||
            'is_active',
 | 
					 | 
				
			||||||
            'is_staff',
 | 
					 | 
				
			||||||
            'profile',
 | 
					 | 
				
			||||||
            'note',
 | 
					 | 
				
			||||||
            'memberships',
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,6 @@ from django.conf import settings
 | 
				
			|||||||
from django.conf.urls import url, include
 | 
					from django.conf.urls import url, include
 | 
				
			||||||
from rest_framework import routers
 | 
					from rest_framework import routers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .views import UserInformationView
 | 
					 | 
				
			||||||
from .viewsets import ContentTypeViewSet, UserViewSet
 | 
					from .viewsets import ContentTypeViewSet, UserViewSet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Routers provide an easy way of automatically determining the URL conf.
 | 
					# Routers provide an easy way of automatically determining the URL conf.
 | 
				
			||||||
@@ -48,6 +47,5 @@ app_name = 'api'
 | 
				
			|||||||
# Additionally, we include login URLs for the browsable API.
 | 
					# Additionally, we include login URLs for the browsable API.
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    url('^', include(router.urls)),
 | 
					    url('^', include(router.urls)),
 | 
				
			||||||
    url('^me/', UserInformationView.as_view()),
 | 
					 | 
				
			||||||
    url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
					    url('^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +0,0 @@
 | 
				
			|||||||
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
 | 
					 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					 | 
				
			||||||
from rest_framework.generics import RetrieveAPIView
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from .serializers import OAuthSerializer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UserInformationView(RetrieveAPIView):
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    These fields are give to OAuth authenticators.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    serializer_class = OAuthSerializer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_queryset(self):
 | 
					 | 
				
			||||||
        return User.objects.filter(pk=self.request.user.pk)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_object(self):
 | 
					 | 
				
			||||||
        return self.request.user
 | 
					 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
# Copyright (C) 2018-2021 by BDE ENS Paris-Saclay
 | 
					 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from cas_server.auth import DjangoAuthUser  # pragma: no cover
 | 
					 | 
				
			||||||
from note.models import Alias
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class CustomAuthUser(DjangoAuthUser):  # pragma: no cover
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    Override Django Auth User model to define a custom Matrix username.
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def attributs(self):
 | 
					 | 
				
			||||||
        d = super().attributs()
 | 
					 | 
				
			||||||
        if self.user:
 | 
					 | 
				
			||||||
            d["normalized_name"] = Alias.normalize(self.user.username)
 | 
					 | 
				
			||||||
        return d
 | 
					 | 
				
			||||||
@@ -134,6 +134,8 @@ class PermissionBackend(ModelBackend):
 | 
				
			|||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sess = get_current_session()
 | 
					        sess = get_current_session()
 | 
				
			||||||
 | 
					        if sess is not None and sess.session_key is None:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if user_obj.is_superuser and sess.get("permission_mask", -1) >= 42:
 | 
					        if user_obj.is_superuser and sess.get("permission_mask", -1) >= 42:
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								docker_ci/Dockerfile.37
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docker_ci/Dockerfile.37
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					FROM debian:buster-backports
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Debian Buster backports image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -t buster-backports -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
							
								
								
									
										22
									
								
								docker_ci/Dockerfile.38
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								docker_ci/Dockerfile.38
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					FROM ubuntu:20.04
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Ubuntu 20.04 image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# fix tzdata prompt
 | 
				
			||||||
 | 
					RUN ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								docker_ci/Dockerfile.39
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								docker_ci/Dockerfile.39
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					FROM debian:bullseye
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Debian Bulleye image with django and tox \
 | 
				
			||||||
 | 
					installed for testing purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apt-get update \
 | 
				
			||||||
 | 
					        && apt-get install --no-install-recommends -y \
 | 
				
			||||||
 | 
					        python3-django python3-django-crispy-forms \
 | 
				
			||||||
 | 
					        python3-django-extensions python3-django-filters \
 | 
				
			||||||
 | 
							python3-django-polymorphic \
 | 
				
			||||||
 | 
					        python3-djangorestframework python3-django-oauth-toolkit \
 | 
				
			||||||
 | 
							python3-psycopg2 python3-pil \
 | 
				
			||||||
 | 
					        python3-babel python3-lockfile python3-pip python3-phonenumbers \
 | 
				
			||||||
 | 
							python3-memcache \
 | 
				
			||||||
 | 
					        python3-bs4 python3-setuptools tox texlive-xetex \
 | 
				
			||||||
 | 
							&&  apt-get clean \
 | 
				
			||||||
 | 
							&& rm -rf /var/lib/apt/lists/*
 | 
				
			||||||
							
								
								
									
										10
									
								
								docker_ci/Dockerfile.ansiblelint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								docker_ci/Dockerfile.ansiblelint
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					FROM python:3.9-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Alpine image with ansible-lint and yamllint \
 | 
				
			||||||
 | 
					installed for linting purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk add --no-cache gcc musl-dev python3-dev libffi-dev openssl-dev cargo
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "yamllint>=1.26.0,<2.0"
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "ansible-lint==5.0.0"
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir "ansible>=2.10,<2.11"
 | 
				
			||||||
							
								
								
									
										8
									
								
								docker_ci/Dockerfile.tox
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker_ci/Dockerfile.tox
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					FROM alpine:3.13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LABEL maintainer="otthorn@crans.org"
 | 
				
			||||||
 | 
					LABEL description="Alpine image with tox \
 | 
				
			||||||
 | 
					installed for linting purposes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk --no-cache add py3-pip=20.3.4-r0
 | 
				
			||||||
 | 
					RUN pip install --no-cache-dir tox==3.22.0
 | 
				
			||||||
							
								
								
									
										21
									
								
								docker_ci/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								docker_ci/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					# Docker CI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Ce dossier contient les images docker à construire pour la CI.  L'idée est
 | 
				
			||||||
 | 
					d'avoir une image pré-construire, au dessus laquel il y a besoin de faire
 | 
				
			||||||
 | 
					tourner uniquement les commandes qui nous intéresse. Cela permet notamment de
 | 
				
			||||||
 | 
					réduire drastiquement le temps que nécessite chaque test car seul la dernière
 | 
				
			||||||
 | 
					couche (layer) de l'image a besoin d'etre éxécuter.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Build les images
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Pour build les images il suffit de lancer les commandes suivantes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					cd docker_ci/
 | 
				
			||||||
 | 
					docker build -t nk20_ci_37 -f Dockerfile.37 .
 | 
				
			||||||
 | 
					docker build -t nk20_ci_38 -f Dockerfile.38 .
 | 
				
			||||||
 | 
					docker build -t nk20_ci_39 -f Dockerfile.39 .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Elles sont acutellement build et disponible sur dockerhub
 | 
				
			||||||
 | 
					https://hub.docker.com/otthorn/nk20_ci_37
 | 
				
			||||||
@@ -1,80 +0,0 @@
 | 
				
			|||||||
Service d'Authentification Centralisé (CAS)
 | 
					 | 
				
			||||||
===========================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Un `CAS <https://fr.wikipedia.org/wiki/Central_Authentication_Service>`_ est
 | 
					 | 
				
			||||||
déployé sur la Note Kfet. Il est accessible à l'adresse `<https://note.crans.org/cas/>`_.
 | 
					 | 
				
			||||||
Il a pour but uniquement d'authentifier les utilisateurs via la note et ne communique
 | 
					 | 
				
			||||||
que peu d'informations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Configuration
 | 
					 | 
				
			||||||
-------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Le serveur CAS utilisé est implémenté grâce au paquet ``django-cas-server``. Il peut être
 | 
					 | 
				
			||||||
installé soit par PIP soit sur une machine Debian via
 | 
					 | 
				
			||||||
``apt install python3-django-cas-server``.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On ajoute ensuite ``cas_server`` aux applications Django installées. On n'oublie pas ni
 | 
					 | 
				
			||||||
d'appliquer les migrations (``./manage.py migrate``) ni de collecter les fichiers
 | 
					 | 
				
			||||||
statiques (``./manage.py collectstatic``).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On enregistre les routes dans ``note_kfet/urls.py`` :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   urlpatterns.append(
 | 
					 | 
				
			||||||
        path('cas/', include('cas_server.urls', namespace='cas_server'))
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Le CAS est désormais déjà prêt à être utilisé. Toutefois, puisque l'on utilise un site
 | 
					 | 
				
			||||||
Django-admin personnalisé, on n'oublie pas d'enregistrer les pages d'administration :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   if "cas_server" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
       from cas_server.admin import *
 | 
					 | 
				
			||||||
       from cas_server.models import *
 | 
					 | 
				
			||||||
       admin_site.register(ServicePattern, ServicePatternAdmin)
 | 
					 | 
				
			||||||
       admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Enfin, on souhaite pouvoir fournir au besoin le pseudo normalisé. Pour cela, on crée une
 | 
					 | 
				
			||||||
classe dans ``member.auth`` :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   class CustomAuthUser(DjangoAuthUser):
 | 
					 | 
				
			||||||
       def attributs(self):
 | 
					 | 
				
			||||||
           d = super().attributs()
 | 
					 | 
				
			||||||
           if self.user:
 | 
					 | 
				
			||||||
               d["normalized_name"] = Alias.normalize(self.user.username)
 | 
					 | 
				
			||||||
           return d
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Puis on source ce fichier dans les paramètres :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   CAS_AUTH_CLASS = 'member.auth.CustomAuthUser'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Utilisation
 | 
					 | 
				
			||||||
-----------
 | 
					 | 
				
			||||||
Le service est accessible sur `<https://note.crans.org/cas/>`_. C'est ce lien qu'il faut
 | 
					 | 
				
			||||||
donner à votre application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
L'application doit néanmoins être autorisée à accéder au CAS. Pour cela, rendez-vous
 | 
					 | 
				
			||||||
dans Django-admin (`<https://note.crans.org/cas/admin/>`_), dans
 | 
					 | 
				
			||||||
``Service Central d'Authentification/Motifs de services``, ajoutez une nouvelle entrée.
 | 
					 | 
				
			||||||
Choisissez votre position favorite puis le nom de l'application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Les champs importants sont les deux suivants :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* **Motif :** il s'agit d'une expression régulière qui doit reconnaitre le site voulu.
 | 
					 | 
				
			||||||
  Par exemple, pour autoriser Belenios (`<https://belenios.crans.org>`_), on rentrera
 | 
					 | 
				
			||||||
  le motif ``^https?://belenios\.crans\.org/.*$``.
 | 
					 | 
				
			||||||
* **Champ d'utilisateur :** C'est le pseudo que renverra le CAS. Par défaut, il s'agira
 | 
					 | 
				
			||||||
  du nom de note principal, mais il arrive parfois que certains sites supportent mal
 | 
					 | 
				
			||||||
  d'avoir des caractères UTF-8 dans le pseudo. C'est par exemple le cas de Belenios.
 | 
					 | 
				
			||||||
  On rentrera alors ``normalized_name`` dans ce champ, qui correspond à la version
 | 
					 | 
				
			||||||
  normalisée (sans accent ni espace ni aucun caractère non-ASCII) du pseudo, et qui
 | 
					 | 
				
			||||||
  suffit à identifier une personne.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On peut également utiliser le ``Single log out`` si besoin.
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
Applications externes
 | 
					 | 
				
			||||||
=====================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. toctree::
 | 
					 | 
				
			||||||
   :maxdepth: 2
 | 
					 | 
				
			||||||
   :caption: Applications externes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   cas
 | 
					 | 
				
			||||||
   oauth2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. warning::
 | 
					 | 
				
			||||||
   L'utilisation de la note par des services externes est actuellement en beta. Il est
 | 
					 | 
				
			||||||
   fort à parier que cette utilisation sera revue et améliorée à l'avenir.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Puisque la Note Kfet recense tous les comptes des adhérents BDE, les clubs ont alors
 | 
					 | 
				
			||||||
la possibilité de développer leurs propres applications et de les interfacer avec la
 | 
					 | 
				
			||||||
note. De cette façon, chaque application peut authentifier ses utilisateurs via la note,
 | 
					 | 
				
			||||||
et récupérer leurs adhésion, leur nom de note afin d'éventuellement faire des transferts
 | 
					 | 
				
			||||||
via l'API.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Deux protocoles d'authentification sont implémentées :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 * `CAS <cas>`_
 | 
					 | 
				
			||||||
 * `OAuth2 <oauth2>`_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
À ce jour, il n'y a pas encore d'exemple d'utilisation d'application qui utilise ce
 | 
					 | 
				
			||||||
mécanisme, mais on peut imaginer par exemple que la Mediatek ou l'AMAP implémentent
 | 
					 | 
				
			||||||
ces protocoles pour récupérer leurs adhérents.
 | 
					 | 
				
			||||||
@@ -1,133 +0,0 @@
 | 
				
			|||||||
OAuth2
 | 
					 | 
				
			||||||
======
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
L'authentification `OAuth2 <https://fr.wikipedia.org/wiki/OAuth>`_ est supportée par la
 | 
					 | 
				
			||||||
Note Kfet. Elle offre l'avantage non seulement d'identifier les utilisateurs, mais aussi
 | 
					 | 
				
			||||||
de transmettre des informations à un service tiers tels que des informations personnelles,
 | 
					 | 
				
			||||||
le solde de la note ou encore les adhésions de l'utilisateur, en l'avertissant sur
 | 
					 | 
				
			||||||
quelles données sont effectivement collectées.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. danger::
 | 
					 | 
				
			||||||
   L'implémentation actuelle ne permet pas de choisir quels droits on offre. Se connecter
 | 
					 | 
				
			||||||
   par OAuth2 offre actuellement exactement les mêmes permissions que l'on n'aurait
 | 
					 | 
				
			||||||
   normalement, avec le masque le plus haut, y compris en écriture.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   Faites alors très attention lorsque vous vous connectez à un service tiers via OAuth2,
 | 
					 | 
				
			||||||
   et contrôlez bien exactement ce que l'application fait de vos données, à savoir si
 | 
					 | 
				
			||||||
   elle ignore bien tout ce dont elle n'a pas besoin.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   À l'avenir, la fenêtre d'authentification pourra vous indiquer clairement quels
 | 
					 | 
				
			||||||
   paramètres sont collectés.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Configuration du serveur
 | 
					 | 
				
			||||||
------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On utilise ``django-oauth-toolkit``, qui peut être installé grâce à PIP ou bien via APT,
 | 
					 | 
				
			||||||
via le paquet ``python3-django-oauth-toolkit``.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On commence par ajouter ``oauth2_provider`` aux applications Django installées. On
 | 
					 | 
				
			||||||
n'oublie pas ni d'appliquer les migrations (``./manage.py migrate``) ni de collecter
 | 
					 | 
				
			||||||
les fichiers statiques (``./manage.py collectstatic``).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On souhaite que l'API gérée par ``django-rest-framework`` puisse être accessible via
 | 
					 | 
				
			||||||
l'authentification OAuth2. On adapte alors la configuration pour permettre cela :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   REST_FRAMEWORK = {
 | 
					 | 
				
			||||||
       'DEFAULT_AUTHENTICATION_CLASSES': [
 | 
					 | 
				
			||||||
           'rest_framework.authentication.SessionAuthentication',
 | 
					 | 
				
			||||||
           'rest_framework.authentication.TokenAuthentication',
 | 
					 | 
				
			||||||
           'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
 | 
					 | 
				
			||||||
           ...
 | 
					 | 
				
			||||||
       ],
 | 
					 | 
				
			||||||
       ...
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
On ajoute les routes dans ``urls.py`` :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   urlpatterns.append(
 | 
					 | 
				
			||||||
        path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
L'OAuth2 est désormais prêt à être utilisé.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Configuration client
 | 
					 | 
				
			||||||
--------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Contrairement au `CAS <cas>`_, n'importe qui peut en théorie créer une application OAuth2.
 | 
					 | 
				
			||||||
En théorie, car pour l'instant les permissions ne leur permettent pas.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Pour créer une application, il faut se rendre à la page
 | 
					 | 
				
			||||||
`/o/applications/ <https://note.crans.org/o/applications/>`_. Dans ``client type``,
 | 
					 | 
				
			||||||
rentrez ``public`` (ou ``confidential`` selon vos choix), et vous rentrerez
 | 
					 | 
				
			||||||
généralement ``authorization-code`` dans ``Authorization Grant Type``.
 | 
					 | 
				
			||||||
Le champ ``Redirect Uris`` contient une liste d'adresses URL autorisées pour des
 | 
					 | 
				
			||||||
redirections post-connexion.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Il vous suffit de donner à votre application :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
* L'identifiant client (client-ID)
 | 
					 | 
				
			||||||
* La clé secrète
 | 
					 | 
				
			||||||
* Les scopes : sous-ensemble de ``[read, write]`` (ignoré pour l'instant, cf premier paragraphe)
 | 
					 | 
				
			||||||
* L'URL d'autorisation : `<https://note.crans.org/o/authorize/>`_
 | 
					 | 
				
			||||||
* L'URL d'obtention de jeton : `<https://note.crans.org/o/token/>`_
 | 
					 | 
				
			||||||
* L'URL de récupération des informations de l'utilisateur : `<https://note.crans.org/api/me/>`_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
N'hésitez pas à consulter la page `<https://note.crans.org/api/me/>`_ pour s'imprégner
 | 
					 | 
				
			||||||
du format renvoyé.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Avec Django-allauth
 | 
					 | 
				
			||||||
###################
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Si vous utilisez Django-allauth pour votre propre application, vous pouvez utiliser
 | 
					 | 
				
			||||||
le module pré-configuré disponible ici :
 | 
					 | 
				
			||||||
`<https://gitlab.crans.org/bde/allauth-note-kfet>`_. Pour l'installer, vous
 | 
					 | 
				
			||||||
pouvez simplement faire :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: bash
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   $ pip3 install git+https://gitlab.crans.org/bde/allauth-note-kfet.git
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
L'installation du module se fera automatiquement.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Il vous suffit ensuite d'inclure l'application ``allauth_note_kfet`` à vos applications
 | 
					 | 
				
			||||||
installées (sur votre propre client), puis de bien ajouter l'application sociale :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   SOCIALACCOUNT_PROVIDERS = {
 | 
					 | 
				
			||||||
       'notekfet': {
 | 
					 | 
				
			||||||
           # 'DOMAIN': 'note.crans.org',
 | 
					 | 
				
			||||||
       },
 | 
					 | 
				
			||||||
       ...
 | 
					 | 
				
			||||||
   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Le paramètre ``DOMAIN`` permet de changer d'instance de Note Kfet. Par défaut, il
 | 
					 | 
				
			||||||
se connectera à ``note.crans.org`` si vous ne renseignez rien.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
En créant l'application sur la note, vous pouvez renseigner
 | 
					 | 
				
			||||||
``https://monsite.example.com/accounts/notekfet/login/callback/`` en URL de redirection,
 | 
					 | 
				
			||||||
à adapter selon votre configuration.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Vous devrez ensuite enregistrer l'application sociale dans la base de données.
 | 
					 | 
				
			||||||
Vous pouvez passer par Django-admin, mais cela peut nécessiter d'avoir déjà un compte,
 | 
					 | 
				
			||||||
alors autant le faire via un shell python :
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
   from allauth.socialaccount.models import SocialApp
 | 
					 | 
				
			||||||
   SocialApp.objects.create(
 | 
					 | 
				
			||||||
           name="Note Kfet",
 | 
					 | 
				
			||||||
           provider="notekfet",
 | 
					 | 
				
			||||||
           client_id="VOTRECLIENTID",
 | 
					 | 
				
			||||||
           secret="VOTRESECRET",
 | 
					 | 
				
			||||||
           key="",
 | 
					 | 
				
			||||||
   )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Si vous avez bien configuré ``django-allauth``, vous êtes désormais prêts par à vous
 | 
					 | 
				
			||||||
connecter via la note :) Par défaut, nom, prénom, pseudo et adresse e-mail sont
 | 
					 | 
				
			||||||
récupérés. Les autres données sont stockées mais inutilisées.
 | 
					 | 
				
			||||||
@@ -12,4 +12,3 @@ Des informations complémentaires sont également disponibles sur le `Wiki Crans
 | 
				
			|||||||
   :caption: Développement de la NK20
 | 
					   :caption: Développement de la NK20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   apps/index
 | 
					   apps/index
 | 
				
			||||||
   external_services/index
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,9 +52,3 @@ if "rest_framework" in settings.INSTALLED_APPS:
 | 
				
			|||||||
    from rest_framework.authtoken.admin import *
 | 
					    from rest_framework.authtoken.admin import *
 | 
				
			||||||
    from rest_framework.authtoken.models import *
 | 
					    from rest_framework.authtoken.models import *
 | 
				
			||||||
    admin_site.register(Token, TokenAdmin)
 | 
					    admin_site.register(Token, TokenAdmin)
 | 
				
			||||||
 | 
					 | 
				
			||||||
if "cas_server" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
    from cas_server.admin import *
 | 
					 | 
				
			||||||
    from cas_server.models import *
 | 
					 | 
				
			||||||
    admin_site.register(ServicePattern, ServicePatternAdmin)
 | 
					 | 
				
			||||||
    admin_site.register(FederatedIendityProvider, FederatedIendityProviderAdmin)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@ def read_env():
 | 
				
			|||||||
    directory.
 | 
					    directory.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        with open(os.path.join(BASE_DIR, '.env')) as f:
 | 
					        with open('.env') as f:
 | 
				
			||||||
            content = f.read()
 | 
					            content = f.read()
 | 
				
			||||||
    except IOError:
 | 
					    except IOError:
 | 
				
			||||||
        content = ''
 | 
					        content = ''
 | 
				
			||||||
@@ -30,7 +30,6 @@ def read_env():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Try to load environment variables from project .env
 | 
					# Try to load environment variables from project .env
 | 
				
			||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 | 
					 | 
				
			||||||
read_env()
 | 
					read_env()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Load base settings
 | 
					# Load base settings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -239,7 +239,6 @@ REST_FRAMEWORK = {
 | 
				
			|||||||
    'DEFAULT_AUTHENTICATION_CLASSES': [
 | 
					    'DEFAULT_AUTHENTICATION_CLASSES': [
 | 
				
			||||||
        'rest_framework.authentication.SessionAuthentication',
 | 
					        'rest_framework.authentication.SessionAuthentication',
 | 
				
			||||||
        'rest_framework.authentication.TokenAuthentication',
 | 
					        'rest_framework.authentication.TokenAuthentication',
 | 
				
			||||||
        'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
 | 
					 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
 | 
					    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
 | 
				
			||||||
    'PAGE_SIZE': 20,
 | 
					    'PAGE_SIZE': 20,
 | 
				
			||||||
@@ -274,6 +273,3 @@ PIC_RATIO = 1
 | 
				
			|||||||
# Custom phone number format
 | 
					# Custom phone number format
 | 
				
			||||||
PHONENUMBER_DB_FORMAT = 'NATIONAL'
 | 
					PHONENUMBER_DB_FORMAT = 'NATIONAL'
 | 
				
			||||||
PHONENUMBER_DEFAULT_REGION = 'FR'
 | 
					PHONENUMBER_DEFAULT_REGION = 'FR'
 | 
				
			||||||
 | 
					 | 
				
			||||||
# We add custom information to CAS, in order to give a normalized name to other services
 | 
					 | 
				
			||||||
CAS_AUTH_CLASS = 'member.auth.CustomAuthUser'
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,11 +45,6 @@ if "oauth2_provider" in settings.INSTALLED_APPS:
 | 
				
			|||||||
        path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
 | 
					        path('o/', include('oauth2_provider.urls', namespace='oauth2_provider'))
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if "cas_server" in settings.INSTALLED_APPS:
 | 
					 | 
				
			||||||
    urlpatterns.append(
 | 
					 | 
				
			||||||
        path('cas/', include('cas_server.urls', namespace='cas_server'))
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if "debug_toolbar" in settings.INSTALLED_APPS:
 | 
					if "debug_toolbar" in settings.INSTALLED_APPS:
 | 
				
			||||||
    import debug_toolbar
 | 
					    import debug_toolbar
 | 
				
			||||||
    urlpatterns = [
 | 
					    urlpatterns = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
beautifulsoup4~=4.7.1
 | 
					beautifulsoup4~=4.7.1
 | 
				
			||||||
Django~=2.2.15
 | 
					Django~=2.2.15
 | 
				
			||||||
django-bootstrap-datepicker-plus~=3.0.5
 | 
					django-bootstrap-datepicker-plus~=3.0.5
 | 
				
			||||||
django-cas-server~=1.2.0
 | 
					 | 
				
			||||||
django-colorfield~=0.3.2
 | 
					django-colorfield~=0.3.2
 | 
				
			||||||
django-crispy-forms~=1.7.2
 | 
					django-crispy-forms~=1.7.2
 | 
				
			||||||
django-extensions~=2.1.4
 | 
					django-extensions~=2.1.4
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user