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 os
|
20
|
import json
|
21
|
import logging
|
22
|
import urlparse
|
23
|
import urllib
|
24
|
|
25
|
from django.conf import settings
|
26
|
from django.contrib.auth import views as auth_views
|
27
|
from django.contrib.auth import logout as auth_logout
|
28
|
from django.contrib.auth import get_user_model
|
29
|
from django.contrib.auth.decorators import login_required
|
30
|
from django.contrib import messages
|
31
|
from django.forms import PasswordInput
|
32
|
from django.forms import models as model_forms
|
33
|
from django.http import HttpResponseRedirect, HttpResponse
|
34
|
from django.shortcuts import get_object_or_404, render, resolve_url
|
35
|
from django.template import RequestContext
|
36
|
from django.views.generic.base import TemplateView
|
37
|
from django.views.decorators.csrf import csrf_exempt
|
38
|
from django.db import IntegrityError
|
39
|
from django.utils.translation import ugettext_lazy as _
|
40
|
from django.template import RequestContext, Template
|
41
|
|
42
|
from .models import UserCredentials
|
43
|
from mandayejs.mandaye.forms import FormFactory
|
44
|
from mandayejs.mandaye.utils import exec_phantom, cookie_builder, get_location
|
45
|
|
46
|
logger = logging.getLogger(__name__)
|
47
|
|
48
|
def login(request, *args, **kwargs):
|
49
|
return auth_views.login(request, *args, **kwargs)
|
50
|
|
51
|
def logout(request, *args, **kwargs):
|
52
|
auth_logout(request)
|
53
|
return HttpResponseRedirect('/')
|
54
|
|
55
|
|
56
|
class Panel(TemplateView):
|
57
|
template_name = 'mandaye/panel.html'
|
58
|
|
59
|
def get_context_data(self, **kwargs):
|
60
|
context = super(Panel, self).get_context_data(**kwargs)
|
61
|
scripts = getattr(settings, 'SITE_SCRIPTS', [])
|
62
|
static_root_path = getattr(settings, 'SITE_STATIC_ROOT_PATH', '')
|
63
|
context['site_scripts'] = [os.path.join(static_root_path, s) for s in scripts]
|
64
|
context['ca_url'] = getattr(settings, 'SITE_CA_URL', '/')
|
65
|
context['is_linked'] = self.is_account_linked()
|
66
|
return context
|
67
|
|
68
|
def is_account_linked(self):
|
69
|
"""Check if user account is associated
|
70
|
"""
|
71
|
try:
|
72
|
User = get_user_model()
|
73
|
user = User.objects.get(username=self.request.user.username)
|
74
|
return user.usercredentials_set.get().linked
|
75
|
except (User.DoesNotExist, UserCredentials.DoesNotExist) as e:
|
76
|
return False
|
77
|
|
78
|
|
79
|
panel = Panel.as_view()
|
80
|
|
81
|
@login_required
|
82
|
def post_login(request, *args, **kwargs):
|
83
|
try:
|
84
|
user = get_user_model().objects.get(username=request.user.username)
|
85
|
logger.debug(user)
|
86
|
credentials = UserCredentials.objects.get(
|
87
|
user=user,
|
88
|
linked=True)
|
89
|
logger.debug(credentials)
|
90
|
except (UserCredentials.DoesNotExist,):
|
91
|
return HttpResponseRedirect(resolve_url('associate'))
|
92
|
|
93
|
context = {}
|
94
|
context['address'] = getattr(settings, 'SITE_HOME_PATH', '/')
|
95
|
return render(request, 'mandaye/post-login.html', context)
|
96
|
|
97
|
@login_required
|
98
|
@csrf_exempt
|
99
|
def associate(request, *args, **kwargs):
|
100
|
if request.POST:
|
101
|
credentials, created = UserCredentials.objects.get_or_create(user=request.user)
|
102
|
credentials.locators = request.POST
|
103
|
credentials.linked = True
|
104
|
credentials.save()
|
105
|
form = FormFactory(request.POST, auto_id=True, locators=settings.SITE_LOCATORS)
|
106
|
else:
|
107
|
form = FormFactory(auto_id=True, locators=settings.SITE_LOCATORS)
|
108
|
if not form.is_valid():
|
109
|
site_static_root = getattr(settings, 'SITE_STATIC_ROOT_PATH', '')
|
110
|
associate_static = getattr(settings, 'SITE_ASSOCIATE_STATIC',
|
111
|
{'css':'', 'js':''})
|
112
|
|
113
|
response = render(request, 'mandaye/associate.html', {
|
114
|
'form': form,
|
115
|
'associate_js': os.path.join(site_static_root, associate_static['js']),
|
116
|
'associate_css': os.path.join(site_static_root, associate_static['css'])
|
117
|
})
|
118
|
return response
|
119
|
|
120
|
return HttpResponseRedirect(resolve_url('post-login'))
|
121
|
|
122
|
@login_required
|
123
|
def dissociate(request, *args, **kwargs):
|
124
|
try:
|
125
|
c_user = UserCredentials.objects.get(
|
126
|
user__username=request.user.username)
|
127
|
c_user.linked = False
|
128
|
c_user.save()
|
129
|
logger.debug("{} dissacioted".format(c_user.user.username))
|
130
|
response = HttpResponseRedirect('/')
|
131
|
for cookie_key in getattr(settings, 'SITE_AUTH_COOKIE_KEYS', []):
|
132
|
response.delete_cookie(cookie_key)
|
133
|
logger.debug("cookie {} deleted".format(cookie_key))
|
134
|
return response
|
135
|
except (UserCredentials.DoesNotExist,):
|
136
|
return HttpResponseRedirect(resolve_url('associate'))
|
137
|
|
138
|
@login_required
|
139
|
def post_login_do(request, *args, **kwargs):
|
140
|
credentials = get_object_or_404(UserCredentials, user=request.user)
|
141
|
site_static_root = os.path.join(getattr(settings, 'STATIC_ROOT'), getattr(settings, 'SITE_STATIC_ROOT_PATH', ''))
|
142
|
site_auth_checker = getattr(settings, 'SITE_AUTH_CHECKER', '')
|
143
|
login_info = {
|
144
|
'address': request.build_absolute_uri(settings.SITE_LOGIN_PATH),
|
145
|
'cookies': [],
|
146
|
'locators': [ credentials.to_login_info() ],
|
147
|
'homepath': getattr(settings, 'SITE_HOME_PATH', '/'),
|
148
|
'auth_checker': os.path.join(site_static_root, site_auth_checker)
|
149
|
}
|
150
|
logger.debug(login_info)
|
151
|
result = exec_phantom(login_info)
|
152
|
logger.debug(result)
|
153
|
if result.get('result') != 'ok':
|
154
|
logger.debug('authentication failed')
|
155
|
User = get_user_model()
|
156
|
user = User.objects.get(username=request.user.username)
|
157
|
c_user = user.usercredentials_set.get()
|
158
|
c_user.linked = False
|
159
|
c_user.save()
|
160
|
logger.debug("redirecting to {}".format(resolve_url('associate')))
|
161
|
messages.error(request, _('wrong user credentials'))
|
162
|
url = resolve_url('associate')
|
163
|
else:
|
164
|
url = getattr(settings, 'SITE_HOME_PATH', '/')
|
165
|
|
166
|
template = Template('<script type="text/javascript">\
|
167
|
window.top.location = "{{url}}";</script>')
|
168
|
context = RequestContext(request, {'url': url})
|
169
|
response = HttpResponse(template.render(context))
|
170
|
if result.get('headers',None):
|
171
|
response.cookies = cookie_builder(result.get('headers'))
|
172
|
|
173
|
return response
|