Merge branch 'master' into packaging
[astakos] / astakos / im / admin / views.py
diff --git a/astakos/im/admin/views.py b/astakos/im/admin/views.py
deleted file mode 100644 (file)
index 54f0910..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-# Copyright 2011 GRNET S.A. All rights reserved.
-# 
-# Redistribution and use in source and binary forms, with or
-# without modification, are permitted provided that the following
-# conditions are met:
-# 
-#   1. Redistributions of source code must retain the above
-#      copyright notice, this list of conditions and the following
-#      disclaimer.
-# 
-#   2. Redistributions in binary form must reproduce the above
-#      copyright notice, this list of conditions and the following
-#      disclaimer in the documentation and/or other materials
-#      provided with the distribution.
-# 
-# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
-# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# 
-# The views and conclusions contained in the software and
-# documentation are those of the authors and should not be
-# interpreted as representing official policies, either expressed
-# or implied, of GRNET S.A.
-
-import socket
-import csv
-
-from functools import wraps
-from math import ceil
-from smtplib import SMTPException
-
-from django.http import HttpResponse, HttpResponseRedirect
-from django.shortcuts import redirect
-from django.template.loader import render_to_string
-from django.utils.http import urlencode
-from django.utils.translation import ugettext as _
-from django.core.urlresolvers import reverse
-from django.contrib import messages
-from django.db import transaction
-
-from astakos.im.models import AstakosUser, Invitation
-from astakos.im.util import get_context
-from astakos.im.forms import *
-from astakos.im.views import render_response, index
-from astakos.im.admin.forms import AdminProfileForm
-from astakos.im.admin.forms import AdminUserCreationForm
-from astakos.im.settings import BYPASS_ADMIN_AUTH, ADMIN_PAGE_LIMIT, DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL
-from astakos.im.admin.functions import activate
-
-def requires_admin(func):
-    """
-    Decorator checkes whether the request.user is a superuser and if not
-    redirects to login page.
-    """
-    @wraps(func)
-    def wrapper(request, *args):
-        if not BYPASS_ADMIN_AUTH:
-            if request.user.is_anonymous():
-                next = urlencode({'next': request.build_absolute_uri()})
-                login_uri = reverse(index) + '?' + next
-                return HttpResponseRedirect(login_uri)
-            if not request.user.is_superuser:
-                return HttpResponse('Forbidden', status=403)
-        return func(request, *args)
-    return wrapper
-
-@requires_admin
-def admin(request, template_name='admin.html', extra_context={}):
-    """
-    Renders the admin page
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``admin.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Template:**
-    
-    admin.html or ``template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * tab: the name of the active tab
-    * stats: dictionary containing the number of all and prending users
-    """
-    stats = {}
-    stats['users'] = AstakosUser.objects.count()
-    stats['pending'] = AstakosUser.objects.filter(is_active = False).count()
-    
-    invitations = Invitation.objects.all()
-    stats['invitations'] = invitations.count()
-    stats['invitations_consumed'] = invitations.filter(is_consumed=True).count()
-    
-    kwargs = {'tab': 'home', 'stats': stats}
-    context = get_context(request, extra_context,**kwargs)
-    return render_response(template_name, context_instance = context)
-
-@requires_admin
-def users_list(request, template_name='users_list.html', extra_context={}):
-    """
-    Displays the list of all users.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``users_list.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Template:**
-    
-    users_list.html or ``template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * users: list of users fitting in current page
-    * filter: search key
-    * pages: the number of pages
-    * prev: the previous page
-    * next: the current page
-    
-   **Settings:**
-    
-    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
-    """
-    users = AstakosUser.objects.order_by('id')
-    
-    filter = request.GET.get('filter', '')
-    if filter:
-        if filter.startswith('-'):
-            users = users.exclude(username__icontains=filter[1:])
-        else:
-            users = users.filter(username__icontains=filter)
-    
-    try:
-        page = int(request.GET.get('page', 1))
-    except ValueError:
-        page = 1
-    offset = max(0, page - 1) * ADMIN_PAGE_LIMIT
-    limit = offset + ADMIN_PAGE_LIMIT
-    
-    npages = int(ceil(1.0 * users.count() / ADMIN_PAGE_LIMIT))
-    prev = page - 1 if page > 1 else None
-    next = page + 1 if page < npages else None
-    
-    kwargs = {'users':users[offset:limit],
-              'filter':filter,
-              'pages':range(1, npages + 1),
-              'prev':prev,
-              'next':next}
-    context = get_context(request, extra_context,**kwargs)
-    return render_response(template_name, context_instance = context)
-
-@requires_admin
-def users_info(request, user_id, template_name='users_info.html', extra_context={}):
-    """
-    Displays the specific user profile.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``users_info.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Template:**
-    
-    users_info.html or ``template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * user: the user instance identified by ``user_id`` keyword argument
-    """
-    if not extra_context:
-        extra_context = {}
-    user = AstakosUser.objects.get(id=user_id)
-    return render_response(template_name,
-                           form = AdminProfileForm(instance=user),
-                           user = user,
-                           context_instance = get_context(request, extra_context))
-
-@requires_admin
-def users_modify(request, user_id, template_name='users_info.html', extra_context={}):
-    """
-    Update the specific user information. Upon success redirects to ``user_info`` view.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    """
-    user = AstakosUser.objects.get(id = user_id)
-    form = AdminProfileForm(request.POST, instance=user)
-    if form.is_valid():
-        form.save()
-        return users_info(request, user.id, template_name, extra_context)
-    return render_response(template_name,
-                           form = form,
-                           context_instance = get_context(request, extra_context))
-
-@requires_admin
-def users_delete(request, user_id):
-    """
-    Deletes the specified user
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    """
-    user = AstakosUser.objects.get(id=user_id)
-    user.delete()
-    return redirect(users_list)
-
-@requires_admin
-def pending_users(request, template_name='pending_users.html', extra_context={}):
-    """
-    Displays the list of the pending users.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``users_list.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Template:**
-    
-    pending_users.html or ``template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * users: list of pending users fitting in current page
-    * filter: search key
-    * pages: the number of pages
-    * prev: the previous page
-    * next: the current page
-    
-   **Settings:**
-    
-    * ADMIN_PAGE_LIMIT: Show these many users per page in admin interface
-    """
-    users = AstakosUser.objects.order_by('id')
-    
-    users = users.filter(is_active = False)
-    
-    filter = request.GET.get('filter', '')
-    if filter:
-        if filter.startswith('-'):
-            users = users.exclude(username__icontains=filter[1:])
-        else:
-            users = users.filter(username__icontains=filter)
-    
-    try:
-        page = int(request.GET.get('page', 1))
-    except ValueError:
-        page = 1
-    offset = max(0, page - 1) * ADMIN_PAGE_LIMIT
-    limit = offset + ADMIN_PAGE_LIMIT
-    
-    npages = int(ceil(1.0 * users.count() / ADMIN_PAGE_LIMIT))
-    prev = page - 1 if page > 1 else None
-    next = page + 1 if page < npages else None
-    kwargs = {'users':users[offset:limit],
-              'filter':filter,
-              'pages':range(1, npages + 1),
-              'page':page,
-              'prev':prev,
-              'next':next}
-    return render_response(template_name,
-                           context_instance = get_context(request, extra_context,**kwargs))
-
-@requires_admin
-@transaction.commit_manually
-def users_activate(request, user_id, template_name='pending_users.html', extra_context={}, email_template_name='welcome_email.txt'):
-    """
-    Activates the specific user and sends an email. Upon success renders the
-    ``template_name`` keyword argument if exists else renders ``pending_users.html``.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``users_list.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Templates:**
-    
-    pending_users.html or ``template_name`` keyword argument.
-    welcome_email.txt or ``email_template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * users: list of pending users fitting in current page
-    * filter: search key
-    * pages: the number of pages
-    * prev: the previous page
-    * next: the current page
-    """
-    user = AstakosUser.objects.get(id=user_id)
-    status = messages.SUCCESS
-    try:
-        activate(user, email_template_name)
-        message = _('Greeting sent to %s' % user.email)
-        transaction.commit()
-    except (SMTPException, socket.error) as e:
-        status = messages.ERROR
-        name = 'strerror'
-        message = getattr(e, name) if hasattr(e, name) else e
-        transaction.rollback()
-    messages.add_message(request, status, message)
-    
-    users = AstakosUser.objects.order_by('id')
-    users = users.filter(is_active = False)
-    
-    try:
-        page = int(request.POST.get('page', 1))
-    except ValueError:
-        page = 1
-    offset = max(0, page - 1) * ADMIN_PAGE_LIMIT
-    limit = offset + ADMIN_PAGE_LIMIT
-    
-    npages = int(ceil(1.0 * users.count() / ADMIN_PAGE_LIMIT))
-    prev = page - 1 if page > 1 else None
-    next = page + 1 if page < npages else None
-    kwargs = {'users':users[offset:limit],
-              'filter':'',
-              'pages':range(1, npages + 1),
-              'page':page,
-              'prev':prev,
-              'next':next}
-    return render_response(template_name,
-                           context_instance = get_context(request, extra_context,**kwargs))
-
-@requires_admin
-def invitations_list(request, template_name='invitations_list.html', extra_context={}):
-    """
-    Displays a list with the Invitations.
-    
-    If the ``request.user`` is not a superuser redirects to login page.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``invitations_list.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Templates:**
-    
-    invitations_list.html or ``template_name`` keyword argument.
-    
-   **Template Context:**
-    
-    The template context is extended by:
-    
-    * invitations: list of invitations fitting in current page
-    * filter: search key
-    * pages: the number of pages
-    * prev: the previous page
-    * next: the current page
-    """
-    invitations = Invitation.objects.order_by('id')
-    
-    filter = request.GET.get('filter', '')
-    if filter:
-        if filter.startswith('-'):
-            invitations = invitations.exclude(username__icontains=filter[1:])
-        else:
-            invitations = invitations.filter(username__icontains=filter)
-    
-    try:
-        page = int(request.GET.get('page', 1))
-    except ValueError:
-        page = 1
-    offset = max(0, page - 1) * ADMIN_PAGE_LIMIT
-    limit = offset + ADMIN_PAGE_LIMIT
-    
-    npages = int(ceil(1.0 * invitations.count() / ADMIN_PAGE_LIMIT))
-    prev = page - 1 if page > 1 else None
-    next = page + 1 if page < npages else None
-    kwargs = {'invitations':invitations[offset:limit],
-              'filter':filter,
-              'pages':range(1, npages + 1),
-              'page':page,
-              'prev':prev,
-              'next':next}
-    return render_response(template_name,
-                           context_instance = get_context(request, extra_context,**kwargs))
-
-@requires_admin
-def invitations_export(request):
-    """
-    Exports the invitation list in csv file.
-    """
-    # Create the HttpResponse object with the appropriate CSV header.
-    response = HttpResponse(mimetype='text/csv')
-    response['Content-Disposition'] = 'attachment; filename=invitations.csv'
-
-    writer = csv.writer(response)
-    writer.writerow(['ID',
-                     'Username',
-                     'Real Name',
-                     'Code',
-                     'Inviter username',
-                     'Inviter Real Name',
-                     'Is_accepted',
-                     'Created',
-                     'Consumed',])
-    invitations = Invitation.objects.order_by('id')
-    for inv in invitations:
-        
-        writer.writerow([inv.id,
-                         inv.username.encode("utf-8"),
-                         inv.realname.encode("utf-8"),
-                         inv.code,
-                         inv.inviter.username.encode("utf-8"),
-                         inv.inviter.realname.encode("utf-8"),
-                         inv.is_accepted,
-                         inv.created,
-                         inv.consumed])
-
-    return response
-
-
-@requires_admin
-def users_export(request):
-    """
-    Exports the user list in csv file.
-    """
-    # Create the HttpResponse object with the appropriate CSV header.
-    response = HttpResponse(mimetype='text/csv')
-    response['Content-Disposition'] = 'attachment; filename=users.csv'
-
-    writer = csv.writer(response)
-    writer.writerow(['ID',
-                     'Username',
-                     'Real Name',
-                     'Admin',
-                     'Affiliation',
-                     'Is active?',
-                     'Quota (GiB)',
-                     'Updated',])
-    users = AstakosUser.objects.order_by('id')
-    for u in users:
-        writer.writerow([u.id,
-                         u.username.encode("utf-8"),
-                         u.realname.encode("utf-8"),
-                         u.is_superuser,
-                         u.affiliation.encode("utf-8"),
-                         u.is_active,
-                         u.quota,
-                         u.updated])
-
-    return response
-
-@requires_admin
-def users_create(request, template_name='users_create.html', extra_context={}):
-    """
-    Creates a user. Upon success redirect to ``users_info`` view.
-    
-   **Arguments**
-    
-    ``template_name``
-        A custom template to use. This is optional; if not specified,
-        this will default to ``users_create.html``.
-    
-    ``extra_context``
-        An dictionary of variables to add to the template context.
-    
-   **Templates:**
-    
-    users_create.html or ``template_name`` keyword argument.
-    """
-    if request.method == 'GET':
-        form = AdminUserCreationForm()
-    elif request.method == 'POST':
-        form = AdminUserCreationForm(request.POST)
-        if form.is_valid():
-            try:
-                user = form.save()
-                return users_info(request, user.id)
-            except ValueError, e:
-                messages.add_message(request, messages.ERROR, e)
-    return render_response(template_name,
-                           form = form,
-                           context_instance=get_context(request, extra_context))