mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
@@ -1 +1 @@
|
||||
[{"pk": 1, "model": "core.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": false, "last_login": "2012-01-26 15:19:25", "groups": [], "user_permissions": [], "password": "{CRYPT}dTTsGDkA5ZHKg", "email": "", "date_joined": "2012-01-26 15:19:25"}},{"pk": 1, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["core", "user"], "object_id": 1}}]
|
||||
[{"pk": 1, "model": "core.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": false, "last_login": "2012-01-26T15:19:26+01:00", "groups": [], "user_permissions": [], "password": "{CRYPT}dTTsGDkA5ZHKg", "email": "", "date_joined": "2012-01-26T15:19:26+01:00"}},{"pk": 1, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["core", "user"], "object_id": 1}}]
|
||||
+10
-2
@@ -304,11 +304,13 @@ class User(PermissionsMixin):
|
||||
self.post_create(creator)
|
||||
|
||||
def from_csv(self, user, row, crypt_password=True):
|
||||
"""Create a new account from a CSV file entry
|
||||
"""Create a new account from a CSV file entry.
|
||||
|
||||
The expected order is the following::
|
||||
|
||||
"account", loginname, password, first name, last name, enabled, group, address[, domain, ...]
|
||||
"account", loginname, password, first name, last name, enabled, group
|
||||
|
||||
Additional fields can be added using the *AccountImported* event.
|
||||
|
||||
:param user: a ``core.User`` instance
|
||||
:param row: a list containing the expected information
|
||||
@@ -346,6 +348,12 @@ class User(PermissionsMixin):
|
||||
events.raiseEvent("AccountImported", user, self, row[7:])
|
||||
|
||||
def to_csv(self, csvwriter):
|
||||
"""Export this account.
|
||||
|
||||
The CSV format is used to export.
|
||||
|
||||
:param csvwriter: csv object
|
||||
"""
|
||||
row = ["account", self.username.encode("utf-8"), self.password.encode("utf-8"),
|
||||
self.first_name.encode("utf-8"), self.last_name.encode("utf-8"),
|
||||
self.is_active, self.group, self.email.encode("utf-8")]
|
||||
|
||||
@@ -133,13 +133,25 @@ def grant_access_to_all_objects(user, role):
|
||||
|
||||
@events.observe("AccountExported")
|
||||
def export_admin_domains(admin):
|
||||
result = [admin.mailbox_set.all()[0].quota] \
|
||||
if admin.mailbox_set.count() else ['']
|
||||
if admin.group != "DomainAdmins":
|
||||
return []
|
||||
return [dom.name for dom in Domain.objects.get_for_admin(admin)]
|
||||
return result
|
||||
return result + [dom.name for dom in Domain.objects.get_for_admin(admin)]
|
||||
|
||||
|
||||
@events.observe("AccountImported")
|
||||
def import_account_mailbox(user, account, row):
|
||||
"""Handle extra fields when an account is imported.
|
||||
|
||||
Expected fields:
|
||||
|
||||
email address; quota; [domain; ...]
|
||||
|
||||
:param User user: user importing the account
|
||||
:param User account: account being imported
|
||||
:param list rom: list of fields (strings)
|
||||
"""
|
||||
account.email = row[0].strip()
|
||||
if account.email != "":
|
||||
account.save()
|
||||
@@ -152,12 +164,14 @@ def import_account_mailbox(user, account, row):
|
||||
)
|
||||
if not user.can_access(domain):
|
||||
raise PermDeniedException
|
||||
quota = int(row[1].strip())
|
||||
use_domain_quota = True if not quota else False
|
||||
mb = Mailbox(address=mailbox, domain=domain,
|
||||
user=account, use_domain_quota=True)
|
||||
mb.set_quota(override_rules=user.has_perm("admin.change_domain"))
|
||||
user=account, use_domain_quota=use_domain_quota)
|
||||
mb.set_quota(quota, override_rules=user.has_perm("admin.change_domain"))
|
||||
mb.save(creator=user)
|
||||
if account.group == "DomainAdmins":
|
||||
for domname in row[1:]:
|
||||
for domname in row[2:]:
|
||||
try:
|
||||
dom = Domain.objects.get(name=domname.strip())
|
||||
except Domain.DoesNotExist:
|
||||
|
||||
@@ -13,11 +13,13 @@ class MailboxFactory(PermissionFactory):
|
||||
FACTORY_FOR = models.Mailbox
|
||||
|
||||
quota = 10
|
||||
enabled = True
|
||||
|
||||
|
||||
class AliasFactory(PermissionFactory):
|
||||
FACTORY_FOR = models.Alias
|
||||
|
||||
enabled = True
|
||||
|
||||
def populate_database():
|
||||
"""Create test data.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[{"pk": 1, "model": "core.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": false, "is_local": true, "last_login": "2012-01-26 15:19:25", "groups": [], "user_permissions": [], "password": "{CRYPT}dTTsGDkA5ZHKg", "email": "", "date_joined": "2012-01-26 15:19:25"}},{"pk": 1, "model": "core.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["core", "user"], "object_id": 1}}]
|
||||
@@ -1 +0,0 @@
|
||||
[{"pk": 2, "model": "admin.user", "fields": {"username": "user@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [2]}},{"pk": 3, "model": "admin.user", "fields": {"username": "admin@test.com", "is_active": "True", "is_superuser": "False", "password": "{PLAIN}toto", "groups": [1]}},{"pk": 4, "model": "admin.user", "fields": {"username": "superadmin@test.com", "is_active": "True", "is_superuser": "True", "password": "{PLAIN}toto", "groups": []}},{"pk": 1, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 2, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 3, "model": "admin.ObjectDates", "fields": {"creation": "2011-09-07 09:27:07.579603", "last_modification": "2011-09-07 09:27:07.579603"}}, {"pk": 1, "model": "admin.Domain", "fields": {"name" : "test.com", "quota" : "100", "dates": "1"}}, {"pk": 1, "model": "admin.Mailbox", "fields": {"address": "user", "domain": "1", "dates": "1", "quota": "10", "user": "2"}}, {"pk": 2, "model": "admin.Mailbox", "fields": {"address": "admin", "domain": "1", "dates": "2", "quota": "10", "user": "3"}}, {"pk": 3, "model": "admin.Mailbox", "fields": {"address": "superadmin", "domain": "1", "dates": "3", "quota": "10", "user": "4"}}, {"pk": "user@test.com", "model": "admin.Quota", "fields": {"mbox": 1, "username": "user@test.com", "bytes": 0, "messages": 0}}, {"pk": "admin@test.com", "model": "admin.Quota", "fields": {"mbox": 2, "username": "admin@test.com", "bytes": 0, "messages": 0}}, {"pk": "superadmin@test.com", "model": "admin.Quota", "fields": {"mbox": 3, "username": "superadmin@test.com", "bytes": 0, "messages": 0}},{"pk": 2, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 2}},{"pk": 3, "model": "admin.objectaccess", "fields": {"is_owner": true, "user": 1, "content_type": ["admin", "user"], "object_id": 3}}]
|
||||
@@ -22,7 +22,7 @@ class ExportTestCase(ModoTestCase):
|
||||
|
||||
def test_export_identities(self):
|
||||
response = self.__export_identities()
|
||||
self.assertEqual(response.content, "account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;\r\naccount;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;test2.com\r\naccount;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com\r\nalias;alias@test.com;False;user@test.com\r\nforward;forward@test.com;False;user@external.com\r\ndlist;postmaster@test.com;False;toto@titi.com;test@truc.fr\r\n")
|
||||
self.assertEqual(response.content, "account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;;\r\naccount;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com\r\naccount;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10\r\nalias;alias@test.com;True;user@test.com\r\nforward;forward@test.com;True;user@external.com\r\ndlist;postmaster@test.com;True;toto@titi.com;test@truc.fr\r\n")
|
||||
|
||||
def test_export_simpleusers(self):
|
||||
response = self.__export_identities(
|
||||
@@ -30,7 +30,7 @@ class ExportTestCase(ModoTestCase):
|
||||
)
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com"
|
||||
"account;user@test.com;{PLAIN}toto;;;True;SimpleUsers;user@test.com;10\r\naccount;user@test2.com;{PLAIN}toto;;;True;SimpleUsers;user@test2.com;10"
|
||||
)
|
||||
|
||||
def test_export_superadmins(self):
|
||||
@@ -39,7 +39,7 @@ class ExportTestCase(ModoTestCase):
|
||||
)
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;"
|
||||
"account;admin;{CRYPT}dTTsGDkA5ZHKg;;;True;SuperAdmins;;"
|
||||
)
|
||||
|
||||
def test_export_domainadmins(self):
|
||||
@@ -48,26 +48,26 @@ class ExportTestCase(ModoTestCase):
|
||||
)
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;test2.com"
|
||||
"account;admin@test.com;{PLAIN}toto;;;True;DomainAdmins;admin@test.com;10;test.com\r\naccount;admin@test2.com;{PLAIN}toto;;;True;DomainAdmins;admin@test2.com;10;test2.com"
|
||||
)
|
||||
|
||||
def test_export_aliases(self):
|
||||
response = self.__export_identities(idtfilter="alias")
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"alias;alias@test.com;False;user@test.com"
|
||||
"alias;alias@test.com;True;user@test.com"
|
||||
)
|
||||
|
||||
def test_export_forwards(self):
|
||||
response = self.__export_identities(idtfilter="forward")
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"forward;forward@test.com;False;user@external.com"
|
||||
"forward;forward@test.com;True;user@external.com"
|
||||
)
|
||||
|
||||
def test_export_dlists(self):
|
||||
response = self.__export_identities(idtfilter="dlist")
|
||||
self.assertEqual(
|
||||
response.content.strip(),
|
||||
"dlist;postmaster@test.com;False;toto@titi.com;test@truc.fr"
|
||||
"dlist;postmaster@test.com;True;toto@titi.com;test@truc.fr"
|
||||
)
|
||||
|
||||
@@ -53,8 +53,8 @@ domainalias;test.alias;test.com;True
|
||||
|
||||
def test_identities_import(self):
|
||||
f = ContentFile(b"""
|
||||
account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com
|
||||
account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; test.com
|
||||
account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 0
|
||||
account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 5; test.com
|
||||
alias; alias1@test.com; True; user1@test.com
|
||||
forward; fwd1@test.com; True; user@extdomain.com
|
||||
dlist; dlist@test.com; True; user1@test.com; user@extdomain.com
|
||||
@@ -65,20 +65,26 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com
|
||||
)
|
||||
admin = User.objects.get(username="admin")
|
||||
u1 = User.objects.get(username="user1@test.com")
|
||||
mb1 = u1.mailbox_set.all()[0]
|
||||
self.assertTrue(admin.is_owner(u1))
|
||||
self.assertEqual(u1.email, "user1@test.com")
|
||||
self.assertEqual(u1.first_name, "User")
|
||||
self.assertEqual(u1.last_name, "One")
|
||||
self.assertTrue(u1.is_active)
|
||||
self.assertEqual(u1.group, "SimpleUsers")
|
||||
self.assertTrue(admin.is_owner(u1.mailbox_set.all()[0]))
|
||||
self.assertEqual(u1.mailbox_set.all()[0].full_address, "user1@test.com")
|
||||
self.assertTrue(mb1.use_domain_quota)
|
||||
self.assertEqual(mb1.quota, 0)
|
||||
self.assertTrue(admin.is_owner(mb1))
|
||||
self.assertEqual(mb1.full_address, "user1@test.com")
|
||||
self.assertTrue(self.clt.login(username="user1@test.com", password="toto"))
|
||||
|
||||
da = User.objects.get(username="truc@test.com")
|
||||
damb = da.mailbox_set.all()[0]
|
||||
self.assertEqual(da.first_name, u"René")
|
||||
self.assertEqual(da.group, "DomainAdmins")
|
||||
self.assertEqual(da.mailbox_set.all()[0].full_address, "truc@test.com")
|
||||
self.assertEqual(damb.quota, 5)
|
||||
self.assertFalse(damb.use_domain_quota)
|
||||
self.assertEqual(damb.full_address, "truc@test.com")
|
||||
dom = Domain.objects.get(name="test.com")
|
||||
self.assertIn(da, dom.admins)
|
||||
u = User.objects.get(username="user@test.com")
|
||||
@@ -97,10 +103,22 @@ dlist; dlist@test.com; True; user1@test.com; user@extdomain.com
|
||||
self.assertIn("user@extdomain.com", dlist.extmboxes)
|
||||
self.assertTrue(admin.is_owner(dlist))
|
||||
|
||||
def test_import_invalid_quota(self):
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
f = ContentFile(b"""
|
||||
account; user1@test.com; toto; User; One; True; SimpleUsers; user1@test.com; 20
|
||||
""", name="identities.csv")
|
||||
resp = self.clt.post(
|
||||
reverse("modoboa.extensions.admin.views.import.import_identities"),
|
||||
{"sourcefile": f, "crypt_password": True}
|
||||
)
|
||||
self.assertIn('Quota is greater than the allowed', resp.content)
|
||||
|
||||
def test_import_duplicate(self):
|
||||
f = ContentFile(b"""
|
||||
account; admin@test.com; toto; Admin; ; True; DomainAdmins; admin@test.com; test.com
|
||||
account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; test.com
|
||||
account; admin@test.com; toto; Admin; ; True; DomainAdmins; admin@test.com; 0; test.com
|
||||
account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; 0; test.com
|
||||
""", name="identities.csv")
|
||||
self.clt.post(
|
||||
reverse("modoboa.extensions.admin.views.import.import_identities"),
|
||||
@@ -119,7 +137,7 @@ account; truc@test.com; toto; René; Truc; True; DomainAdmins; truc@test.com; te
|
||||
self.clt.logout()
|
||||
self.assertTrue(self.clt.login(username="admin@test.com", password="toto"))
|
||||
f = ContentFile(b"""
|
||||
account; sa@test.com; toto; Super; Admin; True; SuperAdmins; superadmin@test.com
|
||||
account; sa@test.com; toto; Super; Admin; True; SuperAdmins; superadmin@test.com; 50
|
||||
""", name="identities.csv")
|
||||
self.clt.post(
|
||||
reverse("modoboa.extensions.admin.views.import.import_identities"),
|
||||
|
||||
@@ -152,7 +152,7 @@ def import_identities(request):
|
||||
|
||||
helptext = _("""Provide a CSV file where lines respect one of the following formats:
|
||||
<ul>
|
||||
<li><em>account; loginname; password; first name; last name; enabled; group; address[, domain, ...]</em></li>
|
||||
<li><em>account; loginname; password; first name; last name; enabled; group; address; quota; [, domain, ...]</em></li>
|
||||
<li><em>alias; address; enabled; internal recipient</em></li>
|
||||
<li><em>forward; address; enabled; external recipient</em></li>
|
||||
<li><em>dlist; address; enabled; recipient; recipient; ...</em></li>
|
||||
|
||||
@@ -58,6 +58,9 @@ class GenericParametersForm(forms.Form):
|
||||
def _load_initial_values(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def _decode_value(self, value):
|
||||
return value.decode('unicode_escape').replace('\\r\\n', '\n')
|
||||
|
||||
def _load_extra_parameters(self, level):
|
||||
params = events.raiseDictEvent('GetExtraParameters', self.app, level)
|
||||
for pname, pdef in params.items():
|
||||
@@ -85,7 +88,7 @@ class AdminParametersForm(GenericParametersForm):
|
||||
|
||||
names = ["%s.%s" % (self.app, name.upper()) for name in self.fields.keys()]
|
||||
for p in Parameter.objects.filter(name__in=names):
|
||||
self.fields[p.shortname].initial = p.value
|
||||
self.fields[p.shortname].initial = self._decode_value(p.value)
|
||||
|
||||
def save(self):
|
||||
from .models import Parameter
|
||||
@@ -127,7 +130,7 @@ class UserParametersForm(GenericParametersForm):
|
||||
|
||||
names = ["%s.%s" % (self.app, name.upper()) for name in self.fields.keys()]
|
||||
for p in UserParameter.objects.filter(user=self.user, name__in=names):
|
||||
self.fields[p.shortname].initial = p.value
|
||||
self.fields[p.shortname].initial = self._decode_value(p.value)
|
||||
|
||||
@staticmethod
|
||||
def has_access(user):
|
||||
@@ -256,7 +259,7 @@ def get_admin(name, app=None, raise_error=True):
|
||||
p = Parameter.objects.get(name="%s.%s" % (app, name))
|
||||
except Parameter.DoesNotExist:
|
||||
return _params["A"][app]["defaults"][name]
|
||||
return p.value.decode("unicode_escape")
|
||||
return p.value.decode("unicode_escape").replace('\\r\\n', '\n')
|
||||
|
||||
|
||||
def get_user(user, name, app=None, raise_error=True):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# coding: utf-8
|
||||
import json
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
from django.utils import simplejson
|
||||
from django import forms
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib import parameters
|
||||
@@ -17,7 +17,7 @@ class ModoTestCase(TestCase):
|
||||
response = getattr(self.clt, method) \
|
||||
(url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, status)
|
||||
return simplejson.loads(response.content)
|
||||
return json.loads(response.content)
|
||||
|
||||
def ajax_post(self, *args, **kwargs):
|
||||
return self.ajax_request('post', *args, **kwargs)
|
||||
|
||||
Reference in New Issue
Block a user