From 17bebf7e770116c6e156466335e9666861dac364 Mon Sep 17 00:00:00 2001 From: Antony Chazapis Date: Tue, 21 Feb 2012 15:16:44 +0200 Subject: [PATCH] Remove custom web admin. Refs #1996 --- astakos/im/admin/forms.py | 101 ----- astakos/im/admin/functions.py | 100 ----- astakos/im/admin/templates/admin.html | 8 - astakos/im/admin/templates/admin_base.html | 51 --- astakos/im/admin/templates/invitations_list.html | 73 --- astakos/im/admin/templates/pending_users.html | 71 --- astakos/im/admin/templates/users_create.html | 13 - astakos/im/admin/templates/users_info.html | 25 -- astakos/im/admin/templates/users_list.html | 72 --- astakos/im/admin/templates/welcome_email.txt | 69 --- astakos/im/admin/urls.py | 50 --- astakos/im/admin/views.py | 524 ---------------------- astakos/im/interface.py | 57 --- astakos/im/models.py | 9 - astakos/im/settings.py | 18 - astakos/im/urls.py | 6 +- 16 files changed, 2 insertions(+), 1245 deletions(-) delete mode 100644 astakos/im/admin/__init__.py delete mode 100644 astakos/im/admin/forms.py delete mode 100644 astakos/im/admin/functions.py delete mode 100644 astakos/im/admin/templates/admin.html delete mode 100644 astakos/im/admin/templates/admin_base.html delete mode 100644 astakos/im/admin/templates/invitations_list.html delete mode 100644 astakos/im/admin/templates/pending_users.html delete mode 100644 astakos/im/admin/templates/users_create.html delete mode 100644 astakos/im/admin/templates/users_info.html delete mode 100644 astakos/im/admin/templates/users_list.html delete mode 100644 astakos/im/admin/templates/welcome_email.txt delete mode 100644 astakos/im/admin/urls.py delete mode 100644 astakos/im/admin/views.py delete mode 100644 astakos/im/interface.py diff --git a/astakos/im/admin/__init__.py b/astakos/im/admin/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/astakos/im/admin/forms.py b/astakos/im/admin/forms.py deleted file mode 100644 index 2861ac0..0000000 --- a/astakos/im/admin/forms.py +++ /dev/null @@ -1,101 +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. - -from django import forms -from django.utils.translation import ugettext as _ - -from astakos.im.models import AstakosUser -from astakos.im.forms import LocalUserCreationForm - -import logging - -logger = logging.getLogger(__name__) - -class AdminProfileForm(forms.ModelForm): - """ - Subclass of ``ModelForm`` for permiting user to edit his/her profile. - Most of the fields are readonly since the user is not allowed to change them. - - The class defines a save method which sets ``is_verified`` to True so as the user - during the next login will not to be redirected to profile page. - """ - quota = forms.CharField(label=_('Quota (GiB)')) - - class Meta: - model = AstakosUser - fields = ('email', 'first_name', 'last_name', 'is_superuser', - 'affiliation', 'is_active', 'invitations', 'quota', - 'auth_token', 'auth_token_created', 'auth_token_expires', - 'date_joined', 'updated') - - def __init__(self, *args, **kwargs): - super(AdminProfileForm, self).__init__(*args, **kwargs) - instance = getattr(self, 'instance', None) - ro_fields = ('date_joined', 'auth_token', 'auth_token_created', - 'auth_token_expires', 'updated', 'email') - if instance and instance.id: - for field in ro_fields: - self.fields[field].widget.attrs['readonly'] = True - user = kwargs['instance'] - if user: - quota = lambda x: int(x) / 1024 ** 3 - self.fields['quota'].widget.attrs['value'] = quota(user.quota) - - def save(self, commit=True): - user = super(AdminProfileForm, self).save(commit=False) - quota = lambda x: int(x or 0) * (1024 ** 3) - user.quota = quota(self.cleaned_data['quota']) - user.save() - -class AdminUserCreationForm(LocalUserCreationForm): - class Meta: - model = AstakosUser - fields = ("email", "first_name", "last_name", "is_superuser", - "is_active", "affiliation") - - def __init__(self, *args, **kwargs): - """ - Changes the order of fields, and removes the username field. - """ - super(AdminUserCreationForm, self).__init__(*args, **kwargs) - self.fields.keyOrder = ['email', 'first_name', 'last_name', - 'is_superuser', 'is_active', 'affiliation', - 'password1', 'password2'] - - def save(self, commit=True): - user = super(AdminUserCreationForm, self).save(commit=False) - user.renew_token() - if commit: - user.save() - logger.info('Created user %s', user) - return user \ No newline at end of file diff --git a/astakos/im/admin/functions.py b/astakos/im/admin/functions.py deleted file mode 100644 index af3063e..0000000 --- a/astakos/im/admin/functions.py +++ /dev/null @@ -1,100 +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 logging - -from django.utils.translation import ugettext as _ -from django.template.loader import render_to_string -from django.core.mail import send_mail -from django.core.urlresolvers import reverse -from urlparse import urljoin -from random import randint - -from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, SITEURL, SITENAME, BASEURL -from astakos.im.models import Invitation - -logger = logging.getLogger(__name__) - -def activate(user, email_template_name='welcome_email.txt'): - """ - Activates the specific user and sends email. - - Raises SMTPException, socket.error - """ - user.is_active = True - user.save() - subject = _('Welcome to %s' % SITENAME) - message = render_to_string(email_template_name, { - 'user': user, - 'url': SITEURL, - 'baseurl': BASEURL, - 'site_name': SITENAME, - 'support': DEFAULT_CONTACT_EMAIL % SITENAME.lower()}) - sender = DEFAULT_FROM_EMAIL % SITENAME - send_mail(subject, message, sender, [user.email]) - logger.info('Sent greeting %s', user) - -def _generate_invitation_code(): - while True: - code = randint(1, 2L**63 - 1) - try: - Invitation.objects.get(code=code) - # An invitation with this code already exists, try again - except Invitation.DoesNotExist: - return code - -def invite(inviter, username, realname): - """ - Send an invitation email and upon success reduces inviter's invitation by one. - - Raises SMTPException, socket.error - """ - code = _generate_invitation_code() - invitation = Invitation(inviter=inviter, - username=username, - code=code, - realname=realname) - invitation.save() - subject = _('Invitation to %s' % SITENAME) - url = '%s?code=%d' % (urljoin(BASEURL, reverse('astakos.im.views.signup')), code) - message = render_to_string('im/invitation.txt', { - 'invitation': invitation, - 'url': url, - 'baseurl': BASEURL, - 'service': SITENAME, - 'support': DEFAULT_CONTACT_EMAIL % SITENAME.lower()}) - sender = DEFAULT_FROM_EMAIL % SITENAME - send_mail(subject, message, sender, [invitation.username]) - logger.info('Sent invitation %s', invitation) - inviter.invitations = max(0, inviter.invitations - 1) - inviter.save() \ No newline at end of file diff --git a/astakos/im/admin/templates/admin.html b/astakos/im/admin/templates/admin.html deleted file mode 100644 index 809114f..0000000 --- a/astakos/im/admin/templates/admin.html +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "admin_base.html" %} - -{% block body %} - -{% endblock body %} diff --git a/astakos/im/admin/templates/admin_base.html b/astakos/im/admin/templates/admin_base.html deleted file mode 100644 index a0690eb..0000000 --- a/astakos/im/admin/templates/admin_base.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - {{ title|default:"Astakos Login" }} - - - - - {% block head %}{% endblock %} - - -
-
- -
- {% block title %}{% endblock %} - - {% if messages %} - - {% endif %} - -{% block tabs %} - -{% endblock %} - - {% block body %}{% endblock %} -
- - - diff --git a/astakos/im/admin/templates/invitations_list.html b/astakos/im/admin/templates/invitations_list.html deleted file mode 100644 index c500ac9..0000000 --- a/astakos/im/admin/templates/invitations_list.html +++ /dev/null @@ -1,73 +0,0 @@ -{% extends "admin_base.html" %} - -{% load formatters %} - -{% block body %} - -
-
-
-
- -
-
-
-
- - - - - - - - - - - - - - - - - {% for inv in invitations %} - - - - - - - - - - - - {% endfor %} - -
IDEmailReal NameCodeInviter emailInviter Real NameIs used?CreatedConsumed
{{ inv.id }}{{ inv.username }}{{ inv.realname }}{{ inv.code }}{{ inv.inviter.email }}{{ inv.inviter.realname }}{{ inv.is_consumed }}{{ inv.created }}{{ inv.consumed }}
- -{% if pages|length > 1 %} - -{% endif %} - -Export - -

-{% endblock body %} diff --git a/astakos/im/admin/templates/pending_users.html b/astakos/im/admin/templates/pending_users.html deleted file mode 100644 index b5c5215..0000000 --- a/astakos/im/admin/templates/pending_users.html +++ /dev/null @@ -1,71 +0,0 @@ -{% extends "admin_base.html" %} - -{% load formatters %} - -{% block body %} - -
-
-
-
- -
-
-
-
- - - - - - - - - - - - - - - {% for user in users %} - - - - - - - - - {% endfor %} - -
IDEmailReal NameAffiliationEmailInviterAction
{{ user.id }}{{ user.email }}{{ user.realname }}{{ user.affiliation }}{{ user.email }}{{ user.inviter.realname }} -
{% csrf_token %} - - -
-
- -{% if pages|length > 1 %} - -{% endif %} - -

-{% endblock body %} diff --git a/astakos/im/admin/templates/users_create.html b/astakos/im/admin/templates/users_create.html deleted file mode 100644 index fffc167..0000000 --- a/astakos/im/admin/templates/users_create.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "admin_base.html" %} - -{% block body %} - -
{% csrf_token %} - {{ form.as_p }} - -
- - -
-
-{% endblock body %} diff --git a/astakos/im/admin/templates/users_info.html b/astakos/im/admin/templates/users_info.html deleted file mode 100644 index d7919e5..0000000 --- a/astakos/im/admin/templates/users_info.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "admin_base.html" %} - -{% load formatters %} - -{% block body %} - -
{% csrf_token %} - {{ form.as_p }} - -
- - -    - Delete User -
- -
-

WARNING: Are you sure you want to delete this user?

-
- Delete - Cancel -
-
-
-{% endblock body %} diff --git a/astakos/im/admin/templates/users_list.html b/astakos/im/admin/templates/users_list.html deleted file mode 100644 index 0f9d645..0000000 --- a/astakos/im/admin/templates/users_list.html +++ /dev/null @@ -1,72 +0,0 @@ -{% extends "admin_base.html" %} - -{% load formatters %} - -{% block body %} - -
-
-
-
- -
-
-
-
- - - - - - - - - - - - - - - - {% for user in users %} - - - - - - - - - - - {% endfor %} - -
IDEmailReal NameAdminAffiliationIs active?QuotaUpdated
{{ user.id }}{{ user.email }}{{ user.realname }}{{ user.is_superuser }}{{ user.affiliation }}{{ user.is_active }}{{ user.quota|GiB }} GiB{{ user.updated }}
- -{% if pages|length > 1 %} - -{% endif %} - -Create a user -Export - -

-{% endblock body %} diff --git a/astakos/im/admin/templates/welcome_email.txt b/astakos/im/admin/templates/welcome_email.txt deleted file mode 100644 index fb1a9d8..0000000 --- a/astakos/im/admin/templates/welcome_email.txt +++ /dev/null @@ -1,69 +0,0 @@ ---- A translation in English follows --- - -Αγαπητέ/η {{ user.realname }}, - -Ο λογαρισμός σας για την υπηρεσία {{ site_name }} της ΕΔΕΤ κατά την Alpha (πιλοτική) -φάση λειτουργίας της έχει ενεργοποιηθεί. - -Για να συνδεθείτε, χρησιμοποιήστε τον παρακάτω σύνδεσμο: - -{{ url }} - -Σημείωση: - -Η υπηρεσία θα είναι για μερικές εβδομάδες σε φάση λειτουργίας Alpha. Αν -και έχουμε κάνει ό,τι είναι δυνατό για να εξασφαλίσουμε την ποιότητα της -υπηρεσίας, δεν αποκλείεται να εμφανιστούν προβλήματα στο λογισμικό -διαχείρισης ή η υπηρεσία να μην είναι διαθέσιμη κατά διαστήματα. Για -αυτό το λόγο, σας παρακαλούμε να μη μεταφέρετε ακόμη σημαντικά αρχεία -στην υπηρεσία {{ site_name }}. Επίσης, παρακαλούμε να έχετε -υπόψη σας ότι όλα τα δεδομένα, θα διαγραφούν κατά τη μετάβαση από την -έκδοση Alpha στην έκδοση Beta. Θα υπάρξει έγκαιρη ειδοποίησή σας πριν -από τη μετάβαση αυτή. - -Περισσότερα για την υπηρεσία θα βρείτε στο {{ baseurl }}, αφού -ενεργοποιήσετε την πρόσκλησή σας. - -Αναμένουμε τα σχόλια και τις παρατηρήσεις σας, για να βελτιώσουμε τη -λειτουργικότητα και την αξιοπιστία της καινοτομικής αυτής υπηρεσίας. - -Για όποιες παρατηρήσεις ή προβλήματα στη λειτουργεία της υπηρεσίας μπορείτε να -απευθυνθείτε στο {{ support }}. - -Σας ευχαριστούμε πολύ για τη συμμετοχή στην Alpha λειτουργία του {{ site_name }}. - -Με εκτίμηση, - -Εθνικό Δίκτυο Έρευνας και Τεχνολογίας (ΕΔΕΤ/GRNET) - --- - -Dear {{ user.realname }}, - -Your account for GRNET's {{ site_name }} service for its Alpha test phase has been -activated. - -To login, please use the following link: - -{{ url }} - -Please note: - -This service is, for a few weeks, in Alpha. Although every care has been -taken to ensure high quality, it is possible there may still be software -bugs, or periods of limited service availability. For this reason we kindly -request you not to transfer important files to {{ site_name}} yet. -Also, please bear in mind that all data will be deleted when the service moves to Beta. -We will notify you before the transition. - -For more information, please visit {{ baseurl }}, after -activating your invitation. - -We look forward to your feedback, to improve the functionality and -reliability of this innovative service. - -For any remarks or problems you can contact {{ support }}. - -Thank you for participating in the Alpha test of {{ site_name }}. - -Greek Research and Technonogy Network - GRNET diff --git a/astakos/im/admin/urls.py b/astakos/im/admin/urls.py deleted file mode 100644 index a239837..0000000 --- a/astakos/im/admin/urls.py +++ /dev/null @@ -1,50 +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. - -from django.conf.urls.defaults import patterns, url - -urlpatterns = patterns('astakos.im.admin.views', - url(r'^$', 'admin'), - - url(r'^users/?$', 'users_list'), - url(r'^users/(\d+)/?$', 'users_info'), - url(r'^users/create$', 'users_create'), - url(r'^users/(\d+)/modify/?$', 'users_modify'), - url(r'^users/(\d+)/delete/?$', 'users_delete'), - url(r'^users/export/?$', 'users_export'), - url(r'^users/pending/?$', 'pending_users'), - url(r'^users/activate/(\d+)/?$', 'users_activate'), - - url(r'^invitations/?$', 'invitations_list'), - url(r'^invitations/export/?$', 'invitations_export'), -) \ No newline at end of file diff --git a/astakos/im/admin/views.py b/astakos/im/admin/views.py deleted file mode 100644 index 54f0910..0000000 --- a/astakos/im/admin/views.py +++ /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)) diff --git a/astakos/im/interface.py b/astakos/im/interface.py deleted file mode 100644 index bf2ce0b..0000000 --- a/astakos/im/interface.py +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2011-2012 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. - -from astakos.im.settings import BACKEND_BLOCK_MODULE, BACKEND_BLOCK_PATH, BACKEND_DB_CONNECTION, BACKEND_DB_MODULE, BACKEND_QUOTA, BACKEND_VERSIONING - -from pithos.backends import connect_backend - -def get_backend(): - backend = connect_backend(db_module=BACKEND_DB_MODULE, - db_connection=BACKEND_DB_CONNECTION, - block_module=BACKEND_BLOCK_MODULE, - block_path=BACKEND_BLOCK_PATH) - backend.default_policy['quota'] = BACKEND_QUOTA - backend.default_policy['versioning'] = BACKEND_VERSIONING - return backend - -def get_quota(user): - backend = get_backend() - quota = backend.get_account_policy(user, user)['quota'] - backend.close() - return quota - -def set_quota(user, quota): - backend = get_backend() - backend.update_account_policy(user, user, {'quota': quota}) - backend.close() - return quota diff --git a/astakos/im/models.py b/astakos/im/models.py index 8e4ace6..9f73e0a 100644 --- a/astakos/im/models.py +++ b/astakos/im/models.py @@ -41,7 +41,6 @@ from base64 import b64encode from django.db import models from django.contrib.auth.models import User, UserManager -from astakos.im.interface import get_quota, set_quota from astakos.im.settings import DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, AUTH_TOKEN_DURATION class AstakosUser(User): @@ -84,14 +83,6 @@ class AstakosUser(User): self.last_name = parts[0] @property - def quota(self): - return get_quota(self.username) - - @quota.setter - def quota(self, value): - set_quota(self.username, value) - - @property def invitation(self): try: return Invitation.objects.get(username=self.email) diff --git a/astakos/im/settings.py b/astakos/im/settings.py index bea865a..ad0e7cc 100644 --- a/astakos/im/settings.py +++ b/astakos/im/settings.py @@ -8,12 +8,6 @@ PROJECT_PATH = getattr(settings, 'PROJECT_PATH', dirname(dirname(abspath(__file_ # to be this many hours after their creation time. AUTH_TOKEN_DURATION = getattr(settings, 'ASTAKOS_AUTH_TOKEN_DURATION', 30 * 24) -# Bypass authentication for user administration. -BYPASS_ADMIN_AUTH = getattr(settings, 'ASTAKOS_BYPASS_ADMIN_AUTH', False) - -# Show these many users per page in admin interface. -ADMIN_PAGE_LIMIT = getattr(settings, 'ASTAKOS_ADMIN_PAGE_LIMIT', 100) - # Authenticate via Twitter. TWITTER_KEY = getattr(settings, 'ASTAKOS_TWITTER_KEY', '') TWITTER_SECRET = getattr(settings, 'ASTAKOS_TWITTER_SECRET', '') @@ -55,15 +49,3 @@ BASEURL = getattr(settings, 'ASTAKOS_BASEURL', 'http://pithos.dev.grnet.gr') # Set service name SITENAME = getattr(settings, 'ASTAKOS_SITENAME', 'Pithos+') - -# SQLAlchemy (choose SQLite/MySQL/PostgreSQL). -BACKEND_DB_MODULE = getattr(settings, 'PITHOS_BACKEND_DB_MODULE', 'pithos.backends.lib.sqlalchemy') -BACKEND_DB_CONNECTION = getattr(settings, 'PITHOS_BACKEND_DB_CONNECTION', 'sqlite:///' + join(PROJECT_PATH, 'backend.db')) - -# Block storage. -BACKEND_BLOCK_MODULE = getattr(settings, 'PITHOS_BACKEND_BLOCK_MODULE', 'pithos.backends.lib.hashfiler') -BACKEND_BLOCK_PATH = getattr(settings, 'PITHOS_BACKEND_BLOCK_PATH', join(PROJECT_PATH, 'data/')) - -# Default setting for new accounts. -BACKEND_QUOTA = getattr(settings, 'PITHOS_BACKEND_QUOTA', 50 * 1024 * 1024 * 1024) -BACKEND_VERSIONING = getattr(settings, 'PITHOS_BACKEND_VERSIONING', 'auto') diff --git a/astakos/im/urls.py b/astakos/im/urls.py index 09c5644..84d728b 100644 --- a/astakos/im/urls.py +++ b/astakos/im/urls.py @@ -43,8 +43,7 @@ urlpatterns = patterns('astakos.im.views', url(r'^feedback/?$', 'send_feedback'), url(r'^signup/?$', 'signup'), url(r'^logout/?$', 'logout'), - url(r'^activate/?$', 'activate'), - url(r'^admin/', include('astakos.im.admin.urls')), + url(r'^activate/?$', 'activate') ) urlpatterns += patterns('astakos.im.target', @@ -73,7 +72,7 @@ if 'local' in IM_MODULES: if INVITATIONS_ENABLED: urlpatterns += patterns('astakos.im.views', - url(r'^invite/?$', 'invite'), + url(r'^invite/?$', 'invite') ) if 'shibboleth' in IM_MODULES: @@ -90,4 +89,3 @@ if 'twitter' in IM_MODULES: urlpatterns += patterns('astakos.im.api', url(r'^authenticate/?$', 'authenticate') ) - -- 1.7.10.4