Massive cleanup (1)

This commit is contained in:
Alexandre Iooss 2019-08-02 14:57:53 +02:00
parent ca394afe20
commit c5f98991aa
No known key found for this signature in database
GPG Key ID: 6C79278F3FCDCC02
38 changed files with 479 additions and 729 deletions

View File

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -1,29 +1,12 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import template
register = template.Library()
@register.filter
def classname(obj):
return obj.__class__.__name__

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,24 +1,6 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf.urls import url

View File

@ -1,58 +1,30 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# App de gestion des statistiques pour re2o
# Gabriel Détraz
# Gplv2
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.shortcuts import get_object_or_404
from django.template.context_processors import csrf
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.template import Context, RequestContext, loader
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.db.models import ProtectedError
from django.forms import ValidationError
from django.db import transaction
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import Count
from django.shortcuts import redirect, render
from django.template.context_processors import csrf
from reversion.models import Revision
from reversion.models import Version
from users.models import User
from med.settings import PAGINATION_NUMBER as pagination_number
from users.models import User
from django.utils import timezone
def form(ctx, template, request):
c = ctx
c.update(csrf(request))
return render(request, template, c)
@login_required
@permission_required('perm')
def index(request):
revisions = Revision.objects.all().order_by('date_created').reverse().select_related('user').prefetch_related('version_set__object')
revisions = Revision.objects.all().order_by('date_created').reverse().select_related('user').prefetch_related(
'version_set__object')
paginator = Paginator(revisions, pagination_number)
page = request.GET.get('page')
try:
@ -61,10 +33,11 @@ def index(request):
# If page is not an integer, deliver first page.
revisions = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
# If page is out of range (e.g. 9999), deliver last page of results.
revisions = paginator.page(paginator.num_pages)
return render(request, 'logs/index.html', {'revisions_list': revisions})
@login_required
@permission_required('bureau')
def revert_action(request, revision_id):
@ -72,20 +45,20 @@ def revert_action(request, revision_id):
try:
revision = Revision.objects.get(id=revision_id)
except Revision.DoesNotExist:
messages.error(request, u"Revision inexistante" )
messages.error(request, u"Revision inexistante")
if request.method == "POST":
revision.revert()
messages.success(request, "L'action a été supprimée")
return redirect("/logs/")
return form({'objet': revision, 'objet_name': revision.__class__.__name__ }, 'logs/delete.html', request)
return form({'objet': revision, 'objet_name': revision.__class__.__name__}, 'logs/delete.html', request)
@login_required
@permission_required('perm')
def stats_actions(request):
onglet = request.GET.get('onglet')
stats = {
'Utilisateur' : {
'Action' : User.objects.annotate(num=Count('revision')).order_by('-num')[:40],
},
'Utilisateur': {
'Action': User.objects.annotate(num=Count('revision')).order_by('-num')[:40],
},
}
return render(request, 'logs/stats_users.html', {'stats_list': stats})

View File

@ -1,22 +0,0 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

View File

@ -1,33 +1,16 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from .settings import SITE_NAME
def context_user(request):
user = request.user
is_perm = user.has_perms(['perm'])
is_bureau = user.has_perms(['bureau'])
return {
'is_perm' : is_perm,
'is_perm': is_perm,
'is_bureau': is_bureau,
'request_user': user,
'site_name': SITE_NAME,

View File

@ -1,18 +1,17 @@
# -*- coding: utf-8 -*-
# Module d'authentification
# David Sinquin, Gabriel Détraz, Goulven Kermarec
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import hashlib
import binascii
import hashlib
import os
from base64 import encodestring
from base64 import decodestring
from base64 import encodestring
from collections import OrderedDict
from django.contrib.auth import hashers
ALGO_NAME = "{SSHA}"
ALGO_LEN = len(ALGO_NAME + "$")
DIGEST_LEN = 20
@ -24,6 +23,7 @@ def makeSecret(password):
h.update(salt)
return ALGO_NAME + "$" + encodestring(h.digest() + salt).decode()[:-1]
def checkPassword(challenge_password, password):
challenge_bytes = decodestring(challenge_password[ALGO_LEN:].encode())
digest = challenge_bytes[:DIGEST_LEN]
@ -37,6 +37,7 @@ def checkPassword(challenge_password, password):
valid_password &= i == j
return valid_password
class SSHAPasswordHasher(hashers.BasePasswordHasher):
"""
SSHA password hashing to allow for LDAP auth compatibility
@ -70,8 +71,8 @@ class SSHAPasswordHasher(hashers.BasePasswordHasher):
return OrderedDict([
('algorithm', self.algorithm),
('iterations', 0),
('salt', hashers.mask_hash(hash[2*DIGEST_LEN:], show=2)),
('hash', hashers.mask_hash(hash[:2*DIGEST_LEN])),
('salt', hashers.mask_hash(hash[2 * DIGEST_LEN:], show=2)),
('hash', hashers.mask_hash(hash[:2 * DIGEST_LEN])),
])
def harden_runtime(self, password, encoded):
@ -81,4 +82,3 @@ class SSHAPasswordHasher(hashers.BasePasswordHasher):
As we are not using multiple iterations the method is pretty useless
"""
pass

View File

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import os
@ -103,16 +103,20 @@ DATABASES = {
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
'NAME': 'django.contrib.auth.'
'password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'NAME': 'django.contrib.auth.'
'password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
'NAME': 'django.contrib.auth.'
'password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
'NAME': 'django.contrib.auth.'
'password_validation.NumericPasswordValidator',
},
]

View File

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2018-2019 by BDE ENS Paris-Saclay
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# Needed to filter which host are trusted

View File

@ -1 +0,0 @@
create allowed_guests bitmap:ip range 10.231.137.0-10.231.137.255

View File

@ -1,39 +1,7 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
"""med URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views

View File

@ -1,36 +1,19 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.template.context_processors import csrf
from django.template import Context, RequestContext, loader
from med.settings import services_urls
def form(ctx, template, request):
c = ctx
c.update(csrf(request))
return render(request, template, c)
def index(request):
i = 0
services = [{}]

View File

@ -1,24 +1,6 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
"""
WSGI config for med project.
@ -30,10 +12,10 @@ https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
from os.path import dirname
import sys
from os.path import dirname
from django.core.wsgi import get_wsgi_application
sys.path.append(dirname(dirname(__file__)))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "med.settings")

View File

@ -1,21 +1,28 @@
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from reversion.admin import VersionAdmin
from django.contrib import admin
from django.contrib.auth.models import Group
from reversion.admin import VersionAdmin
from .models import Auteur, Emprunt, Media, Jeu
class AuteurAdmin(VersionAdmin):
list_display = ('nom',)
class MediaAdmin(VersionAdmin):
list_display = ('titre','cote')
list_display = ('titre', 'cote')
class EmpruntAdmin(VersionAdmin):
list_display = ('media','user','date_emprunt', 'date_rendu', 'permanencier_emprunt', 'permanencier_rendu')
list_display = ('media', 'user', 'date_emprunt', 'date_rendu', 'permanencier_emprunt', 'permanencier_rendu')
class JeuAdmin(VersionAdmin):
list_display = ('nom','proprietaire', 'duree', 'nombre_joueurs_min', 'nombre_joueurs_max', 'comment')
list_display = ('nom', 'proprietaire', 'duree', 'nombre_joueurs_min', 'nombre_joueurs_max', 'comment')
admin.site.register(Auteur, AuteurAdmin)
admin.site.register(Media, MediaAdmin)

View File

@ -1,34 +1,19 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.forms import ModelForm, Form, ValidationError
from django import forms
from django.forms import ModelForm
from .models import Auteur, Media, Jeu, Emprunt
class AuteurForm(ModelForm):
class Meta:
model = Auteur
fields = '__all__'
class MediaForm(ModelForm):
auteur = forms.ModelMultipleChoiceField(Auteur.objects.all(), widget=forms.CheckboxSelectMultiple, required=False)
@ -36,6 +21,7 @@ class MediaForm(ModelForm):
model = Media
fields = '__all__'
class JeuForm(ModelForm):
class Meta:
model = Jeu
@ -46,11 +32,13 @@ class JeuForm(ModelForm):
raise forms.ValidationError("Max ne peut être inférieur à min")
return self.cleaned_data['nombre_joueurs_max']
class EmpruntForm(ModelForm):
class Meta:
model = Emprunt
fields = ['media']
class EditEmpruntForm(ModelForm):
class Meta:
model = Emprunt

View File

@ -0,0 +1,46 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-02 14:47+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: models.py:13
msgid "author"
msgstr ""
#: models.py:14
msgid "authors"
msgstr ""
#: models.py:26
msgid "medium"
msgstr ""
#: models.py:27
msgid "media"
msgstr ""
#: models.py:44
msgid "borrowed item"
msgstr ""
#: models.py:45
msgid "borrowed items"
msgstr ""
#: models.py:68
msgid "game"
msgstr ""
#: models.py:69
msgid "games"
msgstr ""

View File

@ -1,5 +1,11 @@
from django.db import models
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.core.validators import MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
class Auteur(models.Model):
nom = models.CharField(max_length=255, unique=True)
@ -7,39 +13,53 @@ class Auteur(models.Model):
def __str__(self):
return self.nom
class Meta:
verbose_name = _("author")
verbose_name_plural = _("authors")
class Media(models.Model):
titre = models.CharField(max_length=255)
cote = models.CharField(max_length=31)
auteur = models.ManyToManyField('Auteur')
# type = TODO
auteur = models.ManyToManyField('Auteur')
def __str__(self):
return str(self.titre) + ' - ' + str(self.auteur.all().first())
class Meta:
verbose_name = _("medium")
verbose_name_plural = _("media")
class Emprunt(models.Model):
media = models.ForeignKey('Media', on_delete=models.PROTECT)
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
media = models.ForeignKey('Media', on_delete=models.PROTECT)
user = models.ForeignKey('users.User', on_delete=models.PROTECT)
date_emprunt = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S')
date_rendu = models.DateTimeField(help_text='%d/%m/%y %H:%M:%S', blank=True, null=True)
permanencier_emprunt = models.ForeignKey('users.User', on_delete=models.PROTECT, related_name='user_permanencier_emprunt')
permanencier_rendu = models.ForeignKey('users.User', on_delete=models.PROTECT, related_name='user_permanencier_rendu', blank=True, null=True)
permanencier_emprunt = models.ForeignKey('users.User', on_delete=models.PROTECT,
related_name='user_permanencier_emprunt')
permanencier_rendu = models.ForeignKey('users.User', on_delete=models.PROTECT,
related_name='user_permanencier_rendu', blank=True, null=True)
def __str__(self):
return str(self.media) + str(self.user)
class Meta:
verbose_name = _("borrowed item")
verbose_name_plural = _("borrowed items")
class Jeu(models.Model):
DUREE = (
('-1h', '-1h'),
('1-2h', '1-2h'),
('2-3h', '2-3h'),
('3-4h', '3-4h'),
('4h+', '4h+'),
)
('-1h', '-1h'),
('1-2h', '1-2h'),
('2-3h', '2-3h'),
('3-4h', '3-4h'),
('4h+', '4h+'),
)
nom = models.CharField(max_length=255)
proprietaire = models.ForeignKey('users.User', on_delete=models.PROTECT)
proprietaire = models.ForeignKey('users.User', on_delete=models.PROTECT)
duree = models.CharField(choices=DUREE, max_length=255)
nombre_joueurs_min = models.IntegerField(validators=[MinValueValidator(1)])
nombre_joueurs_max = models.IntegerField(validators=[MinValueValidator(1)])
@ -47,3 +67,7 @@ class Jeu(models.Model):
def __str__(self):
return str(self.nom)
class Meta:
verbose_name = _("game")
verbose_name_plural = _("games")

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,24 +1,6 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf.urls import url

View File

@ -1,28 +1,29 @@
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.template.context_processors import csrf
from django.template import Context, RequestContext, loader
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.contrib.auth import authenticate, login
from django.views.decorators.csrf import csrf_exempt
from django.utils import timezone
from .forms import AuteurForm, MediaForm, JeuForm, EmpruntForm, EditEmpruntForm
from .models import Auteur, Media, Jeu, Emprunt
from users.models import User
from django.db import transaction
from django.shortcuts import render, redirect
from django.template.context_processors import csrf
from django.utils import timezone
from reversion import revisions as reversion
from reversion.models import Version
from med.settings import PAGINATION_NUMBER
from users.models import User
from .forms import AuteurForm, MediaForm, JeuForm, EmpruntForm, EditEmpruntForm
from .models import Auteur, Media, Jeu, Emprunt
def form(ctx, template, request):
c = ctx
c.update(csrf(request))
return render(request, template, c)
@login_required
@permission_required('perm')
def add_auteur(request):
@ -36,13 +37,14 @@ def add_auteur(request):
return redirect("/media/index_auteurs/")
return form({'mediaform': auteur}, 'media/media.html', request)
@login_required
@permission_required('perm')
def edit_auteur(request, auteurid):
try:
auteur_instance = Auteur.objects.get(pk=auteurid)
except Auteur.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_auteurs/")
auteur = AuteurForm(request.POST or None, instance=auteur_instance)
if auteur.is_valid():
@ -54,13 +56,14 @@ def edit_auteur(request, auteurid):
return redirect("/media/index_auteurs/")
return form({'mediaform': auteur}, 'media/media.html', request)
@login_required
@permission_required('perm')
def del_auteur(request, auteurid):
try:
auteur_instance = Auteur.objects.get(pk=auteurid)
except Auteur.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_auteurs/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -84,13 +87,14 @@ def add_media(request):
return redirect("/media/index_medias/")
return form({'mediaform': media}, 'media/media.html', request)
@login_required
@permission_required('perm')
def edit_media(request, mediaid):
try:
media_instance = Media.objects.get(pk=mediaid)
except Media.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_medias/")
media = MediaForm(request.POST or None, instance=media_instance)
if media.is_valid():
@ -102,13 +106,14 @@ def edit_media(request, mediaid):
return redirect("/media/index_medias/")
return form({'mediaform': media}, 'media/media.html', request)
@login_required
@permission_required('perm')
def del_media(request, mediaid):
try:
media_instance = Media.objects.get(pk=mediaid)
except Media.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_medias/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -118,6 +123,7 @@ def del_media(request, mediaid):
return redirect("/media/index_medias")
return form({'objet': media_instance, 'objet_name': 'media'}, 'media/delete.html', request)
@login_required
@permission_required('perm')
def add_jeu(request):
@ -131,13 +137,14 @@ def add_jeu(request):
return redirect("/media/index_jeux/")
return form({'mediaform': jeu}, 'media/media.html', request)
@login_required
@permission_required('perm')
def edit_jeu(request, jeuid):
try:
jeu_instance = Jeu.objects.get(pk=jeuid)
except Jeu.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_jeux/")
jeu = JeuForm(request.POST or None, instance=jeu_instance)
if jeu.is_valid():
@ -149,13 +156,14 @@ def edit_jeu(request, jeuid):
return redirect("/media/index_jeux/")
return form({'mediaform': jeu}, 'media/media.html', request)
@login_required
@permission_required('perm')
def del_jeu(request, jeuid):
try:
jeu_instance = Jeu.objects.get(pk=jeuid)
except Jeu.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_jeux/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -165,13 +173,14 @@ def del_jeu(request, jeuid):
return redirect("/media/index_jeux")
return form({'objet': jeu_instance, 'objet_name': 'jeu'}, 'media/delete.html', request)
@login_required
@permission_required('perm')
def add_emprunt(request, userid):
try:
user = User.objects.get(pk=userid)
except User.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_emprunts/")
emprunts_en_cours = Emprunt.objects.filter(date_rendu=None, user=user).count()
if emprunts_en_cours >= user.maxemprunt:
@ -191,13 +200,14 @@ def add_emprunt(request, userid):
return redirect("/media/index_emprunts/")
return form({'mediaform': emprunt}, 'media/media.html', request)
@login_required
@permission_required('perm')
def edit_emprunt(request, empruntid):
try:
emprunt_instance = Emprunt.objects.get(pk=empruntid)
except Emprunt.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_emprunts/")
emprunt = EditEmpruntForm(request.POST or None, instance=emprunt_instance)
if emprunt.is_valid():
@ -209,13 +219,14 @@ def edit_emprunt(request, empruntid):
return redirect("/media/index_emprunts/")
return form({'mediaform': emprunt}, 'media/media.html', request)
@login_required
@permission_required('perm')
def retour_emprunt(request, empruntid):
try:
emprunt_instance = Emprunt.objects.get(pk=empruntid)
except Emprunt.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_emprunts/")
with transaction.atomic(), reversion.create_revision():
emprunt_instance.permanencier_rendu = request.user
@ -225,13 +236,14 @@ def retour_emprunt(request, empruntid):
messages.success(request, "Retour enregistré")
return redirect("/media/index_emprunts/")
@login_required
@permission_required('perm')
def del_emprunt(request, empruntid):
try:
emprunt_instance = Emprunt.objects.get(pk=empruntid)
except Emprunt.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/media/index_emprunts/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -242,8 +254,6 @@ def del_emprunt(request, empruntid):
return form({'objet': emprunt_instance, 'objet_name': 'emprunt'}, 'media/delete.html', request)
@login_required
def index_jeux(request):
jeux_list = Jeu.objects.all()
@ -257,7 +267,8 @@ def index_jeux(request):
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
jeux_list = paginator.page(paginator.num_pages)
return render(request, 'media/index_jeux.html', {'jeux_list':jeux_list})
return render(request, 'media/index_jeux.html', {'jeux_list': jeux_list})
@login_required
def index_auteurs(request):
@ -272,7 +283,8 @@ def index_auteurs(request):
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
auteurs_list = paginator.page(paginator.num_pages)
return render(request, 'media/index_auteurs.html', {'auteurs_list':auteurs_list})
return render(request, 'media/index_auteurs.html', {'auteurs_list': auteurs_list})
@login_required
def index_medias(request):
@ -287,7 +299,7 @@ def index_medias(request):
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
medias_list = paginator.page(paginator.num_pages)
return render(request, 'media/index_medias.html', {'medias_list':medias_list})
return render(request, 'media/index_medias.html', {'medias_list': medias_list})
@login_required
@ -306,35 +318,35 @@ def index(request):
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
emprunts_list = paginator.page(paginator.num_pages)
return render(request, 'media/index_emprunts.html', {'emprunts_list':emprunts_list})
return render(request, 'media/index_emprunts.html', {'emprunts_list': emprunts_list})
@login_required
def history(request, object, id):
if object == 'auteur':
try:
object_instance = Auteur.objects.get(pk=id)
object_instance = Auteur.objects.get(pk=id)
except Auteur.DoesNotExist:
messages.error(request, "Auteur inexistant")
return redirect("/media/index_auteurs")
messages.error(request, "Auteur inexistant")
return redirect("/media/index_auteurs")
elif object == 'media':
try:
object_instance = Media.objects.get(pk=id)
object_instance = Media.objects.get(pk=id)
except Media.DoesNotExist:
messages.error(request, "Media inexistant")
return redirect("/media/index_medias")
messages.error(request, "Media inexistant")
return redirect("/media/index_medias")
elif object == 'emprunt':
try:
object_instance = Emprunt.objects.get(pk=id)
object_instance = Emprunt.objects.get(pk=id)
except Emprunt.DoesNotExist:
messages.error(request, "Emprunt inexistant")
return redirect("/media/index_emprunts")
messages.error(request, "Emprunt inexistant")
return redirect("/media/index_emprunts")
elif object == 'jeu':
try:
object_instance = Jeu.objects.get(pk=id)
object_instance = Jeu.objects.get(pk=id)
except Jeu.DoesNotExist:
messages.error(request, "Jeu inexistant")
return redirect("/media/index_jeux")
messages.error(request, "Jeu inexistant")
return redirect("/media/index_jeux")
reversions = Version.objects.get_for_object(object_instance)
paginator = Paginator(reversions, PAGINATION_NUMBER)
page = request.GET.get('page')
@ -347,4 +359,3 @@ def history(request, object, id):
# If page is out of range (e.g. 9999), deliver last page of results.
reversions = paginator.page(paginator.num_pages)
return render(request, 'med/history.html', {'reversions': reversions, 'object': object_instance})

View File

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View File

@ -1,29 +1,9 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.db import models
from django import forms
from django.forms import Form
from django.forms import ModelForm
CHOICES = (
('0', 'Actifs'),
@ -37,14 +17,18 @@ CHOICES2 = (
('2', 'Emprunts'),
('3', 'Jeu'),
)
class SearchForm(Form):
search_field = forms.CharField(label = 'Search', max_length = 100)
search_field = forms.CharField(label='Search', max_length=100)
class SearchFormPlus(Form):
search_field = forms.CharField(label = 'Search', max_length = 100, required=False)
filtre = forms.MultipleChoiceField(label="Filtre utilisateurs", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES)
affichage = forms.MultipleChoiceField(label="Filtre affichage", required=False, widget =forms.CheckboxSelectMultiple,choices=CHOICES2)
date_deb = forms.DateField(required=False, label="Date de début", help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'])
search_field = forms.CharField(label='Search', max_length=100, required=False)
filtre = forms.MultipleChoiceField(label="Filtre utilisateurs", required=False, widget=forms.CheckboxSelectMultiple,
choices=CHOICES)
affichage = forms.MultipleChoiceField(label="Filtre affichage", required=False, widget=forms.CheckboxSelectMultiple,
choices=CHOICES2)
date_deb = forms.DateField(required=False, label="Date de début", help_text='DD/MM/YYYY',
input_formats=['%d/%m/%Y'])
date_fin = forms.DateField(required=False, help_text='DD/MM/YYYY', input_formats=['%d/%m/%Y'], label="Date de fin")

View File

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

@ -1,24 +1,6 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf.urls import url

View File

@ -1,60 +1,37 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# App de recherche pour re2o
# Augustin lemesle, Gabriel Détraz, Goulven Kermarec
# Gplv2
from django.shortcuts import render
from django.shortcuts import get_object_or_404
from django.template.context_processors import csrf
from django.template import Context, RequestContext, loader
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from users.models import User
from search.forms import SearchForm, SearchFormPlus
from django.shortcuts import render
from django.template.context_processors import csrf
from med.settings import SEARCH_DISPLAY_PAGE
from media.models import Media, Jeu, Emprunt
from search.forms import SearchForm, SearchFormPlus
from users.models import User
def form(ctx, template, request):
c = ctx
c.update(csrf(request))
return render(request, template, c)
def search_result(search, type, request):
date_deb = None
date_fin = None
states=[]
aff=[]
if(type):
states = []
aff = []
if (type):
aff = search.cleaned_data['affichage']
states = search.cleaned_data['filtre']
date_deb = search.cleaned_data['date_deb']
date_fin = search.cleaned_data['date_fin']
date_query = Q()
if aff==[]:
aff = ['0','1','2','3']
if aff == []:
aff = ['0', '1', '2', '3']
if date_deb != None:
date_query = date_query & Q(date_emprunt__gte=date_deb)
if date_fin != None:
@ -62,32 +39,36 @@ def search_result(search, type, request):
search = search.cleaned_data['search_field']
query1 = Q()
for s in states:
query1 = query1 | Q(state = s)
connexion = []
recherche = {'users_list': None, 'emprunts_list' : None, 'medias_list' : None, 'jeux_list': None}
query1 = query1 | Q(state=s)
connexion = []
recherche = {'users_list': None, 'emprunts_list': None, 'medias_list': None, 'jeux_list': None}
if request.user.has_perms(('perm',)):
query = Q(user__pseudo__icontains = search) | Q(user__name__icontains = search) | Q(user__surname__icontains = search)
query = Q(user__pseudo__icontains=search) | Q(user__name__icontains=search) | Q(user__surname__icontains=search)
else:
query = (Q(user__pseudo__icontains = search) | Q(user__name__icontains = search) | Q(user__surname__icontains = search)) & Q(user = request.user)
query = (Q(user__pseudo__icontains=search) | Q(user__name__icontains=search) | Q(
user__surname__icontains=search)) & Q(user=request.user)
for i in aff:
if i == '0':
query_user_list = Q(pseudo__icontains = search) | Q(name__icontains = search) | Q(surname__icontains = search) & query1
query_user_list = Q(pseudo__icontains=search) | Q(name__icontains=search) | Q(
surname__icontains=search) & query1
if request.user.has_perms(('perm',)):
recherche['users_list'] = User.objects.filter(query_user_list).order_by('state', 'surname')
else :
recherche['users_list'] = User.objects.filter(query_user_list & Q(id=request.user.id)).order_by('state', 'surname')
else:
recherche['users_list'] = User.objects.filter(query_user_list & Q(id=request.user.id)).order_by('state',
'surname')
if i == '1':
recherche['emprunts_list'] = Emprunt.objects.filter(query & date_query).order_by('date_emprunt').reverse()
if i == '2':
recherche['medias_list'] = Media.objects.filter(Q(auteur__nom__icontains = search) | Q(titre__icontains = search))
recherche['medias_list'] = Media.objects.filter(
Q(auteur__nom__icontains=search) | Q(titre__icontains=search))
if i == '3':
recherche['jeux_list'] = Jeu.objects.filter(Q(nom__icontains = search) | Q(proprietaire__pseudo__icontains = search) | Q(proprietaire__name__icontains = search) | Q(proprietaire__surname__icontains = search))
recherche['jeux_list'] = Jeu.objects.filter(
Q(nom__icontains=search) | Q(proprietaire__pseudo__icontains=search) | Q(
proprietaire__name__icontains=search) | Q(proprietaire__surname__icontains=search))
for r in recherche:
if recherche[r] != None:
@ -97,17 +78,18 @@ def search_result(search, type, request):
return recherche
@login_required
def search(request):
search = SearchForm(request.POST or None)
if search.is_valid():
return form(search_result(search, False, request), 'search/index.html',request)
return form({'searchform' : search}, 'search/search.html', request)
return form(search_result(search, False, request), 'search/index.html', request)
return form({'searchform': search}, 'search/search.html', request)
@login_required
def searchp(request):
search = SearchFormPlus(request.POST or None)
if search.is_valid():
return form(search_result(search, True, request), 'search/index.html',request)
return form({'searchform' : search}, 'search/search.html', request)
return form(search_result(search, True, request), 'search/index.html', request)
return form({'searchform': search}, 'search/search.html', request)

View File

@ -1,32 +1,14 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group
from reversion.admin import VersionAdmin
from .models import User, Right, Adhesion, ListRight, Clef, Request
from .forms import UserChangeForm, UserCreationForm
from .models import User, Right, Adhesion, ListRight, Clef, Request
class UserAdmin(admin.ModelAdmin):
@ -37,23 +19,29 @@ class UserAdmin(admin.ModelAdmin):
'email',
'state'
)
search_fields = ('name','surname','pseudo')
search_fields = ('name', 'surname', 'pseudo')
class RequestAdmin(admin.ModelAdmin):
list_display = ('user', 'type', 'created_at', 'expires_at')
class RightAdmin(VersionAdmin):
list_display = ('user', 'right')
class ClefAdmin(VersionAdmin):
list_display = ('proprio', 'nom')
class AdhesionAdmin(VersionAdmin):
list_display = ('annee_debut', 'annee_fin')
class ListRightAdmin(VersionAdmin):
list_display = ('listright',)
class UserAdmin(VersionAdmin, BaseUserAdmin):
# The forms to add and change user instances
form = UserChangeForm
@ -67,7 +55,7 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
fieldsets = (
(None, {'fields': ('pseudo', 'password')}),
('Personal info', {'fields': ('name', 'surname', 'email')}),
('Permissions', {'fields': ('is_admin', )}),
('Permissions', {'fields': ('is_admin',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
@ -75,12 +63,13 @@ class UserAdmin(VersionAdmin, BaseUserAdmin):
(None, {
'classes': ('wide',),
'fields': ('pseudo', 'name', 'surname', 'email', 'is_admin', 'password1', 'password2')}
),
),
)
search_fields = ('pseudo',)
ordering = ('pseudo',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
admin.site.register(Request, RequestAdmin)
admin.site.register(ListRight, ListRightAdmin)

View File

@ -1,46 +1,29 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# App de gestion des users pour med
# Goulven Kermarec, Gabriel Détraz, Lemesle Augustin
# Gplv2
from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect
from med.settings import AUTHORIZED_IP_RANGE, AUTHORIZED_IP6_RANGE
import ipaddress
from django.shortcuts import redirect
from med.settings import AUTHORIZED_IP_RANGE, AUTHORIZED_IP6_RANGE
def user_is_in_campus(function):
def wrap(request, *args, **kwargs):
if not request.user.is_authenticated:
remote_ip = get_ip(request)
if not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(AUTHORIZED_IP_RANGE) and not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(AUTHORIZED_IP6_RANGE):
if not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(
AUTHORIZED_IP_RANGE) and not ipaddress.ip_address(remote_ip) in ipaddress.ip_network(
AUTHORIZED_IP6_RANGE):
return redirect("/")
return function(request, *args, **kwargs)
wrap.__doc__ = function.__doc__
wrap.__name__ = function.__name__
return wrap
def get_ip(request):
"""Returns the IP of the request, accounting for the possibility of being
behind a proxy.

View File

@ -1,46 +1,29 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- coding: utf-8 -*-
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django import forms
from django.forms import ModelForm, Form
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.validators import MinLengthValidator
from django.utils import timezone
from django.forms import ModelForm, Form
from .models import Adhesion, Clef, ListRight, Right, User
from .models import Adhesion, Clef, ListRight, Right, Request, User
class PassForm(forms.Form):
passwd1 = forms.CharField(label=u'Nouveau mot de passe', max_length=255, validators=[MinLengthValidator(8)], widget=forms.PasswordInput)
passwd2 = forms.CharField(label=u'Saisir à nouveau le mot de passe', max_length=255, validators=[MinLengthValidator(8)], widget=forms.PasswordInput)
passwd1 = forms.CharField(label=u'Nouveau mot de passe', max_length=255, validators=[MinLengthValidator(8)],
widget=forms.PasswordInput)
passwd2 = forms.CharField(label=u'Saisir à nouveau le mot de passe', max_length=255,
validators=[MinLengthValidator(8)], widget=forms.PasswordInput)
class UserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput, validators=[MinLengthValidator(8)], max_length=255)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput, validators=[MinLengthValidator(8)], max_length=255)
password1 = forms.CharField(label='Password', widget=forms.PasswordInput, validators=[MinLengthValidator(8)],
max_length=255)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput,
validators=[MinLengthValidator(8)], max_length=255)
is_admin = forms.BooleanField(label='is admin')
class Meta:
@ -95,16 +78,18 @@ class UserChangeForm(forms.ModelForm):
user.save()
return user
class ResetPasswordForm(forms.Form):
pseudo = forms.CharField(label=u'Pseudo', max_length=255)
email = forms.EmailField(max_length=255)
class BaseInfoForm(ModelForm):
def __init__(self, *args, **kwargs):
super(BaseInfoForm, self).__init__(*args, **kwargs)
self.fields['name'].label = 'Prénom'
self.fields['surname'].label = 'Nom'
#self.fields['comment'].label = 'Commentaire'
# self.fields['comment'].label = 'Commentaire'
class Meta:
model = User
@ -117,9 +102,10 @@ class BaseInfoForm(ModelForm):
'adresse',
]
class InfoForm(BaseInfoForm):
class Meta(BaseInfoForm.Meta):
fields = [
fields = [
'name',
'pseudo',
'surname',
@ -135,22 +121,26 @@ class PasswordForm(ModelForm):
model = User
fields = ['password']
class StateForm(ModelForm):
class Meta:
model = User
fields = ['state']
class ClefForm(ModelForm):
class Meta:
model = Clef
fields = '__all__'
class BaseClefForm(ClefForm):
class Meta(ClefForm.Meta):
fields = [
fields = [
'commentaire',
]
class AdhesionForm(ModelForm):
adherent = forms.ModelMultipleChoiceField(User.objects.all(), widget=forms.CheckboxSelectMultiple, required=False)
@ -158,6 +148,7 @@ class AdhesionForm(ModelForm):
model = Adhesion
fields = '__all__'
class RightForm(ModelForm):
def __init__(self, *args, **kwargs):
super(RightForm, self).__init__(*args, **kwargs)
@ -170,12 +161,13 @@ class RightForm(ModelForm):
class DelRightForm(Form):
rights = forms.ModelMultipleChoiceField(queryset=Right.objects.all(), widget=forms.CheckboxSelectMultiple)
rights = forms.ModelMultipleChoiceField(queryset=Right.objects.all(), widget=forms.CheckboxSelectMultiple)
def __init__(self, right, *args, **kwargs):
super(DelRightForm, self).__init__(*args, **kwargs)
self.fields['rights'].queryset = Right.objects.filter(right=right)
class ListRightForm(ModelForm):
class Meta:
model = ListRight
@ -185,11 +177,12 @@ class ListRightForm(ModelForm):
super(ListRightForm, self).__init__(*args, **kwargs)
self.fields['listright'].label = 'Nom du droit/groupe'
class NewListRightForm(ListRightForm):
class Meta(ListRightForm.Meta):
fields = '__all__'
class DelListRightForm(Form):
listrights = forms.ModelMultipleChoiceField(queryset=ListRight.objects.all(), label="Droits actuels", widget=forms.CheckboxSelectMultiple)
listrights = forms.ModelMultipleChoiceField(queryset=ListRight.objects.all(), label="Droits actuels",
widget=forms.CheckboxSelectMultiple)

View File

@ -0,0 +1,22 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-02 14:42+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: models.py:195
msgid "right"
msgstr ""
#: models.py:196
msgid "rights"
msgstr ""

View File

@ -1,39 +1,16 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import datetime
import uuid
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models
from django.db.models import Q
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.utils.functional import cached_property
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from med.settings import MAX_EMPRUNT, REQ_EXPIRE_HRS
import re, uuid
import datetime
from django.utils import timezone
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
import subprocess
class UserManager(BaseUserManager):
@ -75,23 +52,23 @@ class User(AbstractBaseUser):
STATE_DISABLED = 1
STATE_ARCHIVE = 2
STATES = (
(0, 'STATE_ACTIVE'),
(1, 'STATE_DISABLED'),
(2, 'STATE_ARCHIVE'),
)
(0, 'STATE_ACTIVE'),
(1, 'STATE_DISABLED'),
(2, 'STATE_ARCHIVE'),
)
name = models.CharField(max_length=255)
surname = models.CharField(max_length=255)
email = models.EmailField()
telephone = models.CharField(max_length=15, null=True, blank=True)
adresse = models.CharField(max_length=255, null=True, blank=True)
maxemprunt = models.IntegerField(default=MAX_EMPRUNT, help_text="Maximum d'emprunts autorisés")
maxemprunt = models.IntegerField(default=MAX_EMPRUNT, help_text="Maximum d'emprunts autorisés")
state = models.IntegerField(choices=STATES, default=STATE_ACTIVE)
pseudo = models.CharField(max_length=32, unique=True, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets. ")
pseudo = models.CharField(max_length=32, unique=True,
help_text="Doit contenir uniquement des lettres, chiffres, ou tirets. ")
comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True)
registered = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'pseudo'
REQUIRED_FIELDS = ['name', 'surname', 'email']
@ -150,16 +127,16 @@ class User(AbstractBaseUser):
def get_admin_right(self):
admin, created = ListRight.objects.get_or_create(listright="admin")
return admin
return admin
def make_admin(self):
""" Make User admin """
user_admin_right = Right(user=self, right=self.get_admin_right())
user_admin_right.save()
def un_admin(self):
try:
user_right = Right.objects.get(user=self,right=self.get_admin_right())
user_right = Right.objects.get(user=self, right=self.get_admin_right())
except Right.DoesNotExist:
return
user_right.delete()
@ -184,40 +161,44 @@ class Request(models.Model):
def save(self):
if not self.expires_at:
self.expires_at = timezone.now() \
+ datetime.timedelta(hours=REQ_EXPIRE_HRS)
+ datetime.timedelta(hours=REQ_EXPIRE_HRS)
if not self.token:
self.token = str(uuid.uuid4()).replace('-', '') # remove hyphens
super(Request, self).save()
class Right(models.Model):
PRETTY_NAME = "Droits affectés à des users"
user = models.ForeignKey('User', on_delete=models.PROTECT)
right = models.ForeignKey('ListRight', on_delete=models.PROTECT)
class Meta:
verbose_name = _("right")
verbose_name_plural = _("rights")
unique_together = ("user", "right")
def __str__(self):
return str(self.user)
class ListRight(models.Model):
PRETTY_NAME = "Liste des droits existants"
listright = models.CharField(max_length=255, unique=True)
details = models.CharField(help_text="Description", max_length=255, blank=True)
def __str__(self):
return self.listright
class Clef(models.Model):
nom = models.CharField(max_length=255, unique=True)
proprio = models.ForeignKey('User', on_delete=models.PROTECT, blank=True, null=True)
commentaire = models.CharField(max_length=255, null=True, blank=True)
class Adhesion(models.Model):
annee_debut = models.IntegerField(unique=True)
annee_fin = models.IntegerField(unique=True)
adherent = models.ManyToManyField('User', blank=True)

View File

@ -1,25 +0,0 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from django.test import TestCase
# Create your tests here.

View File

@ -1,24 +1,6 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
from django.conf.urls import url
@ -56,5 +38,3 @@ urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^index_ajour/$', views.index_ajour, name='index-ajour'),
]

View File

@ -1,52 +1,29 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
# -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2017-2019 by BDE ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
# App de gestion des users pour med
# Goulven Kermarec, Gabriel Détraz, Lemesle Augustin
# Gplv2
from django.shortcuts import get_object_or_404, render, redirect
from django.template.context_processors import csrf
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.template import Context, RequestContext, loader
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.signals import user_logged_in
from django.db.models import Max, ProtectedError
from django.db import IntegrityError
from django.core.mail import send_mail
from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.db import transaction
from reversion.models import Version
from django.db.models import ProtectedError
from django.shortcuts import get_object_or_404, render, redirect
from django.template import loader
from django.template.context_processors import csrf
from django.utils import timezone
from reversion import revisions as reversion
from users.forms import DelListRightForm, NewListRightForm, ListRightForm, RightForm, DelRightForm
from users.forms import InfoForm, BaseInfoForm, StateForm, ClefForm, BaseClefForm, AdhesionForm
from users.models import User, Request, ListRight, Right, Clef, Adhesion
from users.forms import PassForm, ResetPasswordForm
from users.decorators import user_is_in_campus
from media.models import Emprunt
from reversion.models import Version
from med.settings import REQ_EXPIRE_STR, EMAIL_FROM, ASSO_NAME, ASSO_EMAIL, SITE_NAME, PAGINATION_NUMBER
from media.models import Emprunt
from users.decorators import user_is_in_campus
from users.forms import DelListRightForm, NewListRightForm, ListRightForm, RightForm, DelRightForm
from users.forms import InfoForm, BaseInfoForm, StateForm, ClefForm, AdhesionForm
from users.forms import PassForm, ResetPasswordForm
from users.models import User, Request, ListRight, Right, Clef, Adhesion
def form(ctx, template, request):
@ -54,6 +31,7 @@ def form(ctx, template, request):
c.update(csrf(request))
return render(request, template, c)
def password_change_action(u_form, user, request, req=False):
""" Fonction qui effectue le changeemnt de mdp bdd"""
if u_form.cleaned_data['passwd1'] != u_form.cleaned_data['passwd2']:
@ -69,20 +47,21 @@ def password_change_action(u_form, user, request, req=False):
return redirect("/")
return redirect("/users/profil/" + str(user.id))
def reset_passwd_mail(req, request):
""" Prend en argument un request, envoie un mail de réinitialisation de mot de pass """
t = loader.get_template('users/email_passwd_request')
c = {
'name': str(req.user.name) + ' ' + str(req.user.surname),
'asso': ASSO_NAME,
'asso_mail': ASSO_EMAIL,
'site_name': SITE_NAME,
'url': request.build_absolute_uri(
reverse('users:process', kwargs={'token': req.token})),
'expire_in': REQ_EXPIRE_STR,
'name': str(req.user.name) + ' ' + str(req.user.surname),
'asso': ASSO_NAME,
'asso_mail': ASSO_EMAIL,
'site_name': SITE_NAME,
'url': request.build_absolute_uri(
reverse('users:process', kwargs={'token': req.token})),
'expire_in': REQ_EXPIRE_STR,
}
send_mail('Votre compte %s' % SITE_NAME, t.render(c),
EMAIL_FROM, [req.user.email], fail_silently=False)
EMAIL_FROM, [req.user.email], fail_silently=False)
return
@ -101,10 +80,12 @@ def new_user(request):
req.user = user
req.save()
reset_passwd_mail(req, request)
messages.success(request, "L'utilisateur %s a été crée, un mail pour l'initialisation du mot de passe a été envoyé" % user.pseudo)
messages.success(request,
"L'utilisateur %s a été crée, un mail pour l'initialisation du mot de passe a été envoyé" % user.pseudo)
return redirect("/users/profil/" + str(user.id))
return form({'userform': user}, 'users/user.html', request)
@login_required
def edit_info(request, userid):
""" Edite un utilisateur à partir de son id, si l'id est différent de request.user, vérifie la possession du droit admin """
@ -129,6 +110,7 @@ def edit_info(request, userid):
return redirect("/users/profil/" + userid)
return form({'userform': user}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def state(request, userid):
@ -148,6 +130,7 @@ def state(request, userid):
return redirect("/users/profil/" + userid)
return form({'userform': state}, 'users/user.html', request)
@login_required
def password(request, userid):
""" Reinitialisation d'un mot de passe à partir de l'userid,
@ -166,6 +149,7 @@ def password(request, userid):
return password_change_action(u_form, user, request)
return form({'userform': u_form}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def add_listright(request):
@ -181,6 +165,7 @@ def add_listright(request):
return redirect("/users/index_listright/")
return form({'userform': listright}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def edit_listright(request, listrightid):
@ -188,7 +173,7 @@ def edit_listright(request, listrightid):
try:
listright_instance = ListRight.objects.get(pk=listrightid)
except ListRight.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/users/")
listright = ListRightForm(request.POST or None, instance=listright_instance)
if listright.is_valid():
@ -200,6 +185,7 @@ def edit_listright(request, listrightid):
return redirect("/users/index_listright/")
return form({'userform': listright}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def del_listright(request):
@ -221,6 +207,7 @@ def del_listright(request):
return redirect("/users/index_listright/")
return form({'userform': listright}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def add_right(request, userid):
@ -245,30 +232,34 @@ def add_right(request, userid):
return redirect("/users/profil/" + userid)
return form({'userform': right}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def del_right(request):
""" Supprimer un droit à un user, need droit bureau """
user_right_list = dict()
for right in ListRight.objects.all():
user_right_list[right]= DelRightForm(right, request.POST or None)
user_right_list[right] = DelRightForm(right, request.POST or None)
for keys, right_item in user_right_list.items():
if right_item.is_valid():
right_del = right_item.cleaned_data['rights']
with transaction.atomic(), reversion.create_revision():
reversion.set_user(request.user)
reversion.set_comment("Retrait des droit %s" % ','.join(str(deleted_right) for deleted_right in right_del))
reversion.set_comment(
"Retrait des droit %s" % ','.join(str(deleted_right) for deleted_right in right_del))
right_del.delete()
messages.success(request, "Droit retiré avec succès")
return redirect("/users/")
return form({'userform': user_right_list}, 'users/del_right.html', request)
@login_required
@permission_required('perm')
def index_listright(request):
""" Affiche l'ensemble des droits , need droit perm """
listright_list = ListRight.objects.order_by('listright')
return render(request, 'users/index_listright.html', {'listright_list':listright_list})
return render(request, 'users/index_listright.html', {'listright_list': listright_list})
@login_required
@permission_required('bureau')
@ -283,12 +274,13 @@ def add_clef(request):
return redirect("/users/index_clef/")
return form({'userform': clef}, 'users/user.html', request)
@user_is_in_campus
def edit_clef(request, clefid):
try:
clef_instance = Clef.objects.get(pk=clefid)
except Clef.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/users/index_clef/")
clef = ClefForm(request.POST or None, instance=clef_instance)
if clef.is_valid():
@ -301,13 +293,14 @@ def edit_clef(request, clefid):
return redirect("/users/index_clef/")
return form({'userform': clef}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def del_clef(request, clefid):
try:
clef_instance = Clef.objects.get(pk=clefid)
except Clef.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/users/index_clef/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -317,10 +310,12 @@ def del_clef(request, clefid):
return redirect("/users/index_clef")
return form({'objet': clef_instance, 'objet_name': 'clef'}, 'users/delete.html', request)
@user_is_in_campus
def index_clef(request):
clef_list = Clef.objects.all().order_by('nom')
return render(request, 'users/index_clef.html', {'clef_list':clef_list})
return render(request, 'users/index_clef.html', {'clef_list': clef_list})
@login_required
@permission_required('bureau')
@ -335,13 +330,14 @@ def add_adhesion(request):
return redirect("/users/index_adhesion/")
return form({'userform': adhesion}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def edit_adhesion(request, adhesionid):
try:
adhesion_instance = Adhesion.objects.get(pk=adhesionid)
except Adhesion.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/users/index_adhesion/")
adhesion = AdhesionForm(request.POST or None, instance=adhesion_instance)
if adhesion.is_valid():
@ -353,13 +349,14 @@ def edit_adhesion(request, adhesionid):
return redirect("/users/index_adhesion/")
return form({'userform': adhesion}, 'users/user.html', request)
@login_required
@permission_required('bureau')
def del_adhesion(request, adhesionid):
try:
adhesion_instance = Adhesion.objects.get(pk=adhesionid)
except Adhesion.DoesNotExist:
messages.error(request, u"Entrée inexistante" )
messages.error(request, u"Entrée inexistante")
return redirect("/users/index_adhesion/")
if request.method == "POST":
with transaction.atomic(), reversion.create_revision():
@ -369,10 +366,12 @@ def del_adhesion(request, adhesionid):
return redirect("/users/index_adhesion")
return form({'objet': adhesion_instance, 'objet_name': 'adhesion'}, 'users/delete.html', request)
@login_required
def index_adhesion(request):
adhesion_list = Adhesion.objects.all()
return render(request, 'users/index_adhesion.html', {'adhesion_list':adhesion_list})
return render(request, 'users/index_adhesion.html', {'adhesion_list': adhesion_list})
@login_required
@permission_required('perm')
@ -391,6 +390,7 @@ def index(request):
users_list = paginator.page(paginator.num_pages)
return render(request, 'users/index.html', {'users_list': users_list})
@login_required
@permission_required('perm')
def index_ajour(request):
@ -408,46 +408,48 @@ def index_ajour(request):
users_list = paginator.page(paginator.num_pages)
return render(request, 'users/index.html', {'users_list': users_list})
@user_is_in_campus
def history(request, object, id):
""" Affichage de l'historique : (acl, argument)
user : self, userid"""
if object == 'clef':
try:
object_instance = Clef.objects.get(pk=id)
object_instance = Clef.objects.get(pk=id)
except Clef.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
elif not request.user.is_authenticated:
messages.error(request, "Permission denied")
return redirect("/users/")
if object == 'user':
try:
object_instance = User.objects.get(pk=id)
object_instance = User.objects.get(pk=id)
except User.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
if not request.user.has_perms(('perm',)) and object_instance != request.user:
messages.error(request, "Vous ne pouvez pas afficher l'historique d'un autre user que vous sans droit admin")
return redirect("/users/profil/" + str(request.user.id))
messages.error(request,
"Vous ne pouvez pas afficher l'historique d'un autre user que vous sans droit admin")
return redirect("/users/profil/" + str(request.user.id))
elif object == 'clef':
try:
object_instance = Clef.objects.get(pk=id)
object_instance = Clef.objects.get(pk=id)
except Clef.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
elif object == 'adhesion':
try:
object_instance = Adhesion.objects.get(pk=id)
object_instance = Adhesion.objects.get(pk=id)
except Adhesion.DoesNotExist:
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
messages.error(request, "Utilisateur inexistant")
return redirect("/users/")
elif object == 'listright':
try:
object_instance = ListRight.objects.get(pk=id)
object_instance = ListRight.objects.get(pk=id)
except ListRight.DoesNotExist:
messages.error(request, "Droit inexistant")
return redirect("/users/")
messages.error(request, "Droit inexistant")
return redirect("/users/")
else:
messages.error(request, "Objet inconnu")
return redirect("/users/")
@ -464,10 +466,12 @@ def history(request, object, id):
reversions = paginator.page(paginator.num_pages)
return render(request, 'med/history.html', {'reversions': reversions, 'object': object_instance})
@login_required
def mon_profil(request):
return redirect("/users/profil/" + str(request.user.id))
@login_required
def profil(request, userid):
try:
@ -486,10 +490,11 @@ def profil(request, userid):
{
'user': users,
'emprunts_list': emprunts_list,
'list_droits': list_droits,
'list_droits': list_droits,
}
)
@login_required
@permission_required('bureau')
def adherer(request, userid):
@ -506,13 +511,13 @@ def adherer(request, userid):
reversion.set_comment("Adhesion de %s" % users)
messages.success(request, "Adhesion effectuee")
return redirect("/users/profil/" + userid)
def reset_password(request):
userform = ResetPasswordForm(request.POST or None)
if userform.is_valid():
try:
user = User.objects.get(pseudo=userform.cleaned_data['pseudo'],email=userform.cleaned_data['email'])
user = User.objects.get(pseudo=userform.cleaned_data['pseudo'], email=userform.cleaned_data['email'])
except User.DoesNotExist:
messages.error(request, "Cet utilisateur n'existe pas")
return form({'userform': userform}, 'users/user.html', request)
@ -525,6 +530,7 @@ def reset_password(request):
redirect("/")
return form({'userform': userform}, 'users/user.html', request)
def process(request, token):
valid_reqs = Request.objects.filter(expires_at__gt=timezone.now())
req = get_object_or_404(valid_reqs, token=token)
@ -537,6 +543,7 @@ def process(request, token):
messages.error(request, "Entrée incorrecte, contactez un admin")
redirect("/")
def process_passwd(request, req):
u_form = PassForm(request.POST or None)
user = req.user