1
|
import os
|
2
|
import lasso
|
3
|
|
4
|
from quixote import get_publisher, get_response, get_session, redirect, get_session_manager
|
5
|
from quixote.directory import Directory
|
6
|
from quixote.util import StaticDirectory
|
7
|
|
8
|
import admin
|
9
|
import liberty
|
10
|
import saml2
|
11
|
|
12
|
import errors
|
13
|
import logger
|
14
|
import misc
|
15
|
import template
|
16
|
from form import *
|
17
|
|
18
|
from users import User
|
19
|
from sites import SiteUI
|
20
|
|
21
|
class RootDirectory(Directory):
|
22
|
_q_exports = ['', 'admin', 'login', 'logout', 'liberty', 'token', 'saml']
|
23
|
|
24
|
def _q_index [html] (self):
|
25
|
return 'Nothing to see here yet'
|
26
|
|
27
|
def login [html] (self):
|
28
|
logger.info('login')
|
29
|
idps = misc.cfg.get('idp', {})
|
30
|
|
31
|
if len(idps) == 0:
|
32
|
return template.error_page(_('SSO support is not yet configured'))
|
33
|
|
34
|
if len(idps) == 1 or len([x for x in idps.values() if not x.get('hide', False)]) == 1:
|
35
|
# if there is only one visible IdP, perform login automatically on
|
36
|
# this one.
|
37
|
server = misc.get_lasso_server('liberty')
|
38
|
for x in server.providerIds:
|
39
|
key_provider_id = x.replace(str('://'), str('-')).replace(str('/'), str('-'))
|
40
|
if not idps.get(key_provider_id, {}).get('hide', False):
|
41
|
return self.liberty.perform_login(x)
|
42
|
|
43
|
server = misc.get_lasso_server('saml2')
|
44
|
for x in server.providerIds:
|
45
|
key_provider_id = x.replace(str('://'), str('-')).replace(str('/'), str('-'))
|
46
|
if not idps.get(key_provider_id, {}).get('hide', False):
|
47
|
return self.saml.perform_login(x)
|
48
|
|
49
|
form = Form(enctype='multipart/form-data')
|
50
|
options = []
|
51
|
# XXX: use intro cookie to get preferred value
|
52
|
value = None
|
53
|
providers = {}
|
54
|
for kidp, idp in misc.cfg.get('idp', {}).items():
|
55
|
if idp.get('hide'):
|
56
|
continue
|
57
|
p = lasso.Provider(lasso.PROVIDER_ROLE_IDP,
|
58
|
misc.get_abs_path(idp['metadata']),
|
59
|
misc.get_abs_path(idp['publickey']), None)
|
60
|
providers[p.providerId] = p
|
61
|
|
62
|
include_protocol = True
|
63
|
if len([x for x in providers.values() if
|
64
|
x.getProtocolConformance() == lasso.PROTOCOL_SAML_2_0]) in (0, len(providers)):
|
65
|
include_protocol = False
|
66
|
|
67
|
for p in providers.values():
|
68
|
label = misc.get_provider_label(p)
|
69
|
if include_protocol:
|
70
|
if p.getProtocolConformance() == lasso.PROTOCOL_SAML_2_0:
|
71
|
label = '%s (SAML 2.0)' % label
|
72
|
else:
|
73
|
label = '%s (Liberty ID-FF 1.2)' % label
|
74
|
options.append((p.providerId, label))
|
75
|
if not value:
|
76
|
value = p.providerId
|
77
|
form.add(RadiobuttonsWidget, 'idp', value = value, options = options, delim = '<br/>')
|
78
|
form.add_submit('submit', _('Submit'))
|
79
|
|
80
|
if form.is_submitted() and not form.has_errors():
|
81
|
idp = form.get_widget('idp').parse()
|
82
|
p = providers[form.get_widget('idp').parse()]
|
83
|
if p.getProtocolConformance() == lasso.PROTOCOL_SAML_2_0:
|
84
|
return self.saml.perform_login(idp)
|
85
|
else:
|
86
|
return self.liberty.perform_login(idp)
|
87
|
|
88
|
template.html_top(_('Login'))
|
89
|
'<p>%s</p>' % _('Select the identity provider you want to use.')
|
90
|
form.render()
|
91
|
|
92
|
def logout(self):
|
93
|
logger.info('logout')
|
94
|
session = get_session()
|
95
|
if not session:
|
96
|
return redirect('/')
|
97
|
# add settings to disable single logout?
|
98
|
# (and to set it as none/get/soap?)
|
99
|
return self.liberty.singleLogout()
|
100
|
|
101
|
def token [html] (self):
|
102
|
if not get_request().user:
|
103
|
raise errors.AccessUnauthorizedError()
|
104
|
|
105
|
form = Form(enctype='multipart/form-data')
|
106
|
form.add(StringWidget, 'token', title = _('Identification Token'),
|
107
|
required = True, size = 30)
|
108
|
form.add_submit('submit', _('Submit'))
|
109
|
form.add_submit('cancel', _('Cancel'))
|
110
|
|
111
|
if form.get_widget('cancel').parse():
|
112
|
return redirect('.')
|
113
|
|
114
|
if not form.is_submitted() or form.has_errors():
|
115
|
template.html_top(_('Identification Token'))
|
116
|
'<p>' # XXX: include explanation (?)
|
117
|
_('Please enter your identification token.')
|
118
|
'</p>'
|
119
|
form.render()
|
120
|
else:
|
121
|
session = get_session()
|
122
|
if get_request().user:
|
123
|
lasso_dump = get_request().user.lasso_dump
|
124
|
else:
|
125
|
return template.error_page('No Lasso Identity Dump (???)')
|
126
|
token = form.get_widget('token').parse()
|
127
|
users_with_token = list(User.select(lambda x: x.identification_token == token))
|
128
|
if len(users_with_token) == 0:
|
129
|
return template.error_page(_('Unknown Token'))
|
130
|
|
131
|
user = users_with_token[0]
|
132
|
user.name_identifiers.append(session.name_identifier)
|
133
|
user.lasso_dump = str(lasso_dump)
|
134
|
user.identification_token = None
|
135
|
user.store()
|
136
|
|
137
|
old_name = session.user
|
138
|
session.set_user(user.id)
|
139
|
|
140
|
return redirect('.')
|
141
|
|
142
|
|
143
|
def _q_traverse(self, path):
|
144
|
session = get_session()
|
145
|
if session:
|
146
|
get_request().user = session.get_user()
|
147
|
else:
|
148
|
get_request().user = None
|
149
|
|
150
|
# response = get_response()
|
151
|
# response.filter = {}
|
152
|
# if not hasattr(response, 'breadcrumb'):
|
153
|
# response.breadcrumb = [ ('', _('Home')) ]
|
154
|
|
155
|
try:
|
156
|
return Directory._q_traverse(self, path)
|
157
|
except errors.TraversalError:
|
158
|
pass
|
159
|
|
160
|
return self._q_index()
|
161
|
# return forms.root.RootDirectory()._q_traverse(path)
|
162
|
|
163
|
def _q_lookup(self, component):
|
164
|
return SiteUI(component)
|
165
|
# if component == 'themes':
|
166
|
# dirname = os.path.join(get_publisher().data_dir, 'themes')
|
167
|
# return StaticDirectory(dirname, follow_symlinks = True)
|
168
|
|
169
|
# is this a category ?
|
170
|
# try:
|
171
|
# category = Category.get_by_urlname(component)
|
172
|
# except KeyError:
|
173
|
# pass
|
174
|
# else:
|
175
|
# return forms.root.RootDirectory(category)
|
176
|
|
177
|
# or a form ?
|
178
|
# return forms.root.RootDirectory()._q_lookup(component)
|
179
|
#return self._q_index()
|
180
|
|
181
|
admin = admin.RootDirectory()
|
182
|
saml = saml2.RootDirectory()
|
183
|
liberty = liberty.RootDirectory()
|