From a3a2e253304b711c6bd756eb833590e38282a642 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Sun, 13 Jan 2013 09:22:07 +0100 Subject: [PATCH] Code refactoring. see #317 --- modoboa/admin/forms.py | 6 ++++ modoboa/admin/models.py | 62 +++++++++++++++++++++++------------------ modoboa/admin/views.py | 40 +++++++++++++------------- 3 files changed, 62 insertions(+), 46 deletions(-) diff --git a/modoboa/admin/forms.py b/modoboa/admin/forms.py index 6a1607eaa..87166df75 100644 --- a/modoboa/admin/forms.py +++ b/modoboa/admin/forms.py @@ -333,6 +333,12 @@ class ImportDataForm(forms.Form): return ";" return str(self.cleaned_data["sepchar"]) +class ImportIdentitiesForm(ImportDataForm): + crypt_password = forms.BooleanField( + label=ugettext_lazy("Crypt passwords"), + help_text=ugettext_lazy("Check this option if passwords contained in your file are not crypted") + ) + class AccountFormGeneral(forms.ModelForm): username = forms.CharField(label=ugettext_lazy("Username"), max_length=254) role = forms.ChoiceField( diff --git a/modoboa/admin/models.py b/modoboa/admin/models.py index 6fdba1d4e..a2e64657d 100644 --- a/modoboa/admin/models.py +++ b/modoboa/admin/models.py @@ -336,6 +336,38 @@ class User(DUser): return True return False + def from_csv(self, user, row, crypt_password=True): + """Create a new account from a CSV file entry + + The expected order is the following:: + + [loginname, password, first name, last name, address] + + :param line: a list containing the expected information + """ + if len(row) < 5: + raise AdminError(_("Invalid line")) + self.username = row[1].strip() + if crypt_password: + self.set_password(row[2].strip()) + else: + self.password = row[2].strip() + self.first_name = row[3].strip() + self.last_name = row[4].strip() + self.save() + if len(row) > 5: + self.email = row[5].strip() + mailbox, domname = split_mailbox(line[5].strip()) + try: + domain = Domain.objects.get(name=domname) + except Domain.DoesNotExist: + raise AdminError(_("Cannot import this account because the specified domain does not exist")) + if not user.can_access(domain): + raise PermDeniedException + mb = Mailbox() + mb.save_from_user(localpart, domain, self, owner=user) + self.save() + def to_csv(self, csvwriter): csvwriter.writerow(["account", self.username.encode("utf-8"), self.password, self.first_name.encode("utf-8"), self.last_name.encode("utf-8"), @@ -478,7 +510,7 @@ class Domain(DatesAware): def __str__(self): return self.name - def create_from_csv(self, user, row): + def from_csv(self, user, row): if len(row) < 3: raise AdminError(_("Invalid line")) self.name = row[1].strip() @@ -726,30 +758,6 @@ class Mailbox(DatesAware): self.set_quota(quota, True if (owner and owner.has_perm("admin.add_domain")) else False) super(Mailbox, self).save() - def create_from_csv(self, user, line): - """Create a new mailbox from a CSV file entry - - The expected order is the following:: - - [loginname, password, first name, last name, address] - - :param line: a list containing the expected information - """ - if len(line) < 6: - raise AdminError(_("Invalid line")) - mailbox, domname = split_mailbox(line[5].strip()) - self.address = mailbox - try: - self.domain = Domain.objects.get(name=domname) - except Domain.DoesNotExist: - raise AdminError(_("Cannot import this mailbox because the associated domain does not exist")) - if not user.can_access(self.domain): - raise PermDeniedException - - name = "%s %s" % (line[3].strip(), line[4].strip()) - self.save(username=line[1].strip(), name=name, - password=line[2].strip(), enabled=True, quota=None) - def delete(self, keepdir=False): from modoboa.lib.permissions import ungrant_access_to_object @@ -850,7 +858,7 @@ class Alias(DatesAware): return True return False - def create_from_csv(self, user, row, expected_elements=4): + def from_csv(self, user, row, expected_elements=4): if len(row) < expected_elements: raise AdminError(_("Invalid line: %s" % row)) localpart, domname = split_mailbox(row[1].strip()) @@ -888,7 +896,7 @@ class Alias(DatesAware): altype = "forward" else: altype = "alias" - row = [altype, self.address] + row = [altype, self.full_address] row += self.get_recipients() csvwriter.writerow(row) diff --git a/modoboa/admin/views.py b/modoboa/admin/views.py index fd62098df..2cbb3c327 100644 --- a/modoboa/admin/views.py +++ b/modoboa/admin/views.py @@ -553,46 +553,48 @@ def information(request, tplname="admin/information.html"): "content" : render_to_string(tplname, {}) }) -def import_domain(user, row): +def import_domain(user, row, formopts): """Specific code for domains import""" dom = Domain() - dom.create_from_csv(user, row) + dom.from_csv(user, row) grant_access_to_object(user, dom, is_owner=True) events.raiseEvent("CreateDomain", user, dom) -def import_domainalias(user, row): +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) -def import_account(user, row): +def import_account(user, row, formopts): """Specific code for accounts import""" - mb = Mailbox() - mb.create_from_csv(user, row) - grant_access_to_object(user, mb.user, is_owner=True) - grant_access_to_object(user, mb, is_owner=True) - events.raiseEvent("AccountCreated", mb.user) - events.raiseEvent("CreateMailbox", user, mb) + account = User() + account.from_csv(user, row, formopts["crypt_password"]) + grant_access_to_object(user, account, is_owner=True) + events.raiseEvent("AccountCreated", account) + if len(row) > 5: + mb = account.mailbox_set.all()[0] + grant_access_to_object(user, mb, is_owner=True) + events.raiseEvent("CreateMailbox", user, mb) def _import_alias(user, row, **kwargs): """Specific code for aliases import""" alias = Alias() - alias.create_from_csv(user, row, **kwargs) + 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): +def import_alias(user, row, formopts): _import_alias(user, row, expected_elements=3) -def import_forward(user, row): +def import_forward(user, row, formopts): _import_alias(user, row, expected_elements=3) -def import_dlist(user, row): +def import_dlist(user, row, formopts): _import_alias(user, row) -def importdata(request): +def importdata(request, formclass=ImportDataForm): """Generic import function As the process of importing data from a CSV file is the same @@ -603,7 +605,7 @@ def importdata(request): :return: a ``Response`` instance """ error = None - form = ImportDataForm(request.POST, request.FILES) + form = formclass(request.POST, request.FILES) if form.is_valid(): import csv @@ -621,7 +623,7 @@ def importdata(request): fct = globals()["import_%s" % row[0].strip()] except KeyError: continue - fct(request.user, row) + fct(request.user, row, form.cleaned_data) cpt += 1 msg = _("%d objects imported successfully" % cpt) return render(request, "admin/import_done.html", { @@ -639,7 +641,7 @@ def importdata(request): @transaction.commit_on_success def import_identities(request): if request.method == "POST": - return importdata(request) + return importdata(request, ImportIdentitiesForm) helptext = _("""Provide a CSV file where lines respect one of the following formats: