This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
univnautes-old/virtualenv/pffedportal/base/views.py

179 lines
6.8 KiB
Python

import subprocess
import urlparse
import syslog
from django.conf import settings
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.shortcuts import redirect
from django.contrib import messages
import django.contrib.auth
from authentic2.authsaml2.utils import register_next_target
from authentic2.authsaml2.saml2_endpoints import sso as authentic2_sso
import authentic2.saml.models as saml_models
import pfsense
from forms import MailForm, EMAIL_SUBJECTS_CHOICES, IDP_CHOICES
from django.core.mail import send_mail
#from smtplib import SMTPException
def redirect302(request):
next_url = 'http://' + request.META['HTTP_HOST'] + request.META['REQUEST_URI']
return redirect('https://%s/login?next_url=%s' % (settings.HTTPS_HOSTNAME, next_url))
def index(request):
if not 'pfsenseid' in request.session:
return redirect('/login')
pfsenseid = request.session['pfsenseid']
# dirty hack to handle errors and blacklisted users (see auth.py)
if pfsenseid in ('BLACKLISTED', 'ERROR'):
django.contrib.auth.logout(request)
return redirect('/login')
if 'next_url' in request.session:
# display next_url and forget it
next_url = request.session['next_url']
del request.session['next_url']
request.session.set_expiry(settings.SESSION_COOKIE_AGE)
else:
next_url = None
if 'display_name' in request.session:
display_name = request.session['display_name']
else:
display_name = ''
pfsense_session = pfsense.get_captive_portal_session(ip = request.META['REMOTE_ADDR'])
if settings.REDIRECT_URL:
values = {
'next_url': next_url,
'redirect_delay': settings.REDIRECT_DELAY,
'display_name': display_name,
'pfsenseid': pfsenseid,
}
values.update(pfsense_session)
next_url = settings.REDIRECT_URL % values
if settings.REDIRECT_DELAY == 0 and next_url != None:
response = redirect(next_url)
else:
try:
next_url_host = urlparse.urlsplit(next_url)[1]
except:
next_url_host = next_url
if settings.EMAIL_RCPT and settings.EMAIL_HOST:
mailform = True
else:
mailform = False
response = render_to_response('index.html',
{'next_url': next_url,
'next_url_host': next_url_host,
'redirect_delay': settings.REDIRECT_DELAY,
'display_name': display_name,
'pfsenseid': pfsenseid,
'pfsense_session': pfsense_session,
'prefered_idp': request.session.get('prefered_idp', ''),
'mailform': mailform,
'https_hostname': settings.HTTPS_HOSTNAME,
},
context_instance=RequestContext(request))
# store prefered_idp in a cookie with a ten days ttl
if 'prefered_idp' in request.session:
response.set_cookie('prefered_idp', request.session['prefered_idp'], max_age=10*24*3600)
return response
def login(request):
# if we are already logged (or supposed to be), go to index
if 'pfsenseid' in request.session:
return redirect('/')
if 'next_url' in request.GET:
request.session['next_url'] = request.GET['next_url']
else:
request.session['next_url'] = None
try:
prefered_idp = request.COOKIES.get('prefered_idp', settings.DEFAULT_IDP)
default_idp = saml_models.LibertyProvider.objects.get(entity_id=prefered_idp)
except:
default_idp = None
register_next_target(request, url='/')
if settings.EMAIL_RCPT and settings.EMAIL_HOST:
mailform = True
else:
mailform = False
return render_to_response('login.html',
{'default_idp': default_idp,
'mailform': mailform,
'https_hostname': settings.HTTPS_HOSTNAME,
'disco_stores_read': settings.DISCO_STORES_READ,
'disco_stores_write': settings.DISCO_STORES_WRITE,
},
context_instance=RequestContext(request))
def sso(request, is_passive=None, force_authn=None, http_method=None):
'''log a sso request and send it to authentic2'''
entity_id = request.REQUEST.get('entity_id')
ip = request.META['REMOTE_ADDR']
mac = pfsense.get_mac_from_ip(ip)
syslog.openlog("logportalauth", syslog.LOG_PID)
syslog.syslog(syslog.LOG_LOCAL4 | syslog.LOG_INFO , "SSOREDIRECT: %s,%s to %s" % (ip, mac, entity_id))
return authentic2_sso(request, is_passive=is_passive, force_authn=force_authn, http_method=http_method)
def logout(request):
if 'pfsenseid' in request.session:
pfsenseid = request.session['pfsenseid']
else:
pfsenseid = None
ip = request.META['REMOTE_ADDR']
django.contrib.auth.logout(request)
if pfsenseid:
cmd = ['cp_disconnect', 'sessionid=%s' % pfsenseid, 'ip=%s' % ip]
else:
cmd = ['cp_disconnect', 'ip=%s' % ip ]
try:
p = subprocess.Popen(cmd, close_fds=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError, e:
return
stdout, stderr = p.communicate()
return redirect('/login')
def mail(request):
if request.method == 'POST':
form = MailForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
from_email = form.cleaned_data['from_email']
idp = form.cleaned_data['idp']
idp_name = dict(IDP_CHOICES).get(idp)
phone = form.cleaned_data.get('phone', '')
n_subject = form.cleaned_data['subject']
subject = dict(EMAIL_SUBJECTS_CHOICES).get(n_subject, 'unknown subject ?')
body = form.cleaned_data['body']
total_body = u'Nom: %(name)s <%(from_email)s>\nTel: %(phone)s\n' \
'IdP: %(idp_name)s <%(idp)s>\n\n' \
'Message:\n%(body)s\n\n-- \nUnivNautes\n' % {
'name': name, 'from_email': from_email,
'idp': idp or None, 'idp_name': idp_name,
'phone': phone,
'body': body }
try:
send_mail(u'[Contact UnivNautes] %s' % subject,
total_body,
u'%s' % from_email,
[settings.EMAIL_RCPT],
fail_silently=False)
except Exception, e:
messages.add_message(request, messages.ERROR, 'send_mail error: %s' % e)
else:
response = redirect('.')
return response
else:
form = MailForm()
return render_to_response('mail.html',
{ 'form': form, },
context_instance=RequestContext(request))