34 |
34 |
import json
|
35 |
35 |
import logging
|
36 |
36 |
import socket
|
|
37 |
import csv
|
37 |
38 |
|
38 |
39 |
from datetime import datetime
|
39 |
40 |
from functools import wraps
|
... | ... | |
75 |
76 |
return func(request, *args)
|
76 |
77 |
return wrapper
|
77 |
78 |
|
78 |
|
|
79 |
79 |
def requires_admin(func):
|
80 |
80 |
@wraps(func)
|
81 |
81 |
def wrapper(request, *args):
|
... | ... | |
91 |
91 |
|
92 |
92 |
|
93 |
93 |
def index(request):
|
94 |
|
return render_response('index.html', next=request.GET.get('next', ''))
|
|
94 |
kwargs = {'standard_modules':settings.IM_STANDARD_MODULES,
|
|
95 |
'other_modules':settings.IM_OTHER_MODULES}
|
|
96 |
return render_response('index.html',
|
|
97 |
next=request.GET.get('next', ''),
|
|
98 |
**kwargs)
|
95 |
99 |
|
96 |
100 |
|
97 |
101 |
@requires_admin
|
... | ... | |
134 |
138 |
page=page,
|
135 |
139 |
prev=prev,
|
136 |
140 |
next=next)
|
137 |
|
|
138 |
|
@requires_admin
|
139 |
|
def users_create(request):
|
140 |
|
if request.method == 'GET':
|
141 |
|
return render_response('users_create.html')
|
142 |
|
if request.method == 'POST':
|
143 |
|
user = User()
|
144 |
|
user.uniq = request.POST.get('uniq')
|
145 |
|
user.realname = request.POST.get('realname')
|
146 |
|
user.is_admin = True if request.POST.get('admin') else False
|
147 |
|
user.affiliation = request.POST.get('affiliation')
|
148 |
|
user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3) # In GiB
|
149 |
|
user.renew_token()
|
150 |
|
user.save()
|
151 |
|
return redirect(users_info, user.id)
|
152 |
141 |
|
153 |
142 |
@requires_admin
|
154 |
143 |
def users_info(request, user_id):
|
... | ... | |
229 |
218 |
defaults={'code': code, 'realname': realname})
|
230 |
219 |
|
231 |
220 |
try:
|
232 |
|
send_invitation(request.get_host(), invitation)
|
|
221 |
send_invitation(request.build_absolute_uri('/').rstrip('/'), invitation)
|
233 |
222 |
if created:
|
234 |
223 |
inviter.invitations = max(0, inviter.invitations - 1)
|
235 |
224 |
inviter.save()
|
... | ... | |
257 |
246 |
return HttpResponse(html)
|
258 |
247 |
|
259 |
248 |
def send_verification(baseurl, user):
|
260 |
|
next = quote('http://%s' % baseurl)
|
261 |
249 |
url = settings.ACTIVATION_LOGIN_TARGET % (baseurl,
|
262 |
250 |
quote(user.auth_token),
|
263 |
|
next)
|
|
251 |
quote(baseurl))
|
264 |
252 |
message = render_to_string('activation.txt', {
|
265 |
253 |
'user': user,
|
266 |
254 |
'url': url,
|
... | ... | |
309 |
297 |
user.level = 1
|
310 |
298 |
user.renew_token()
|
311 |
299 |
try:
|
312 |
|
send_verification(request.get_host(), user)
|
|
300 |
send_verification(request.build_absolute_uri('/').rstrip('/'), user)
|
313 |
301 |
message = _('Verification sent to %s' % user.email)
|
314 |
302 |
user.save()
|
315 |
303 |
except (SMTPException, socket.error) as e:
|
... | ... | |
324 |
312 |
return response
|
325 |
313 |
|
326 |
314 |
def send_password(baseurl, user):
|
327 |
|
next = quote('http://%s' % baseurl)
|
328 |
315 |
url = settings.PASSWORD_RESET_TARGET % (baseurl,
|
329 |
316 |
quote(user.uniq),
|
330 |
|
next)
|
|
317 |
quote(baseurl))
|
331 |
318 |
message = render_to_string('password.txt', {
|
332 |
319 |
'user': user,
|
333 |
320 |
'url': url,
|
... | ... | |
347 |
334 |
try:
|
348 |
335 |
user = User.objects.get(uniq=username)
|
349 |
336 |
try:
|
350 |
|
send_password(request.get_host(), user)
|
|
337 |
send_password(request.build_absolute_uri('/').rstrip('/'), user)
|
351 |
338 |
status = 'success'
|
352 |
339 |
message = _('Password reset sent to %s' % user.email)
|
353 |
340 |
user.status = 'UNVERIFIED'
|
... | ... | |
364 |
351 |
'status': status,
|
365 |
352 |
'message': message})
|
366 |
353 |
return HttpResponse(html)
|
|
354 |
|
|
355 |
@requires_admin
|
|
356 |
def invitations_list(request):
|
|
357 |
invitations = Invitation.objects.order_by('id')
|
|
358 |
|
|
359 |
filter = request.GET.get('filter', '')
|
|
360 |
if filter:
|
|
361 |
if filter.startswith('-'):
|
|
362 |
invitations = invitations.exclude(uniq__icontains=filter[1:])
|
|
363 |
else:
|
|
364 |
invitations = invitations.filter(uniq__icontains=filter)
|
|
365 |
|
|
366 |
try:
|
|
367 |
page = int(request.GET.get('page', 1))
|
|
368 |
except ValueError:
|
|
369 |
page = 1
|
|
370 |
offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
|
|
371 |
limit = offset + settings.ADMIN_PAGE_LIMIT
|
|
372 |
|
|
373 |
npages = int(ceil(1.0 * invitations.count() / settings.ADMIN_PAGE_LIMIT))
|
|
374 |
prev = page - 1 if page > 1 else None
|
|
375 |
next = page + 1 if page < npages else None
|
|
376 |
return render_response('invitations_list.html',
|
|
377 |
invitations=invitations[offset:limit],
|
|
378 |
filter=filter,
|
|
379 |
pages=range(1, npages + 1),
|
|
380 |
page=page,
|
|
381 |
prev=prev,
|
|
382 |
next=next)
|
|
383 |
|
|
384 |
@requires_admin
|
|
385 |
def invitations_export(request):
|
|
386 |
# Create the HttpResponse object with the appropriate CSV header.
|
|
387 |
response = HttpResponse(mimetype='text/csv')
|
|
388 |
response['Content-Disposition'] = 'attachment; filename=invitations.csv'
|
|
389 |
|
|
390 |
writer = csv.writer(response)
|
|
391 |
writer.writerow(['ID',
|
|
392 |
'Uniq',
|
|
393 |
'Real Name',
|
|
394 |
'Code',
|
|
395 |
'Inviter Uniq',
|
|
396 |
'Inviter Real Name',
|
|
397 |
'Is_accepted',
|
|
398 |
'Created',
|
|
399 |
'Accepted',])
|
|
400 |
invitations = Invitation.objects.order_by('id')
|
|
401 |
for inv in invitations:
|
|
402 |
writer.writerow([inv.id,
|
|
403 |
inv.uniq.encode("utf-8"),
|
|
404 |
inv.realname.encode("utf-8"),
|
|
405 |
inv.code,
|
|
406 |
inv.inviter.uniq.encode("utf-8"),
|
|
407 |
inv.inviter.realname.encode("utf-8"),
|
|
408 |
inv.is_accepted,
|
|
409 |
inv.created,
|
|
410 |
inv.accepted])
|
|
411 |
|
|
412 |
return response
|
|
413 |
|
|
414 |
|
|
415 |
@requires_admin
|
|
416 |
def users_export(request):
|
|
417 |
# Create the HttpResponse object with the appropriate CSV header.
|
|
418 |
response = HttpResponse(mimetype='text/csv')
|
|
419 |
response['Content-Disposition'] = 'attachment; filename=users.csv'
|
|
420 |
|
|
421 |
writer = csv.writer(response)
|
|
422 |
writer.writerow(['ID',
|
|
423 |
'Uniq',
|
|
424 |
'Real Name',
|
|
425 |
'Admin',
|
|
426 |
'Affiliation',
|
|
427 |
'State',
|
|
428 |
'Quota (GiB)',
|
|
429 |
'Updated',])
|
|
430 |
users = User.objects.order_by('id')
|
|
431 |
for u in users:
|
|
432 |
writer.writerow([u.id,
|
|
433 |
u.uniq.encode("utf-8"),
|
|
434 |
u.realname.encode("utf-8"),
|
|
435 |
u.is_admin,
|
|
436 |
u.affiliation.encode("utf-8"),
|
|
437 |
u.state.encode("utf-8"),
|
|
438 |
u.quota,
|
|
439 |
u.updated])
|
|
440 |
|
|
441 |
return response
|
|
442 |
|
|
443 |
@requires_admin
|
|
444 |
def users_create(request):
|
|
445 |
if request.method == 'GET':
|
|
446 |
return render_response('users_create.html')
|
|
447 |
if request.method == 'POST':
|
|
448 |
user = User()
|
|
449 |
user.uniq = request.POST.get('uniq')
|
|
450 |
user.realname = request.POST.get('realname')
|
|
451 |
user.is_admin = True if request.POST.get('admin') else False
|
|
452 |
user.affiliation = request.POST.get('affiliation')
|
|
453 |
user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3) # In GiB
|
|
454 |
user.renew_token()
|
|
455 |
user.save()
|
|
456 |
return redirect(users_info, user.id)
|
|
457 |
|
|
458 |
@requires_login
|
|
459 |
def users_profile(request):
|
|
460 |
next = request.GET.get('next')
|
|
461 |
user = User.objects.get(uniq=request.user)
|
|
462 |
states = [x[0] for x in User.ACCOUNT_STATE]
|
|
463 |
return render_response('users_profile.html',
|
|
464 |
user=user,
|
|
465 |
states=states,
|
|
466 |
next=next)
|
|
467 |
|
|
468 |
@requires_login
|
|
469 |
def users_edit(request):
|
|
470 |
user = User.objects.get(uniq=request.user)
|
|
471 |
user.realname = request.POST.get('realname')
|
|
472 |
user.affiliation = request.POST.get('affiliation')
|
|
473 |
user.is_verified = True
|
|
474 |
user.save()
|
|
475 |
next = request.POST.get('next')
|
|
476 |
if next:
|
|
477 |
return redirect(next)
|
|
478 |
|
|
479 |
status = 'success'
|
|
480 |
message = _('Profile has been updated')
|
|
481 |
html = render_to_string('users_profile.html', {
|
|
482 |
'user': user,
|
|
483 |
'status': status,
|
|
484 |
'message': message})
|
|
485 |
return HttpResponse(html)
|
|
486 |
|