mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
@@ -21,6 +21,7 @@ class GroupFactory(factory.DjangoModelFactory):
|
||||
|
||||
class UserFactory(PermissionFactory):
|
||||
FACTORY_FOR = models.User
|
||||
FACTORY_DJANGO_GET_OR_CREATE = ("username", )
|
||||
|
||||
email = factory.LazyAttribute(lambda a: a.username)
|
||||
password = '{PLAIN}toto'
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
"""
|
||||
Fixtures factories.
|
||||
"""
|
||||
import factory
|
||||
|
||||
from modoboa.core.factories import PermissionFactory, UserFactory
|
||||
from . import models
|
||||
|
||||
|
||||
class DomainFactory(PermissionFactory):
|
||||
FACTORY_FOR = models.Domain
|
||||
FACTORY_DJANGO_GET_OR_CREATE = ("name", )
|
||||
|
||||
quota = 10
|
||||
enabled = True
|
||||
@@ -12,6 +18,8 @@ class DomainFactory(PermissionFactory):
|
||||
class MailboxFactory(PermissionFactory):
|
||||
FACTORY_FOR = models.Mailbox
|
||||
|
||||
domain = factory.SubFactory(DomainFactory)
|
||||
user = factory.SubFactory(UserFactory)
|
||||
quota = 10
|
||||
enabled = True
|
||||
|
||||
@@ -21,6 +29,7 @@ class AliasFactory(PermissionFactory):
|
||||
|
||||
enabled = True
|
||||
|
||||
|
||||
def populate_database():
|
||||
"""Create test data.
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ from modoboa.lib import parameters
|
||||
from modoboa.core.models import User
|
||||
from modoboa.core.factories import UserFactory
|
||||
from modoboa.extensions.admin.factories import (
|
||||
DomainFactory, MailboxFactory, populate_database
|
||||
populate_database
|
||||
)
|
||||
from modoboa.extensions.admin.models import Alias, Domain, DomainAlias
|
||||
from modoboa.extensions.admin.models import Alias, Domain
|
||||
from modoboa.extensions.limits.models import LimitTemplates
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Fixtures factories.
|
||||
"""
|
||||
import factory
|
||||
|
||||
from modoboa.extensions.admin.factories import (
|
||||
DomainFactory, MailboxFactory
|
||||
)
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class UserCalendarFactory(factory.DjangoModelFactory):
|
||||
FACTORY_FOR = models.UserCalendar
|
||||
|
||||
name = factory.Sequence(lambda n: 'User calendar %s' % n)
|
||||
mailbox = factory.SubFactory(MailboxFactory)
|
||||
|
||||
|
||||
class SharedCalendarFactory(factory.DjangoModelFactory):
|
||||
FACTORY_FOR = models.SharedCalendar
|
||||
|
||||
name = factory.Sequence(lambda n: 'Shared calendar %s' % n)
|
||||
domain = factory.SubFactory(DomainFactory)
|
||||
|
||||
|
||||
class AccessRuleFactory(factory.DjangoModelFactory):
|
||||
FACTORY_FOR = models.AccessRule
|
||||
|
||||
mailbox = factory.SubFactory(MailboxFactory)
|
||||
calendar = factory.SubFactory(UserCalendarFactory)
|
||||
@@ -4,7 +4,9 @@ from optparse import make_option
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.extensions.admin import Domain
|
||||
from modoboa.extensions.radicale import Radicale
|
||||
from modoboa.extensions.radicale.models import (
|
||||
AccessRule
|
||||
@@ -24,14 +26,14 @@ class Command(BaseCommand):
|
||||
def _generate_acr(self, name, user, collection, perm="rw", comment=None):
|
||||
"""Write a new access control rule to the config file.
|
||||
"""
|
||||
if comment is not None:
|
||||
self._cfgfile.write("\n# %s" % comment)
|
||||
self._cfgfile.write("""
|
||||
%s
|
||||
[%s]
|
||||
user = %s
|
||||
collection = %s
|
||||
permission = %s
|
||||
""" % ("" if comment is None else ("# %s" % comment),
|
||||
name, user, collection, perm)
|
||||
""" % (name, user, collection, perm)
|
||||
)
|
||||
|
||||
def _user_access_rules(self):
|
||||
@@ -39,7 +41,7 @@ permission = %s
|
||||
"""
|
||||
for acr in AccessRule.objects.select_related().all():
|
||||
section = "%s-to-%s-acr" % (
|
||||
acr.calendar.mailbox, acr.mailbox
|
||||
acr.mailbox, acr.calendar
|
||||
)
|
||||
permission = ""
|
||||
if acr.read:
|
||||
@@ -54,7 +56,7 @@ permission = %s
|
||||
"""Generate access rules for super administrators.
|
||||
"""
|
||||
for sa in User.objects.filter(is_superuser=True):
|
||||
section = "[sa-%s-acr]" % sa.username
|
||||
section = "sa-%s-acr" % sa.username
|
||||
self._generate_acr(
|
||||
section, sa.username, ".*"
|
||||
)
|
||||
@@ -64,7 +66,7 @@ permission = %s
|
||||
"""
|
||||
for da in User.objects.filter(groups__name="DomainAdmins"):
|
||||
for domain in Domain.objects.get_for_admin(da):
|
||||
section = "[da-%s-to-%s-acr]" % (da.email, da.name)
|
||||
section = "da-%s-to-%s-acr" % (da.email, domain.name)
|
||||
self._generate_acr(
|
||||
section, da.email, "%s/user/.*" % domain.name
|
||||
)
|
||||
|
||||
@@ -1,16 +1,269 @@
|
||||
"""
|
||||
This file demonstrates writing tests using the unittest module. These will pass
|
||||
when you run "manage.py test".
|
||||
|
||||
Replace this with more appropriate tests for your application.
|
||||
Radicale extension unit tests.
|
||||
"""
|
||||
import os
|
||||
import tempfile
|
||||
from ConfigParser import SafeConfigParser
|
||||
|
||||
from django.test import TestCase
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core import management
|
||||
|
||||
from modoboa.lib import parameters
|
||||
from modoboa.lib.tests import ExtTestCase
|
||||
from modoboa.extensions.admin.factories import (
|
||||
MailboxFactory, populate_database
|
||||
)
|
||||
from modoboa.extensions.admin.models import (
|
||||
Domain, Mailbox
|
||||
)
|
||||
|
||||
from .factories import (
|
||||
UserCalendarFactory, SharedCalendarFactory, AccessRuleFactory
|
||||
)
|
||||
from .models import UserCalendar, SharedCalendar, AccessRule
|
||||
|
||||
|
||||
class SimpleTest(TestCase):
|
||||
def test_basic_addition(self):
|
||||
"""
|
||||
Tests that 1 + 1 always equals 2.
|
||||
"""
|
||||
self.assertEqual(1 + 1, 2)
|
||||
class UserCalendarTestCase(ExtTestCase):
|
||||
fixtures = ["initial_users.json"]
|
||||
|
||||
def setUp(self):
|
||||
super(UserCalendarTestCase, self).setUp()
|
||||
self.activate_extensions('radicale')
|
||||
populate_database()
|
||||
|
||||
def assertRuleEqual(self, calname, username, read=False, write=False):
|
||||
acr = AccessRule.objects.get(
|
||||
mailbox__user__username=username,
|
||||
calendar__name=calname)
|
||||
self.assertEqual(acr.read, read)
|
||||
self.assertEqual(acr.write, write)
|
||||
|
||||
def test_add_calendar(self):
|
||||
MailboxFactory(
|
||||
address="polo", domain__name="test.com",
|
||||
user__username="polo@test.com")
|
||||
|
||||
# As a super administrator
|
||||
mbox = Mailbox.objects.get(address='user', domain__name='test.com')
|
||||
values = {
|
||||
"name": "Test calendar",
|
||||
"mailbox": mbox.pk,
|
||||
"username": "admin@test.com",
|
||||
"read_access": 1,
|
||||
"stepid": "step2"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_user_calendar"), values)
|
||||
self.clt.logout()
|
||||
self.assertRuleEqual("Test calendar", "admin@test.com", read=True)
|
||||
|
||||
# As a domain administrator
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
values = {
|
||||
"name": "Test calendar 2",
|
||||
"mailbox": mbox.pk,
|
||||
"username": "admin@test.com",
|
||||
"read_access": 1,
|
||||
"write_access": 1,
|
||||
"stepid": "step2"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_user_calendar"), values)
|
||||
self.clt.logout()
|
||||
self.assertRuleEqual(
|
||||
"Test calendar 2", "admin@test.com", read=True, write=True
|
||||
)
|
||||
|
||||
# As a user
|
||||
self.clt.login(username="user@test.com", password="toto")
|
||||
values = {
|
||||
"name": "My calendar",
|
||||
"username": "admin@test.com",
|
||||
"read_access": 1,
|
||||
"write_access": 1,
|
||||
"username_1": "polo@test.com",
|
||||
"write_access_1": 1,
|
||||
"stepid": "step2"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_user_calendar"), values)
|
||||
UserCalendar.objects.get(name="My calendar")
|
||||
self.assertRuleEqual(
|
||||
"My calendar", "admin@test.com", read=True, write=True)
|
||||
self.assertRuleEqual("My calendar", "polo@test.com", write=True)
|
||||
|
||||
def test_edit_calendar(self):
|
||||
cal = UserCalendarFactory(
|
||||
mailbox__user__username='test@modoboa.org',
|
||||
mailbox__address='test', mailbox__domain__name='modoboa.org')
|
||||
values = {
|
||||
"name": "Modified", "mailbox": cal.mailbox.pk
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("user_calendar", args=[cal.pk]), values
|
||||
)
|
||||
|
||||
def test_del_calendar(self):
|
||||
cal = UserCalendarFactory(
|
||||
mailbox__user__username='test@modoboa.org',
|
||||
mailbox__address='test', mailbox__domain__name='modoboa.org')
|
||||
self.ajax_delete(
|
||||
reverse("user_calendar", args=[cal.pk])
|
||||
)
|
||||
with self.assertRaises(ObjectDoesNotExist):
|
||||
UserCalendar.objects.get(pk=cal.pk)
|
||||
|
||||
def test_del_calendar_denied(self):
|
||||
cal = UserCalendarFactory(
|
||||
mailbox__user__username='test@modoboa.org',
|
||||
mailbox__address='test', mailbox__domain__name='modoboa.org')
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
self.ajax_delete(
|
||||
reverse("user_calendar", args=[cal.pk]), status=403
|
||||
)
|
||||
|
||||
def test_add_calendar_denied(self):
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
values = {
|
||||
"name": "Test calendar",
|
||||
"mailbox": Mailbox.objects.get(
|
||||
address="user", domain__name="test2.com").pk,
|
||||
"stepid": "step2"
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_user_calendar"), values, status=400)
|
||||
|
||||
|
||||
class SharedCalendarTestCase(ExtTestCase):
|
||||
fixtures = ["initial_users.json"]
|
||||
|
||||
def setUp(self):
|
||||
super(SharedCalendarTestCase, self).setUp()
|
||||
self.activate_extensions('radicale')
|
||||
populate_database()
|
||||
|
||||
def test_add_calendar(self):
|
||||
# As a super administrator
|
||||
domain = Domain.objects.get(name="test.com")
|
||||
values = {
|
||||
"name": "Test calendar",
|
||||
"domain": domain.pk,
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_shared_calendar"), values)
|
||||
self.clt.logout()
|
||||
|
||||
# As a domain administrator
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
values = {
|
||||
"name": "Test calendar 2",
|
||||
"domain": domain.pk
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_shared_calendar"), values)
|
||||
self.clt.logout()
|
||||
|
||||
def test_add_calendar_denied(self):
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
values = {
|
||||
"name": "Test calendar",
|
||||
"domain": Domain.objects.get(name="test2.com")
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("new_shared_calendar"), values, status=400)
|
||||
|
||||
def test_edit_calendar(self):
|
||||
cal = SharedCalendarFactory(
|
||||
domain__name='modoboa.org')
|
||||
values = {
|
||||
"name": "Modified", "domain": cal.domain.pk
|
||||
}
|
||||
self.ajax_post(
|
||||
reverse("shared_calendar", args=[cal.pk]), values
|
||||
)
|
||||
cal = SharedCalendar.objects.get(pk=cal.pk)
|
||||
self.assertEqual(cal.name, "Modified")
|
||||
|
||||
def test_del_calendar(self):
|
||||
cal = SharedCalendarFactory(domain__name='modoboa.org')
|
||||
self.ajax_delete(
|
||||
reverse("shared_calendar", args=[cal.pk])
|
||||
)
|
||||
with self.assertRaises(ObjectDoesNotExist):
|
||||
SharedCalendar.objects.get(pk=cal.pk)
|
||||
|
||||
def test_del_calendar_denied(self):
|
||||
cal = SharedCalendarFactory(domain__name='modoboa.org')
|
||||
self.clt.logout()
|
||||
self.clt.login(username="admin@test.com", password="toto")
|
||||
self.ajax_delete(
|
||||
reverse("shared_calendar", args=[cal.pk]), status=403
|
||||
)
|
||||
|
||||
|
||||
class AccessRuleTestCase(ExtTestCase):
|
||||
fixtures = ["initial_users.json"]
|
||||
|
||||
def setUp(self):
|
||||
super(AccessRuleTestCase, self).setUp()
|
||||
self.activate_extensions('radicale')
|
||||
populate_database()
|
||||
self.rights_file_path = tempfile.mktemp()
|
||||
parameters.save_admin(
|
||||
"RIGHTS_FILE_PATH", self.rights_file_path, app="radicale")
|
||||
|
||||
def tearDown(self):
|
||||
os.unlink(self.rights_file_path)
|
||||
|
||||
def test_rights_file_generation(self):
|
||||
mbox = Mailbox.objects.get(address="admin", domain__name="test.com")
|
||||
cal = UserCalendarFactory(mailbox=mbox)
|
||||
|
||||
AccessRuleFactory(
|
||||
mailbox=Mailbox.objects.get(
|
||||
address="user", domain__name="test.com"),
|
||||
calendar=cal, read=True)
|
||||
management.call_command("generate_rights", verbosity=False)
|
||||
|
||||
cfg = SafeConfigParser()
|
||||
with open(self.rights_file_path) as fpo:
|
||||
cfg.readfp(fpo)
|
||||
|
||||
# Check mandatory rules
|
||||
self.assertTrue(cfg.has_section("domain-shared-calendars"))
|
||||
self.assertTrue(cfg.has_section("owners-access"))
|
||||
|
||||
# Check user-defined rules
|
||||
section = "user@test.com-to-User calendar 1-acr"
|
||||
self.assertTrue(cfg.has_section(section))
|
||||
self.assertEqual(cfg.get(section, "user"), "user@test.com")
|
||||
self.assertEqual(
|
||||
cfg.get(section, "collection"),
|
||||
"test.com/user/admin/User calendar 1"
|
||||
)
|
||||
self.assertEqual(cfg.get(section, "permission"), "r")
|
||||
|
||||
def test_rights_file_generation_with_admin(self):
|
||||
parameters.save_admin(
|
||||
"ALLOW_CALENDARS_ADMINISTRATION", "yes", app="radicale")
|
||||
management.call_command("generate_rights", verbosity=False)
|
||||
cfg = SafeConfigParser()
|
||||
with open(self.rights_file_path) as fpo:
|
||||
cfg.readfp(fpo)
|
||||
|
||||
# Check mandatory rules
|
||||
self.assertTrue(cfg.has_section("domain-shared-calendars"))
|
||||
self.assertTrue(cfg.has_section("owners-access"))
|
||||
|
||||
# Super admin rules
|
||||
section = "sa-admin-acr"
|
||||
self.assertTrue(cfg.has_section(section))
|
||||
|
||||
# Domain admin rules
|
||||
for section in ["da-admin@test.com-to-test.com-acr",
|
||||
"da-admin@test2.com-to-test2.com-acr"]:
|
||||
self.assertTrue(cfg.has_section(section))
|
||||
|
||||
@@ -13,7 +13,9 @@ class ModoTestCase(TestCase):
|
||||
self.clt = Client()
|
||||
self.assertEqual(self.clt.login(username=username, password=password), True)
|
||||
|
||||
def ajax_request(self, method, url, params, status=200):
|
||||
def ajax_request(self, method, url, params=None, status=200):
|
||||
if params is None:
|
||||
params = {}
|
||||
response = getattr(self.clt, method) \
|
||||
(url, params, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, status)
|
||||
@@ -22,6 +24,12 @@ class ModoTestCase(TestCase):
|
||||
def ajax_post(self, *args, **kwargs):
|
||||
return self.ajax_request('post', *args, **kwargs)
|
||||
|
||||
def ajax_put(self, *args, **kwargs):
|
||||
return self.ajax_request('put', *args, **kwargs)
|
||||
|
||||
def ajax_delete(self, *args, **kwargs):
|
||||
return self.ajax_request('delete', *args, **kwargs)
|
||||
|
||||
def ajax_get(self, *args, **kwargs):
|
||||
return self.ajax_request('get', *args, **kwargs)
|
||||
|
||||
|
||||
+1
-1
@@ -8,5 +8,5 @@ sievelib
|
||||
chardet
|
||||
argparse
|
||||
rfc6266
|
||||
factory-boy
|
||||
factory-boy<2.4
|
||||
passlib
|
||||
|
||||
Reference in New Issue
Block a user