Work in progress. I've moved permissions management to the new dedicated page. Adding permissions is working but deleting ones. I must also filter the list of users available when creating a super admin because the default admin appears inside :p
This commit is contained in:
tonio
2010-11-25 23:19:04 +01:00
parent f7ec14bc87
commit eff3c7d815
14 changed files with 240 additions and 171 deletions
+29
View File
@@ -1,7 +1,9 @@
from django import forms
from modoboa.admin.models import Domain, Mailbox, Alias
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from modoboa.admin.templatetags.admin_extras import gender
from modoboa.lib import tables
class DomainForm(forms.ModelForm):
class Meta:
@@ -63,3 +65,30 @@ class PermissionForm(forms.Form):
choices=(("SuperAdmins", _("Super administrator")),
("DomainAdmins", _("Domain administrator"))),
help_text=_("Select the role you want this user to have"))
class SuperAdminForm(forms.Form):
user = forms.ModelChoiceField(queryset=User.objects.all(),
label=_("User"), required=True,
help_text=_("Select a user in the list"))
class DomainAdminForm(forms.Form):
domain = forms.ModelChoiceField(queryset=Domain.objects.all(), label=_("Domain"),
required=True,
help_text=_("Select a domain in the list"))
user = forms.ChoiceField(label=_("User"), required=True,
help_text=_("Select a user in the list"))
class SuperAdminsTable(tables.Table):
idkey = "id"
selection = tables.SelectionColumn("selection", width="4%", first=True)
_1_user_name = tables.Column("user_name", label=_("User name"))
_2_full_name = tables.Column("full_name", label=_("Full name"))
_3_enabled = tables.Column("enabled", label=_("Enabled_m"), width="10%")
class DomainAdminsTable(tables.Table):
idkey = "id"
selection = tables.SelectionColumn("selection", width="4%", first=True)
_1_domain = tables.Column("domain", label=_("Domain"))
_2_full_name = tables.Column("full_name", label=_("Full name"))
_3_enabled = tables.Column("enabled", label=_("Enabled_m"), width="10%")
+8
View File
@@ -99,6 +99,14 @@ class Mailbox(models.Model):
% (parameters.get_admin("STORAGE_PATH"),
self.domain.name, self.address))
def tohash(self):
return {
"id" : self.id,
"domain" : self.domain.name,
"full_name" : self.name,
"enabled" : self.user.is_active
}
class Alias(models.Model):
address = models.CharField(_('address'), max_length=100,
help_text=_("The alias address (without the domain part)"))
+15 -13
View File
@@ -31,7 +31,7 @@ def admin_menu(user):
if user.has_perm("auth.view_permissions"):
entries[0]["menu"] += [
{"name" : "permissions",
"url" : "",
"url" : reverse(admin.views.permissions),
"label" : _("Permissions"),
"img" : static_url("pics/permissions.png")}
]
@@ -40,7 +40,7 @@ def admin_menu(user):
{"name" : "settings",
"img" : static_url("pics/settings.png"),
"label" : _("Settings"),
"url" : reverse(admin.views.settings)}
"url" : reverse(admin.views.viewparameters)}
]
if not len(entries[0]["menu"]):
@@ -48,7 +48,6 @@ def admin_menu(user):
return render_to_string("common/menulist.html",
{"entries" : entries, "user" : user})
@register.simple_tag
def domain_menu(domain_id, selection, user):
entries = [
@@ -86,16 +85,6 @@ def domain_menu(domain_id, selection, user):
@register.simple_tag
def settings_menu(selection, user):
entries = [
{"name" : "permissions",
"url" : reverse(admin.views.settings),
"label" : _("Permissions"),
"img" : static_url("pics/permissions.png")},
{"name" : "addperm",
"url" : reverse(admin.views.addpermission),
"img" : static_url("pics/add.png"),
"label" : _("Add permission"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:320,y:210}}"},
{"name" : "parameters",
"url" : reverse(admin.views.viewparameters),
"img" : static_url("pics/domains.png"),
@@ -129,6 +118,19 @@ def domains_menu(selection, user):
{"entries" : entries, "selection" : selection,
"user" : user})
@register.simple_tag
def permissions_menu(user):
entries = [
{"name" : "addperm",
"label" : _("Add permission"),
"img" : static_url("pics/add.png")},
{"name" : "delperms",
"label" : _("Remove permissions"),
"img" : static_url("pics/remove.png")},
]
return render_to_string('common/menu.html',
{"entries" : entries, "user" : user})
@register.simple_tag
def loadadminextmenu(user):
menu = events.raiseQueryEvent("AdminMenuDisplay", target="admin_menu_box",
+4 -2
View File
@@ -16,11 +16,13 @@ urlpatterns = patterns('modoboa.admin.views',
url(r'^domains/(?P<dom_id>\d+)/aliases/$', "aliases", name="full-aliases"),
url(r'^domains/(?P<dom_id>\d+)/aliases/(?P<mbox_id>\d+)/$', "aliases", name="mbox-aliases"),
(r'^domains/(?P<dom_id>\d+)/delalias/(?P<alias_id>\d+)/$', 'delalias'),
(r'^settings/$', 'settings'),
(r'^settings/addperm/$', 'addpermission'),
(r'^settings/$', 'viewparameters'),
(r'^settings/delperm/(?P<mbox_id>\d+)/(?P<group>\w+)/$', 'deletepermission'),
(r'^settings/parameters/$', 'viewparameters'),
(r'^settings/parameters/save/$', 'saveparameters'),
(r'^settings/extensions/$', 'viewextensions'),
(r'^settings/extensions/save/$', 'saveextensions'),
(r'^permissions/$', 'permissions'),
(r'^permissions/superadmin/add/$', 'add_superadmin'),
(r'^permissions/domainadmin/add/$', 'add_domain_admin'),
)
+72 -29
View File
@@ -14,11 +14,10 @@ from django.contrib.auth.models import User, Group
from django.contrib import messages
from modoboa import admin, userprefs
from modoboa.admin.models import *
from forms import MailboxForm, DomainForm, AliasForm, PermissionForm
from models import *
from forms import *
from modoboa.lib.authbackends import crypt_password
from modoboa.lib import _render, _ctx_ok, _ctx_ko, getctx
from modoboa.lib import events, parameters
from modoboa.lib import _render, _ctx_ok, _ctx_ko, getctx, events, parameters
from modoboa.lib.models import Parameter
import string
import copy
@@ -88,7 +87,7 @@ def newdomain(request):
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = DomainForm()
return render_to_response('admin/newdomain.html', {
return _render(request, 'admin/newdomain.html', {
"form" : form
})
@@ -356,43 +355,87 @@ def delalias(request, dom_id, alias_id):
args=[dom_id]))
@login_required
@user_passes_test(lambda u: u.is_superuser)
def settings(request):
admins = User.objects.filter(is_superuser=True)
@permission_required("auth.view_permissions")
def permissions(request):
permtables = []
if request.user.is_superuser:
admins = User.objects.filter(is_superuser=True)
admins_list = []
for admin in admins:
admins_list += [{"id" : admin.id, "user_name" : admin.username,
"full_name" : "%s %s" % (admin.first_name, admin.last_name),
"enabled" : admin.is_active}]
permtables += [
{"title" : _("Super administrators"),
"content" : SuperAdminsTable(admins_list).render(request),
"addurl" : reverse(add_superadmin)}
]
permtables += events.raiseQueryEvent("PermsGetTables", user=request.user)
domadmins = Mailbox.objects.filter(user__groups__name="DomainAdmins")
domadmins_list = []
for admin in domadmins:
domadmins_list += [admin.tohash()]
permtables += [
{"title" : _("Domain administrators"),
"content" : DomainAdminsTable(domadmins_list).render(request),
"addurl" : reverse(add_domain_admin)}
]
return _render(request, 'admin/permissions.html', {
"admins" : admins, "domadmins" : domadmins
"permtables" : permtables
})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def addpermission(request):
def add_superadmin(request):
if request.method == "POST":
form = PermissionForm(request.POST)
if request.POST.has_key('user'):
mboxid = request.POST['user']
form.fields["user"].choices = \
[(mboxid, Mailbox.objects.get(pk=mboxid)),]
form = SuperAdminForm(request.POST)
if form.is_valid():
mb = Mailbox.objects.get(pk=request.POST["user"])
if request.POST["role"] == "SuperAdmins":
mb.user.is_superuser = True
mb.user.groups.clear()
else:
mb.user.is_superuser = False
mb.user.groups.add(Group.objects.get(name=request.POST["role"]))
mb.user.save()
ctx = _ctx_ok(reverse(admin.views.settings))
user = User.objects.get(pk=request.POST["user"])
user.is_superuser = True
user.groups.clear()
user.save()
ctx = _ctx_ok(reverse(admin.views.permissions))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/addpermission.html", {
ctx = _ctx_ko("admin/add_superadmin.html", {
"form" : form
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = PermissionForm()
return _render(request, 'admin/addpermission.html', {
"form" : form
form = SuperAdminForm()
return _render(request, 'admin/add_permission.html', {
"form" : form, "title" : _("Add super administrator"),
"action" : reverse(add_superadmin)
})
@login_required
@permission_required("domains.create")
def add_domain_admin(request):
if request.method == "POST":
form = DomainAdminForm(request.POST)
mboxid = request.POST['user']
form.fields["user"].choices = \
[(mboxid, Mailbox.objects.get(pk=mboxid)),]
if form.is_valid():
mb = Mailbox.objects.get(pk=request.POST["user"])
mb.user.is_superuser = False
mb.user.groups.add(Group.objects.get(name="DomainAdmins"))
mb.user.save()
ctx = _ctx_ok(reverse(admin.views.permissions))
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
ctx = _ctx_ko("admin/add_domain_admin.html", {
"form" : form
})
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
form = DomainAdminForm()
return _render(request, 'admin/add_domain_admin.html', {
"form" : form, "title" : _("Add domain administrator"),
"action" : reverse(add_domain_admin)
})
@login_required
+2
View File
@@ -15,6 +15,8 @@ events = ["CreateDomain",
"UserMenuDisplay",
"AdminMenuDisplay",
"PermsGetTables",
"UserLogin",
"UserLogout"]
+10 -4
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import inspect
import lxml
from django.utils.translation import ugettext as _
from django.template import Template, Context
from django.template.loader import render_to_string
@@ -83,15 +84,20 @@ class Table(object):
self.rows += [nrow]
def render(self, request):
t = Template("""
if len(self.rows):
t = Template("""
<table id="{{ tableid }}">
{% include "common/table_head.html" %}
{% include "common/table_body.html" %}
</table>
""")
return t.render(Context({
"table" : self, "tableid" : self.tableid
}))
return t.render(Context({
"table" : self, "tableid" : self.tableid
}))
t = Template("""
<div class="info">%s</div>
""" % _("No entries to display"))
return t.render(Context())
def render_head(self, request):
t = Template("""
+13 -13
View File
@@ -1,7 +1,7 @@
window.addEvent('domready', function(){
parse_menubar('topmenubar');
parse_menubar('menubar');
infobox = new InfoBox({
parent : $("menubar"),
message : "Loading"
@@ -21,7 +21,7 @@ get_callback = function(name) {
current_anchor = null;
check_anchor = function() {
if (current_anchor.serialized == location.hash
if (current_anchor.serialized == location.hash
&& !$defined(current_anchor.force)) {
return;
}
@@ -67,9 +67,9 @@ function HashWrapper(deflocation) {
};
this.parse_string = function(value, reset) {
var splits = (value.charAt(0) == '#')
var splits = (value.charAt(0) == '#')
? value.substring(1).split('?') : value.split('?');
if (splits.length == 0) {
return this;
}
@@ -143,7 +143,7 @@ function HashWrapper(deflocation) {
this.params.set(name, value);
return this;
};
this.setparams = function(params) {
this.params.extend(params);
return this;
@@ -191,7 +191,7 @@ parse_menubar = function(id) {
var myFx = new Fx.Slide(list, {
duration: 200
});
myFx.wrapper.setStyles({
/*"clear" : "both",*/
"position" : "absolute"
@@ -227,12 +227,12 @@ get_iframe_body = function(id) {
data = targetif.contentDocument.defaultView.document.body;
} else {
data = targetif.document.body;
}
}
} else if (targetif.contentWindow && !saf) {
// IE 5.5 & 6.x
data = targetif.contentWindow.document.body;
}
return (data);
return (data);
}
confirmation = function(question, action, callback) {
@@ -244,12 +244,12 @@ confirmation = function(question, action, callback) {
var elt = ibody.getElement("input[name=result]");
if (elt.get("value") == "ok") {
params = ""
params = "";
if (typeof callback != "undefined") {
params = callback(ibody);
}
new Request({
method: "get",
method: "get",
url: action.get("href"),
onSuccess: function(res) {
window.location.reload();
@@ -262,7 +262,7 @@ confirmation = function(question, action, callback) {
}
setDivHeight = function(id, extrah, modulo) {
var contentsize = $(document.body).getSize().y
var contentsize = $(document.body).getSize().y
- $("topmenubar").getSize().y
- $("header").getSize().y
- $("footer").getSize().y
@@ -326,7 +326,7 @@ searchbox_init = function() {
$("searchfield").addEvent("click", function(event) {
$("searchfield").select();
});
$("searchfield").addEvent("blur", function(event) {
if ($("searchfield").value == "") {
$("searchfield").set("value", gettext("Search..."));
@@ -352,7 +352,7 @@ gethref = function(obj) {
var url = obj.get("href");
var re = new RegExp("^(https?):");
var scheme = re.exec(url);
if (scheme != null) {
var baseurl = scheme[0] + "://" + location.host + location.pathname;
return url.replace(baseurl, "");
+6 -16
View File
@@ -1,34 +1,24 @@
window.addEvent('domready', function() {
var handlers = new Array();
if ($defined($("domcontent"))) {
SqueezeBox.assign($("domcontent").getElements('a[class=boxed]'), {
parse: 'rel',
parse: 'rel',
});
}
if ($defined($("subcontent"))) {
SqueezeBox.assign($("subcontent").getElements('a[class=boxed]'), {
parse: 'rel',
parse: 'rel',
});
}
// handlers['loadDom'] = function(obj, target) {
/* $$('a[name=loadDom]').setStyles({'color' : '#999'});*/
/* obj.setStyles({"color": "black"});*/
// loadPage(target, "content", null);
// };
// handlers['loadContent'] = function(obj, target) {
// loadPage(target, "content", null);
// };
if ($$("a[name=deleteDom]"))
$$("a[name=deleteDom]").addEvent('click', function(event) {
if (!confirm(gettext("Delete this domain?")))
event.stop();
});
if ($$("a[name=deleteMb]"))
$$("a[name=deleteMb]").addEvent('click', function(event) {
event.stop();
@@ -50,7 +40,7 @@ window.addEvent('domready', function() {
event.stop();
});
$(document.body).addEvent('click', function(event) {
target = event.target;
if (target.get('tag') == 'a') {
@@ -92,7 +82,7 @@ newdom = function() {
loadPage = function(url, destination, callback) {
var destination = (destination == null) ? "page" : destination;
if (callback)
new Request({url: url, method: "get", onSuccess: callback}).send();
else
+28
View File
@@ -0,0 +1,28 @@
window.addEvent('domready', function() {
var tip = new Tips($$(".Tips"));
var addperm_url = "";
var accordion = new Accordion('h3.atStart', 'div.atStart', {
opacity: true,
onActive: function(toggler, element){
toggler.setStyle('color', '#ff3300');
addperm_url = element.get("name");
},
onBackground: function(toggler, element) {
toggler.setStyle('color', '#222');
}
}, $('accordion'));
$$("a[name=addperm]").addEvent("click", function(evt) {
evt.stop();
if (addperm_url == "") {
return;
}
SqueezeBox.initialize({
size: {x: 300, y: 280},
handler: 'iframe'
});
SqueezeBox.open(addperm_url);
});
});
+20
View File
@@ -0,0 +1,20 @@
{% extends "admin/add_permission.html" %}
{% block html_head %}
{{ block.super }}
<script type="text/javascript">
window.addEvent("domready", function() {
$("id_domain").addEvent("change", function(event) {
domid = this.value;
if (domid == "") {
$("id_user").set("html", "");
return;
}
{% url domains as doms_url %}
new Request({url: "{{ doms_url }}" + domid + "/raw/",
method: "get", onSuccess: function(data) {
$("id_user").set("html", data);
}}).send();
});
});
</script>
{% endblock %}
+18
View File
@@ -0,0 +1,18 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
{% if error %}<div class="error">{{ error }}</div>{% endif %}
<form action="{{ action }}" method="POST" id="permform" name="permform">
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{% trans 'Add' %}" />
</div>
</form>
{% endblock %}
-36
View File
@@ -1,36 +0,0 @@
{% extends "layout_simple.html" %}
{% load i18n %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/form.js" type="text/javascript"></script>
<script type="text/javascript">
window.addEvent("domready", function() {
$("id_domain").addEvent("change", function(event) {
domid = this.value;
if (domid == "") {
$("id_user").set("html", "");
return;
}
{% url domains as doms_url %}
new Request({url: "{{ doms_url }}" + domid + "/raw/",
method: "get", onSuccess: function(data) {
$("id_user").set("html", data);
}}).send();
});
});
</script>
{% endblock %}
{% block content %}
<div class="title"><h1>{% trans "Add permission" %}</h1></div>
{% if error %}<div class="error">{{ error }}</div>{% endif %}
{% url admin.views.addpermission as addperm_url %}
<form action="{{ addperm_url }}" method="POST" id="permform" name="permform">
{% include "common/genericform.html" %}
<div class="spacer"></div>
<div class="lastrow" align="center">
<input type="submit" name="submit" value="{% trans 'Create' %}" />
</div>
</form>
{% endblock %}
+15 -58
View File
@@ -1,62 +1,19 @@
{% extends "admin/settings_header.html" %}
{% extends "nlayout.html" %}
{% load i18n admin_extras %}
{% block html_head %}
<script src="{{ MEDIA_URL }}js/permissions.js" type="text/javascript"></script>
{% endblock %}
{% block middletitle %}{% trans "Permissions" %}{% endblock %}
{% block menu %}
{% load admin_extras %}
{% settings_menu "permissions" user %}
{% permissions_menu user %}
{% endblock %}
{% block setcontent %}
{% load i18n %}
{% if not admins %}
<p>{% trans "No superuser defined?!" %}</p>
{% else %}
<h4>{% trans "Super administrators" %}</h4>
<table>
<tr>
<th width="50px">{% trans "Actions" %}</th>
<th width="210px">{% trans "Full name" %}</th>
<th>{% trans "User name" %}</th>
<th width="50px">{% trans "Enabled" %}</th>
</tr>
{% for admin in admins %}
<tr class="{% cycle 'odd' 'even' %}">
<td>
{% url admin.views.deletepermission admin.id "SuperAdmins" as del_url %}
<a href="{{ del_url }}" name="deletePerm">
<img src="{{ MEDIA_URL }}pics/remove.png" border="0" title="{% trans 'Remove permission' %}" />
</a>
</td>
<td>{{ admin.first_name }} {{ admin.last_name }}</td>
<td>{{ admin.username }}</td>
<td>{{ admin.is_active|yesno }}</td>
</tr>
{% block content %}
<div id="accordion">
{% for table in permtables %}
<h3 class="toggler atStart">{{ table.title }}</h3>
<div class="element atStart" name="{{ table.addurl }}">
{{ table.content }}
</div>
{% endfor %}
</table>
<br/><br/>
{% endif %}
<h4>{% trans "Domain administrators" %}</h4>
{% if not domadmins %}
<p>{% trans "No domain admin defined." %}</p>
{% else %}
<table>
<tr>
<th width="50px">{% trans "Actions" %}</th>
<th width="210px">{% trans "Domain" %}</th>
<th>{% trans "Name" %}</th>
<th width="50px">{% trans "Enabled" %}</th>
</tr>
{% for admin in domadmins %}
<tr class="{% cycle 'odd' 'even' %}">
<td>
{% url admin.views.deletepermission admin.id "DomainAdmins" as del_url %}
<a href="{{ del_url }}" name="deletePerm">
<img src="{{ MEDIA_URL }}pics/remove.png" border="0"
title="{% trans 'Remove permission' %}" />
</a>
</td>
<td>{{ admin.domain.name }}</td>
<td>{{ admin.name }}</td>
<td>{{ admin.user.is_active|yesno }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
{% endblock %}