mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
WIP: change the way extensions initial data is loaded.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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()
|
||||
+1
-1
@@ -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)
|
||||
]
|
||||
@@ -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)
|
||||
)
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user