Statistics
| Branch: | Tag: | Revision:

root / astakos / im / admin / views.py @ 890b0eaf

History | View | Annotate | Download (18.4 kB)

1 0905ccd2 Sofia Papagiannaki
# Copyright 2011 GRNET S.A. All rights reserved.
2 0905ccd2 Sofia Papagiannaki
# 
3 0905ccd2 Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 0905ccd2 Sofia Papagiannaki
# without modification, are permitted provided that the following
5 0905ccd2 Sofia Papagiannaki
# conditions are met:
6 0905ccd2 Sofia Papagiannaki
# 
7 0905ccd2 Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 0905ccd2 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 0905ccd2 Sofia Papagiannaki
#      disclaimer.
10 0905ccd2 Sofia Papagiannaki
# 
11 0905ccd2 Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 0905ccd2 Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 0905ccd2 Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 0905ccd2 Sofia Papagiannaki
#      provided with the distribution.
15 0905ccd2 Sofia Papagiannaki
# 
16 0905ccd2 Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 0905ccd2 Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 0905ccd2 Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 0905ccd2 Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 0905ccd2 Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 0905ccd2 Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 0905ccd2 Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 0905ccd2 Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 0905ccd2 Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 0905ccd2 Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 0905ccd2 Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 0905ccd2 Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 0905ccd2 Sofia Papagiannaki
# 
29 0905ccd2 Sofia Papagiannaki
# The views and conclusions contained in the software and
30 0905ccd2 Sofia Papagiannaki
# documentation are those of the authors and should not be
31 0905ccd2 Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 0905ccd2 Sofia Papagiannaki
# or implied, of GRNET S.A.
33 0905ccd2 Sofia Papagiannaki
34 0905ccd2 Sofia Papagiannaki
import json
35 0905ccd2 Sofia Papagiannaki
import logging
36 0905ccd2 Sofia Papagiannaki
import socket
37 0905ccd2 Sofia Papagiannaki
import csv
38 0905ccd2 Sofia Papagiannaki
import sys
39 0905ccd2 Sofia Papagiannaki
40 0905ccd2 Sofia Papagiannaki
from datetime import datetime
41 0905ccd2 Sofia Papagiannaki
from functools import wraps
42 0905ccd2 Sofia Papagiannaki
from math import ceil
43 0905ccd2 Sofia Papagiannaki
from random import randint
44 0905ccd2 Sofia Papagiannaki
from smtplib import SMTPException
45 0905ccd2 Sofia Papagiannaki
from hashlib import new as newhasher
46 0905ccd2 Sofia Papagiannaki
from urllib import quote
47 0905ccd2 Sofia Papagiannaki
48 0905ccd2 Sofia Papagiannaki
from django.conf import settings
49 0905ccd2 Sofia Papagiannaki
from django.core.mail import send_mail
50 0905ccd2 Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
51 0905ccd2 Sofia Papagiannaki
from django.shortcuts import redirect
52 0905ccd2 Sofia Papagiannaki
from django.template.loader import render_to_string
53 0905ccd2 Sofia Papagiannaki
from django.utils.http import urlencode
54 0905ccd2 Sofia Papagiannaki
from django.utils.translation import ugettext as _
55 0905ccd2 Sofia Papagiannaki
from django.core.urlresolvers import reverse
56 890b0eaf Sofia Papagiannaki
from django.contrib import messages
57 890b0eaf Sofia Papagiannaki
from django.db import transaction
58 890b0eaf Sofia Papagiannaki
from django.contrib.auth.models import AnonymousUser
59 890b0eaf Sofia Papagiannaki
from django.contrib.sites.models import get_current_site
60 0905ccd2 Sofia Papagiannaki
61 0905ccd2 Sofia Papagiannaki
from astakos.im.models import AstakosUser, Invitation
62 0905ccd2 Sofia Papagiannaki
from astakos.im.util import isoformat, get_or_create_user, get_context
63 0905ccd2 Sofia Papagiannaki
from astakos.im.forms import *
64 0905ccd2 Sofia Papagiannaki
from astakos.im.backends import get_backend
65 0905ccd2 Sofia Papagiannaki
from astakos.im.views import render_response, index
66 890b0eaf Sofia Papagiannaki
from astakos.im.admin.forms import AdminProfileForm
67 0905ccd2 Sofia Papagiannaki
68 0905ccd2 Sofia Papagiannaki
def requires_admin(func):
69 890b0eaf Sofia Papagiannaki
    """
70 890b0eaf Sofia Papagiannaki
    Decorator checkes whether the request.user is a superuser and if not
71 890b0eaf Sofia Papagiannaki
    redirects to login page.
72 890b0eaf Sofia Papagiannaki
    """
73 0905ccd2 Sofia Papagiannaki
    @wraps(func)
74 0905ccd2 Sofia Papagiannaki
    def wrapper(request, *args):
75 0905ccd2 Sofia Papagiannaki
        if not settings.BYPASS_ADMIN_AUTH:
76 890b0eaf Sofia Papagiannaki
            if isinstance(request.user, AnonymousUser):
77 0905ccd2 Sofia Papagiannaki
                next = urlencode({'next': request.build_absolute_uri()})
78 0905ccd2 Sofia Papagiannaki
                login_uri = reverse(index) + '?' + next
79 0905ccd2 Sofia Papagiannaki
                return HttpResponseRedirect(login_uri)
80 0905ccd2 Sofia Papagiannaki
            if not request.user.is_superuser:
81 0905ccd2 Sofia Papagiannaki
                return HttpResponse('Forbidden', status=403)
82 0905ccd2 Sofia Papagiannaki
        return func(request, *args)
83 0905ccd2 Sofia Papagiannaki
    return wrapper
84 0905ccd2 Sofia Papagiannaki
85 0905ccd2 Sofia Papagiannaki
@requires_admin
86 0905ccd2 Sofia Papagiannaki
def admin(request, template_name='admin.html', extra_context={}):
87 890b0eaf Sofia Papagiannaki
    """
88 890b0eaf Sofia Papagiannaki
    Renders the admin page
89 890b0eaf Sofia Papagiannaki
    
90 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
91 890b0eaf Sofia Papagiannaki
    
92 890b0eaf Sofia Papagiannaki
   **Arguments**
93 890b0eaf Sofia Papagiannaki
    
94 890b0eaf Sofia Papagiannaki
    ``template_name``
95 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
96 890b0eaf Sofia Papagiannaki
        this will default to ``admin.html``.
97 890b0eaf Sofia Papagiannaki
    
98 890b0eaf Sofia Papagiannaki
    ``extra_context``
99 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
100 890b0eaf Sofia Papagiannaki
    
101 890b0eaf Sofia Papagiannaki
   **Template:**
102 890b0eaf Sofia Papagiannaki
    
103 890b0eaf Sofia Papagiannaki
    admin.html or ``template_name`` keyword argument.
104 890b0eaf Sofia Papagiannaki
    
105 890b0eaf Sofia Papagiannaki
   **Template Context:**
106 890b0eaf Sofia Papagiannaki
    
107 890b0eaf Sofia Papagiannaki
    The template context is extended by:
108 890b0eaf Sofia Papagiannaki
    
109 890b0eaf Sofia Papagiannaki
    * tab: the name of the active tab
110 890b0eaf Sofia Papagiannaki
    * stats: dictionary containing the number of all and prending users
111 890b0eaf Sofia Papagiannaki
    """
112 0905ccd2 Sofia Papagiannaki
    stats = {}
113 0905ccd2 Sofia Papagiannaki
    stats['users'] = AstakosUser.objects.count()
114 0905ccd2 Sofia Papagiannaki
    stats['pending'] = AstakosUser.objects.filter(is_active = False).count()
115 0905ccd2 Sofia Papagiannaki
    
116 0905ccd2 Sofia Papagiannaki
    invitations = Invitation.objects.all()
117 0905ccd2 Sofia Papagiannaki
    stats['invitations'] = invitations.count()
118 0905ccd2 Sofia Papagiannaki
    stats['invitations_consumed'] = invitations.filter(is_consumed=True).count()
119 0905ccd2 Sofia Papagiannaki
    
120 0905ccd2 Sofia Papagiannaki
    kwargs = {'tab': 'home', 'stats': stats}
121 890b0eaf Sofia Papagiannaki
    context = get_context(request, extra_context,**kwargs)
122 0905ccd2 Sofia Papagiannaki
    return render_response(template_name, context_instance = context)
123 0905ccd2 Sofia Papagiannaki
124 0905ccd2 Sofia Papagiannaki
@requires_admin
125 0905ccd2 Sofia Papagiannaki
def users_list(request, template_name='users_list.html', extra_context={}):
126 890b0eaf Sofia Papagiannaki
    """
127 890b0eaf Sofia Papagiannaki
    Displays the list of all users.
128 890b0eaf Sofia Papagiannaki
    
129 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
130 890b0eaf Sofia Papagiannaki
    
131 890b0eaf Sofia Papagiannaki
   **Arguments**
132 890b0eaf Sofia Papagiannaki
    
133 890b0eaf Sofia Papagiannaki
    ``template_name``
134 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
135 890b0eaf Sofia Papagiannaki
        this will default to ``users_list.html``.
136 890b0eaf Sofia Papagiannaki
    
137 890b0eaf Sofia Papagiannaki
    ``extra_context``
138 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
139 890b0eaf Sofia Papagiannaki
    
140 890b0eaf Sofia Papagiannaki
   **Template:**
141 890b0eaf Sofia Papagiannaki
    
142 890b0eaf Sofia Papagiannaki
    users_list.html or ``template_name`` keyword argument.
143 890b0eaf Sofia Papagiannaki
    
144 890b0eaf Sofia Papagiannaki
   **Template Context:**
145 890b0eaf Sofia Papagiannaki
    
146 890b0eaf Sofia Papagiannaki
    The template context is extended by:
147 890b0eaf Sofia Papagiannaki
    
148 890b0eaf Sofia Papagiannaki
    * users: list of users fitting in current page
149 890b0eaf Sofia Papagiannaki
    * filter: search key
150 890b0eaf Sofia Papagiannaki
    * pages: the number of pages
151 890b0eaf Sofia Papagiannaki
    * prev: the previous page
152 890b0eaf Sofia Papagiannaki
    * next: the current page
153 890b0eaf Sofia Papagiannaki
    
154 890b0eaf Sofia Papagiannaki
   **Settings:**
155 890b0eaf Sofia Papagiannaki
    
156 890b0eaf Sofia Papagiannaki
    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
157 890b0eaf Sofia Papagiannaki
    """
158 0905ccd2 Sofia Papagiannaki
    users = AstakosUser.objects.order_by('id')
159 0905ccd2 Sofia Papagiannaki
    
160 0905ccd2 Sofia Papagiannaki
    filter = request.GET.get('filter', '')
161 0905ccd2 Sofia Papagiannaki
    if filter:
162 0905ccd2 Sofia Papagiannaki
        if filter.startswith('-'):
163 0905ccd2 Sofia Papagiannaki
            users = users.exclude(username__icontains=filter[1:])
164 0905ccd2 Sofia Papagiannaki
        else:
165 0905ccd2 Sofia Papagiannaki
            users = users.filter(username__icontains=filter)
166 0905ccd2 Sofia Papagiannaki
    
167 0905ccd2 Sofia Papagiannaki
    try:
168 0905ccd2 Sofia Papagiannaki
        page = int(request.GET.get('page', 1))
169 0905ccd2 Sofia Papagiannaki
    except ValueError:
170 0905ccd2 Sofia Papagiannaki
        page = 1
171 0905ccd2 Sofia Papagiannaki
    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
172 0905ccd2 Sofia Papagiannaki
    limit = offset + settings.ADMIN_PAGE_LIMIT
173 0905ccd2 Sofia Papagiannaki
    
174 0905ccd2 Sofia Papagiannaki
    npages = int(ceil(1.0 * users.count() / settings.ADMIN_PAGE_LIMIT))
175 0905ccd2 Sofia Papagiannaki
    prev = page - 1 if page > 1 else None
176 0905ccd2 Sofia Papagiannaki
    next = page + 1 if page < npages else None
177 0905ccd2 Sofia Papagiannaki
    
178 0905ccd2 Sofia Papagiannaki
    kwargs = {'users':users[offset:limit],
179 0905ccd2 Sofia Papagiannaki
              'filter':filter,
180 0905ccd2 Sofia Papagiannaki
              'pages':range(1, npages + 1),
181 0905ccd2 Sofia Papagiannaki
              'prev':prev,
182 0905ccd2 Sofia Papagiannaki
              'next':next}
183 890b0eaf Sofia Papagiannaki
    context = get_context(request, extra_context,**kwargs)
184 0905ccd2 Sofia Papagiannaki
    return render_response(template_name, context_instance = context)
185 0905ccd2 Sofia Papagiannaki
186 0905ccd2 Sofia Papagiannaki
@requires_admin
187 0905ccd2 Sofia Papagiannaki
def users_info(request, user_id, template_name='users_info.html', extra_context={}):
188 890b0eaf Sofia Papagiannaki
    """
189 890b0eaf Sofia Papagiannaki
    Displays the specific user profile.
190 890b0eaf Sofia Papagiannaki
    
191 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
192 890b0eaf Sofia Papagiannaki
    
193 890b0eaf Sofia Papagiannaki
   **Arguments**
194 890b0eaf Sofia Papagiannaki
    
195 890b0eaf Sofia Papagiannaki
    ``template_name``
196 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
197 890b0eaf Sofia Papagiannaki
        this will default to ``users_info.html``.
198 890b0eaf Sofia Papagiannaki
    
199 890b0eaf Sofia Papagiannaki
    ``extra_context``
200 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
201 890b0eaf Sofia Papagiannaki
    
202 890b0eaf Sofia Papagiannaki
   **Template:**
203 890b0eaf Sofia Papagiannaki
    
204 890b0eaf Sofia Papagiannaki
    users_info.html or ``template_name`` keyword argument.
205 890b0eaf Sofia Papagiannaki
    
206 890b0eaf Sofia Papagiannaki
   **Template Context:**
207 890b0eaf Sofia Papagiannaki
    
208 890b0eaf Sofia Papagiannaki
    The template context is extended by:
209 890b0eaf Sofia Papagiannaki
    
210 890b0eaf Sofia Papagiannaki
    * user: the user instance identified by ``user_id`` keyword argument
211 890b0eaf Sofia Papagiannaki
    """
212 0905ccd2 Sofia Papagiannaki
    if not extra_context:
213 0905ccd2 Sofia Papagiannaki
        extra_context = {}
214 890b0eaf Sofia Papagiannaki
    user = AstakosUser.objects.get(id=user_id)
215 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
216 890b0eaf Sofia Papagiannaki
                           form = AdminProfileForm(instance=user),
217 890b0eaf Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
218 0905ccd2 Sofia Papagiannaki
219 0905ccd2 Sofia Papagiannaki
@requires_admin
220 890b0eaf Sofia Papagiannaki
def users_modify(request, user_id, template_name='users_info.html', extra_context={}):
221 890b0eaf Sofia Papagiannaki
    """
222 890b0eaf Sofia Papagiannaki
    Update the specific user information. Upon success redirects to ``user_info`` view.
223 890b0eaf Sofia Papagiannaki
    
224 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
225 890b0eaf Sofia Papagiannaki
    """
226 890b0eaf Sofia Papagiannaki
    form = AdminProfileForm(request.POST)
227 890b0eaf Sofia Papagiannaki
    if form.is_valid():
228 890b0eaf Sofia Papagiannaki
        form.save()
229 890b0eaf Sofia Papagiannaki
        return redirect(users_info, user.id, template_name, extra_context)
230 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
231 890b0eaf Sofia Papagiannaki
                           form = form,
232 890b0eaf Sofia Papagiannaki
                           context_instance = get_context(request, extra_context))
233 0905ccd2 Sofia Papagiannaki
234 0905ccd2 Sofia Papagiannaki
@requires_admin
235 0905ccd2 Sofia Papagiannaki
def users_delete(request, user_id):
236 890b0eaf Sofia Papagiannaki
    """
237 890b0eaf Sofia Papagiannaki
    Deletes the specified user
238 890b0eaf Sofia Papagiannaki
    
239 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
240 890b0eaf Sofia Papagiannaki
    """
241 0905ccd2 Sofia Papagiannaki
    user = AstakosUser.objects.get(id=user_id)
242 0905ccd2 Sofia Papagiannaki
    user.delete()
243 0905ccd2 Sofia Papagiannaki
    return redirect(users_list)
244 0905ccd2 Sofia Papagiannaki
245 0905ccd2 Sofia Papagiannaki
@requires_admin
246 0905ccd2 Sofia Papagiannaki
def pending_users(request, template_name='pending_users.html', extra_context={}):
247 890b0eaf Sofia Papagiannaki
    """
248 890b0eaf Sofia Papagiannaki
    Displays the list of the pending users.
249 890b0eaf Sofia Papagiannaki
    
250 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
251 890b0eaf Sofia Papagiannaki
    
252 890b0eaf Sofia Papagiannaki
   **Arguments**
253 890b0eaf Sofia Papagiannaki
    
254 890b0eaf Sofia Papagiannaki
    ``template_name``
255 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
256 890b0eaf Sofia Papagiannaki
        this will default to ``users_list.html``.
257 890b0eaf Sofia Papagiannaki
    
258 890b0eaf Sofia Papagiannaki
    ``extra_context``
259 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
260 890b0eaf Sofia Papagiannaki
    
261 890b0eaf Sofia Papagiannaki
   **Template:**
262 890b0eaf Sofia Papagiannaki
    
263 890b0eaf Sofia Papagiannaki
    pending_users.html or ``template_name`` keyword argument.
264 890b0eaf Sofia Papagiannaki
    
265 890b0eaf Sofia Papagiannaki
   **Template Context:**
266 890b0eaf Sofia Papagiannaki
    
267 890b0eaf Sofia Papagiannaki
    The template context is extended by:
268 890b0eaf Sofia Papagiannaki
    
269 890b0eaf Sofia Papagiannaki
    * users: list of pending users fitting in current page
270 890b0eaf Sofia Papagiannaki
    * filter: search key
271 890b0eaf Sofia Papagiannaki
    * pages: the number of pages
272 890b0eaf Sofia Papagiannaki
    * prev: the previous page
273 890b0eaf Sofia Papagiannaki
    * next: the current page
274 890b0eaf Sofia Papagiannaki
    
275 890b0eaf Sofia Papagiannaki
   **Settings:**
276 890b0eaf Sofia Papagiannaki
    
277 890b0eaf Sofia Papagiannaki
    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
278 890b0eaf Sofia Papagiannaki
    """
279 0905ccd2 Sofia Papagiannaki
    users = AstakosUser.objects.order_by('id')
280 0905ccd2 Sofia Papagiannaki
    
281 0905ccd2 Sofia Papagiannaki
    users = users.filter(is_active = False)
282 0905ccd2 Sofia Papagiannaki
    
283 0905ccd2 Sofia Papagiannaki
    filter = request.GET.get('filter', '')
284 0905ccd2 Sofia Papagiannaki
    if filter:
285 0905ccd2 Sofia Papagiannaki
        if filter.startswith('-'):
286 0905ccd2 Sofia Papagiannaki
            users = users.exclude(username__icontains=filter[1:])
287 0905ccd2 Sofia Papagiannaki
        else:
288 0905ccd2 Sofia Papagiannaki
            users = users.filter(username__icontains=filter)
289 0905ccd2 Sofia Papagiannaki
    
290 0905ccd2 Sofia Papagiannaki
    try:
291 0905ccd2 Sofia Papagiannaki
        page = int(request.GET.get('page', 1))
292 0905ccd2 Sofia Papagiannaki
    except ValueError:
293 0905ccd2 Sofia Papagiannaki
        page = 1
294 0905ccd2 Sofia Papagiannaki
    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
295 0905ccd2 Sofia Papagiannaki
    limit = offset + settings.ADMIN_PAGE_LIMIT
296 0905ccd2 Sofia Papagiannaki
    
297 0905ccd2 Sofia Papagiannaki
    npages = int(ceil(1.0 * users.count() / settings.ADMIN_PAGE_LIMIT))
298 0905ccd2 Sofia Papagiannaki
    prev = page - 1 if page > 1 else None
299 0905ccd2 Sofia Papagiannaki
    next = page + 1 if page < npages else None
300 0905ccd2 Sofia Papagiannaki
    kwargs = {'users':users[offset:limit],
301 0905ccd2 Sofia Papagiannaki
              'filter':filter,
302 0905ccd2 Sofia Papagiannaki
              'pages':range(1, npages + 1),
303 0905ccd2 Sofia Papagiannaki
              'page':page,
304 0905ccd2 Sofia Papagiannaki
              'prev':prev,
305 0905ccd2 Sofia Papagiannaki
              'next':next}
306 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
307 890b0eaf Sofia Papagiannaki
                            context_instance = get_context(request, extra_context,**kwargs))
308 0905ccd2 Sofia Papagiannaki
309 890b0eaf Sofia Papagiannaki
def _send_greeting(request, user, template_name):
310 0905ccd2 Sofia Papagiannaki
    url = reverse('astakos.im.views.index')
311 0905ccd2 Sofia Papagiannaki
    subject = _('Welcome to %s' %settings.SERVICE_NAME)
312 890b0eaf Sofia Papagiannaki
    site = get_current_site(request)
313 890b0eaf Sofia Papagiannaki
    baseurl = request.build_absolute_uri('/').rstrip('/')
314 890b0eaf Sofia Papagiannaki
    message = render_to_string(template_name, {
315 0905ccd2 Sofia Papagiannaki
                'user': user,
316 0905ccd2 Sofia Papagiannaki
                'url': url,
317 0905ccd2 Sofia Papagiannaki
                'baseurl': baseurl,
318 890b0eaf Sofia Papagiannaki
                'site_name': site.name,
319 0905ccd2 Sofia Papagiannaki
                'support': settings.DEFAULT_CONTACT_EMAIL})
320 0905ccd2 Sofia Papagiannaki
    sender = settings.DEFAULT_FROM_EMAIL
321 0905ccd2 Sofia Papagiannaki
    send_mail(subject, message, sender, [user.email])
322 0905ccd2 Sofia Papagiannaki
    logging.info('Sent greeting %s', user)
323 0905ccd2 Sofia Papagiannaki
324 0905ccd2 Sofia Papagiannaki
@requires_admin
325 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
326 890b0eaf Sofia Papagiannaki
def users_activate(request, user_id, template_name='pending_users.html', extra_context={}, email_template_name='welcome_email.txt'):
327 890b0eaf Sofia Papagiannaki
    """
328 890b0eaf Sofia Papagiannaki
    Activates the specific user and sends an email. Upon success renders the
329 890b0eaf Sofia Papagiannaki
    ``template_name`` keyword argument if exists else renders ``pending_users.html``.
330 890b0eaf Sofia Papagiannaki
    
331 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
332 890b0eaf Sofia Papagiannaki
    
333 890b0eaf Sofia Papagiannaki
   **Arguments**
334 890b0eaf Sofia Papagiannaki
    
335 890b0eaf Sofia Papagiannaki
    ``template_name``
336 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
337 890b0eaf Sofia Papagiannaki
        this will default to ``users_list.html``.
338 890b0eaf Sofia Papagiannaki
    
339 890b0eaf Sofia Papagiannaki
    ``extra_context``
340 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
341 890b0eaf Sofia Papagiannaki
    
342 890b0eaf Sofia Papagiannaki
   **Templates:**
343 890b0eaf Sofia Papagiannaki
    
344 890b0eaf Sofia Papagiannaki
    pending_users.html or ``template_name`` keyword argument.
345 890b0eaf Sofia Papagiannaki
    welcome_email.txt or ``email_template_name`` keyword argument.
346 890b0eaf Sofia Papagiannaki
    
347 890b0eaf Sofia Papagiannaki
   **Template Context:**
348 890b0eaf Sofia Papagiannaki
    
349 890b0eaf Sofia Papagiannaki
    The template context is extended by:
350 890b0eaf Sofia Papagiannaki
    
351 890b0eaf Sofia Papagiannaki
    * users: list of pending users fitting in current page
352 890b0eaf Sofia Papagiannaki
    * filter: search key
353 890b0eaf Sofia Papagiannaki
    * pages: the number of pages
354 890b0eaf Sofia Papagiannaki
    * prev: the previous page
355 890b0eaf Sofia Papagiannaki
    * next: the current page
356 890b0eaf Sofia Papagiannaki
    """
357 0905ccd2 Sofia Papagiannaki
    user = AstakosUser.objects.get(id=user_id)
358 0905ccd2 Sofia Papagiannaki
    user.is_active = True
359 890b0eaf Sofia Papagiannaki
    user.save()
360 890b0eaf Sofia Papagiannaki
    status = messages.SUCCESS
361 0905ccd2 Sofia Papagiannaki
    try:
362 890b0eaf Sofia Papagiannaki
        _send_greeting(request, user, email_template_name)
363 0905ccd2 Sofia Papagiannaki
        message = _('Greeting sent to %s' % user.email)
364 890b0eaf Sofia Papagiannaki
        transaction.commit()
365 0905ccd2 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
366 890b0eaf Sofia Papagiannaki
        status = messages.ERROR
367 0905ccd2 Sofia Papagiannaki
        name = 'strerror'
368 0905ccd2 Sofia Papagiannaki
        message = getattr(e, name) if hasattr(e, name) else e
369 890b0eaf Sofia Papagiannaki
        transaction.rollback()
370 890b0eaf Sofia Papagiannaki
    messages.add_message(request, status, message)
371 0905ccd2 Sofia Papagiannaki
    
372 0905ccd2 Sofia Papagiannaki
    users = AstakosUser.objects.order_by('id')
373 0905ccd2 Sofia Papagiannaki
    users = users.filter(is_active = False)
374 0905ccd2 Sofia Papagiannaki
    
375 0905ccd2 Sofia Papagiannaki
    try:
376 0905ccd2 Sofia Papagiannaki
        page = int(request.POST.get('page', 1))
377 0905ccd2 Sofia Papagiannaki
    except ValueError:
378 0905ccd2 Sofia Papagiannaki
        page = 1
379 0905ccd2 Sofia Papagiannaki
    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
380 0905ccd2 Sofia Papagiannaki
    limit = offset + settings.ADMIN_PAGE_LIMIT
381 0905ccd2 Sofia Papagiannaki
    
382 0905ccd2 Sofia Papagiannaki
    npages = int(ceil(1.0 * users.count() / settings.ADMIN_PAGE_LIMIT))
383 0905ccd2 Sofia Papagiannaki
    prev = page - 1 if page > 1 else None
384 0905ccd2 Sofia Papagiannaki
    next = page + 1 if page < npages else None
385 0905ccd2 Sofia Papagiannaki
    kwargs = {'users':users[offset:limit],
386 0905ccd2 Sofia Papagiannaki
              'filter':'',
387 0905ccd2 Sofia Papagiannaki
              'pages':range(1, npages + 1),
388 0905ccd2 Sofia Papagiannaki
              'page':page,
389 0905ccd2 Sofia Papagiannaki
              'prev':prev,
390 890b0eaf Sofia Papagiannaki
              'next':next}
391 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
392 890b0eaf Sofia Papagiannaki
                           context_instance = get_context(request, extra_context,**kwargs))
393 0905ccd2 Sofia Papagiannaki
394 0905ccd2 Sofia Papagiannaki
@requires_admin
395 0905ccd2 Sofia Papagiannaki
def invitations_list(request, template_name='invitations_list.html', extra_context={}):
396 890b0eaf Sofia Papagiannaki
    """
397 890b0eaf Sofia Papagiannaki
    Displays a list with the Invitations.
398 890b0eaf Sofia Papagiannaki
    
399 890b0eaf Sofia Papagiannaki
    If the ``request.user`` is not a superuser redirects to login page.
400 890b0eaf Sofia Papagiannaki
    
401 890b0eaf Sofia Papagiannaki
   **Arguments**
402 890b0eaf Sofia Papagiannaki
    
403 890b0eaf Sofia Papagiannaki
    ``template_name``
404 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
405 890b0eaf Sofia Papagiannaki
        this will default to ``invitations_list.html``.
406 890b0eaf Sofia Papagiannaki
    
407 890b0eaf Sofia Papagiannaki
    ``extra_context``
408 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
409 890b0eaf Sofia Papagiannaki
    
410 890b0eaf Sofia Papagiannaki
   **Templates:**
411 890b0eaf Sofia Papagiannaki
    
412 890b0eaf Sofia Papagiannaki
    invitations_list.html or ``template_name`` keyword argument.
413 890b0eaf Sofia Papagiannaki
    
414 890b0eaf Sofia Papagiannaki
   **Template Context:**
415 890b0eaf Sofia Papagiannaki
    
416 890b0eaf Sofia Papagiannaki
    The template context is extended by:
417 890b0eaf Sofia Papagiannaki
    
418 890b0eaf Sofia Papagiannaki
    * invitations: list of invitations fitting in current page
419 890b0eaf Sofia Papagiannaki
    * filter: search key
420 890b0eaf Sofia Papagiannaki
    * pages: the number of pages
421 890b0eaf Sofia Papagiannaki
    * prev: the previous page
422 890b0eaf Sofia Papagiannaki
    * next: the current page
423 890b0eaf Sofia Papagiannaki
    """
424 0905ccd2 Sofia Papagiannaki
    invitations = Invitation.objects.order_by('id')
425 0905ccd2 Sofia Papagiannaki
    
426 0905ccd2 Sofia Papagiannaki
    filter = request.GET.get('filter', '')
427 0905ccd2 Sofia Papagiannaki
    if filter:
428 0905ccd2 Sofia Papagiannaki
        if filter.startswith('-'):
429 0905ccd2 Sofia Papagiannaki
            invitations = invitations.exclude(username__icontains=filter[1:])
430 0905ccd2 Sofia Papagiannaki
        else:
431 0905ccd2 Sofia Papagiannaki
            invitations = invitations.filter(username__icontains=filter)
432 0905ccd2 Sofia Papagiannaki
    
433 0905ccd2 Sofia Papagiannaki
    try:
434 0905ccd2 Sofia Papagiannaki
        page = int(request.GET.get('page', 1))
435 0905ccd2 Sofia Papagiannaki
    except ValueError:
436 0905ccd2 Sofia Papagiannaki
        page = 1
437 0905ccd2 Sofia Papagiannaki
    offset = max(0, page - 1) * settings.ADMIN_PAGE_LIMIT
438 0905ccd2 Sofia Papagiannaki
    limit = offset + settings.ADMIN_PAGE_LIMIT
439 0905ccd2 Sofia Papagiannaki
    
440 0905ccd2 Sofia Papagiannaki
    npages = int(ceil(1.0 * invitations.count() / settings.ADMIN_PAGE_LIMIT))
441 0905ccd2 Sofia Papagiannaki
    prev = page - 1 if page > 1 else None
442 0905ccd2 Sofia Papagiannaki
    next = page + 1 if page < npages else None
443 0905ccd2 Sofia Papagiannaki
    kwargs = {'invitations':invitations[offset:limit],
444 0905ccd2 Sofia Papagiannaki
              'filter':filter,
445 0905ccd2 Sofia Papagiannaki
              'pages':range(1, npages + 1),
446 0905ccd2 Sofia Papagiannaki
              'page':page,
447 0905ccd2 Sofia Papagiannaki
              'prev':prev,
448 0905ccd2 Sofia Papagiannaki
              'next':next}
449 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
450 890b0eaf Sofia Papagiannaki
                           context_instance = get_context(request, extra_context,**kwargs))
451 0905ccd2 Sofia Papagiannaki
452 0905ccd2 Sofia Papagiannaki
@requires_admin
453 0905ccd2 Sofia Papagiannaki
def invitations_export(request):
454 890b0eaf Sofia Papagiannaki
    """
455 890b0eaf Sofia Papagiannaki
    Exports the invitation list in csv file.
456 890b0eaf Sofia Papagiannaki
    """
457 0905ccd2 Sofia Papagiannaki
    # Create the HttpResponse object with the appropriate CSV header.
458 0905ccd2 Sofia Papagiannaki
    response = HttpResponse(mimetype='text/csv')
459 0905ccd2 Sofia Papagiannaki
    response['Content-Disposition'] = 'attachment; filename=invitations.csv'
460 0905ccd2 Sofia Papagiannaki
461 0905ccd2 Sofia Papagiannaki
    writer = csv.writer(response)
462 0905ccd2 Sofia Papagiannaki
    writer.writerow(['ID',
463 0905ccd2 Sofia Papagiannaki
                     'Username',
464 0905ccd2 Sofia Papagiannaki
                     'Real Name',
465 0905ccd2 Sofia Papagiannaki
                     'Code',
466 0905ccd2 Sofia Papagiannaki
                     'Inviter username',
467 0905ccd2 Sofia Papagiannaki
                     'Inviter Real Name',
468 0905ccd2 Sofia Papagiannaki
                     'Is_accepted',
469 0905ccd2 Sofia Papagiannaki
                     'Created',
470 0905ccd2 Sofia Papagiannaki
                     'Accepted',])
471 0905ccd2 Sofia Papagiannaki
    invitations = Invitation.objects.order_by('id')
472 0905ccd2 Sofia Papagiannaki
    for inv in invitations:
473 0905ccd2 Sofia Papagiannaki
        
474 0905ccd2 Sofia Papagiannaki
        writer.writerow([inv.id,
475 0905ccd2 Sofia Papagiannaki
                         inv.username.encode("utf-8"),
476 0905ccd2 Sofia Papagiannaki
                         inv.realname.encode("utf-8"),
477 0905ccd2 Sofia Papagiannaki
                         inv.code,
478 0905ccd2 Sofia Papagiannaki
                         inv.inviter.username.encode("utf-8"),
479 0905ccd2 Sofia Papagiannaki
                         inv.inviter.realname.encode("utf-8"),
480 0905ccd2 Sofia Papagiannaki
                         inv.is_accepted,
481 0905ccd2 Sofia Papagiannaki
                         inv.created,
482 0905ccd2 Sofia Papagiannaki
                         inv.accepted])
483 0905ccd2 Sofia Papagiannaki
484 0905ccd2 Sofia Papagiannaki
    return response
485 0905ccd2 Sofia Papagiannaki
486 0905ccd2 Sofia Papagiannaki
487 0905ccd2 Sofia Papagiannaki
@requires_admin
488 0905ccd2 Sofia Papagiannaki
def users_export(request):
489 890b0eaf Sofia Papagiannaki
    """
490 890b0eaf Sofia Papagiannaki
    Exports the user list in csv file.
491 890b0eaf Sofia Papagiannaki
    """
492 0905ccd2 Sofia Papagiannaki
    # Create the HttpResponse object with the appropriate CSV header.
493 0905ccd2 Sofia Papagiannaki
    response = HttpResponse(mimetype='text/csv')
494 0905ccd2 Sofia Papagiannaki
    response['Content-Disposition'] = 'attachment; filename=users.csv'
495 0905ccd2 Sofia Papagiannaki
496 0905ccd2 Sofia Papagiannaki
    writer = csv.writer(response)
497 0905ccd2 Sofia Papagiannaki
    writer.writerow(['ID',
498 0905ccd2 Sofia Papagiannaki
                     'Username',
499 0905ccd2 Sofia Papagiannaki
                     'Real Name',
500 0905ccd2 Sofia Papagiannaki
                     'Admin',
501 0905ccd2 Sofia Papagiannaki
                     'Affiliation',
502 0905ccd2 Sofia Papagiannaki
                     'Is active?',
503 0905ccd2 Sofia Papagiannaki
                     'Quota (GiB)',
504 0905ccd2 Sofia Papagiannaki
                     'Updated',])
505 0905ccd2 Sofia Papagiannaki
    users = AstakosUser.objects.order_by('id')
506 0905ccd2 Sofia Papagiannaki
    for u in users:
507 0905ccd2 Sofia Papagiannaki
        writer.writerow([u.id,
508 0905ccd2 Sofia Papagiannaki
                         u.username.encode("utf-8"),
509 0905ccd2 Sofia Papagiannaki
                         u.realname.encode("utf-8"),
510 0905ccd2 Sofia Papagiannaki
                         u.is_superuser,
511 0905ccd2 Sofia Papagiannaki
                         u.affiliation.encode("utf-8"),
512 0905ccd2 Sofia Papagiannaki
                         u.is_active,
513 0905ccd2 Sofia Papagiannaki
                         u.quota,
514 0905ccd2 Sofia Papagiannaki
                         u.updated])
515 0905ccd2 Sofia Papagiannaki
516 0905ccd2 Sofia Papagiannaki
    return response
517 0905ccd2 Sofia Papagiannaki
518 0905ccd2 Sofia Papagiannaki
@requires_admin
519 0905ccd2 Sofia Papagiannaki
def users_create(request, template_name='users_create.html', extra_context={}):
520 890b0eaf Sofia Papagiannaki
    """
521 890b0eaf Sofia Papagiannaki
    Creates a user. Upon success redirect to ``users_info`` view.
522 890b0eaf Sofia Papagiannaki
    
523 890b0eaf Sofia Papagiannaki
   **Arguments**
524 890b0eaf Sofia Papagiannaki
    
525 890b0eaf Sofia Papagiannaki
    ``template_name``
526 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
527 890b0eaf Sofia Papagiannaki
        this will default to ``users_create.html``.
528 890b0eaf Sofia Papagiannaki
    
529 890b0eaf Sofia Papagiannaki
    ``extra_context``
530 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
531 890b0eaf Sofia Papagiannaki
    
532 890b0eaf Sofia Papagiannaki
   **Templates:**
533 890b0eaf Sofia Papagiannaki
    
534 890b0eaf Sofia Papagiannaki
    users_create.html or ``template_name`` keyword argument.
535 890b0eaf Sofia Papagiannaki
    """
536 0905ccd2 Sofia Papagiannaki
    if request.method == 'GET':
537 0905ccd2 Sofia Papagiannaki
        return render_response(template_name,
538 0905ccd2 Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
539 0905ccd2 Sofia Papagiannaki
    if request.method == 'POST':
540 0905ccd2 Sofia Papagiannaki
        user = AstakosUser()
541 0905ccd2 Sofia Papagiannaki
        user.username = request.POST.get('username')
542 0905ccd2 Sofia Papagiannaki
        user.email = request.POST.get('email')
543 0905ccd2 Sofia Papagiannaki
        user.first_name = request.POST.get('first_name')
544 0905ccd2 Sofia Papagiannaki
        user.last_name = request.POST.get('last_name')
545 0905ccd2 Sofia Papagiannaki
        user.is_superuser = True if request.POST.get('admin') else False
546 0905ccd2 Sofia Papagiannaki
        user.affiliation = request.POST.get('affiliation')
547 890b0eaf Sofia Papagiannaki
        user.quota = int(request.POST.get('quota') or 0) * (1024**3)  # In GiB
548 0905ccd2 Sofia Papagiannaki
        user.renew_token()
549 0905ccd2 Sofia Papagiannaki
        user.provider = 'local'
550 0905ccd2 Sofia Papagiannaki
        user.save()
551 0905ccd2 Sofia Papagiannaki
        return redirect(users_info, user.id)