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.
mandayejs/mandayejs/mandaye/views.py

193 lines
6.9 KiB
Python

# mandayejs - saml reverse proxy
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import
import logging
import urlparse
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.contrib.auth.signals import user_logged_out
from django.contrib import messages
from django.dispatch import receiver
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, resolve_url
from django.template import RequestContext
from django.views.generic.base import TemplateView
from django.views.decorators.csrf import csrf_exempt
from django.utils.translation import ugettext_lazy as _
from django.template import Template
from .models import UserCredentials
from mandayejs.mandaye.forms import FormFactory
from mandayejs.mandaye.utils import exec_phantom, cookie_builder,\
get_login_info, get_logout_info
from mandayejs.applications import get_app_settings
from mellon.views import logout as mellon_logout
logger = logging.getLogger(__name__)
def home(request):
return HttpResponseRedirect('/')
def logout(request, *args, **kwargs):
logger.debug("running slo")
response = mellon_logout(request, *args, **kwargs)
logger.debug("deleting cookies")
app_settings = get_app_settings()
for cookie in app_settings.SITE_AUTH_COOKIE_KEYS:
response.delete_cookie(cookie)
if getattr(app_settings, 'SITE_LOGIN_PATH_PREFIX', None):
response.delete_cookie(cookie, path=app_settings.SITE_LOGIN_PATH_PREFIX)
return response
@receiver(user_logged_out)
def local_logout(sender, request, user, **kwargs):
data = get_logout_info(request)
logger.debug(data)
result = exec_phantom(data, script='do_logout.js')
logger.debug(result)
class Panel(TemplateView):
template_name = 'mandaye/panel.html'
def get_context_data(self, **kwargs):
context = super(Panel, self).get_context_data(**kwargs)
app_settings = get_app_settings()
scripts = getattr(app_settings, 'SITE_APP_SCRIPTS', None)
context['site_scripts'] = scripts
context['force_redirect_url'] = getattr(app_settings, 'SITE_FORCE_REDIRECT_URL', '')
context['force_redirect_locator'] = getattr(app_settings, 'SITE_FORCE_REDIRECT_LOCATOR', '')
context['logout_locator'] = getattr(app_settings, 'SITE_LOGOUT_LOCATOR', '')
context['is_linked'] = self.is_account_linked()
return context
def is_account_linked(self):
"""Check if user account is associated
"""
try:
user = User.objects.get(username=self.request.user.username)
return user.usercredentials_set.get().linked
except (User.DoesNotExist, UserCredentials.DoesNotExist) as e:
return False
panel = Panel.as_view()
@login_required
def post_login(request, *args, **kwargs):
try:
user = User.objects.get(username=request.user.username)
logger.debug(user)
credentials = UserCredentials.objects.get(user=user)
logger.debug(credentials)
except (UserCredentials.DoesNotExist,):
return HttpResponseRedirect(resolve_url('associate'))
next_url = request.GET.get('next_url')
return render(request, 'mandaye/post-login.html', {'next_url': next_url})
@login_required
@csrf_exempt
def associate(request, *args, **kwargs):
if request.method == 'POST':
form = FormFactory(request.POST)
if form.is_valid():
credentials, created = UserCredentials.objects.get_or_create(user=request.user)
credentials.locators = form.cleaned_data
credentials.linked = False
credentials.save()
return HttpResponseRedirect(resolve_url('post-login'))
else:
form = FormFactory()
app_settings = get_app_settings()
response = render(request, 'mandaye/associate.html', {
'form': form, 'app': {
'name': app_settings.get_name(), 'slug': app_settings.get_slug()}})
return response
@login_required
def dissociate(request, *args, **kwargs):
try:
c_user = UserCredentials.objects.get(user__username=request.user.username)
c_user.delete()
logger.debug("{} dissacioted".format(c_user.user.username))
return HttpResponseRedirect(
request.META.get(
'HTTP_REFERER', app_settings.SITE_LOGIN_PATH)
)
except (UserCredentials.DoesNotExist,):
return HttpResponseRedirect(resolve_url('associate'))
@login_required
def post_login_do(request, *args, **kwargs):
user = User.objects.get(username=request.user.username)
try:
credentials = user.usercredentials_set.get()
except (UserCredentials.DoesNotExist,):
return HttpResponseRedirect(resolve_url('associate'))
login_info = get_login_info(request, credentials)
logger.debug(login_info)
login_info['locators'] = [credentials.to_login_info(decrypt=True)]
result = exec_phantom(login_info)
logger.debug(result)
if result.get('result') == 'failure':
logger.debug('authentication failed')
logger.debug("redirecting to {}".format(resolve_url('associate')))
credentials.delete()
messages.error(request, _('wrong user credentials'))
url = resolve_url('associate')
elif result.get('result') == 'timeout':
messages.error(request, _('server took too long to respond'))
url = resolve_url('associate')
elif result.get('result') == 'json_error':
messages.error(request, _('invalid response from server'))
url = resolve_url('associate')
elif result.get('result') == 'redirect':
url = urlparse.urlsplit(result.get('url', '/'))
url = urlparse.urlunsplit((None, None, url.path, url.query, url.fragment))
else:
credentials.linked = True
credentials.save()
url = result.get('url', '/')
# redirect user only if SSO successful
if request.GET.get('next_url') and result['result'] == 'ok':
url = request.GET['next_url']
template = Template('<script type="text/javascript">\
window.top.location = "{{url}}";</script>')
context = RequestContext(request, {'url': url})
response = HttpResponse(template.render(context))
if result.get('headers', None):
response.cookies = cookie_builder(result.get('headers'))
return response