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
|
import os
|
18
|
import json
|
19
|
import logging
|
20
|
import subprocess
|
21
|
import urlparse
|
22
|
import urllib
|
23
|
|
24
|
from django.conf import settings
|
25
|
from django.contrib.auth import views as auth_views
|
26
|
from django.contrib.auth import logout as auth_logout
|
27
|
from django.contrib.auth import get_user_model
|
28
|
from django.contrib.auth.decorators import login_required
|
29
|
from django.forms import PasswordInput
|
30
|
from django.forms import models as model_forms
|
31
|
from django.http import HttpResponseRedirect, HttpResponse
|
32
|
from django.shortcuts import get_object_or_404, render, resolve_url
|
33
|
from django.template import RequestContext
|
34
|
from django.views.generic.base import TemplateView
|
35
|
from django.views.decorators.csrf import csrf_exempt
|
36
|
from django.db import IntegrityError
|
37
|
from django.utils.translation import ugettext_lazy as _
|
38
|
|
39
|
from .models import UserCredentials
|
40
|
from mandayejs.mandaye.forms import FormFactory
|
41
|
from mandayejs.mandaye.utils import cookie_builder, get_location
|
42
|
|
43
|
def login(request, *args, **kwargs):
|
44
|
return auth_views.login(request, *args, **kwargs)
|
45
|
|
46
|
def logout(request, *args, **kwargs):
|
47
|
auth_logout(request)
|
48
|
return HttpResponseRedirect('/')
|
49
|
|
50
|
|
51
|
class Panel(TemplateView):
|
52
|
template_name = 'mandaye/panel.html'
|
53
|
|
54
|
def get_context_data(self, **kwargs):
|
55
|
context = super(Panel, self).get_context_data(**kwargs)
|
56
|
context['login_txt'] = _('login')
|
57
|
context['logout_txt'] = _('logout')
|
58
|
context['site_scripts'] = getattr(settings, 'SITE_SCRIPTS', [])
|
59
|
context['ca_url'] = getattr(settings, 'SITE_CA_URL', '/')
|
60
|
context['is_linked'] = self.is_account_linked()
|
61
|
return context
|
62
|
|
63
|
def is_account_linked(self):
|
64
|
"""Check if user account is associated
|
65
|
"""
|
66
|
try:
|
67
|
UserCredentials.objects.get(user=self.request.user)
|
68
|
return True
|
69
|
except :
|
70
|
return False
|
71
|
|
72
|
|
73
|
panel = Panel.as_view()
|
74
|
|
75
|
@login_required
|
76
|
def post_login(request, *args, **kwargs):
|
77
|
try:
|
78
|
credentials = UserCredentials.objects.get(
|
79
|
user=request.user)
|
80
|
except UserCredentials.DoesNotExist:
|
81
|
return HttpResponseRedirect(resolve_url('associate'))
|
82
|
|
83
|
context = {}
|
84
|
context['address'] = getattr(settings, 'SITE_HOME_PATH', '/')
|
85
|
return render(request, 'mandaye/post-login.html', context)
|
86
|
|
87
|
@login_required
|
88
|
@csrf_exempt
|
89
|
def associate(request, *args, **kwargs):
|
90
|
if request.POST:
|
91
|
credentials = UserCredentials()
|
92
|
credentials.user = request.user
|
93
|
credentials.locators = request.POST
|
94
|
form = FormFactory(request.POST, auto_id=True, locators=settings.SITE_LOCATORS)
|
95
|
else:
|
96
|
form = FormFactory(auto_id=True, locators=settings.SITE_LOCATORS)
|
97
|
if not form.is_valid():
|
98
|
return render(request, 'mandaye/associate.html', {
|
99
|
'form': form,
|
100
|
'submit': _('submit'),
|
101
|
'associate': _('associate your account'),
|
102
|
'associate_static': getattr(settings,
|
103
|
'SITE_ASSOCIATE_STATIC',
|
104
|
{'css':'', 'js':''})
|
105
|
})
|
106
|
try:
|
107
|
credentials.save()
|
108
|
except (IntegrityError,) as e:
|
109
|
pass
|
110
|
|
111
|
return HttpResponseRedirect(resolve_url('post-login'))
|
112
|
|
113
|
@login_required
|
114
|
def dissociate(request, *args, **kwargs):
|
115
|
try:
|
116
|
User = get_user_model()
|
117
|
User.objects.get(username=request.user).delete()
|
118
|
return HttpResponseRedirect(resolve_url('mellon_logout'))
|
119
|
except (User.DoesNotExist,) as e:
|
120
|
return HttpResponseRedirect(resolve_url('associate'))
|
121
|
|
122
|
@login_required
|
123
|
def post_login_do(request, *args, **kwargs):
|
124
|
credentials = get_object_or_404(UserCredentials, user=request.user)
|
125
|
login_info = {
|
126
|
'address': request.build_absolute_uri(settings.SITE_LOGIN_PATH),
|
127
|
'cookies': [],
|
128
|
'locators': [ credentials.to_login_info() ]
|
129
|
}
|
130
|
result = exec_phantom(login_info)
|
131
|
if result.get('result') != 'ok':
|
132
|
return HttpResponseRedirect('/')
|
133
|
location = get_location(result.get('url','/'))
|
134
|
response = HttpResponseRedirect(location)
|
135
|
response.cookies = cookie_builder(result.get('headers'))
|
136
|
return response
|
137
|
|
138
|
def exec_phantom(data):
|
139
|
phantom = subprocess.Popen(['/usr/bin/phantomjs',
|
140
|
'--ignore-ssl-errors=yes',
|
141
|
'--ssl-protocol=any',
|
142
|
'--cookies-file=cookies.txt',
|
143
|
os.path.join(settings.BASE_DIR,'mandayejs/do_login.js')],
|
144
|
close_fds=True,
|
145
|
stdin=subprocess.PIPE,
|
146
|
stdout=subprocess.PIPE)
|
147
|
stdout, stderr = phantom.communicate(json.dumps(data))
|
148
|
result = json.loads(stdout)
|
149
|
return result
|