179 lines
6.8 KiB
Python
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))
|
|
|