diff --git a/INSTALL b/INSTALL index 6a528e415..0885d707f 100644 --- a/INSTALL +++ b/INSTALL @@ -146,6 +146,41 @@ Then, edit your /etc/dovecot/dovecot-sql.conf and modify following lines:: password_query = SELECT full_address AS user, password FROM admin_mailbox WHERE full_address = '%u' user_query = SELECT path AS home, uid, gid FROM admin_mailbox WHERE full_address = '%u' +Enable quotas with Dovecot +-------------------------- + +Put the following lines inside your dovecot.conf file:: + + protocol imap { + mail_plugins = quota quota_imap + } + +If you use version prior to 1.1, add also the following configuration:: + + plugin { + # 10 MB default quota limit + quota = maildir:storage=10240 + } + +Then modify the above user_query inside dovecot-sql.conf file like +that to activate per user quotas:: + + user_query = SELECT path AS home, uid, gid, concat('maildir:storage=', quota / 1024) AS quota FROM admin_mailbox WHERE full_address = '%u' + +For version >= 1.1, put the following configuration inside dovecot.conf file:: + + plugin { + # Default 10M storage limit with an extra 5M limit when saving to Trash. + quota = maildir:User quota + quota_rule = *:storage=10M + quota_rule2 = Trash:storage=5M + } + +Then modify the above user_query inside dovecot-sql.conf to activate +user quotas:: + + user_query = SELECT path AS home, uid, gid, concat('*:storage=', quota, 'M') AS quota_rule FROM admin_mailbox WHERE full_address = '%u' + Tips to server Mailng behind Apache2 ------------------------------------ diff --git a/admin/templatetags/admin_extras.py b/admin/templatetags/admin_extras.py index 11993e6b8..02b117e98 100644 --- a/admin/templatetags/admin_extras.py +++ b/admin/templatetags/admin_extras.py @@ -9,10 +9,11 @@ genders = { } @register.simple_tag -def domain_menu(domain_id, selection): +def domain_menu(domain_id, selection, perms): return render_to_string('admin/domain_menu.html', {"selection" : selection, - "domain_id" : domain_id}) + "domain_id" : domain_id, + "perms" : perms}) @register.simple_tag def settings_menu(selection): diff --git a/admin/urls.py b/admin/urls.py index 7d86ab0c2..770268375 100644 --- a/admin/urls.py +++ b/admin/urls.py @@ -17,5 +17,6 @@ urlpatterns = patterns('mailng.admin.views', url(r'^domains/(?P\d+)/aliases/(?P\d+)/$', "aliases", name="mbox-aliases"), (r'^domains/(?P\d+)/delalias/(?P\d+)/$', 'delalias'), (r'^settings/$', 'settings'), - (r'^settings/addperm/$', 'addpermission') + (r'^settings/addperm/$', 'addpermission'), + (r'^settings/delperm/(?P\d+)/(?P\w+)/$', 'deletepermission') ) diff --git a/admin/views.py b/admin/views.py index dc80156ad..663efe130 100644 --- a/admin/views.py +++ b/admin/views.py @@ -12,7 +12,7 @@ from django.contrib.auth.models import User, Group from mailng import admin from mailng.admin.models import Domain, Mailbox, Alias from forms import MailboxForm, DomainForm, AliasForm, PermissionForm -import md5 +from mailng.lib.authbackends import crypt_password def _ctx_ok(url): return {"status" : "ok", "url" : url} @@ -106,8 +106,6 @@ def editdomain(request, dom_id): @login_required @permission_required("admin.delete_domain") def deldomain(request, dom_id): - if not is_superuser(request.user): - return mailboxes(request, dom_id) domain = Domain.objects.get(pk=dom_id) domain.delete_dir() domain.delete() @@ -155,7 +153,8 @@ def newmailbox(request, dom_id=None): user.save() mb.user = user - mb.password = md5.new(request.POST["password1"]).hexdigest() + mb.password = crypt_password(request.POST["password1"]) + mb.uid = mb.gid = 500 mb.domain = domain mb.quota = request.POST["quota"] @@ -351,5 +350,11 @@ def addpermission(request): "form" : form }) -def deletepermission(request): - pass +@login_required +@user_passes_test(lambda u: u.is_superuser) +def deletepermission(request, mbox_id, group): + mbox = Mailbox.objects.get(pk=mbox_id) + grp = Group.objects.get(name=group) + mbox.user.groups.remove(grp) + mbox.user.save() + return HttpResponseRedirect(reverse(admin.views.settings)) diff --git a/lib/authbackends.py b/lib/authbackends.py index 877abadb3..a283c1b30 100644 --- a/lib/authbackends.py +++ b/lib/authbackends.py @@ -1,6 +1,9 @@ from django.contrib.auth.models import User from mailng.admin.models import Mailbox -import md5 +import hashlib +import crypt +import string +from random import Random class SimpleBackend: def authenticate(self, username=None, password=None): @@ -12,7 +15,7 @@ class SimpleBackend: mb = Mailbox.objects.get(full_address=username) except Exception: return None - if mb.password != md5.new(password).hexdigest(): + if not check_password(password, mb.password): return None return user @@ -21,3 +24,16 @@ class SimpleBackend: return User.objects.get(pk=user_id) except User.DoesNotExist: return None + +def check_password(password, crypted): + if True: + return crypt.crypt(password, crypted) == crypted + else: + return hashlib.md5(password).hexdigest() == crypted + +def crypt_password(password): + if True: + salt = ''.join(Random().sample(string.letters + string.digits, 2)) + return crypt.crypt(password, salt) + else: + return hashlib.md5(password).hexdigest() diff --git a/static/js/settings.js b/static/js/settings.js index fc6ff91ed..014a8b98f 100644 --- a/static/js/settings.js +++ b/static/js/settings.js @@ -3,4 +3,10 @@ window.addEvent('domready', function() { parse: 'rel', }); + + if ($$("a[name=deletePerm]")) + $$("a[name=deletePerm]").addEvent('click', function(event) { + if (!confirm(gettext("Remove this permission?"))) + event.stop(); + }); }); \ No newline at end of file diff --git a/templates/admin/mailboxes.html b/templates/admin/mailboxes.html index 1edf11088..be7bd900d 100644 --- a/templates/admin/mailboxes.html +++ b/templates/admin/mailboxes.html @@ -1,7 +1,7 @@ {% extends "admin/domain_header.html" %} {% block menu %} {% load admin_extras %} -{% domain_menu domain.id "mailboxes" %} +{% domain_menu domain.id "mailboxes" perms %} {% endblock %} {% block domcontent %} diff --git a/templates/admin/permissions.html b/templates/admin/permissions.html index 442d90c05..dcec7fe80 100644 --- a/templates/admin/permissions.html +++ b/templates/admin/permissions.html @@ -43,7 +43,11 @@ {% for admin in domadmins %} - + {% url admin.views.deletepermission admin.id "DomainAdmins" as del_url %} + + + {{ admin.domain.name }} {{ admin.name }}