diff --git a/re2o/settings_local.example.py b/re2o/settings_local.example.py index 662c1447..5e8e91ba 100644 --- a/re2o/settings_local.example.py +++ b/re2o/settings_local.example.py @@ -110,3 +110,6 @@ GID_RANGES = { # Some Django apps you want to add in you local project OPTIONNAL_APPS = () + +CAPTIVE_IP_RANGE = "10.51.0.0/16" + diff --git a/re2o/templates/re2o/portail_login.html b/re2o/templates/re2o/portail_login.html new file mode 100644 index 00000000..579b66bc --- /dev/null +++ b/re2o/templates/re2o/portail_login.html @@ -0,0 +1,46 @@ +{% 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 static %} +{% block title %}Machine non reconnue{% endblock %} + +{% block content %} +{% bootstrap_form_errors loginform %} + +
+ + +{% if success %} + +Votre Machine a été enregistré avec succès, débranchez votre cable, attendez quelques secondes puis rebranchez le, vous devriez alors avoir internet ! (si vous êtes à jour de cotisation). + +{% endif %} + +{% endblock %} diff --git a/re2o/urls.py b/re2o/urls.py index 39f51ec3..1f2d4eaa 100644 --- a/re2o/urls.py +++ b/re2o/urls.py @@ -48,7 +48,7 @@ from django.conf.urls import include, url from django.contrib import admin from django.contrib.auth import views as auth_views -from .views import index, about_page, contact_page +from .views import index, about_page, contact_page, portail_login handler500 = 're2o.views.handler500' handler404 = 're2o.views.handler404' @@ -58,6 +58,7 @@ urlpatterns = [ url(r'^about/$', about_page, name='about'), url(r'^contact/$', contact_page, name='contact'), url('^logout/', auth_views.logout, {'next_page': '/'}), + url(r'^portail_login/$', portail_login, name='portail_login'), url('^', include('django.contrib.auth.urls')), url(r'^i18n/', include('django.conf.urls.i18n')), url(r'^admin/', include(admin.site.urls)), diff --git a/re2o/views.py b/re2o/views.py index c3f13332..5564766f 100644 --- a/re2o/views.py +++ b/re2o/views.py @@ -34,6 +34,11 @@ from django.template.context_processors import csrf from django.conf import settings from django.utils.translation import ugettext as _ from django.views.decorators.cache import cache_page +from django.contrib.auth.forms import AuthenticationForm +from django.contrib import messages + +import subprocess +import ipaddress from preferences.models import ( Service, @@ -41,9 +46,10 @@ from preferences.models import ( AssoOption, HomeOption ) +from machines.models import Nas from .contributors import CONTRIBUTORS - +from re2o.settings import CAPTIVE_IP_RANGE def form(ctx, template, request): """Form générique, raccourci importé par les fonctions views du site""" @@ -69,6 +75,60 @@ def index(request): 'asso_name': asso_name }, 're2o/index.html', request) +def get_ip(request): + """Returns the IP of the request, accounting for the possibility of being + behind a proxy. + """ + ip = request.META.get("HTTP_X_FORWARDED_FOR", None) + if ip: + # X_FORWARDED_FOR returns client1, proxy1, proxy2,... + ip = ip.split(", ")[0] + else: + ip = request.META.get("REMOTE_ADDR", "") + return ip + +def apply(cmd): + return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + +def mac_from_ip(ip): + cmd = ['/usr/sbin/arp','-na',ip] + p = apply(cmd) + output, errors = p.communicate() + if output is not None : + mac_addr = output.decode().split()[3] + return str(mac_addr) + else: + return None + +def portail_login(request): + """ Check for authentication. If success, register the current machine for the user.""" + login_form = AuthenticationForm(data=request.POST) + success = False + if login_form.is_valid(): + remote_ip = get_ip(request) + if ipaddress.ip_address(remote_ip) in ipaddress.ip_network(CAPTIVE_IP_RANGE): + mac_addr = mac_from_ip(remote_ip) + if mac_addr: + nas_type = Nas.objects.get(name="Switches") + result, reason = login_form.user_cache.autoregister_machine(mac_addr, nas_type) + if result: + success=True + else: + messages.error(request, "Erreur dans l'enregistrement de la machine : %s" % reason, '') + else: + messages.error(request, "Erreur dans la récupération de la MAC") + else: + messages.error(request, "Merci de vous connecter en filaire pour enregistrer une machine") + return form( + { + 'loginform': login_form, + 'success' : success + }, + 're2o/portail_login.html', + request + ) + + def about_page(request): """ The view for the about page.