1
|
import random
|
2
|
|
3
|
import lasso
|
4
|
|
5
|
from quixote import get_request, get_session, redirect, get_publisher
|
6
|
from quixote.directory import Directory
|
7
|
|
8
|
from qommon.admin.menu import html_top, error_page, command_icon
|
9
|
from qommon.errors import EmailError
|
10
|
from qommon.form import *
|
11
|
from qommon import emails
|
12
|
|
13
|
from larpe import errors
|
14
|
from larpe import misc
|
15
|
from larpe.users import User
|
16
|
from larpe.hosts import Host
|
17
|
|
18
|
class UserUI:
|
19
|
def __init__(self, user):
|
20
|
self.user = user
|
21
|
|
22
|
def form_new(self):
|
23
|
form = Form(enctype="multipart/form-data")
|
24
|
form.add(StringWidget, "name", title = _('User Name'), required = True, size=30)
|
25
|
form.add(StringWidget, "email", title = _('Email'), required = False, size=30)
|
26
|
form.add_submit("submit", _("Submit"))
|
27
|
form.add_submit("cancel", _("Cancel"))
|
28
|
return form
|
29
|
|
30
|
def form_edit(self):
|
31
|
form = Form(enctype="multipart/form-data")
|
32
|
form.add(StringWidget, "name", title = _('User Name'), required = True, size=30,
|
33
|
value = self.user.name)
|
34
|
form.add(StringWidget, "email", title = _('Email'), required = False, size=30,
|
35
|
value = self.user.email)
|
36
|
form.add_submit("submit", _("Submit"))
|
37
|
form.add_submit("cancel", _("Cancel"))
|
38
|
return form
|
39
|
|
40
|
def submit_form(self, form):
|
41
|
if not self.user:
|
42
|
self.user = User()
|
43
|
for f in ('name', 'email'):
|
44
|
widget = form.get_widget(f)
|
45
|
if widget:
|
46
|
setattr(self.user, f, widget.parse())
|
47
|
self.user.is_admin = True
|
48
|
self.user.store()
|
49
|
|
50
|
|
51
|
class UserPage(Directory):
|
52
|
_q_exports = ['', 'edit', 'delete', 'token']
|
53
|
|
54
|
def __init__(self, component):
|
55
|
self.user = User.get(component)
|
56
|
self.user_ui = UserUI(self.user)
|
57
|
get_response().breadcrumb.append((component + '/', self.user.name))
|
58
|
|
59
|
def _q_index [html] (self):
|
60
|
html_top('users', '%s - %s' % (_('User'), self.user.name))
|
61
|
'<h2>%s - %s</h2>' % (_('User'), self.user.name)
|
62
|
'<div class="form">'
|
63
|
'<div class="title">%s</div>' % _('Name')
|
64
|
'<div class="StringWidget content">%s</div>' % self.user.name
|
65
|
if self.user.email:
|
66
|
'<div class="title">%s</div>' % _('Email')
|
67
|
'<div class="StringWidget content">%s</div>' % self.user.email
|
68
|
# if self.user.lasso_dump:
|
69
|
# identity = lasso.Identity.newFromDump(self.user.lasso_dump)
|
70
|
# server = misc.get_lasso_server()
|
71
|
# if len(identity.providerIds) and server:
|
72
|
# '<h3>%s</h3>' % _('Liberty Alliance Details')
|
73
|
# '<div class="StringWidget content"><ul>'
|
74
|
# for pid in identity.providerIds:
|
75
|
# provider = server.getProvider(pid)
|
76
|
# label = misc.get_provider_label(provider)
|
77
|
# if label:
|
78
|
# label = '%s (%s)' % (label, pid)
|
79
|
# else:
|
80
|
# label = pid
|
81
|
# federation = identity.getFederation(pid)
|
82
|
# '<li>'
|
83
|
# _('Account federated with %s') % label
|
84
|
# '<br />'
|
85
|
# if federation.localNameIdentifier:
|
86
|
# _("local: ") + federation.localNameIdentifier.content
|
87
|
# if federation.remoteNameIdentifier:
|
88
|
# _("remote: ") + federation.remoteNameIdentifier.content
|
89
|
# '</li>'
|
90
|
# '</ul></div>'
|
91
|
|
92
|
# # XXX: only display this in debug mode:
|
93
|
# '<h4>%s</h4>' % _('Lasso Identity Dump')
|
94
|
# '<pre>%s</pre>' % self.user.lasso_dump
|
95
|
'</div>'
|
96
|
|
97
|
def debug [html] (self):
|
98
|
get_response().breadcrumb.append( ('debug', _('Debug')) )
|
99
|
html_top('users', 'Debug')
|
100
|
"<h2>Debug - %s</h2>" % self.user.name
|
101
|
"<pre>"
|
102
|
self.user.lasso_dump
|
103
|
"</pre>"
|
104
|
|
105
|
def edit [html] (self):
|
106
|
form = self.user_ui.form_edit()
|
107
|
if form.get_widget('cancel').parse():
|
108
|
return redirect('..')
|
109
|
if not form.is_submitted() or form.has_errors():
|
110
|
get_response().breadcrumb.append( ('edit', _('Edit')) )
|
111
|
html_top('users', title = _('Edit User'))
|
112
|
'<h2>%s</h2>' % _('Edit User')
|
113
|
form.render()
|
114
|
else:
|
115
|
self.user_ui.submit_form(form)
|
116
|
return redirect('..')
|
117
|
|
118
|
def delete [html] (self):
|
119
|
form = Form(enctype="multipart/form-data")
|
120
|
form.widgets.append(HtmlWidget('<p>%s</p>' % _(
|
121
|
"You are about to irrevocably delete this user.")))
|
122
|
form.add_submit("submit", _("Submit"))
|
123
|
form.add_submit("cancel", _("Cancel"))
|
124
|
if form.get_widget('cancel').parse():
|
125
|
return redirect('..')
|
126
|
if not form.is_submitted() or form.has_errors():
|
127
|
get_response().breadcrumb.append(('delete', _('Delete')))
|
128
|
html_top('users', title = _('Delete User'))
|
129
|
'<h2>%s %s</h2>' % (_('Deleting User :'), self.user.name)
|
130
|
form.render()
|
131
|
else:
|
132
|
self.user.remove_self()
|
133
|
return redirect('..')
|
134
|
|
135
|
def token [html] (self):
|
136
|
form = Form(enctype="multipart/form-data", use_tokens = False)
|
137
|
form.add_submit("submit", _("Generate"))
|
138
|
form.add_submit("cancel", _("Cancel"))
|
139
|
request = get_request()
|
140
|
if request.form.has_key('cancel') or request.form.has_key('done'):
|
141
|
return redirect('..')
|
142
|
|
143
|
get_response().breadcrumb.append(('token', _('Identification Token')))
|
144
|
|
145
|
if not form.is_submitted() or form.has_errors():
|
146
|
html_top('users', title = _('Identification Token'))
|
147
|
'<h2>%s</h2>' % _('Identification Token')
|
148
|
'<p>%s</p>' % _('You are about to generate a token than can be used to federate the account.')
|
149
|
'<p>%s</p>' % _('After that, you will have the choice to send it to the user by email so that he can federate his accounts.')
|
150
|
if self.user.identification_token:
|
151
|
'<p>%s</p>' % _('Note that user has already been issued an identification token : %s') % self.user.identification_token
|
152
|
form.render()
|
153
|
else:
|
154
|
if request.form.has_key('submit'):
|
155
|
html_top('users', title = _('Identification Token'))
|
156
|
token = '-'.join(['%04d' % random.randint(1, 9999) for x in range(4)])
|
157
|
self.user.identification_token = str(token)
|
158
|
self.user.store()
|
159
|
|
160
|
'<p>'
|
161
|
_('Identification Token for %s') % self.user.name
|
162
|
' : %s</p>' % self.user.identification_token
|
163
|
|
164
|
form = Form(enctype="multipart/form-data", use_tokens = False)
|
165
|
form.add_submit('done', _('Done'))
|
166
|
if self.user.email:
|
167
|
form.add_submit("submit-email", _("Send by email"))
|
168
|
form.render()
|
169
|
else:
|
170
|
site_url = '%s://%s%s/token?token=%s' \
|
171
|
% (request.get_scheme(), request.get_server(),
|
172
|
get_request().environ['SCRIPT_NAME'], self.user.identification_token)
|
173
|
body = _("""You have been given an identification token.
|
174
|
|
175
|
Your token is %(token)s
|
176
|
|
177
|
Click on %(url)s to use it.
|
178
|
""") % {'token': self.user.identification_token, 'url': site_url}
|
179
|
try:
|
180
|
emails.email(_('Identification Token'), body, self.user.email)
|
181
|
except EmailError, e:
|
182
|
html_top('users', title = _('Identification Token'))
|
183
|
_('Failed sending email. Check your email configuration.')
|
184
|
'<div class="buttons"><a href=".."><input type="button" value="%s" /></a></div><br />' % _('Back')
|
185
|
else:
|
186
|
return redirect('..')
|
187
|
|
188
|
class UsersDirectory(Directory):
|
189
|
|
190
|
_q_exports = ['', 'new']
|
191
|
|
192
|
def _q_index [html] (self):
|
193
|
get_publisher().reload_cfg()
|
194
|
get_response().breadcrumb.append( ('users/', _('Users')) )
|
195
|
html_top('users', title = _('Users'))
|
196
|
|
197
|
|
198
|
if not list(Host.select(lambda x: x.name == 'larpe')):
|
199
|
'<p>%s</p>' % _('Liberty support must be setup before creating users.')
|
200
|
else:
|
201
|
"""<ul id="nav-users-admin">
|
202
|
<li><a href="new">%s</a></li>
|
203
|
</ul>""" % _('New User')
|
204
|
|
205
|
debug_cfg = get_publisher().cfg.get('debug', {})
|
206
|
|
207
|
users = User.select(lambda x: x.name is not None, order_by = 'name')
|
208
|
|
209
|
'<ul class="biglist">'
|
210
|
for user in users:
|
211
|
'<li>'
|
212
|
'<strong class="label">%s</strong>' % user.name
|
213
|
if user.email:
|
214
|
'<p class="details">'
|
215
|
user.email
|
216
|
'</p>'
|
217
|
|
218
|
'<p class="commands">'
|
219
|
command_icon('%s/' % user.id, 'view')
|
220
|
if not user.name_identifiers:
|
221
|
if not user.identification_token:
|
222
|
command_icon('%s/token' % user.id, 'token',
|
223
|
label = _('Identification Token'), icon = 'stock_exec_16.png')
|
224
|
else:
|
225
|
command_icon('%s/token' % user.id, 'token',
|
226
|
label = _('Identification Token (current: %s)') % \
|
227
|
user.identification_token,
|
228
|
icon = 'stock_exec_16.png')
|
229
|
command_icon('%s/edit' % user.id, 'edit')
|
230
|
command_icon('%s/delete' % user.id, 'remove')
|
231
|
if debug_cfg.get('logger', False):
|
232
|
command_icon('../logger/by_user/%s/' % user.id, 'logs',
|
233
|
label = _('Logs'), icon = 'stock_harddisk_16.png')
|
234
|
'</p></li>'
|
235
|
'</ul>'
|
236
|
|
237
|
def new [html] (self):
|
238
|
get_response().breadcrumb.append( ('users/', _('Users')) )
|
239
|
get_response().breadcrumb.append( ('new', _('New')) )
|
240
|
hosts = list(Host.select(lambda x: x.name == 'larpe'))
|
241
|
if not hosts:
|
242
|
return error_page('users', _('Liberty support must be setup before creating users.'))
|
243
|
host = hosts[0]
|
244
|
# XXX: user must be logged in to get here
|
245
|
user_ui = UserUI(None)
|
246
|
# FIXME : should be able to use User.count(). Track fake user creations.
|
247
|
users = User.select(lambda x: x.name is not None)
|
248
|
first_user = (len(users) == 0)
|
249
|
form = user_ui.form_new()
|
250
|
if form.get_widget('cancel').parse():
|
251
|
return redirect('.')
|
252
|
|
253
|
if not form.is_submitted() or form.has_errors():
|
254
|
html_top('users', title = _('New User'))
|
255
|
'<h2>%s</h2>' % _('New User')
|
256
|
form.render()
|
257
|
else:
|
258
|
user_ui.submit_form(form)
|
259
|
if first_user:
|
260
|
session = get_session()
|
261
|
if hasattr(session, str('lasso_dump')):
|
262
|
user_ui.user.name_identifiers = [ session.name_identifier ]
|
263
|
user_ui.user.lasso_dumps = [ session.lasso_anonymous_identity_dump ]
|
264
|
user_ui.user.store()
|
265
|
if misc.get_current_protocol() == lasso.PROTOCOL_SAML_2_0:
|
266
|
get_session().set_user(user_ui.user.id, host.saml2_provider_id)
|
267
|
else:
|
268
|
get_session().set_user(user_ui.user.id, host.provider_id)
|
269
|
return redirect('.')
|
270
|
|
271
|
def _q_lookup(self, component):
|
272
|
get_response().breadcrumb.append( ('users/', _('Users')) )
|
273
|
try:
|
274
|
return UserPage(component)
|
275
|
except KeyError:
|
276
|
raise errors.TraversalError()
|