mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
Refactoring and Shorcuts added:
* Possibility to create an administrator with a new domain * Possibility to create default aliases with a new domain fixes #344
This commit is contained in:
+67
-67
@@ -8,7 +8,6 @@ from modoboa.admin.templatetags.admin_extras import gender
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.permissions import get_account_roles
|
||||
from modoboa.lib.formutils import *
|
||||
from modoboa.lib.permissions import *
|
||||
|
||||
|
||||
class DomainFormGeneral(forms.ModelForm, DynamicForm):
|
||||
@@ -101,9 +100,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
|
||||
continue
|
||||
events.raiseEvent("CanCreate", user, "domain_aliases")
|
||||
al = DomainAlias(name=v, target=d, enabled=d.enabled)
|
||||
al.save()
|
||||
grant_access_to_object(user, al, is_owner=True)
|
||||
events.raiseEvent("DomainAliasCreated", user, al)
|
||||
al.save(creator=user)
|
||||
|
||||
for dalias in d.domainalias_set.all():
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == dalias.name,
|
||||
@@ -112,6 +109,67 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm):
|
||||
return d
|
||||
|
||||
|
||||
class DomainFormOptions(forms.Form):
|
||||
create_dom_admin = YesNoField(
|
||||
label=ugettext_lazy("Create a domain administrator"),
|
||||
initial="no",
|
||||
help_text=ugettext_lazy("Automatically create an administrator for this domain")
|
||||
)
|
||||
|
||||
dom_admin_username = forms.CharField(
|
||||
label=ugettext_lazy("Name"),
|
||||
initial="admin",
|
||||
help_text=ugettext_lazy("The administrator's name. Don't include the domain's name here, it will be automatically appended."),
|
||||
widget=forms.widgets.TextInput(attrs={"class": "input-small"}),
|
||||
required=False
|
||||
)
|
||||
|
||||
create_aliases = YesNoField(
|
||||
label=ugettext_lazy("Create aliases"),
|
||||
initial="yes",
|
||||
help_text=ugettext_lazy("Automatically create standard aliases for this domain"),
|
||||
required=False
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DomainFormOptions, self).__init__(*args, **kwargs)
|
||||
if args:
|
||||
if args[0].get("create_dom_admin", "no") == "yes":
|
||||
self.fields["dom_admin_username"].required = True
|
||||
self.fields["create_aliases"].required = True
|
||||
|
||||
def clean_dom_admin_username(self):
|
||||
if '@' in self.cleaned_data["dom_admin_username"]:
|
||||
raise forms.ValidationError(_("Invalid format"))
|
||||
return self.cleaned_data["dom_admin_username"]
|
||||
|
||||
def save(self, user, domain):
|
||||
if self.cleaned_data["create_dom_admin"] == "no":
|
||||
return
|
||||
username = "%s@%s" % (self.cleaned_data["dom_admin_username"], domain.name)
|
||||
try:
|
||||
da = User.objects.get(username=username)
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
raise AdminError(_("User '%s' already exists" % username))
|
||||
da = User(username=username, email=username, is_active=True)
|
||||
da.set_password("password")
|
||||
da.save()
|
||||
da.set_role("DomainAdmins")
|
||||
da.post_create(user)
|
||||
mb = Mailbox(address=self.cleaned_data["dom_admin_username"], domain=domain,
|
||||
user=da, use_domain_quota=True)
|
||||
mb.set_quota()
|
||||
mb.save(creator=user)
|
||||
|
||||
if self.cleaned_data["create_aliases"] == "yes":
|
||||
al = Alias(address="postmaster", domain=domain, enabled=True)
|
||||
al.save([mb], [], creator=user)
|
||||
|
||||
domain.add_admin(da)
|
||||
|
||||
|
||||
class DomainForm(TabForms):
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
self.user = user
|
||||
@@ -464,19 +522,6 @@ class AccountFormGeneral(forms.ModelForm):
|
||||
raise forms.ValidationError(_("The two password fields didn't match."))
|
||||
return password2
|
||||
|
||||
def give_all_accesses(self, account):
|
||||
"""Give access to all objects defined in the database
|
||||
|
||||
Must be used when an account is promoted as a super user.
|
||||
|
||||
:param account: a ``User`` instance
|
||||
"""
|
||||
grant_access_to_objects(account, User.objects.all(), get_content_type(User))
|
||||
grant_access_to_objects(account, Domain.objects.all(), get_content_type(Domain))
|
||||
grant_access_to_objects(account, DomainAlias.objects.all(), get_content_type(DomainAlias))
|
||||
grant_access_to_objects(account, Mailbox.objects.all(), get_content_type(Mailbox))
|
||||
grant_access_to_objects(account, Alias.objects.all(), get_content_type(Alias))
|
||||
|
||||
def save(self, commit=True):
|
||||
account = super(AccountFormGeneral, self).save(commit=False)
|
||||
if self.user == account and not self.cleaned_data["is_active"]:
|
||||
@@ -490,20 +535,7 @@ class AccountFormGeneral(forms.ModelForm):
|
||||
role = self.cleaned_data["role"]
|
||||
elif self.user.group == "DomainAdmins" and self.user != account:
|
||||
role = "SimpleUsers"
|
||||
|
||||
if role is None or account.group == role:
|
||||
return account
|
||||
|
||||
account.groups.clear()
|
||||
if role == "SuperAdmins":
|
||||
account.is_superuser = True
|
||||
self.give_all_accesses(account)
|
||||
else:
|
||||
if account.is_superuser:
|
||||
ObjectAccess.objects.filter(user=account).delete()
|
||||
account.is_superuser = False
|
||||
account.groups.add(Group.objects.get(name=role))
|
||||
account.save()
|
||||
account.set_role(role)
|
||||
return account
|
||||
|
||||
|
||||
@@ -576,18 +608,7 @@ class AccountFormMail(forms.Form, DynamicForm):
|
||||
use_domain_quota=self.cleaned_data["quota_act"])
|
||||
self.mb.set_quota(self.cleaned_data["quota"],
|
||||
user.has_perm("admin.add_domain"))
|
||||
self.mb.save()
|
||||
grant_access_to_object(user, self.mb, is_owner=True)
|
||||
events.raiseEvent("CreateMailbox", user, self.mb)
|
||||
if user.is_superuser and not self.mb.user.has_perm("admin.add_domain"):
|
||||
# A super user is creating a new mailbox. Give
|
||||
# access to that mailbox (and the associated
|
||||
# account) to the appropriate domain admins,
|
||||
# except if the new account has a more important
|
||||
# role (SuperAdmin, Reseller)
|
||||
for admin in self.mb.domain.admins:
|
||||
grant_access_to_object(admin, self.mb)
|
||||
grant_access_to_object(admin, self.mb.user)
|
||||
self.mb.save(creator=user)
|
||||
else:
|
||||
newaddress = None
|
||||
if self.cleaned_data["email"] != self.mb.full_address:
|
||||
@@ -627,20 +648,13 @@ class AccountFormMail(forms.Form, DynamicForm):
|
||||
events.raiseEvent("CanCreate", user, "mailbox_aliases")
|
||||
al = Alias(address=local_part, enabled=account.is_active)
|
||||
al.domain = Domain.objects.get(name=domname)
|
||||
al.save([self.mb], [])
|
||||
grant_access_to_object(user, al, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, al)
|
||||
if user.is_superuser:
|
||||
for admin in al.domain.admins:
|
||||
grant_access_to_object(admin, al)
|
||||
al.save([self.mb], [], creator=user)
|
||||
|
||||
for alias in self.mb.alias_set.all():
|
||||
if len(alias.get_recipients()) >= 2:
|
||||
continue
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == alias.full_address,
|
||||
self.cleaned_data.keys())):
|
||||
events.raiseEvent("MailboxAliasDeleted", alias)
|
||||
ungrant_access_to_object(alias)
|
||||
alias.delete()
|
||||
|
||||
return self.mb
|
||||
@@ -677,26 +691,12 @@ class AccountPermissionsForm(forms.Form, DynamicForm):
|
||||
continue
|
||||
if not value in current_domains:
|
||||
domain = Domain.objects.get(name=value)
|
||||
grant_access_to_object(self.account, domain)
|
||||
for mb in domain.mailbox_set.all():
|
||||
if mb.user.has_perm("admin.add_domain"):
|
||||
continue
|
||||
grant_access_to_object(self.account, mb)
|
||||
grant_access_to_object(self.account, mb.user)
|
||||
for al in Alias.objects.filter(domain=domain):
|
||||
grant_access_to_object(self.account, al)
|
||||
domain.add_admin(self.account)
|
||||
|
||||
for domain in self.account.get_domains():
|
||||
if not len(filter(lambda name: self.cleaned_data[name] == domain.name,
|
||||
self.cleaned_data.keys())):
|
||||
ungrant_access_to_object(domain, self.account)
|
||||
for mb in domain.mailbox_set.all():
|
||||
if mb.user.has_perm("admin.add_domain"):
|
||||
continue
|
||||
ungrant_access_to_object(mb, self.account)
|
||||
ungrant_access_to_object(mb.user, self.account)
|
||||
for al in Alias.objects.filter(domain=domain):
|
||||
ungrant_access_to_object(al, self.account)
|
||||
domain.remove_admin(self.account)
|
||||
|
||||
|
||||
class AccountForm(TabForms):
|
||||
|
||||
+193
-56
@@ -14,8 +14,9 @@ from modoboa.lib.exceptions import PermDeniedException
|
||||
from modoboa.lib.sysutils import exec_cmd, exec_as_vuser
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.extensions import exts_pool
|
||||
from exceptions import *
|
||||
import os, sys
|
||||
from exceptions import AdminError
|
||||
import os
|
||||
import sys
|
||||
import pwd
|
||||
import re
|
||||
import crypt, hashlib, string, base64
|
||||
@@ -27,6 +28,7 @@ try:
|
||||
except ImportError:
|
||||
ldap_available = False
|
||||
|
||||
|
||||
class User(DUser):
|
||||
"""Proxy for the ``User`` model.
|
||||
|
||||
@@ -216,7 +218,7 @@ class User(DUser):
|
||||
return self.groups.all()[0].name
|
||||
except IndexError:
|
||||
return "?"
|
||||
|
||||
|
||||
@property
|
||||
def enabled(self):
|
||||
return self.is_active
|
||||
@@ -269,7 +271,7 @@ class User(DUser):
|
||||
else:
|
||||
q &= Q(groups__name__in=grpfilter)
|
||||
accounts = User.objects.select_related().filter(q)
|
||||
|
||||
|
||||
aliases = []
|
||||
if not idtfilter or ("alias" in idtfilter
|
||||
or "forward" in idtfilter
|
||||
@@ -290,7 +292,6 @@ class User(DUser):
|
||||
|
||||
return chain(accounts, aliases)
|
||||
|
||||
|
||||
def get_domains(self):
|
||||
"""Return the domains belonging to this user
|
||||
|
||||
@@ -408,6 +409,54 @@ class User(DUser):
|
||||
return True
|
||||
return False
|
||||
|
||||
def grant_access_to_all_objects(self):
|
||||
"""Give access to all objects defined in the database
|
||||
|
||||
Must be used when an account is promoted as a super user.
|
||||
"""
|
||||
from modoboa.lib.permissions import grant_access_to_objects, get_content_type
|
||||
grant_access_to_objects(self, User.objects.all(), get_content_type(User))
|
||||
grant_access_to_objects(self, Domain.objects.all(), get_content_type(Domain))
|
||||
grant_access_to_objects(self, DomainAlias.objects.all(), get_content_type(DomainAlias))
|
||||
grant_access_to_objects(self, Mailbox.objects.all(), get_content_type(Mailbox))
|
||||
grant_access_to_objects(self, Alias.objects.all(), get_content_type(Alias))
|
||||
|
||||
def set_role(self, role):
|
||||
"""Set administrative role for this account
|
||||
|
||||
:param string role: the role to set
|
||||
"""
|
||||
if role is None or self.group == role:
|
||||
return
|
||||
self.groups.clear()
|
||||
if role == "SuperAdmins":
|
||||
self.is_superuser = True
|
||||
self.grant_access_to_all_objects()
|
||||
else:
|
||||
if self.is_superuser:
|
||||
ObjectAccess.objects.filter(user=self).delete()
|
||||
self.is_superuser = False
|
||||
try:
|
||||
self.groups.add(Group.objects.get(name=role))
|
||||
except Group.DoesNotExist:
|
||||
self.groups.add(Group.objects.get(name="SimpleUsers"))
|
||||
self.save()
|
||||
|
||||
def post_create(self, creator):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(creator, self, is_owner=True)
|
||||
events.raiseEvent("AccountCreated", self)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if "creator" in kwargs:
|
||||
creator = kwargs["creator"]
|
||||
del kwargs["creator"]
|
||||
else:
|
||||
creator = None
|
||||
super(User, self).save(*args, **kwargs)
|
||||
if creator is not None:
|
||||
self.post_create(creator)
|
||||
|
||||
def from_csv(self, user, row, crypt_password=True):
|
||||
"""Create a new account from a CSV file entry
|
||||
|
||||
@@ -419,8 +468,6 @@ class User(DUser):
|
||||
:param row: a list containing the expected information
|
||||
:param crypt_password:
|
||||
"""
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
|
||||
if len(row) < 6:
|
||||
raise AdminError(_("Invalid line"))
|
||||
self.username = row[1].strip()
|
||||
@@ -431,17 +478,8 @@ class User(DUser):
|
||||
self.first_name = row[3].strip()
|
||||
self.last_name = row[4].strip()
|
||||
self.is_active = (row[5].strip() == 'True')
|
||||
grpname = row[6].strip()
|
||||
if grpname == "SuperAdmins":
|
||||
self.is_superuser = True
|
||||
self.save()
|
||||
else:
|
||||
self.save()
|
||||
try:
|
||||
self.groups.add(Group.objects.get(name=grpname))
|
||||
except Group.DoesNotExist:
|
||||
self.groups.add(Group.objects.get(name="SimpleUsers"))
|
||||
self.save()
|
||||
self.save(creator=user)
|
||||
self.set_role(row[6].strip())
|
||||
|
||||
self.email = row[7].strip()
|
||||
if self.email != "":
|
||||
@@ -454,12 +492,11 @@ class User(DUser):
|
||||
raise PermDeniedException
|
||||
mb = Mailbox(address=mailbox, domain=domain, user=self, use_domain_quota=True)
|
||||
mb.set_quota(override_rules=user.has_perm("admin.change_domain"))
|
||||
mb.save()
|
||||
self.save()
|
||||
if grpname == "DomainAdmins":
|
||||
mb.save(creator=user)
|
||||
if self.group == "DomainAdmins":
|
||||
for domname in row[8:]:
|
||||
try:
|
||||
grant_access_to_object(self, Domain.objects.get(name=domname))
|
||||
Domain.objects.get(name=domname).add_admin(self)
|
||||
except Domain.DoesNotExist:
|
||||
pass
|
||||
|
||||
@@ -470,7 +507,8 @@ class User(DUser):
|
||||
if self.group == "DomainAdmins":
|
||||
row += [dom.name for dom in self.get_domains()]
|
||||
csvwriter.writerow(row)
|
||||
|
||||
|
||||
|
||||
class ObjectAccess(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
content_type = models.ForeignKey(ContentType)
|
||||
@@ -483,7 +521,8 @@ class ObjectAccess(models.Model):
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s => %s (%s)" % (self.user, self.content_object, self.content_type)
|
||||
|
||||
|
||||
|
||||
class ObjectDates(models.Model):
|
||||
"""Dates recording for admin objects
|
||||
|
||||
@@ -530,21 +569,26 @@ class DatesAware(models.Model):
|
||||
def last_modification(self):
|
||||
return self.dates.last_modification
|
||||
|
||||
|
||||
class Domain(DatesAware):
|
||||
name = models.CharField(ugettext_lazy('name'), max_length=100, unique=True,
|
||||
help_text=ugettext_lazy("The domain name"))
|
||||
quota = models.IntegerField(help_text=ugettext_lazy("Default quota in MB applied to mailboxes"))
|
||||
enabled = models.BooleanField(ugettext_lazy('enabled'),
|
||||
help_text=ugettext_lazy("Check to activate this domain"))
|
||||
quota = models.IntegerField(
|
||||
help_text=ugettext_lazy("Default quota in MB applied to mailboxes")
|
||||
)
|
||||
enabled = models.BooleanField(
|
||||
ugettext_lazy('enabled'),
|
||||
help_text=ugettext_lazy("Check to activate this domain")
|
||||
)
|
||||
owners = generic.GenericRelation(ObjectAccess)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_domain", "View domain"),
|
||||
("view_domains", "View domains"),
|
||||
)
|
||||
)
|
||||
ordering = ["name"]
|
||||
|
||||
|
||||
@property
|
||||
def domainalias_count(self):
|
||||
return self.domainalias_set.count()
|
||||
@@ -559,8 +603,42 @@ class Domain(DatesAware):
|
||||
|
||||
@property
|
||||
def admins(self):
|
||||
"""Return the domain administrators of this domain
|
||||
|
||||
:return: a list of User objects
|
||||
"""
|
||||
return [oa.user for oa in self.owners.filter(user__is_superuser=False)]
|
||||
|
||||
def add_admin(self, account):
|
||||
"""Add a new administrator for this domain
|
||||
|
||||
:param User account: the administrotor to add
|
||||
"""
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(account, self)
|
||||
for mb in self.mailbox_set.all():
|
||||
if mb.user.has_perm("admin.add_domain"):
|
||||
continue
|
||||
grant_access_to_object(account, mb)
|
||||
grant_access_to_object(account, mb.user)
|
||||
for al in self.alias_set.all():
|
||||
grant_access_to_object(account, al)
|
||||
|
||||
def remove_admin(self, account):
|
||||
"""Remove an administrator for this domain
|
||||
|
||||
:param User account: the administrotor to remove
|
||||
"""
|
||||
from modoboa.lib.permissions import ungrant_access_to_object
|
||||
ungrant_access_to_object(account, self)
|
||||
for mb in self.mailbox_set.all():
|
||||
if mb.user.has_perm("admin.add_domain"):
|
||||
continue
|
||||
ungrant_access_to_object(mb, account)
|
||||
ungrant_access_to_object(mb.user, account)
|
||||
for al in self.alias_set.all():
|
||||
ungrant_access_to_object(al, account)
|
||||
|
||||
def delete(self, fromuser, keepdir=False):
|
||||
from modoboa.lib.permissions import ungrant_access_to_object, ungrant_access_to_objects
|
||||
|
||||
@@ -588,13 +666,28 @@ class Domain(DatesAware):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def post_create(self, creator):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(creator, self, is_owner=True)
|
||||
events.raiseEvent("CreateDomain", creator, self)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if "creator" in kwargs:
|
||||
creator = kwargs["creator"]
|
||||
del kwargs["creator"]
|
||||
else:
|
||||
creator = None
|
||||
super(Domain, self).save(*args, **kwargs)
|
||||
if creator is not None:
|
||||
self.post_create(creator)
|
||||
|
||||
def from_csv(self, user, row):
|
||||
if len(row) < 4:
|
||||
raise AdminError(_("Invalid line"))
|
||||
self.name = row[1].strip()
|
||||
self.quota = int(row[2].strip())
|
||||
self.enabled = (row[3].strip() == 'True')
|
||||
self.save()
|
||||
self.save(creator=user)
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
csvwriter.writerow(["domain", self.name, self.quota, self.enabled])
|
||||
@@ -603,21 +696,38 @@ class Domain(DatesAware):
|
||||
class DomainAlias(DatesAware):
|
||||
name = models.CharField(ugettext_lazy("name"), max_length=100, unique=True,
|
||||
help_text=ugettext_lazy("The alias name"))
|
||||
target = models.ForeignKey(Domain, verbose_name=ugettext_lazy('target'),
|
||||
help_text=ugettext_lazy("The domain this alias points to"))
|
||||
target = models.ForeignKey(
|
||||
Domain, verbose_name=ugettext_lazy('target'),
|
||||
help_text=ugettext_lazy("The domain this alias points to")
|
||||
)
|
||||
enabled = models.BooleanField(
|
||||
ugettext_lazy('enabled'),
|
||||
help_text=ugettext_lazy("Check to activate this alias")
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_domaliases", "View domain aliases"),
|
||||
)
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def post_create(self, creator):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(creator, self, is_owner=True)
|
||||
events.raiseEvent("DomainAliasCreated", creator, self)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if "creator" in kwargs:
|
||||
creator = kwargs["creator"]
|
||||
del kwargs["creator"]
|
||||
else:
|
||||
creator = None
|
||||
super(DomainAlias, self).save(*args, **kwargs)
|
||||
if creator is not None:
|
||||
self.post_create(creator)
|
||||
|
||||
def delete(self):
|
||||
from modoboa.lib.permissions import ungrant_access_to_object
|
||||
events.raiseEvent("DomainAliasDeleted", self)
|
||||
@@ -628,7 +738,7 @@ class DomainAlias(DatesAware):
|
||||
"""Create a domain alias from a CSV row
|
||||
|
||||
Expected format: ["domainalias", domain alias name, targeted domain, enabled]
|
||||
|
||||
|
||||
:param user: a ``User`` object
|
||||
:param row: a list containing the alias definition
|
||||
"""
|
||||
@@ -641,7 +751,7 @@ class DomainAlias(DatesAware):
|
||||
except Domain.DoesNotExist:
|
||||
raise AdminError(_("Unknown domain %s" % domname))
|
||||
self.enabled = row[3].strip() == 'True'
|
||||
self.save()
|
||||
self.save(creator=user)
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
"""Export a domain alias using CSV format
|
||||
@@ -650,11 +760,12 @@ class DomainAlias(DatesAware):
|
||||
"""
|
||||
csvwriter.writerow(["domainalias", self.name, self.target.name, self.enabled])
|
||||
|
||||
|
||||
class Mailbox(DatesAware):
|
||||
address = models.CharField(
|
||||
ugettext_lazy('address'), max_length=100,
|
||||
help_text=ugettext_lazy("Mailbox address (without the @domain.tld part)")
|
||||
)
|
||||
)
|
||||
quota = models.PositiveIntegerField()
|
||||
use_domain_quota = models.BooleanField(default=False)
|
||||
domain = models.ForeignKey(Domain)
|
||||
@@ -671,10 +782,10 @@ class Mailbox(DatesAware):
|
||||
|
||||
def __str__(self):
|
||||
return self.full_address
|
||||
|
||||
|
||||
def __full_address(self, localpart):
|
||||
return "%s@%s" % (localpart, self.domain.name)
|
||||
|
||||
|
||||
@property
|
||||
def full_address(self):
|
||||
return self.__full_address(self.address)
|
||||
@@ -776,8 +887,29 @@ class Mailbox(DatesAware):
|
||||
q = Quota.objects.get(username=self.full_address)
|
||||
return int(q.bytes / float(self.quota * 1048576) * 100)
|
||||
|
||||
def post_create(self, creator):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(creator, self, True)
|
||||
events.raiseEvent("CreateMailbox", creator, self)
|
||||
if creator.is_superuser and not self.user.has_perm("admin.add_domain"):
|
||||
# A super user is creating a new mailbox. Give
|
||||
# access to that mailbox (and the associated
|
||||
# account) to the appropriate domain admins,
|
||||
# except if the new account has a more important
|
||||
# role (SuperAdmin, Reseller)
|
||||
for admin in self.domain.admins:
|
||||
grant_access_to_object(admin, self)
|
||||
grant_access_to_object(admin, self.user)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if "creator" in kwargs:
|
||||
creator = kwargs["creator"]
|
||||
del kwargs["creator"]
|
||||
else:
|
||||
creator = None
|
||||
super(Mailbox, self).save(*args, **kwargs)
|
||||
if creator is not None:
|
||||
self.post_create(creator)
|
||||
try:
|
||||
q = self.quota_value
|
||||
except Quota.DoesNotExist:
|
||||
@@ -889,12 +1021,27 @@ class Alias(DatesAware):
|
||||
altype = self.type
|
||||
return [{"name" : altype, "label" : labels[altype], "type" : "idt"}]
|
||||
|
||||
def post_create(self, creator):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
grant_access_to_object(creator, self, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", creator, self)
|
||||
if creator.is_superuser:
|
||||
for admin in self.domain.admins:
|
||||
grant_access_to_object(admin, self)
|
||||
|
||||
def save(self, int_rcpts, ext_rcpts, *args, **kwargs):
|
||||
if len(ext_rcpts):
|
||||
self.extmboxes = ",".join(ext_rcpts)
|
||||
else:
|
||||
self.extmboxes = ""
|
||||
if "creator" in kwargs:
|
||||
creator = kwargs["creator"]
|
||||
del kwargs["creator"]
|
||||
else:
|
||||
creator = None
|
||||
super(Alias, self).save(*args, **kwargs)
|
||||
if creator is not None:
|
||||
self.post_create(creator)
|
||||
curmboxes = self.mboxes.all()
|
||||
for t in int_rcpts:
|
||||
if not t in curmboxes:
|
||||
@@ -961,7 +1108,7 @@ class Alias(DatesAware):
|
||||
domain__name=domname)]
|
||||
except Mailbox.DoesNotExist:
|
||||
raise AdminError(_("Mailbox %s does not exist" % rcpt))
|
||||
self.save(int_rcpts, ext_rcpts)
|
||||
self.save(int_rcpts, ext_rcpts, creator=user)
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
row = [self.type, self.full_address, self.enabled]
|
||||
@@ -1032,11 +1179,8 @@ def populate_callback(user):
|
||||
from modoboa.lib.permissions import grant_access_to_object
|
||||
|
||||
sadmins = User.objects.filter(is_superuser=True)
|
||||
|
||||
user.groups.add(Group.objects.get(name="SimpleUsers"))
|
||||
user.save()
|
||||
events.raiseEvent("AccountCreated", user)
|
||||
grant_access_to_object(sadmins[0], user, True)
|
||||
user.set_role("SimpleUsers")
|
||||
user.post_create(sadmins[0])
|
||||
for su in sadmins[1:]:
|
||||
grant_access_to_object(su, user)
|
||||
|
||||
@@ -1044,13 +1188,8 @@ def populate_callback(user):
|
||||
try:
|
||||
domain = Domain.objects.get(name=domname)
|
||||
except Domain.DoesNotExist:
|
||||
domain = Domain()
|
||||
domain.name = domname
|
||||
domain.enabled = True
|
||||
domain.quota = 0
|
||||
domain.save()
|
||||
events.raiseEvent("CreateDomain", sadmins[0], domain)
|
||||
grant_access_to_object(sadmins[0], domain, True)
|
||||
domain = Domain(name=domname, enabled=True, quota=0)
|
||||
domain.save(creator=sadmin[0])
|
||||
for su in sadmins[1:]:
|
||||
grant_access_to_object(su, domain)
|
||||
try:
|
||||
@@ -1058,8 +1197,6 @@ def populate_callback(user):
|
||||
except Mailbox.DoesNotExist:
|
||||
mb = Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True)
|
||||
mb.set_quota()
|
||||
mb.save()
|
||||
events.raiseEvent("CreateMailbox", sadmins[0], mb)
|
||||
grant_access_to_object(sadmins[0], mb, True)
|
||||
mb.save(creator=sadmins[0])
|
||||
for su in sadmins[1:]:
|
||||
grant_access_to_object(su, domain)
|
||||
grant_access_to_object(su, mb)
|
||||
|
||||
@@ -161,17 +161,35 @@ Domains.prototype = {
|
||||
});
|
||||
},
|
||||
|
||||
domainform_cb: function() {
|
||||
change_inputs_state: function(value) {
|
||||
$("#id_dom_admin_username").attr("disabled", value);
|
||||
$("input[name=create_aliases]").attr("disabled", value);
|
||||
},
|
||||
|
||||
create_dom_admin_changed: function(e) {
|
||||
var $target = $(e.target);
|
||||
this.change_inputs_state(($target.attr("value") == "yes") ? false : true);
|
||||
},
|
||||
|
||||
generalform_init: function() {
|
||||
$('input:text:visible:first').focus();
|
||||
$("#id_aliases").dynamic_input();
|
||||
$(".submit").one('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "domform",
|
||||
error_cb: $.proxy(this.domainform_cb, this),
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
}, this));
|
||||
},
|
||||
|
||||
optionsform_init: function() {
|
||||
$("input[name=create_dom_admin]").click($.proxy(this.create_dom_admin_changed, this));
|
||||
this.change_inputs_state(
|
||||
$("input[name=create_dom_admin]:checked").attr("value") == "yes" ? false : true
|
||||
);
|
||||
this.optionsform_prefill();
|
||||
},
|
||||
|
||||
optionsform_prefill: function() {
|
||||
var $span = $("#id_dom_admin_username").next("span");
|
||||
$span.html("@" + $("#id_name").attr("value"));
|
||||
},
|
||||
|
||||
domadminsform_init: function() {
|
||||
$("a[name=removeperm]").click(function(e) {
|
||||
var $tr = $(this).parent().parent();
|
||||
simple_ajax_request.apply(this, [e, {
|
||||
@@ -184,6 +202,35 @@ Domains.prototype = {
|
||||
}
|
||||
}]);
|
||||
});
|
||||
},
|
||||
|
||||
newdomain_cb: function() {
|
||||
this.generalform_init();
|
||||
this.optionsform_init();
|
||||
$("#wizard").cwizard({
|
||||
formid: "domform",
|
||||
transition_callbacks: {
|
||||
1: this.optionsform_prefill
|
||||
},
|
||||
error_callbacks: {
|
||||
1: this.generalform_init,
|
||||
2: $.proxy(this.optionsform_init, this)
|
||||
},
|
||||
success_callback: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
},
|
||||
|
||||
domainform_cb: function() {
|
||||
this.generalform_init();
|
||||
this.domadminsform_init();
|
||||
$(".submit").one('click', $.proxy(function(e) {
|
||||
simple_ajax_form_post(e, {
|
||||
formid: "domform",
|
||||
error_cb: $.proxy(this.domainform_cb, this),
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.reload_listing, this)
|
||||
});
|
||||
}, this));
|
||||
$(document).trigger('domform_init');
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{% load i18n libextras %}
|
||||
{% render_field form.create_dom_admin %}
|
||||
{% render_field_appended form.dom_admin_username "@" %}
|
||||
{% render_field form.create_aliases %}
|
||||
@@ -2,10 +2,7 @@
|
||||
{% block pagetitle %}{% trans "Identities" %}{% endblock %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/jquery.sortable.css" />
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/creation_wizard.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/autocompleter.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.sortable.js"></script>
|
||||
<script type="text/javascript">
|
||||
function get_domains_list(container) {
|
||||
$.getJSON("{% url 'modoboa.admin.views.domains_list' %}", function(data) {
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
{% extends "admin/header.html" %}{% load i18n admin_extras libextras %}
|
||||
{% block html_head %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/jquery.sortable.css" />
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/creation_wizard.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/dynamic_input.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}js/jquery.sortable.js"></script>
|
||||
<script type="text/javascript">
|
||||
var admin;
|
||||
</script>
|
||||
|
||||
@@ -76,7 +76,7 @@ def domains_menu(selection, user):
|
||||
"label" : _("Add domain"),
|
||||
"img" : "icon-plus",
|
||||
"modal" : True,
|
||||
"modalcb" : "admin.domainform_cb",
|
||||
"modalcb" : "admin.newdomain_cb",
|
||||
"url" : reverse("modoboa.admin.views.newdomain")},
|
||||
{"name" : "import",
|
||||
"label" : _("Import"),
|
||||
|
||||
+41
-38
@@ -20,7 +20,8 @@ from modoboa.lib.webutils \
|
||||
import _render, ajax_response, ajax_simple_response, _render_to_string
|
||||
from modoboa.lib.emailutils import split_mailbox
|
||||
from modoboa.lib.models import Parameter
|
||||
from modoboa.lib.permissions import *
|
||||
from modoboa.lib.formutils import CreationWizard
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
@@ -67,8 +68,6 @@ def _validate_domain(request, form, successmsg, commonctx, tplname,
|
||||
domain = form.save(request.user)
|
||||
except AdminError, e:
|
||||
error = str(e)
|
||||
# except IntegrityError:
|
||||
# error = _("An alias with this name already exists")
|
||||
else:
|
||||
if callback is not None:
|
||||
callback(request.user, domain)
|
||||
@@ -81,23 +80,49 @@ def _validate_domain(request, form, successmsg, commonctx, tplname,
|
||||
@login_required
|
||||
@permission_required("admin.add_domain")
|
||||
@transaction.commit_on_success
|
||||
def newdomain(request, tplname="admin/newdomainform.html"):
|
||||
def newdomain(request, tplname="common/wizard_forms.html"):
|
||||
events.raiseEvent("CanCreate", request.user, "domains")
|
||||
def newdomain_cb(user, domain):
|
||||
grant_access_to_object(user, domain, is_owner=True)
|
||||
events.raiseEvent("CreateDomain", user, domain)
|
||||
|
||||
def newdomain_cb(steps):
|
||||
genform = steps[0]["form"]
|
||||
genform.is_valid()
|
||||
domain = genform.save(request.user)
|
||||
domain.post_create(request.user)
|
||||
steps[1]["form"].save(request.user, domain)
|
||||
|
||||
commonctx = {"title" : _("New domain"),
|
||||
"action_label" : _("Create"),
|
||||
"action_classes" : "submit",
|
||||
"action" : reverse(newdomain),
|
||||
"formid" : "domform"}
|
||||
cwizard = CreationWizard(newdomain_cb)
|
||||
cwizard.add_step(DomainFormGeneral, _("General"),
|
||||
[dict(classes="btn-inverse next", label=_("Next"))],
|
||||
formtpl="admin/domain_general_form.html")
|
||||
cwizard.add_step(DomainFormOptions, _("Options"),
|
||||
[dict(classes="btn-primary submit", label=_("Create")),
|
||||
dict(classes="btn-inverse prev", label=_("Previous"))],
|
||||
formtpl="admin/domain_options_form.html")
|
||||
|
||||
if request.method == "POST":
|
||||
form = DomainFormGeneral(request.POST)
|
||||
return _validate_domain(request, form, _("Domain created"), commonctx,
|
||||
tplname, callback=newdomain_cb)
|
||||
form = DomainFormGeneral()
|
||||
commonctx["form"] = form
|
||||
retcode, data = cwizard.validate_step(request)
|
||||
if retcode == -1:
|
||||
raise AdminError(data)
|
||||
if retcode == 1:
|
||||
return ajax_simple_response(dict(
|
||||
status="ok", title=cwizard.get_title(data + 1), stepid=data
|
||||
))
|
||||
if retcode == 2:
|
||||
return ajax_simple_response(dict(status="ok", respmsg=_("Domain created")))
|
||||
|
||||
from modoboa.lib.templatetags.libextras import render_form
|
||||
return ajax_simple_response(dict(
|
||||
status="ko", stepid=data, form=render_form(cwizard.steps[data]["form"])
|
||||
))
|
||||
|
||||
cwizard.create_forms()
|
||||
commonctx.update(steps=cwizard.steps)
|
||||
commonctx.update(subtitle="1. %s" % cwizard.steps[0]['title'])
|
||||
return render(request, tplname, commonctx)
|
||||
|
||||
@login_required
|
||||
@@ -188,11 +213,7 @@ def _new_alias(request, tplname, formclass, ctx, successmsg):
|
||||
ctx.update(action_label=_("Create"), action_classes="submit")
|
||||
if request.method == "POST":
|
||||
def callback(user, alias):
|
||||
grant_access_to_object(user, alias, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, alias)
|
||||
if user.is_superuser:
|
||||
for admin in alias.domain.admins:
|
||||
grant_access_to_object(admin, alias)
|
||||
alias.post_create(user)
|
||||
|
||||
form = formclass(request.user, request.POST)
|
||||
return _validate_alias(request, form, successmsg, tplname, ctx, callback)
|
||||
@@ -382,9 +403,7 @@ def list_quotas(request, tplname="admin/quotas.html"):
|
||||
@login_required
|
||||
@permission_required("auth.add_user")
|
||||
@transaction.commit_on_success
|
||||
def newaccount(request, tplname='admin/newaccount.html'):
|
||||
from modoboa.lib.formutils import CreationWizard
|
||||
|
||||
def newaccount(request, tplname='common/wizard_forms.html'):
|
||||
def create_account(steps):
|
||||
"""Account creation callback
|
||||
|
||||
@@ -395,8 +414,7 @@ def newaccount(request, tplname='admin/newaccount.html'):
|
||||
genform = steps[0]["form"]
|
||||
genform.is_valid()
|
||||
account = genform.save()
|
||||
grant_access_to_object(request.user, account, is_owner=True)
|
||||
events.raiseEvent("AccountCreated", account)
|
||||
account.post_create(request.user)
|
||||
|
||||
mailform = steps[1]["form"]
|
||||
mb = mailform.save(request.user, account)
|
||||
@@ -508,7 +526,7 @@ def remove_permission(request):
|
||||
raise AdminError(_("Invalid request"))
|
||||
if not request.user.can_access(account) or not request.user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
ungrant_access_to_object(domain, account)
|
||||
domain.remove_admin(account)
|
||||
return ajax_simple_response(dict(status="ok"))
|
||||
|
||||
@login_required
|
||||
@@ -598,39 +616,24 @@ def import_domain(user, row, formopts):
|
||||
"""Specific code for domains import"""
|
||||
dom = Domain()
|
||||
dom.from_csv(user, row)
|
||||
grant_access_to_object(user, dom, is_owner=True)
|
||||
events.raiseEvent("CreateDomain", user, dom)
|
||||
|
||||
@transaction.commit_on_success
|
||||
def import_domainalias(user, row, formopts):
|
||||
"""Specific code for domain aliases import"""
|
||||
domalias = DomainAlias()
|
||||
domalias.from_csv(user, row)
|
||||
grant_access_to_object(user, domalias, is_owner=True)
|
||||
events.raiseEvent("DomainAliasCreated", user, domalias)
|
||||
|
||||
@transaction.commit_on_success
|
||||
def import_account(user, row, formopts):
|
||||
"""Specific code for accounts import"""
|
||||
account = User()
|
||||
account.from_csv(user, row, formopts["crypt_password"])
|
||||
grant_access_to_object(user, account, is_owner=True)
|
||||
if account.is_superuser:
|
||||
# Give access to the existing user
|
||||
grant_access_to_object(account, user)
|
||||
events.raiseEvent("AccountCreated", account)
|
||||
if account.mailbox_set.count():
|
||||
mb = account.mailbox_set.all()[0]
|
||||
grant_access_to_object(user, mb, is_owner=True)
|
||||
events.raiseEvent("CreateMailbox", user, mb)
|
||||
|
||||
@transaction.commit_on_success
|
||||
def _import_alias(user, row, **kwargs):
|
||||
"""Specific code for aliases import"""
|
||||
alias = Alias()
|
||||
alias.from_csv(user, row, **kwargs)
|
||||
grant_access_to_object(user, alias, is_owner=True)
|
||||
events.raiseEvent("MailboxAliasCreated", user, alias)
|
||||
|
||||
def import_alias(user, row, formopts):
|
||||
_import_alias(user, row, expected_elements=4)
|
||||
|
||||
@@ -3,7 +3,7 @@ from functools import wraps
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.db import IntegrityError
|
||||
from modoboa.admin.models import ObjectAccess, IntegrityError
|
||||
from modoboa.admin.models import ObjectAccess
|
||||
import events
|
||||
from exceptions import ModoboaException
|
||||
|
||||
@@ -89,7 +89,8 @@ def grant_access_to_objects(user, objects, ct):
|
||||
ObjectAccess.objects.create(user=user, content_type=ct, object_id=obj.id)
|
||||
except IntegrityError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def ungrant_access_to_object(obj, user=None):
|
||||
"""Ungrant access to an object for a specific user
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
};
|
||||
|
||||
$.fn.cwizard.defaults = {
|
||||
|
||||
transition_callbacks: {}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
+2
-4
@@ -7,13 +7,11 @@
|
||||
<form class="form-horizontal" action="{{ action }}" enctype="{{ enctype }}"
|
||||
method="POST" id="{{ formid }}" name="{{ formid }}">
|
||||
<div id="wizard" class="carousel">
|
||||
<div class="carousel-inner">
|
||||
{% for step in steps %}
|
||||
<div class="carousel-inner">{% for step in steps %}
|
||||
<div id="step{{ forloop.counter }}"
|
||||
class="item{% if forloop.first %} active{% endif %}">
|
||||
{% if step.formtpl %}{% render_form step.form step.formtpl %}{% else %}{% render_form step.form %}{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
Reference in New Issue
Block a user