WIP: change the way extensions initial data is loaded.

This commit is contained in:
Antoine Nguyen
2015-01-29 21:06:15 +01:00
parent d40bbeb5ff
commit dde98c235c
19 changed files with 186 additions and 195 deletions
+10
View File
@@ -18,6 +18,7 @@ BASE_EVENTS = [
"ExtraAccountActions",
"RoleChanged",
"GetExtraRoles",
"GetExtraRolePermissions",
"PasswordChange",
"UserCanSetRole",
@@ -41,6 +42,15 @@ BASE_EVENTS = [
"SaveExtraFormFields",
]
PERMISSIONS = {
"DomainAdmins": [
["core", "user", "add_user"],
["core", "user", "change_user"],
["core", "user", "delete_user"],
],
"SimpleUsers": []
}
def load_core_settings():
"""Load core settings.
+4 -9
View File
@@ -6,6 +6,7 @@ import sys
import subprocess
import django
from django.core import management
from django.template import Context, Template
@@ -138,6 +139,7 @@ class DeployCommand(Command):
return info
def handle(self, parsed_args):
django.setup()
management.call_command(
'startproject', parsed_args.name, verbosity=False
)
@@ -215,17 +217,10 @@ class DeployCommand(Command):
os.unlink("%s/settings.pyc" % path)
if parsed_args.dbaction == "install":
self._exec_django_command(
"syncdb", parsed_args.name, '--noinput'
)
exec_cmd('sed -ri "s|^#(\s+\'south)|\\1|" %s/settings.py' % path)
self._exec_django_command(
"syncdb", parsed_args.name,
"migrate", parsed_args.name, '--noinput'
)
self._exec_django_command(
'migrate', parsed_args.name, '--fake'
)
self._exec_django_command(
"loaddata", parsed_args.name, 'initial_users.json'
"load_initial_data", parsed_args.name
)
elif parsed_args.dbaction == "upgrade":
exec_cmd('sed -ri "s|^#(\s+\'south)|\\1|" %s/settings.py' % path)
@@ -46,7 +46,6 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.staticfiles',
# 'south',
'reversion',
)
@@ -150,9 +149,6 @@ STATICFILES_DIRS = (
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# South settings
SOUTH_TESTS_MIGRATE = False
# Modoboa settings
#MODOBOA_CUSTOM_LOGO = os.path.join(MEDIA_URL, "custom_logo.png")
+4
View File
@@ -29,6 +29,10 @@ class ModoExtension(object):
always_active=self.always_active
)
def load_initial_data(self):
"""Declare extension data in this method."""
pass
def load(self):
pass
@@ -0,0 +1,51 @@
"""A management command to load Modoboa initial data:
* Create a default super admin if none exists
* Create groups and permissions
"""
from django.contrib.auth.models import Group
from django.core.management.base import BaseCommand
from modoboa.core import PERMISSIONS
from modoboa.core.extensions import exts_pool
from modoboa.core.models import User, ObjectAccess
from modoboa.lib import events
from modoboa.lib.permissions import add_permissions_to_group
from . import CloseConnectionMixin
class Command(BaseCommand, CloseConnectionMixin):
"""Command defintion."""
help = "Load Modoboa initial data"
def handle(self, *args, **options):
"""Command entry point."""
if not User.objects.filter(pk=1, username="admin").exists():
admin = User(username="admin", is_superuser=True)
admin.set_password("password")
admin.save()
ObjectAccess.objects.create(
user=admin, content_object=admin, is_owner=True)
groups = PERMISSIONS.keys() + [
role[0] for role in events.raiseQueryEvent("GetExtraRoles")
]
for groupname in groups:
group, created = Group.objects.get_or_create(name=groupname)
permissions = (
PERMISSIONS.get(groupname, []) +
events.raiseQueryEvent("GetExtraRolePermissions", groupname)
)
if not permissions:
continue
add_permissions_to_group(group, permissions)
exts_pool.load_all()
for extname in exts_pool.extensions.keys():
extension = exts_pool.get_extension(extname)
extension.load_initial_data()
@@ -7,7 +7,7 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('core', '0002_load_initial_data'),
('core', '0001_initial'),
]
operations = [
@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
def load_initial_data(apps, schema_editor):
"""Load initial data."""
User = apps.get_model("core", "User")
user = User(username="admin", is_superuser=True)
user.set_password("password")
user.save()
ObjectAccess = apps.get_model("core", "ObjectAccess")
ObjectAccess.objects.create(user=user, content_object=user, is_owner=True)
class Migration(migrations.Migration):
dependencies = [
('core', '0001_initial'),
]
operations = [
migrations.RunPython(load_initial_data)
]
@@ -1,43 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from modoboa.lib.migration_tools import add_permissions_to_group
PERMISSIONS = [
["core", "user", "add_user"],
["core", "user", "change_user"],
["core", "user", "delete_user"],
["admin", "domain", "view_domain"],
["admin", "mailbox", "add_mailbox"],
["admin", "mailbox", "change_mailbox"],
["admin", "mailbox", "delete_mailbox"],
["admin", "alias", "add_alias"],
["admin", "alias", "change_alias"],
["admin", "alias", "delete_alias"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "view_aliases"],
["admin", "domainalias", "view_domainaliases"],
["admin", "domainalias", "add_domainalias"],
["admin", "domainalias", "change_domainalias"],
["admin", "domainalias", "delete_domainalias"]
]
def load_initial_data(apps, schema_editor):
"""Load initial data."""
Group = apps.get_model("auth", "Group")
dadmins = Group.objects.create(name="DomainAdmins")
add_permissions_to_group(apps, dadmins, PERMISSIONS)
Group.objects.create(name="SimpleUsers")
class Migration(migrations.Migration):
dependencies = [
('admin', '0001_initial'),
]
operations = [
migrations.RunPython(load_initial_data)
]
@@ -45,6 +45,24 @@ ADMIN_EVENTS = [
"ImportObject"
]
PERMISSIONS = {
"DomainAdmins": [
["admin", "domain", "view_domain"],
["admin", "mailbox", "add_mailbox"],
["admin", "mailbox", "change_mailbox"],
["admin", "mailbox", "delete_mailbox"],
["admin", "alias", "add_alias"],
["admin", "alias", "change_alias"],
["admin", "alias", "delete_alias"],
["admin", "mailbox", "view_mailboxes"],
["admin", "alias", "view_aliases"],
["admin", "domainalias", "view_domainaliases"],
["admin", "domainalias", "add_domainalias"],
["admin", "domainalias", "change_domainalias"],
["admin", "domainalias", "delete_domainalias"]
]
}
class AdminConsole(ModoExtension):
name = "admin"
@@ -64,6 +82,12 @@ class AdminConsole(ModoExtension):
exts_pool.register_extension(AdminConsole)
@events.observe("GetExtraRolePermissions")
def extra_permissions(rolename):
"""Return extra permissions for :kw:`rolename`."""
return PERMISSIONS.get(rolename, [])
@events.observe("ExtraUprefsRoutes")
def extra_routes():
from django.conf.urls import url
@@ -2,11 +2,25 @@
from django.utils.translation import ugettext as _
from modoboa.core import PERMISSIONS as CORE_PERMS
from modoboa.extensions.admin.modo_extension import PERMISSIONS as ADMIN_PERMS
from modoboa.extensions.limits.forms import ResourcePoolForm
from modoboa.extensions.limits.models import LimitTemplates
from modoboa.lib import events
PERMISSIONS = {
"Resellers": (
CORE_PERMS.get("DomainAdmins") +
ADMIN_PERMS.get("DomainAdmins") +
[["admin", "domain", "view_domains"],
["admin", "domain", "add_domain"],
["admin", "domain", "change_domain"],
["admin", "domain", "delete_domain"]]
)
}
@events.observe("GetExtraRoles")
def get_extra_roles(user):
if user.is_superuser:
@@ -14,6 +28,12 @@ def get_extra_roles(user):
return []
@events.observe("GetExtraRolePermissions")
def extra_permissions(rolename):
"""Return extra permissions for Resellers."""
return PERMISSIONS.get(rolename, [])
@events.observe("ExtraAdminContent")
def display_pool_usage(user, target, currentpage):
from django.template.loader import render_to_string
@@ -3,37 +3,18 @@ from __future__ import unicode_literals
from django.db import models, migrations
from modoboa.core.extensions import exts_pool
from modoboa.lib.migration_tools import add_permissions_to_group
from modoboa.extensions.limits.midels import LimitTemplates
from modoboa.extensions.limits.models import LimitTemplates
def load_initial_data(apps, schema_editor):
"""Load initial data."""
Group = apps.get_model("auth", "Group")
User = apps.get_model("core", "User")
LimitsPool = apps.get_model("limits", "LimitsPool")
Limit = apps.get_model("limits", "Limit")
dagrp = Group.objects.get(name="DomainAdmins")
grp = Group(name="Resellers")
grp.save()
grp.permissions.add(*dagrp.permissions.all())
add_permissions_to_group(
apps, grp, [("admin", "domain", "view_domains"),
("admin", "domain", "add_domain"),
("admin", "domain", "change_domain"),
("admin", "domain", "delete_domain")]
)
if exts_pool.is_extension_installed(
"modoboa.extensions.postfix_relay_domains"):
from modoboa.extensions.postfix_relay_domains.modo_extension \
import RESELLERS_PERMISSIONS
add_permissions_to_group(apps, grp, RESELLERS_PERMISSIONS)
for user in User.objects.filter(groups__name="DomainAdmins"):
pool, created = LimitsPool.objects.get_or_create(user=user)
for tpl in LimitTemplates().templates():
for tpl in LimitTemplates().templates:
Limit.objects.create(name=tpl[0], pool=pool, maxvalue=0)
@@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy
from modoboa.core.extensions import ModoExtension, exts_pool
from modoboa.lib import events, parameters
from .models import LimitsPool, Limit
EVENTS = [
@@ -32,4 +33,11 @@ class Limits(ModoExtension):
events.declare(EVENTS)
from modoboa.extensions.limits import general_callbacks
def load_initial_data(self):
"""Complete existing pools with new limits."""
new_limits = ["relay_domains_limit", "relay_domain_aliases_limit"]
for pool in LimitsPool.objects.all():
for lname in new_limits:
Limit.objects.get_or_create(name=lname, pool=pool, maxvalue=0)
exts_pool.register_extension(Limits)
@@ -6,8 +6,33 @@ from django.db.models import Q
from django.template import Template, Context
from django.utils.translation import ugettext_lazy
from .models import RelayDomain, RelayDomainAlias
from modoboa.core.extensions import exts_pool
from modoboa.lib import events
from .models import RelayDomain, RelayDomainAlias
PERMISSIONS = {
"Resellers": [
("postfix_relay_domains", "relaydomain", "add_relaydomain"),
("postfix_relay_domains", "relaydomain", "change_relaydomain"),
("postfix_relay_domains", "relaydomain", "delete_relaydomain"),
("postfix_relay_domains", "relaydomainalias", "add_relaydomainalias"),
("postfix_relay_domains", "relaydomainalias",
"change_relaydomainalias"),
("postfix_relay_domains", "relaydomainalias",
"delete_relaydomainalias"),
("postfix_relay_domains", "service", "add_service"),
("postfix_relay_domains", "service", "change_service"),
("postfix_relay_domains", "service", "delete_service")
]
}
@events.observe("GetExtraRolePermissions")
def extra_permissions(rolename):
"""Return extra permissions for Resellers."""
if not exts_pool.is_extension_installed("modoboa.extensions.limit"):
return []
return PERMISSIONS.get(rolename, [])
@events.observe('GetStaticContent')
@@ -3,11 +3,6 @@ from __future__ import unicode_literals
from django.db import models, migrations
from modoboa.core.extensions import exts_pool
from modoboa.lib.migration_tools import add_permissions_to_group
from ..modo_extension import RESELLERS_PERMISSIONS
def load_initial_data(apps, schema_editor):
"""Load initial data."""
@@ -15,24 +10,6 @@ def load_initial_data(apps, schema_editor):
for service_name in ['relay', 'smtp']:
Service.objects.get_or_create(name=service_name)
if not exts_pool.is_extension_installed("modoboa.extensions.limits"):
return
Group = apps.get_model("auth", "Group")
LimitsPool = apps.get_model("limits", "LimitsPool")
Limit = apps.get_model("limits", "Limit")
# Add new limits to existing pools. Set maxvalue to 0 because we
# don't want to load the parameters module here...
new_limits = ["relay_domains_limit", "relay_domain_aliases_limit"]
for pool in LimitsPool.objects.all():
for lname in new_limits:
Limit.objects.create(name=lname, pool=pool, maxvalue=0)
# Add new permissions to the Resellers group.
grp = Group.objects.get(name='Resellers')
add_permissions_to_group(apps, grp, RESELLERS_PERMISSIONS)
class Migration(migrations.Migration):
@@ -18,18 +18,6 @@ EXTENSION_EVENTS = [
"FillRelayDomainInstances"
]
RESELLERS_PERMISSIONS = [
("postfix_relay_domains", "relaydomain", "add_relaydomain"),
("postfix_relay_domains", "relaydomain", "change_relaydomain"),
("postfix_relay_domains", "relaydomain", "delete_relaydomain"),
("postfix_relay_domains", "relaydomainalias", "add_relaydomainalias"),
("postfix_relay_domains", "relaydomainalias", "change_relaydomainalias"),
("postfix_relay_domains", "relaydomainalias", "delete_relaydomainalias"),
("postfix_relay_domains", "service", "add_service"),
("postfix_relay_domains", "service", "change_service"),
("postfix_relay_domains", "service", "delete_service")
]
class PostfixRelayDomains(ModoExtension):
@@ -6,6 +6,26 @@ from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from modoboa.lib import events
PERMISSIONS = [
("radicale", "usercalendar", "add_usercalendar"),
("radicale", "usercalendar", "change_usercalendar"),
("radicale", "usercalendar", "delete_usercalendar"),
("radicale", "sharedcalendar", "add_sharedcalendar"),
("radicale", "sharedcalendar", "change_sharedcalendar"),
("radicale", "sharedcalendar", "delete_sharedcalendar")
]
ROLES_PERMISSIONS = {
"DomainAdmins": PERMISSIONS,
"Resellers": PERMISSIONS
}
@events.observe("GetExtraRolePermissions")
def extra_permissions(rolename):
"""Extra permissions."""
return ROLES_PERMISSIONS.get(rolename, [])
@events.observe("UserMenuDisplay")
def top_menu(target, user):
@@ -1,37 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from modoboa.core.extensions import exts_pool
from modoboa.lib.migration_tools import add_permissions_to_group
def load_initial_data(apps, schema_editor):
"""Load initial data."""
permissions = [
("radicale", "usercalendar", "add_usercalendar"),
("radicale", "usercalendar", "change_usercalendar"),
("radicale", "usercalendar", "delete_usercalendar"),
("radicale", "sharedcalendar", "add_sharedcalendar"),
("radicale", "sharedcalendar", "change_sharedcalendar"),
("radicale", "sharedcalendar", "delete_sharedcalendar")
]
add_permissions_to_group(apps, "DomainAdmins", permissions)
if not exts_pool.is_extension_installed(
"modoboa.extensions.limits"):
return
add_permissions_to_group(apps, "Resellers", permissions)
class Migration(migrations.Migration):
dependencies = [
('radicale', '0001_initial'),
]
operations = [
migrations.RunPython(load_initial_data)
]
-18
View File
@@ -1,18 +0,0 @@
"""Additional functions available for migration scripts."""
def add_permissions_to_group(apps, group, permissions):
"""Add the specified permissions to a django group."""
Permission = apps.get_model("auth", "Permission")
ContentType = apps.get_model("contenttypes", "ContentType")
if isinstance(group, basestring):
Group = apps.get_model("auth", "Group")
group = Group.objects.get(name=group)
for appname, modelname, permname in permissions:
ct = ContentType.objects.get_by_natural_key(
appname, modelname)
group.permissions.add(
Permission.objects.get(content_type=ct, codename=permname)
)
+16
View File
@@ -1,5 +1,6 @@
# coding: utf-8
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db import IntegrityError
from django.utils.translation import ugettext as _
@@ -147,3 +148,18 @@ def get_object_owner(obj):
except ObjectAccess.DoesNotExist:
return None
return entry.user
def add_permissions_to_group(group, permissions):
"""Add the specified permissions to a django group."""
if isinstance(group, basestring):
group = Group.objects.get(name=group)
for appname, modelname, permname in permissions:
ct = ContentType.objects.get_by_natural_key(appname, modelname)
if group.permissions.filter(
content_type=ct, codename=permname).exists():
continue
group.permissions.add(
Permission.objects.get(content_type=ct, codename=permname)
)