Ce serveur Gitlab sera éteint le 30 juin 2020, pensez à migrer vos projets vers les serveurs gitlab-research.centralesupelec.fr et gitlab-student.centralesupelec.fr !

...
 
Commits (7)
# Re2o # Re2o
Gnu public license v2.0 GNU public license v2.0
## Avant propos ## Avant propos
Re2o est un logiciel d'administration développé initiallement au rezometz. Il Re2o est un logiciel d'administration développé initialement au rezometz. Il
se veut agnostique au réseau considéré, de manière à être installable en se veut agnostique au réseau considéré, de manière à être installable en
quelques clics. quelques clics.
...@@ -31,15 +31,15 @@ Pour cela : ...@@ -31,15 +31,15 @@ Pour cela :
## Fonctionnement général ## Fonctionnement général
Re2o est séparé entre les models, qui sont visible sur le schéma des Re2o est séparé entre les models, qui sont visibles sur le schéma des
dépendances. Il s'agit en réalité des tables sql, et les fields etant les dépendances. Il s'agit en réalité des tables sql, et les fields étant les
colonnes. colonnes.
Ceci dit il n'est jamais nécessaire de toucher directement au sql, django Ceci dit il n'est jamais nécessaire de toucher directement au sql, django
procédant automatiquement à tout cela. procédant automatiquement à tout cela.
On crée donc différents models (user, right pour les droits des users, On crée donc différents models (user, right pour les droits des users,
interfaces, IpList pour l'ensemble des adresses ip, etc) interfaces, IpList pour l'ensemble des adresses ip, etc)
Du coté des forms, il s'agit des formulaire d'édition des models. Il Du coté des forms, il s'agit des formulaires d'édition des models. Il
s'agit de ModelForms django, qui héritent des models très simplement, voir la s'agit de ModelForms django, qui héritent des models très simplement, voir la
documentation django models forms. documentation django models forms.
...@@ -56,12 +56,20 @@ d'accéder à ces vues, utilisé par re2o-tools. ...@@ -56,12 +56,20 @@ d'accéder à ces vues, utilisé par re2o-tools.
# Requète en base de donnée # Requète en base de donnée
Pour avoir un shell, il suffit de lancer '''python3 manage.py shell''' Pour avoir un shell, lancer :
Pour charger des objets, example avec User, faire : ```.bash
''' from users.models import User''' python3 manage.py shell
Pour charger les objets django, il suffit de faire User.objects.all() ```
pour tous les users par exemple.
Il est ensuite aisé de faire des requètes, par exemple Pour charger des objets (exemple avec User), faire :
User.objects.filter(pseudo='test') ```.python
Des exemples et la documentation complète sur les requètes django sont from users.models import User
```
Pour charger les objets django, il suffit de faire `User.objects.all()`
pour tous les users par exemple.
Il est ensuite aisé de faire des requêtes, par exemple
`User.objects.filter(pseudo='test')`
Des exemples et la documentation complète sur les requêtes django sont
disponible sur le site officiel. disponible sur le site officiel.
...@@ -148,7 +148,7 @@ def new_facture(request, user, userid): ...@@ -148,7 +148,7 @@ def new_facture(request, user, userid):
p.facture = new_invoice_instance p.facture = new_invoice_instance
p.save() p.save()
send_mail_invoice(new_invoice_instance) #send_mail_invoice(new_invoice_instance)
return new_invoice_instance.paiement.end_payment( return new_invoice_instance.paiement.end_payment(
new_invoice_instance, new_invoice_instance,
......
...@@ -34,7 +34,11 @@ from .models import ( ...@@ -34,7 +34,11 @@ from .models import (
OptionalTopologie, OptionalTopologie,
GeneralOption, GeneralOption,
Service, Service,
<<<<<<< HEAD
MailContact, MailContact,
=======
>>>>>>> 5a88882... Ajoute le réglage reminder et factorise la liste des services
Reminder,
AssoOption, AssoOption,
MailMessageOption, MailMessageOption,
HomeOption HomeOption
...@@ -85,6 +89,9 @@ class HomeOptionAdmin(VersionAdmin): ...@@ -85,6 +89,9 @@ class HomeOptionAdmin(VersionAdmin):
"""Class admin options home""" """Class admin options home"""
pass pass
class ReminderAdmin(VersionAdmin):
"""Class reminder"""
pass
admin.site.register(OptionalUser, OptionalUserAdmin) admin.site.register(OptionalUser, OptionalUserAdmin)
admin.site.register(OptionalMachine, OptionalMachineAdmin) admin.site.register(OptionalMachine, OptionalMachineAdmin)
...@@ -93,5 +100,6 @@ admin.site.register(GeneralOption, GeneralOptionAdmin) ...@@ -93,5 +100,6 @@ admin.site.register(GeneralOption, GeneralOptionAdmin)
admin.site.register(HomeOption, HomeOptionAdmin) admin.site.register(HomeOption, HomeOptionAdmin)
admin.site.register(Service, ServiceAdmin) admin.site.register(Service, ServiceAdmin)
admin.site.register(MailContact, MailContactAdmin) admin.site.register(MailContact, MailContactAdmin)
admin.site.register(Reminder, ReminderAdmin)
admin.site.register(AssoOption, AssoOptionAdmin) admin.site.register(AssoOption, AssoOptionAdmin)
admin.site.register(MailMessageOption, MailMessageOptionAdmin) admin.site.register(MailMessageOption, MailMessageOptionAdmin)
...@@ -24,6 +24,7 @@ Formulaire d'edition des réglages : user, machine, topologie, asso... ...@@ -24,6 +24,7 @@ Formulaire d'edition des réglages : user, machine, topologie, asso...
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from re2o.mixins import FormRevMixin
from django.forms import ModelForm, Form from django.forms import ModelForm, Form
from django import forms from django import forms
...@@ -39,6 +40,7 @@ from .models import ( ...@@ -39,6 +40,7 @@ from .models import (
HomeOption, HomeOption,
Service, Service,
MailContact MailContact
Reminder
) )
...@@ -211,7 +213,7 @@ class EditHomeOptionForm(ModelForm): ...@@ -211,7 +213,7 @@ class EditHomeOptionForm(ModelForm):
self.fields['twitter_account_name'].label = _("Twitter account name") self.fields['twitter_account_name'].label = _("Twitter account name")
class ServiceForm(ModelForm): class ServiceForm(FormRevMixin, ModelForm):
"""Edition, ajout de services sur la page d'accueil""" """Edition, ajout de services sur la page d'accueil"""
class Meta: class Meta:
model = Service model = Service
...@@ -226,6 +228,7 @@ class ServiceForm(ModelForm): ...@@ -226,6 +228,7 @@ class ServiceForm(ModelForm):
self.fields['image'].label = _("Image") self.fields['image'].label = _("Image")
class DelServiceForm(Form): class DelServiceForm(Form):
"""Suppression de services sur la page d'accueil""" """Suppression de services sur la page d'accueil"""
services = forms.ModelMultipleChoiceField( services = forms.ModelMultipleChoiceField(
...@@ -269,3 +272,24 @@ class DelMailContactForm(Form): ...@@ -269,3 +272,24 @@ class DelMailContactForm(Form):
else: else:
self.fields['mailcontacts'].queryset = MailContact.objects.all() self.fields['mailcontacts'].queryset = MailContact.objects.all()
class ReminderForm(FormRevMixin, ModelForm):
"""Edition, ajout de rappel"""
class Meta:
model = Reminder
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(ReminderForm, self).__init__(*args, prefix=prefix, **kwargs)
class ReminderForm(FormRevMixin, ModelForm):
"""Edition, ajout de rappel"""
class Meta:
model = Reminder
fields = '__all__'
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(ReminderForm, self).__init__(*args, prefix=prefix, **kwargs)
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-05-05 10:53
from __future__ import unicode_literals
from django.db import migrations, models
import re2o.mixins
class Migration(migrations.Migration):
dependencies = [
('preferences', '0034_auto_20180416_1120'),
]
operations = [
migrations.CreateModel(
name='Reminder',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('days', models.IntegerField(default=7, help_text="Délais entre le mail et la fin d'adhésion", unique=True)),
('message', models.CharField(blank=True, default='', max_length=255, null=True)),
],
options={
'permissions': (('view_reminder', 'Peut voir un objet reminder'),),
},
bases=(re2o.mixins.AclMixin, models.Model),
),
]
...@@ -215,6 +215,32 @@ def optionaltopologie_post_save(**kwargs): ...@@ -215,6 +215,32 @@ def optionaltopologie_post_save(**kwargs):
topologie_pref.set_in_cache() topologie_pref.set_in_cache()
class Reminder(AclMixin, models.Model):
"""Options pour les mails de notification de fin d'adhésion.
Days: liste des nombres de jours pour lesquells un mail est envoyé
optionalMessage: message additionel pour le mail
"""
PRETTY_NAME="Options pour le mail de fin d'adhésion"
days = models.IntegerField(
default=7,
unique=True,
help_text="Délais entre le mail et la fin d'adhésion"
)
message = models.CharField(
max_length=255,
default="",
null=True,
blank=True,
help_text="Message affiché spécifiquement pour ce rappel"
)
class Meta:
permissions = (
("view_reminder", "Peut voir un objet reminder"),
)
class GeneralOption(AclMixin, PreferencesModel): class GeneralOption(AclMixin, PreferencesModel):
"""Options générales : nombre de resultats par page, nom du site, """Options générales : nombre de resultats par page, nom du site,
temps où les liens sont valides""" temps où les liens sont valides"""
......
{% comment %}
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.
{% endcomment %}
{% load acl %}
<table class="table table-striped">
<thead>
<tr>
<th>Nombre de jours avant le rappel</th>
<th>Message custom pour ce rappel</th>
<th></th>
<th></th>
</tr>
</thead>
{% for reminder in reminder_list %}
<tr>
<td>{{ reminder.days }}</td>
<td>{{ reminder.message }}</td>
<td class="text-right">
{% can_edit reminder %}
{% include 'buttons/edit.html' with href='preferences:edit-reminder' id=reminder.id %}
{% acl_end %}
{% include 'buttons/history.html' with href='preferences:history' name='reminder' id=reminder.id %}
</td>
</tr>
{% endfor %}
</table>
...@@ -224,8 +224,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -224,8 +224,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
{% acl_end %} {% acl_end %}
<a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-mailcontact' %}"><i class="fa fa-trash"></i>{% trans "Delete one or several addresses" %}</a> <a class="btn btn-danger btn-sm" role="button" href="{% url 'preferences:del-mailcontact' %}"><i class="fa fa-trash"></i>{% trans "Delete one or several addresses" %}</a>
{% include "preferences/aff_mailcontact.html" with mailcontact_list=mailcontact_list %} {% include "preferences/aff_mailcontact.html" with mailcontact_list=mailcontact_list %}
<p>
</p>
<table class="table table-striped"> <table class="table table-striped">
<tr> <tr>
<th>{% trans "Twitter account URL" %}</th> <th>{% trans "Twitter account URL" %}</th>
...@@ -238,5 +237,36 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -238,5 +237,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<td>{{ homeoptions.facebook_url }}</td> <td>{{ homeoptions.facebook_url }}</td>
</tr> </tr>
</table> </table>
<table class="table table-striped">
{% for line in assooptions %}
<tr>
{% for text, field in line %}
<th>{{ field }}</th>
<td>{{ text }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<table class="table table-striped">
{% for line in assooptions %}
<tr>
{% for text, field in line %}
<th>{{ field }}</th>
<td>{{ text }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<h2>Options pour le mail de fin d'adhésion</h2>
{% can_create preferences.Reminder%}
<a class="btn btn-primary btn-sm" role="button" href="{% url 'preferences:add-reminder' %}"><i class="fa fa-plus"></i> Ajouter un rappel</a>
{% acl_end %}
{% include "preferences/aff_reminder.html" with reminder_list=reminder_list %}
<br />
<br />
<br />
{% endblock %} {% endblock %}
...@@ -74,6 +74,20 @@ urlpatterns = [ ...@@ -74,6 +74,20 @@ urlpatterns = [
), ),
url(r'^del_service/$', views.del_service, name='del-service'), url(r'^del_service/$', views.del_service, name='del-service'),
url(r'^add_mailcontact/$', views.add_mailcontact, name='add-mailcontact'), url(r'^add_mailcontact/$', views.add_mailcontact, name='add-mailcontact'),
url(r'^add_reminder/$', views.add_reminder, name='add-reminder'),
url(r'^add_reminder/$', views.add_reminder, name='add-reminder'),
url(
r'^edit_reminder/(?P<reminderid>[0-9]+)$',
views.edit_reminder,
name='edit-reminder'
),
url(r'^del_reminder/$', views.del_reminder, name='del-reminder'),
url(
r'^edit_reminder/(?P<reminderid>[0-9]+)$',
views.edit_reminder,
name='edit-reminder'
),
url(r'^del_reminder/$', views.del_reminder, name='del-reminder'),
url( url(
r'^edit_mailcontact/(?P<mailcontactid>[0-9]+)$', r'^edit_mailcontact/(?P<mailcontactid>[0-9]+)$',
views.edit_mailcontact, views.edit_mailcontact,
......
...@@ -41,11 +41,12 @@ from django.utils.translation import ugettext as _ ...@@ -41,11 +41,12 @@ from django.utils.translation import ugettext as _
from reversion import revisions as reversion from reversion import revisions as reversion
from re2o.views import form from re2o.views import form
from re2o.acl import can_create, can_edit, can_delete_set, can_view_all from re2o.acl import can_create, can_edit, can_delete, can_view_all
from .forms import ( from .forms import (
ServiceForm, DelServiceForm, MailContactForm, DelMailContactForm ServiceForm, DelServiceForm, MailContactForm, DelMailContactForm, ReminderForm, ReminderForm
) )
from .models import ( from .models import (
Service, Service,
MailContact, MailContact,
...@@ -133,11 +134,8 @@ def add_service(request): ...@@ -133,11 +134,8 @@ def add_service(request):
"""Ajout d'un service de la page d'accueil""" """Ajout d'un service de la page d'accueil"""
service = ServiceForm(request.POST or None, request.FILES or None) service = ServiceForm(request.POST or None, request.FILES or None)
if service.is_valid(): if service.is_valid():
with transaction.atomic(), reversion.create_revision(): service.save()
service.save() messages.success(request, "Ce service a été ajouté")
reversion.set_user(request.user)
reversion.set_comment("Creation")
messages.success(request, _("The service was added."))
return redirect(reverse('preferences:display-options')) return redirect(reverse('preferences:display-options'))
return form( return form(
{'preferenceform': service, 'action_name': _("Add a service")}, {'preferenceform': service, 'action_name': _("Add a service")},
...@@ -156,15 +154,8 @@ def edit_service(request, service_instance, **_kwargs): ...@@ -156,15 +154,8 @@ def edit_service(request, service_instance, **_kwargs):
instance=service_instance instance=service_instance
) )
if service.is_valid(): if service.is_valid():
with transaction.atomic(), reversion.create_revision(): service.save()
service.save() messages.success(request, "Service modifié")
reversion.set_user(request.user)
reversion.set_comment(
"Field(s) edited: %s" % ', '.join(
field for field in service.changed_data
)
)
messages.success(request, _("The service was edited."))
return redirect(reverse('preferences:display-options')) return redirect(reverse('preferences:display-options'))
return form( return form(
{'preferenceform': service, 'action_name': _("Edit")}, {'preferenceform': service, 'action_name': _("Edit")},
...@@ -172,6 +163,34 @@ def edit_service(request, service_instance, **_kwargs): ...@@ -172,6 +163,34 @@ def edit_service(request, service_instance, **_kwargs):
request request
) )
@login_required
@can_delete(Service)
def del_service(request, service_instance, **_kwargs):
"""Destruction d'un service"""
if request.method == "POST":
service_instance.delete()
messages.success(request, "Le service a été détruit")
return redirect(reverse('preferences:display-options'))
return form(
{'objet': service_instance, 'objet_name': 'service'},
'preferences/delete.html',
request
)
@login_required
@can_create(Reminder)
def add_reminder(request):
"""Ajout d'un rappel"""
reminder = ReminderForm(request.POST or None)
if reminder.is_valid():
reminder.save()
messages.success(request, "Ce rappel a été ajouté")
return redirect(reverse('preferences:display-options'))
return form(
{'preferenceform': reminder, 'action_name': 'Ajouter'},
'preferences/preferences.html',
request
)
@login_required @login_required
@can_delete_set(Service) @can_delete_set(Service)
...@@ -232,6 +251,17 @@ def edit_mailcontact(request, mailcontact_instance, **_kwargs): ...@@ -232,6 +251,17 @@ def edit_mailcontact(request, mailcontact_instance, **_kwargs):
return redirect(reverse('preferences:display-options')) return redirect(reverse('preferences:display-options'))
return form( return form(
{'preferenceform': mailcontact, 'action_name': _("Edit")}, {'preferenceform': mailcontact, 'action_name': _("Edit")},
@can_edit(Reminder)
def edit_reminder(request, reminder_instance, **_kwargs):
"""Edition des rappels"""
reminder = ReminderForm(request.POST or None, instance=reminder_instance)
if reminder.is_valid():
reminder.save()
messages.success(request, "Service modifié")
return redirect(reverse('preferences:display-options'))
return form(
{'preferenceform': reminder, 'action_name': 'Editer'},
'preferences/preferences.html', 'preferences/preferences.html',
request request
) )
...@@ -258,3 +288,18 @@ def del_mailcontact(request, instances): ...@@ -258,3 +288,18 @@ def del_mailcontact(request, instances):
request request
) )
@login_required
@can_delete(Reminder)
def del_reminder(request, reminder_instance, **_kwargs):
"""Destruction d'un reminder"""
if request.method == "POST":
reminder_instance.delete()
messages.success(request, "Le reminder a été détruit")
return redirect(reverse('preferences:display-options'))
return form(
{'objet': reminder_instance, 'objet_name': 'reminder'},
'preferences/delete.html',
request
)
...@@ -232,7 +232,7 @@ msgstr "Accéder à mon profil" ...@@ -232,7 +232,7 @@ msgstr "Accéder à mon profil"
#: templates/re2o/index.html:79 #: templates/re2o/index.html:79
msgid "Services of the organisation" msgid "Services of the organisation"
msgstr "Serices de l'association" msgstr "Services de l'association"
#: templates/re2o/index.html:93 #: templates/re2o/index.html:93
msgid "Go there" msgid "Go there"
......
...@@ -79,6 +79,65 @@ from django.contrib.contenttypes.models import ContentType ...@@ -79,6 +79,65 @@ from django.contrib.contenttypes.models import ContentType
register = template.Library() register = template.Library()
MODEL_NAME = {
# cotisations
'Facture': cotisations.models.Facture,
'Vente': cotisations.models.Vente,
'Article': cotisations.models.Article,
'Banque': cotisations.models.Banque,
'Paiement': cotisations.models.Paiement,
'Cotisation': cotisations.models.Cotisation,
# machines
'Machine': machines.models.Machine,
'MachineType': machines.models.MachineType,
'IpType': machines.models.IpType,
'Vlan': machines.models.Vlan,
'Nas': machines.models.Nas,
'SOA': machines.models.SOA,
'Extension': machines.models.Extension,
'Mx': machines.models.Mx,
'Ns': machines.models.Ns,
'Txt': machines.models.Txt,
'Srv': machines.models.Srv,
'Interface': machines.models.Interface,
'Domain': machines.models.Domain,
'IpList': machines.models.IpList,
'Ipv6List': machines.models.Ipv6List,
'machines.Service': machines.models.Service,
'Service_link': machines.models.Service_link,
'OuverturePortList': machines.models.OuverturePortList,
'OuverturePort': machines.models.OuverturePort,
# preferences
'OptionalUser': preferences.models.OptionalUser,
'OptionalMachine': preferences.models.OptionalMachine,
'OptionalTopologie': preferences.models.OptionalTopologie,
'GeneralOption': preferences.models.GeneralOption,
'preferences.Service': preferences.models.Service,
'preferences.Reminder': preferences.models.Reminder,
'AssoOption': preferences.models.AssoOption,
'MailMessageOption': preferences.models.MailMessageOption,
# topologie
'Stack': topologie.models.Stack,
'Switch': topologie.models.Switch,
'AccessPoint': topologie.models.AccessPoint,
'ModelSwitch': topologie.models.ModelSwitch,
'ConstructorSwitch': topologie.models.ConstructorSwitch,
'Port': topologie.models.Port,
'Room': topologie.models.Room,
'Building': topologie.models.Building,
'SwitchBay': topologie.models.SwitchBay,
# users
'User': users.models.User,
'Adherent': users.models.Adherent,
'Club': users.models.Club,
'ServiceUser': users.models.ServiceUser,
'School': users.models.School,
'ListRight': users.models.ListRight,
'ListShell': users.models.ListShell,
'Ban': users.models.Ban,
'Whitelist': users.models.Whitelist,
}
def get_model(model_name): def get_model(model_name):
"""Retrieve the model object from its name""" """Retrieve the model object from its name"""
......
...@@ -62,12 +62,128 @@ def index(request): ...@@ -62,12 +62,128 @@ def index(request):
twitter_account_name = HomeOption.get_cached_value('twitter_account_name') twitter_account_name = HomeOption.get_cached_value('twitter_account_name')
asso_name = AssoOption.get_cached_value('pseudo') asso_name = AssoOption.get_cached_value('pseudo')
return form({ return form({
<<<<<<< HEAD
'services_urls': services, 'services_urls': services,
'twitter_url': twitter_url, 'twitter_url': twitter_url,
'twitter_account_name': twitter_account_name, 'twitter_account_name': twitter_account_name,
'facebook_url': facebook_url, 'facebook_url': facebook_url,
'asso_name': asso_name 'asso_name': asso_name
}, 're2o/index.html', request) }, 're2o/index.html', request)
=======
'services_urls': services,
'twitter_url': twitter_url,
'twitter_account_name' : twitter_account_name,
'facebook_url': facebook_url,
'asso_name': asso_name
}, 're2o/index.html', request)
#: Binding the corresponding char sequence of history url to re2o models.
HISTORY_BIND = {
'users': {
'user': users.models.User,
'ban': users.models.Ban,
'whitelist': users.models.Whitelist,
'school': users.models.School,
'listright': users.models.ListRight,
'serviceuser': users.models.ServiceUser,
'listshell': users.models.ListShell,
},
'preferences': {
'service': preferences.models.Service,
'reminder': preferences.models.Reminder,
},
'cotisations': {
'facture': cotisations.models.Facture,
'article': cotisations.models.Article,
'paiement': cotisations.models.Paiement,
'banque': cotisations.models.Banque,
},
'topologie': {
'switch': topologie.models.Switch,
'port': topologie.models.Port,
'room': topologie.models.Room,
'stack': topologie.models.Stack,
'modelswitch': topologie.models.ModelSwitch,
'constructorswitch': topologie.models.ConstructorSwitch,
'accesspoint': topologie.models.AccessPoint,
'switchbay': topologie.models.SwitchBay,
'building': topologie.models.Building,
},
'machines': {
'machine': machines.models.Machine,
'interface': machines.models.Interface,
'domain': machines.models.Domain,
'machinetype': machines.models.MachineType,
'iptype': machines.models.IpType,
'extension': machines.models.Extension,
'soa': machines.models.SOA,
'mx': machines.models.Mx,
'txt': machines.models.Txt,
'srv': machines.models.Srv,
'ns': machines.models.Ns,
'service': machines.models.Service,
'vlan': machines.models.Vlan,
'nas': machines.models.Nas,
'ipv6list': machines.models.Ipv6List,
},
}
@login_required
def history(request, application, object_name, object_id):
"""Render history for a model.
The model is determined using the `HISTORY_BIND` dictionnary if none is
found, raises a Http404. The view checks if the user is allowed to see the
history using the `can_view` method of the model.
Args:
request: The request sent by the user.
object_name: Name of the model.
object_id: Id of the object you want to acces history.
Returns:
The rendered page of history if access is granted, else the user is
redirected to their profile page, with an error message.
Raises:
Http404: This kind of models doesn't have history.
"""
try:
model = HISTORY_BIND[application][object_name]
except KeyError:
raise Http404(u"Il n'existe pas d'historique pour ce modèle.")
object_name_id = object_name + 'id'
kwargs = {object_name_id: object_id}
try:
instance = model.get_instance(**kwargs)
except model.DoesNotExist:
messages.error(request, u"Entrée inexistante")
return redirect(reverse(
'users:profil',
kwargs={'userid': str(request.user.id)}
))
can, msg = instance.can_view(request.user)
if not can:
messages.error(request, msg or "Vous ne pouvez pas accéder à ce menu")
return redirect(reverse(
'users:profil',
kwargs={'userid': str(request.user.id)}
))
pagination_number = GeneralOption.get_cached_value('pagination_number')
reversions = Version.objects.get_for_object(instance)
if hasattr(instance, 'linked_objects'):
for related_object in chain(instance.linked_objects()):
reversions = (reversions |
Version.objects.get_for_object(related_object))
reversions = re2o_paginator(request, reversions, pagination_number)
return render(
request,
're2o/history.html',
{'reversions': reversions, 'object': instance}
)
>>>>>>> 5a88882... Ajoute le réglage reminder et factorise la liste des services
def about_page(request): def about_page(request):
......
...@@ -41,6 +41,8 @@ from django.utils import timezone ...@@ -41,6 +41,8 @@ from django.utils import timezone
from django.contrib.auth.models import Group, Permission from django.contrib.auth.models import Group, Permission
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from machines.models import Interface, Machine, Nas
from topologie.models import Port
from preferences.models import OptionalUser from preferences.models import OptionalUser
from re2o.utils import remove_user_room, get_input_formats_help_text from re2o.utils import remove_user_room, get_input_formats_help_text
from re2o.mixins import FormRevMixin from re2o.mixins import FormRevMixin
...@@ -660,3 +662,53 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm): ...@@ -660,3 +662,53 @@ class EmailSettingsForm(FormRevMixin, FieldPermissionFormMixin, ModelForm):
model = User model = User
fields = ['email','local_email_enabled', 'local_email_redirect'] fields = ['email','local_email_enabled', 'local_email_redirect']
class InitialRegisterForm(forms.Form):
register_room = forms.BooleanField(required=False)
register_machine = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
switch_ip = kwargs.pop('switch_ip')
switch_port = kwargs.pop('switch_port')
client_mac = kwargs.pop('client_mac')
self.user = kwargs.pop('user')
if switch_ip and switch_port:
# Looking for a port
port = Port.objects.filter(switch__interface__ipv4__ipv4=switch_ip, port=switch_port).first()
# If a port exists, checking there is a room AND radius
if port:
if port.get_port_profile.radius_type != 'NO' and port.get_port_profile.radius_mode == 'STRICT' and hasattr(port, 'room'):
# Requesting user is not in this room ?
if self.user.room != port.room:
self.new_room = port.room
if client_mac and switch_ip:
# If this interface doesn't already exists
if not Interface.objects.filter(mac_address=client_mac):
self.mac_address = client_mac
self.nas_type = Nas.objects.filter(nas_type__interface__ipv4__ipv4=switch_ip).first()
super(InitialRegisterForm, self).__init__(*args, **kwargs)
if hasattr(self, 'new_room'):
self.fields['register_room'].label = _("New connection from room %s. Is it yours? If that is the case, type OK." % self.new_room)
else:
self.fields.pop('register_room')
if hasattr(self, 'mac_address'):
self.fields['register_machine'].label = _("New connection from new device. Register it? Say Yes to get Internet access from it (MAC Address : %s)." % self.mac_address)
else:
self.fields.pop('register_machine')
def clean_register_room(self):
if self.cleaned_data['register_room']:
if self.user.is_class_adherent:
remove_user_room(self.new_room)
user = self.user.adherent
user.room = self.new_room
user.save()
if self.user.is_class_club:
user = self.user.club
user.room = self.new_room
user.save()
def clean_register_machine(self):
if self.cleaned_data['register_machine']:
if self.mac_address and self.nas_type:
self.user.autoregister_machine(self.mac_address, self.nas_type)
This diff is collapsed.
{% extends "users/sidebar.html" %}
{% comment %}
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.
{% endcomment %}
{% load bootstrap3 %}
{% load massive_bootstrap_form %}
{% load static %}
{% load i18n %}
{% block title %}{% trans "Users" %}{% endblock %}
{% block content %}
<h3>{% trans "Your machine and your room were successfully registered. Please disconnect and reconnect your Ethernet cable to benefit from a wired connection." %}</h3>
<center><img src="{% static '/images/rj45.gif' %}" alt="rj45_in_out"></center>
<br/>
<br/>
<br/>
{% endblock %}
...@@ -109,6 +109,7 @@ urlpatterns = [ ...@@ -109,6 +109,7 @@ urlpatterns = [
url(r'^mass_archive/$', views.mass_archive, name='mass-archive'), url(r'^mass_archive/$', views.mass_archive, name='mass-archive'),
url(r'^$', views.index, name='index'), url(r'^$', views.index, name='index'),
url(r'^index_clubs/$', views.index_clubs, name='index-clubs'), url(r'^index_clubs/$', views.index_clubs, name='index-clubs'),
url(r'^initial_register/$', views.initial_register, name='initial-register'),
url(r'^rest/ml/std/$', url(r'^rest/ml/std/$',
views.ml_std_list, views.ml_std_list,
name='ml-std-list'), name='ml-std-list'),
......
...@@ -105,7 +105,8 @@ from .forms import ( ...@@ -105,7 +105,8 @@ from .forms import (
PassForm, PassForm,
ResetPasswordForm, ResetPasswordForm,
ClubAdminandMembersForm, ClubAdminandMembersForm,
GroupForm GroupForm,
InitialRegisterForm
) )
...@@ -1081,6 +1082,30 @@ def process_passwd(request, req): ...@@ -1081,6 +1082,30 @@ def process_passwd(request, req):
request request
) )
@login_required
def initial_register(request):
u_form = InitialRegisterForm(request.POST or None, user=request.user, switch_ip=request.GET.get('switch_ip', None), switch_port=request.GET.get('switch_port', None), client_mac=request.GET.get('client_mac', None))
if not u_form.fields:
messages.error(request, _("Incorrect URL, or already registered device"))
return redirect(reverse(
'users:profil',
kwargs={'userid': str(request.user.id)}
))
if u_form.is_valid():
messages.success(request, _("Successful registration! Please"
" disconnect and reconnect your Ethernet"
" cable to get Internet access."))
return form(
{},
'users/plugin_out.html',
request
)
return form(
{'userform': u_form, 'action_name': _("Register device or room")},
'users/user.html',
request
)
class JSONResponse(HttpResponse): class JSONResponse(HttpResponse):
""" Framework Rest """ """ Framework Rest """
......