Projet

Général

Profil

Télécharger (7 ko) Statistiques
| Branche: | Tag: | Révision:

mandayejs / mandayejs / mandaye / views.py @ 83c9a56a

1
# mandayejs - saml reverse proxy
2
# Copyright (C) 2015  Entr'ouvert
3
#
4
# This program is free software: you can redistribute it and/or modify it
5
# under the terms of the GNU Affero General Public License as published
6
# by the Free Software Foundation, either version 3 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU Affero General Public License for more details.
13
#
14
# You should have received a copy of the GNU Affero General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

    
17
from __future__ import absolute_import
18

    
19
import logging
20

    
21
from django.contrib.auth.models import User
22
from django.contrib.auth.decorators import login_required
23
from django.contrib.auth.signals import user_logged_out
24
from django.contrib import messages
25
from django.dispatch import receiver
26
from django.http import HttpResponseRedirect, HttpResponse
27
from django.shortcuts import render, resolve_url
28
from django.template import RequestContext
29
from django.views.generic.base import TemplateView
30
from django.views.decorators.csrf import csrf_exempt
31
from django.utils.six.moves.urllib import parse as urlparse
32
from django.utils.translation import ugettext_lazy as _
33
from django.template import Template
34

    
35
from .models import UserCredentials
36
from mandayejs.mandaye.forms import FormFactory
37
from mandayejs.mandaye.utils import exec_phantom, cookie_builder,\
38
    get_login_info, get_logout_info
39
from mandayejs.applications import get_app_settings
40

    
41
from mellon.views import logout as mellon_logout
42

    
43

    
44
logger = logging.getLogger(__name__)
45

    
46

    
47
def home(request):
48
    return HttpResponseRedirect('/')
49

    
50

    
51
def logout(request, *args, **kwargs):
52
    logger.debug("running slo")
53
    response = mellon_logout(request, *args, **kwargs)
54
    logger.debug("deleting cookies")
55
    app_settings = get_app_settings()
56
    for cookie in app_settings.SITE_AUTH_COOKIE_KEYS:
57
        response.delete_cookie(cookie)
58
        if getattr(app_settings, 'SITE_LOGIN_PATH_PREFIX', None):
59
            response.delete_cookie(cookie, path=app_settings.SITE_LOGIN_PATH_PREFIX)
60
    return response
61

    
62

    
63
@receiver(user_logged_out)
64
def local_logout(sender, request, user, **kwargs):
65
    data = get_logout_info(request)
66
    logger.debug(data)
67
    result = exec_phantom(data, script='do_logout.js')
68
    logger.debug(result)
69

    
70

    
71
class Panel(TemplateView):
72
    template_name = 'mandaye/panel.html'
73

    
74
    def get_context_data(self, **kwargs):
75
        context = super(Panel, self).get_context_data(**kwargs)
76
        app_settings = get_app_settings()
77
        scripts = getattr(app_settings, 'SITE_APP_SCRIPTS', None)
78
        context['site_scripts'] = scripts
79
        context['force_redirect_url'] = getattr(app_settings, 'SITE_FORCE_REDIRECT_URL', '')
80
        context['force_redirect_locator'] = getattr(app_settings, 'SITE_FORCE_REDIRECT_LOCATOR', '')
81
        context['logout_locator'] = getattr(app_settings, 'SITE_LOGOUT_LOCATOR', '')
82
        context['is_linked'] = self.is_account_linked()
83
        return context
84

    
85
    def is_account_linked(self):
86
        """Check if user account is associated
87
        """
88
        try:
89
            user = User.objects.get(username=self.request.user.username)
90
            return user.usercredentials_set.get().linked
91
        except (User.DoesNotExist, UserCredentials.DoesNotExist) as e:
92
            return False
93

    
94

    
95
panel = Panel.as_view()
96

    
97

    
98
@login_required
99
def post_login(request, *args, **kwargs):
100
    try:
101
        user = User.objects.get(username=request.user.username)
102
        logger.debug(user)
103
        credentials = UserCredentials.objects.get(user=user)
104
        logger.debug(credentials)
105
    except (UserCredentials.DoesNotExist,):
106
        return HttpResponseRedirect(resolve_url('associate'))
107
    next_url = request.GET.get('next_url')
108
    return render(request, 'mandaye/post-login.html', {'next_url': next_url})
109

    
110

    
111
@login_required
112
@csrf_exempt
113
def associate(request, *args, **kwargs):
114
    if request.method == 'POST':
115

    
116
        form = FormFactory(request.POST)
117
        if form.is_valid():
118
            credentials, created = UserCredentials.objects.get_or_create(user=request.user)
119
            credentials.locators = form.cleaned_data
120
            credentials.linked = False
121
            credentials.save()
122

    
123
            return HttpResponseRedirect(resolve_url('post-login'))
124
    else:
125
        form = FormFactory()
126
    app_settings = get_app_settings()
127
    response = render(request, 'mandaye/associate.html', {
128
        'form': form, 'app': {
129
            'name': app_settings.get_name(), 'slug': app_settings.get_slug()}})
130
    return response
131

    
132

    
133
@login_required
134
def dissociate(request, *args, **kwargs):
135
    try:
136
        c_user = UserCredentials.objects.get(user__username=request.user.username)
137
        c_user.delete()
138
        logger.debug("{} dissacioted".format(c_user.user.username))
139
        app_settings = get_app_settings()
140
        return HttpResponseRedirect(
141
            request.META.get(
142
                'HTTP_REFERER', app_settings.SITE_LOGIN_PATH)
143
        )
144
    except (UserCredentials.DoesNotExist,):
145
        return HttpResponseRedirect(resolve_url('associate'))
146

    
147

    
148
@login_required
149
def post_login_do(request, *args, **kwargs):
150
    user = User.objects.get(username=request.user.username)
151
    try:
152
        credentials = user.usercredentials_set.get()
153
    except (UserCredentials.DoesNotExist,):
154
        return HttpResponseRedirect(resolve_url('associate'))
155

    
156
    login_info = get_login_info(request, credentials)
157

    
158
    logger.debug(login_info)
159
    login_info['locators'] = [credentials.to_login_info(decrypt=True)]
160
    result = exec_phantom(login_info)
161
    logger.debug(result)
162

    
163
    if result.get('result') == 'failure':
164
        logger.debug('authentication failed')
165
        logger.debug("redirecting to {}".format(resolve_url('associate')))
166
        credentials.delete()
167
        messages.error(request, _('wrong user credentials'))
168
        url = resolve_url('associate')
169
    elif result.get('result') == 'timeout':
170
        messages.error(request, _('server took too long to respond'))
171
        url = resolve_url('associate')
172
    elif result.get('result') == 'json_error':
173
        messages.error(request, _('invalid response from server'))
174
        url = resolve_url('associate')
175
    elif result.get('result') == 'redirect':
176
        url = urlparse.urlsplit(result.get('url', '/'))
177
        url = urlparse.urlunsplit((None, None, url.path, url.query, url.fragment))
178
    else:
179
        credentials.linked = True
180
        credentials.save()
181
        url = result.get('url', '/')
182

    
183
    # redirect user only if SSO successful
184
    if request.GET.get('next_url') and result['result'] == 'ok':
185
        url = request.GET['next_url']
186
    template = Template('<script type="text/javascript">\
187
                window.top.location = "{{url}}";</script>')
188
    context = RequestContext(request, {'url': url})
189
    response = HttpResponse(template.render(context))
190
    if result.get('headers', None):
191
        response.cookies = cookie_builder(result.get('headers'))
192

    
193
    return response
(7-7/7)