Revision 890b0eaf astakos/im/admin/views.py

b/astakos/im/admin/views.py
53 53
from django.utils.http import urlencode
54 54
from django.utils.translation import ugettext as _
55 55
from django.core.urlresolvers import reverse
56
from django.contrib import messages
57
from django.db import transaction
58
from django.contrib.auth.models import AnonymousUser
59
from django.contrib.sites.models import get_current_site
56 60

  
57
#from astakos.im.openid_store import PithosOpenIDStore
58 61
from astakos.im.models import AstakosUser, Invitation
59 62
from astakos.im.util import isoformat, get_or_create_user, get_context
60 63
from astakos.im.forms import *
61 64
from astakos.im.backends import get_backend
62 65
from astakos.im.views import render_response, index
66
from astakos.im.admin.forms import AdminProfileForm
63 67

  
64 68
def requires_admin(func):
69
    """
70
    Decorator checkes whether the request.user is a superuser and if not
71
    redirects to login page.
72
    """
65 73
    @wraps(func)
66 74
    def wrapper(request, *args):
67 75
        if not settings.BYPASS_ADMIN_AUTH:
68
            if not request.user:
76
            if isinstance(request.user, AnonymousUser):
69 77
                next = urlencode({'next': request.build_absolute_uri()})
70 78
                login_uri = reverse(index) + '?' + next
71 79
                return HttpResponseRedirect(login_uri)
......
76 84

  
77 85
@requires_admin
78 86
def admin(request, template_name='admin.html', extra_context={}):
87
    """
88
    Renders the admin page
89
    
90
    If the ``request.user`` is not a superuser redirects to login page.
91
    
92
   **Arguments**
93
    
94
    ``template_name``
95
        A custom template to use. This is optional; if not specified,
96
        this will default to ``admin.html``.
97
    
98
    ``extra_context``
99
        An dictionary of variables to add to the template context.
100
    
101
   **Template:**
102
    
103
    admin.html or ``template_name`` keyword argument.
104
    
105
   **Template Context:**
106
    
107
    The template context is extended by:
108
    
109
    * tab: the name of the active tab
110
    * stats: dictionary containing the number of all and prending users
111
    """
79 112
    stats = {}
80 113
    stats['users'] = AstakosUser.objects.count()
81 114
    stats['pending'] = AstakosUser.objects.filter(is_active = False).count()
......
85 118
    stats['invitations_consumed'] = invitations.filter(is_consumed=True).count()
86 119
    
87 120
    kwargs = {'tab': 'home', 'stats': stats}
88
    context = get_context(request, extra_context, **kwargs)
121
    context = get_context(request, extra_context,**kwargs)
89 122
    return render_response(template_name, context_instance = context)
90 123

  
91 124
@requires_admin
92 125
def users_list(request, template_name='users_list.html', extra_context={}):
126
    """
127
    Displays the list of all users.
128
    
129
    If the ``request.user`` is not a superuser redirects to login page.
130
    
131
   **Arguments**
132
    
133
    ``template_name``
134
        A custom template to use. This is optional; if not specified,
135
        this will default to ``users_list.html``.
136
    
137
    ``extra_context``
138
        An dictionary of variables to add to the template context.
139
    
140
   **Template:**
141
    
142
    users_list.html or ``template_name`` keyword argument.
143
    
144
   **Template Context:**
145
    
146
    The template context is extended by:
147
    
148
    * users: list of users fitting in current page
149
    * filter: search key
150
    * pages: the number of pages
151
    * prev: the previous page
152
    * next: the current page
153
    
154
   **Settings:**
155
    
156
    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
157
    """
93 158
    users = AstakosUser.objects.order_by('id')
94 159
    
95 160
    filter = request.GET.get('filter', '')
......
115 180
              'pages':range(1, npages + 1),
116 181
              'prev':prev,
117 182
              'next':next}
118
    context = get_context(request, extra_context, **kwargs)
183
    context = get_context(request, extra_context,**kwargs)
119 184
    return render_response(template_name, context_instance = context)
120 185

  
121 186
@requires_admin
122 187
def users_info(request, user_id, template_name='users_info.html', extra_context={}):
188
    """
189
    Displays the specific user profile.
190
    
191
    If the ``request.user`` is not a superuser redirects to login page.
192
    
193
   **Arguments**
194
    
195
    ``template_name``
196
        A custom template to use. This is optional; if not specified,
197
        this will default to ``users_info.html``.
198
    
199
    ``extra_context``
200
        An dictionary of variables to add to the template context.
201
    
202
   **Template:**
203
    
204
    users_info.html or ``template_name`` keyword argument.
205
    
206
   **Template Context:**
207
    
208
    The template context is extended by:
209
    
210
    * user: the user instance identified by ``user_id`` keyword argument
211
    """
123 212
    if not extra_context:
124 213
        extra_context = {}
125
    kwargs = {'user':AstakosUser.objects.get(id=user_id)}
126
    context = get_context(request, extra_context, **kwargs)
127
    return render_response(template_name, context_instance = context)
214
    user = AstakosUser.objects.get(id=user_id)
215
    return render_response(template_name,
216
                           form = AdminProfileForm(instance=user),
217
                           context_instance = get_context(request, extra_context))
128 218

  
129 219
@requires_admin
130
def users_modify(request, user_id):
131
    user = AstakosUser.objects.get(id=user_id)
132
    user.username = request.POST.get('username')
133
    user.first_name = request.POST.get('first_name')
134
    user.last_name = request.POST.get('last_name')
135
    user.is_superuser = True if request.POST.get('admin') else False
136
    user.affiliation = request.POST.get('affiliation')
137
    user.is_active = True if request.POST.get('is_active') else False
138
    user.invitations = int(request.POST.get('invitations') or 0)
139
    #user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
140
    user.auth_token = request.POST.get('auth_token')
141
    try:
142
        auth_token_expires = request.POST.get('auth_token_expires')
143
        d = datetime.strptime(auth_token_expires, '%Y-%m-%dT%H:%MZ')
144
        user.auth_token_expires = d
145
    except ValueError:
146
        pass
147
    user.save()
148
    return redirect(users_info, user.id)
220
def users_modify(request, user_id, template_name='users_info.html', extra_context={}):
221
    """
222
    Update the specific user information. Upon success redirects to ``user_info`` view.
223
    
224
    If the ``request.user`` is not a superuser redirects to login page.
225
    """
226
    form = AdminProfileForm(request.POST)
227
    if form.is_valid():
228
        form.save()
229
        return redirect(users_info, user.id, template_name, extra_context)
230
    return render_response(template_name,
231
                           form = form,
232
                           context_instance = get_context(request, extra_context))
149 233

  
150 234
@requires_admin
151 235
def users_delete(request, user_id):
236
    """
237
    Deletes the specified user
238
    
239
    If the ``request.user`` is not a superuser redirects to login page.
240
    """
152 241
    user = AstakosUser.objects.get(id=user_id)
153 242
    user.delete()
154 243
    return redirect(users_list)
155 244

  
156 245
@requires_admin
157 246
def pending_users(request, template_name='pending_users.html', extra_context={}):
247
    """
248
    Displays the list of the pending users.
249
    
250
    If the ``request.user`` is not a superuser redirects to login page.
251
    
252
   **Arguments**
253
    
254
    ``template_name``
255
        A custom template to use. This is optional; if not specified,
256
        this will default to ``users_list.html``.
257
    
258
    ``extra_context``
259
        An dictionary of variables to add to the template context.
260
    
261
   **Template:**
262
    
263
    pending_users.html or ``template_name`` keyword argument.
264
    
265
   **Template Context:**
266
    
267
    The template context is extended by:
268
    
269
    * users: list of pending users fitting in current page
270
    * filter: search key
271
    * pages: the number of pages
272
    * prev: the previous page
273
    * next: the current page
274
    
275
   **Settings:**
276
    
277
    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
278
    """
158 279
    users = AstakosUser.objects.order_by('id')
159 280
    
160 281
    users = users.filter(is_active = False)
......
183 304
              'prev':prev,
184 305
              'next':next}
185 306
    return render_response(template_name,
186
                            context_instance = get_context(request, extra_context, **kwargs))
307
                            context_instance = get_context(request, extra_context,**kwargs))
187 308

  
188
def _send_greeting(baseurl, user):
309
def _send_greeting(request, user, template_name):
189 310
    url = reverse('astakos.im.views.index')
190 311
    subject = _('Welcome to %s' %settings.SERVICE_NAME)
191
    message = render_to_string('welcome.txt', {
312
    site = get_current_site(request)
313
    baseurl = request.build_absolute_uri('/').rstrip('/')
314
    message = render_to_string(template_name, {
192 315
                'user': user,
193 316
                'url': url,
194 317
                'baseurl': baseurl,
195
                'service': settings.SERVICE_NAME,
318
                'site_name': site.name,
196 319
                'support': settings.DEFAULT_CONTACT_EMAIL})
197 320
    sender = settings.DEFAULT_FROM_EMAIL
198 321
    send_mail(subject, message, sender, [user.email])
199 322
    logging.info('Sent greeting %s', user)
200 323

  
201 324
@requires_admin
202
def users_activate(request, user_id, template_name='pending_users.html', extra_context={}):
325
@transaction.commit_manually
326
def users_activate(request, user_id, template_name='pending_users.html', extra_context={}, email_template_name='welcome_email.txt'):
327
    """
328
    Activates the specific user and sends an email. Upon success renders the
329
    ``template_name`` keyword argument if exists else renders ``pending_users.html``.
330
    
331
    If the ``request.user`` is not a superuser redirects to login page.
332
    
333
   **Arguments**
334
    
335
    ``template_name``
336
        A custom template to use. This is optional; if not specified,
337
        this will default to ``users_list.html``.
338
    
339
    ``extra_context``
340
        An dictionary of variables to add to the template context.
341
    
342
   **Templates:**
343
    
344
    pending_users.html or ``template_name`` keyword argument.
345
    welcome_email.txt or ``email_template_name`` keyword argument.
346
    
347
   **Template Context:**
348
    
349
    The template context is extended by:
350
    
351
    * users: list of pending users fitting in current page
352
    * filter: search key
353
    * pages: the number of pages
354
    * prev: the previous page
355
    * next: the current page
356
    """
203 357
    user = AstakosUser.objects.get(id=user_id)
204 358
    user.is_active = True
205
    status = 'success'
359
    user.save()
360
    status = messages.SUCCESS
206 361
    try:
207
        _send_greeting(request.build_absolute_uri('/').rstrip('/'), user)
362
        _send_greeting(request, user, email_template_name)
208 363
        message = _('Greeting sent to %s' % user.email)
209
        user.save()
364
        transaction.commit()
210 365
    except (SMTPException, socket.error) as e:
211
        status = 'error'
366
        status = messages.ERROR
212 367
        name = 'strerror'
213 368
        message = getattr(e, name) if hasattr(e, name) else e
369
        transaction.rollback()
370
    messages.add_message(request, status, message)
214 371
    
215 372
    users = AstakosUser.objects.order_by('id')
216 373
    users = users.filter(is_active = False)
......
230 387
              'pages':range(1, npages + 1),
231 388
              'page':page,
232 389
              'prev':prev,
233
              'next':next,
234
              'message':message}
390
              'next':next}
235 391
    return render_response(template_name,
236
                           context_instance = get_context(request, extra_context, **kwargs))
392
                           context_instance = get_context(request, extra_context,**kwargs))
237 393

  
238 394
@requires_admin
239 395
def invitations_list(request, template_name='invitations_list.html', extra_context={}):
396
    """
397
    Displays a list with the Invitations.
398
    
399
    If the ``request.user`` is not a superuser redirects to login page.
400
    
401
   **Arguments**
402
    
403
    ``template_name``
404
        A custom template to use. This is optional; if not specified,
405
        this will default to ``invitations_list.html``.
406
    
407
    ``extra_context``
408
        An dictionary of variables to add to the template context.
409
    
410
   **Templates:**
411
    
412
    invitations_list.html or ``template_name`` keyword argument.
413
    
414
   **Template Context:**
415
    
416
    The template context is extended by:
417
    
418
    * invitations: list of invitations fitting in current page
419
    * filter: search key
420
    * pages: the number of pages
421
    * prev: the previous page
422
    * next: the current page
423
    """
240 424
    invitations = Invitation.objects.order_by('id')
241 425
    
242 426
    filter = request.GET.get('filter', '')
......
263 447
              'prev':prev,
264 448
              'next':next}
265 449
    return render_response(template_name,
266
                           context_instance = get_context(request, extra_context, **kwargs))
450
                           context_instance = get_context(request, extra_context,**kwargs))
267 451

  
268 452
@requires_admin
269 453
def invitations_export(request):
454
    """
455
    Exports the invitation list in csv file.
456
    """
270 457
    # Create the HttpResponse object with the appropriate CSV header.
271 458
    response = HttpResponse(mimetype='text/csv')
272 459
    response['Content-Disposition'] = 'attachment; filename=invitations.csv'
......
299 486

  
300 487
@requires_admin
301 488
def users_export(request):
489
    """
490
    Exports the user list in csv file.
491
    """
302 492
    # Create the HttpResponse object with the appropriate CSV header.
303 493
    response = HttpResponse(mimetype='text/csv')
304 494
    response['Content-Disposition'] = 'attachment; filename=users.csv'
......
327 517

  
328 518
@requires_admin
329 519
def users_create(request, template_name='users_create.html', extra_context={}):
520
    """
521
    Creates a user. Upon success redirect to ``users_info`` view.
522
    
523
   **Arguments**
524
    
525
    ``template_name``
526
        A custom template to use. This is optional; if not specified,
527
        this will default to ``users_create.html``.
528
    
529
    ``extra_context``
530
        An dictionary of variables to add to the template context.
531
    
532
   **Templates:**
533
    
534
    users_create.html or ``template_name`` keyword argument.
535
    """
330 536
    if request.method == 'GET':
331 537
        return render_response(template_name,
332 538
                               context_instance=get_context(request, extra_context))
......
338 544
        user.last_name = request.POST.get('last_name')
339 545
        user.is_superuser = True if request.POST.get('admin') else False
340 546
        user.affiliation = request.POST.get('affiliation')
341
        user.quota = int(request.POST.get('quota') or 0) * (1024 ** 3)  # In GiB
547
        user.quota = int(request.POST.get('quota') or 0) * (1024**3)  # In GiB
342 548
        user.renew_token()
343 549
        user.provider = 'local'
344 550
        user.save()

Also available in: Unified diff