mirror of
				https://github.com/optim-enterprises-bv/Mailu.git
				synced 2025-10-30 01:32:23 +00:00 
			
		
		
		
	Clean most of the refactored code
This commit is contained in:
		| @@ -1,44 +1,40 @@ | ||||
| import flask | ||||
| import flask_bootstrap | ||||
|  | ||||
| import os | ||||
| import docker | ||||
| import socket | ||||
| import uuid | ||||
|  | ||||
| from mailu import utils, debug, db | ||||
| from mailu import utils, debug, models, configuration | ||||
|  | ||||
|  | ||||
| def create_app_from_config(config): | ||||
|     """ Create a new application based on the given configuration | ||||
|     """ | ||||
|     app = flask.Flask(__name__) | ||||
|     app.config = config | ||||
|     app.app_context().push() | ||||
|  | ||||
|     # Bootstrap is used for basic JS and CSS loading | ||||
|     # TODO: remove this and use statically generated assets instead | ||||
|     app.bootstrap = flask_bootstrap.Bootstrap(app) | ||||
|  | ||||
|     # Initialize application extensions | ||||
|     config.init_app(app) | ||||
|     models.db.init_app(app) | ||||
|     utils.limiter.init_app(app) | ||||
|     utils.babel.init_app(app) | ||||
|     utils.login.init_app(app) | ||||
|     utils.login.user_loader(models.User.query.get) | ||||
|     utils.proxy.init_app(app) | ||||
|     manage.migrate.init_app(app) | ||||
|     manage.manager.init_app(app) | ||||
|  | ||||
|     # Initialize debugging tools | ||||
|     if app.config.get("app.debug"): | ||||
|     if app.config.get("DEBUG"): | ||||
|         debug.toolbar.init_app(app) | ||||
|         debug.profiler.init_app(app) | ||||
|         # TODO: add a specific configuration variable for profiling | ||||
|         # debug.profiler.init_app(app) | ||||
|  | ||||
|     # Inject the default variables in the Jinja parser | ||||
|     # TODO: move this to blueprints when needed | ||||
|     @app.context_processor | ||||
|     def inject_defaults(): | ||||
|         signup_domains = models.Domain.query.filter_by(signup_enabled=True).all() | ||||
|         return dict( | ||||
|             current_user=utils.login.current_user, | ||||
|             signup_domains=signup_domains, | ||||
|             config=app.config | ||||
|         ) | ||||
|   | ||||
| @@ -4,7 +4,7 @@ import os | ||||
| DEFAULT_CONFIG = { | ||||
|     # Specific to the admin UI | ||||
|     'SQLALCHEMY_DATABASE_URI': 'sqlite:////data/main.db', | ||||
|     'SQLALCHEMY_TRACK_MODIFICATIONS': False, | ||||
|     'SQLALCHEMY_TRACK_MODIFICATIONS': True, | ||||
|     'DOCKER_SOCKET': 'unix:///var/run/docker.sock', | ||||
|     'BABEL_DEFAULT_LOCALE': 'en', | ||||
|     'BABEL_DEFAULT_TIMEZONE': 'UTC', | ||||
| @@ -13,6 +13,7 @@ DEFAULT_CONFIG = { | ||||
|     'QUOTA_STORAGE_URL': 'redis://redis/1', | ||||
|     'DEBUG': False, | ||||
|     'DOMAIN_REGISTRATION': False, | ||||
|     'TEMPLATES_AUTO_RELOAD': True, | ||||
|     # Statistics management | ||||
|     'INSTANCE_ID_PATH': '/data/instance', | ||||
|     'STATS_ENDPOINT': '0.{}.stats.mailu.io', | ||||
| @@ -58,13 +59,29 @@ class ConfigManager(object): | ||||
|     """ | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.config = { | ||||
|             os.environ.get(key, value) | ||||
|         self.config = dict() | ||||
|  | ||||
|     def init_app(self, app): | ||||
|         self.config.update(app.config) | ||||
|         self.config.update({ | ||||
|             key: os.environ.get(key, value) | ||||
|             for key, value in DEFAULT_CONFIG.items() | ||||
|         } | ||||
|         }) | ||||
|         app.config = self | ||||
|  | ||||
|     def setdefault(self, key, value): | ||||
|         if key not in self.config: | ||||
|             self.config[key] = value | ||||
|         return self.config[key] | ||||
|  | ||||
|     def get(self, *args): | ||||
|         return self.config.get(*args) | ||||
|  | ||||
|     def __getitem__(self, key): | ||||
|         return self.get(key) | ||||
|         return self.config.get(key) | ||||
|  | ||||
|     def __setitem__(self, key, value): | ||||
|         self.config[key] = value | ||||
|  | ||||
|     def __contains__(self, key): | ||||
|         return key in self.config | ||||
|   | ||||
| @@ -9,7 +9,7 @@ toolbar = flask_debugtoolbar.DebugToolbarExtension() | ||||
|  | ||||
| # Profiler | ||||
| class Profiler(object): | ||||
|     def init_app(self): | ||||
|     def init_app(self, app): | ||||
|         app.wsgi_app = werkzeug_profiler.ProfilerMiddleware( | ||||
|             app.wsgi_app, restrictions=[30] | ||||
|         ) | ||||
|   | ||||
| @@ -14,12 +14,13 @@ db = models.db | ||||
|  | ||||
|  | ||||
| @click.group() | ||||
| def cli(cls=flask_cli.FlaskGroup, create_app=mailu.create_app): | ||||
| def cli(cls=flask_cli.FlaskGroup, create_app=create_app): | ||||
|     """ Main command group | ||||
|     """ | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @flask_cli.with_appcontext | ||||
| def advertise(): | ||||
|     """ Advertise this server against statistic services. | ||||
|     """ | ||||
| @@ -38,9 +39,10 @@ def advertise(): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('localpart', help='localpart for the new admin') | ||||
| @cli.argument('domain_name', help='domain name for the new admin') | ||||
| @cli.argument('password', help='plain password for the new admin') | ||||
| @click.argument('localpart') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('password') | ||||
| @flask_cli.with_appcontext | ||||
| def admin(localpart, domain_name, password): | ||||
|     """ Create an admin user | ||||
|     """ | ||||
| @@ -59,14 +61,16 @@ def admin(localpart, domain_name, password): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('localpart', help='localpart for the new user') | ||||
| @cli.argument('domain_name', help='domain name for the new user') | ||||
| @cli.argument('password', help='plain password for the new user') | ||||
| @cli.argument('hash_scheme', help='password hashing scheme') | ||||
| def user(localpart, domain_name, password, | ||||
|          hash_scheme=app.config['PASSWORD_SCHEME']): | ||||
| @click.argument('localpart') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('password') | ||||
| @click.argument('hash_scheme') | ||||
| @flask_cli.with_appcontext | ||||
| def user(localpart, domain_name, password, hash_scheme=None): | ||||
|     """ Create a user | ||||
|     """ | ||||
|     if hash_scheme is None: | ||||
|         hash_scheme = app.config['PASSWORD_SCHEME'] | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
| @@ -82,10 +86,11 @@ def user(localpart, domain_name, password, | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.option('-n', '--domain_name', dest='domain_name') | ||||
| @cli.option('-u', '--max_users', dest='max_users') | ||||
| @cli.option('-a', '--max_aliases', dest='max_aliases') | ||||
| @cli.option('-q', '--max_quota_bytes', dest='max_quota_bytes') | ||||
| @click.option('-n', '--domain_name') | ||||
| @click.option('-u', '--max_users') | ||||
| @click.option('-a', '--max_aliases') | ||||
| @click.option('-q', '--max_quota_bytes') | ||||
| @flask_cli.with_appcontext | ||||
| def domain(domain_name, max_users=0, max_aliases=0, max_quota_bytes=0): | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
| @@ -95,14 +100,16 @@ def domain(domain_name, max_users=0, max_aliases=0, max_quota_bytes=0): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('localpart', help='localpart for the new user') | ||||
| @cli.argument('domain_name', help='domain name for the new user') | ||||
| @cli.argument('password_hash', help='password hash for the new user') | ||||
| @cli.argument('hash_scheme', help='password hashing scheme') | ||||
| def user_import(localpart, domain_name, password_hash, | ||||
|                 hash_scheme=app.config['PASSWORD_SCHEME']): | ||||
| @click.argument('localpart') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('password_hash') | ||||
| @click.argument('hash_scheme') | ||||
| @flask_cli.with_appcontext | ||||
| def user_import(localpart, domain_name, password_hash, hash_scheme = None): | ||||
|     """ Import a user along with password hash. | ||||
|     """ | ||||
|     if hash_scheme is None: | ||||
|         hash_scheme = app.config['PASSWORD_SCHEME'] | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
| @@ -118,8 +125,9 @@ def user_import(localpart, domain_name, password_hash, | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.option('-v', dest='verbose') | ||||
| @cli.option('-d', dest='delete_objects') | ||||
| @click.option('-v', '--verbose') | ||||
| @click.option('-d', '--delete_objects') | ||||
| @flask_cli.with_appcontext | ||||
| def config_update(verbose=False, delete_objects=False): | ||||
|     """sync configuration with data from YAML-formatted stdin""" | ||||
|     import yaml | ||||
| @@ -259,7 +267,8 @@ def config_update(verbose=False, delete_objects=False): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('email', help='email address to be deleted') | ||||
| @click.argument('email') | ||||
| @flask_cli.with_appcontext | ||||
| def user_delete(email): | ||||
|     """delete user""" | ||||
|     user = models.User.query.get(email) | ||||
| @@ -269,7 +278,8 @@ def user_delete(email): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('email', help='email alias to be deleted') | ||||
| @click.argument('email') | ||||
| @flask_cli.with_appcontext | ||||
| def alias_delete(email): | ||||
|     """delete alias""" | ||||
|     alias = models.Alias.query.get(email) | ||||
| @@ -279,9 +289,10 @@ def alias_delete(email): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('localpart', help='localpart for the new alias') | ||||
| @cli.argument('domain_name', help='domain name for the new alias') | ||||
| @cli.argument('destination', help='destination for the new alias') | ||||
| @click.argument('localpart') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('destination') | ||||
| @flask_cli.with_appcontext | ||||
| def alias(localpart, domain_name, destination): | ||||
|     """ Create an alias | ||||
|     """ | ||||
| @@ -300,10 +311,11 @@ def alias(localpart, domain_name, destination): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('domain_name', help='domain to be updated') | ||||
| @cli.argument('max_users', help='maximum user count') | ||||
| @cli.argument('max_aliases', help='maximum alias count') | ||||
| @cli.argument('max_quota_bytes', help='maximum quota bytes par user') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('max_users') | ||||
| @click.argument('max_aliases') | ||||
| @click.argument('max_quota_bytes') | ||||
| @flask_cli.with_appcontext | ||||
| def setlimits(domain_name, max_users, max_aliases, max_quota_bytes): | ||||
|     """ Set domain limits | ||||
|     """ | ||||
| @@ -316,8 +328,9 @@ def setlimits(domain_name, max_users, max_aliases, max_quota_bytes): | ||||
|  | ||||
|  | ||||
| @cli.command() | ||||
| @cli.argument('domain_name', help='target domain name') | ||||
| @cli.argument('user_name', help='username inside the target domain') | ||||
| @click.argument('domain_name') | ||||
| @click.argument('user_name') | ||||
| @flask_cli.with_appcontext | ||||
| def setmanager(domain_name, user_name='manager'): | ||||
|     """ Make a user manager of a domain | ||||
|     """ | ||||
| @@ -327,3 +340,6 @@ def setmanager(domain_name, user_name='manager'): | ||||
|     db.session.add(domain) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     cli() | ||||
|   | ||||
| @@ -307,24 +307,28 @@ class User(Base, Email): | ||||
|                    'SHA256-CRYPT': "sha256_crypt", | ||||
|                    'MD5-CRYPT': "md5_crypt", | ||||
|                    'CRYPT': "des_crypt"} | ||||
|     pw_context = context.CryptContext( | ||||
|         schemes = scheme_dict.values(), | ||||
|         default=scheme_dict[app.config['PASSWORD_SCHEME']], | ||||
|     ) | ||||
|  | ||||
|     def get_password_context(self): | ||||
|         return context.CryptContext( | ||||
|             schemes=self.scheme_dict.values(), | ||||
|             default=self.scheme_dict[app.config['PASSWORD_SCHEME']], | ||||
|         ) | ||||
|  | ||||
|     def check_password(self, password): | ||||
|         reference = re.match('({[^}]+})?(.*)', self.password).group(2) | ||||
|         return User.pw_context.verify(password, reference) | ||||
|         return self.get_password_context().verify(password, reference) | ||||
|  | ||||
|     def set_password(self, password, hash_scheme=app.config['PASSWORD_SCHEME'], raw=False): | ||||
|     def set_password(self, password, hash_scheme=None, raw=False): | ||||
|         """Set password for user with specified encryption scheme | ||||
|            @password: plain text password to encrypt (if raw == True the hash itself) | ||||
|         """ | ||||
|         if hash_scheme is None: | ||||
|             hash_scheme = app.config['PASSWORD_SCHEME'] | ||||
|         # for the list of hash schemes see https://wiki2.dovecot.org/Authentication/PasswordSchemes | ||||
|         if raw: | ||||
|             self.password = '{'+hash_scheme+'}' + password | ||||
|         else: | ||||
|             self.password = '{'+hash_scheme+'}' + User.pw_context.encrypt(password, self.scheme_dict[hash_scheme]) | ||||
|             self.password = '{'+hash_scheme+'}' + self.get_password_context().encrypt(password, self.scheme_dict[hash_scheme]) | ||||
|  | ||||
|     def get_managed_domains(self): | ||||
|         if self.global_admin: | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| from mailu import db, models | ||||
| from mailu import models | ||||
| from mailu.ui import ui, forms, access | ||||
|  | ||||
| import flask | ||||
|   | ||||
| @@ -1,3 +1,5 @@ | ||||
| from mailu import models | ||||
|  | ||||
| import flask | ||||
| import flask_login | ||||
| import flask_script | ||||
| @@ -5,13 +7,14 @@ import flask_migrate | ||||
| import flask_babel | ||||
| import flask_limiter | ||||
|  | ||||
| from werkzeug.contrib import fixers | ||||
|  | ||||
|  | ||||
| # Login configuration | ||||
| login = flask_login.LoginManager() | ||||
| login.login_view = "ui.login" | ||||
| login.user_loader(models.User.query.get) | ||||
|  | ||||
| @login_manager.unauthorized_handler | ||||
| @login.unauthorized_handler | ||||
| def handle_needs_login(): | ||||
|     return flask.redirect( | ||||
|         flask.url_for('ui.login', next=flask.request.endpoint) | ||||
|   | ||||
| @@ -1,298 +0,0 @@ | ||||
| from mailu import app, manager, db, models | ||||
|  | ||||
| import os | ||||
| import socket | ||||
| import uuid | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def advertise(): | ||||
|     """ Advertise this server against statistic services. | ||||
|     """ | ||||
|     if os.path.isfile(app.config["INSTANCE_ID_PATH"]): | ||||
|         with open(app.config["INSTANCE_ID_PATH"], "r") as handle: | ||||
|             instance_id = handle.read() | ||||
|     else: | ||||
|         instance_id = str(uuid.uuid4()) | ||||
|         with open(app.config["INSTANCE_ID_PATH"], "w") as handle: | ||||
|             handle.write(instance_id) | ||||
|     if app.config["DISABLE_STATISTICS"].lower() != "true": | ||||
|         try: | ||||
|             socket.gethostbyname(app.config["STATS_ENDPOINT"].format(instance_id)) | ||||
|         except: | ||||
|             pass | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def admin(localpart, domain_name, password): | ||||
|     """ Create an admin user | ||||
|     """ | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
|         db.session.add(domain) | ||||
|     user = models.User( | ||||
|         localpart=localpart, | ||||
|         domain=domain, | ||||
|         global_admin=True | ||||
|     ) | ||||
|     user.set_password(password) | ||||
|     db.session.add(user) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def user(localpart, domain_name, password, | ||||
|          hash_scheme=app.config['PASSWORD_SCHEME']): | ||||
|     """ Create a user | ||||
|     """ | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
|         db.session.add(domain) | ||||
|     user = models.User( | ||||
|         localpart=localpart, | ||||
|         domain=domain, | ||||
|         global_admin=False | ||||
|     ) | ||||
|     user.set_password(password, hash_scheme=hash_scheme) | ||||
|     db.session.add(user) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.option('-n', '--domain_name', dest='domain_name') | ||||
| @manager.option('-u', '--max_users', dest='max_users') | ||||
| @manager.option('-a', '--max_aliases', dest='max_aliases') | ||||
| @manager.option('-q', '--max_quota_bytes', dest='max_quota_bytes') | ||||
| def domain(domain_name, max_users=0, max_aliases=0, max_quota_bytes=0): | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
|         db.session.add(domain) | ||||
|         db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def user_import(localpart, domain_name, password_hash, | ||||
|                 hash_scheme=app.config['PASSWORD_SCHEME']): | ||||
|     """ Import a user along with password hash. Available hashes: | ||||
|                    'SHA512-CRYPT' | ||||
|                    'SHA256-CRYPT' | ||||
|                    'MD5-CRYPT' | ||||
|                    'CRYPT' | ||||
|     """ | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
|         db.session.add(domain) | ||||
|     user = models.User( | ||||
|         localpart=localpart, | ||||
|         domain=domain, | ||||
|         global_admin=False | ||||
|     ) | ||||
|     user.set_password(password_hash, hash_scheme=hash_scheme, raw=True) | ||||
|     db.session.add(user) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def config_update(verbose=False, delete_objects=False): | ||||
|     """sync configuration with data from YAML-formatted stdin""" | ||||
|     import yaml | ||||
|     import sys | ||||
|     new_config = yaml.load(sys.stdin) | ||||
|     # print new_config | ||||
|     domains = new_config.get('domains', []) | ||||
|     tracked_domains = set() | ||||
|     for domain_config in domains: | ||||
|         if verbose: | ||||
|             print(str(domain_config)) | ||||
|         domain_name = domain_config['name'] | ||||
|         max_users = domain_config.get('max_users', 0) | ||||
|         max_aliases = domain_config.get('max_aliases', 0) | ||||
|         max_quota_bytes = domain_config.get('max_quota_bytes', 0) | ||||
|         tracked_domains.add(domain_name) | ||||
|         domain = models.Domain.query.get(domain_name) | ||||
|         if not domain: | ||||
|             domain = models.Domain(name=domain_name, | ||||
|                                    max_users=max_users, | ||||
|                                    max_aliases=max_aliases, | ||||
|                                    max_quota_bytes=max_quota_bytes) | ||||
|             db.session.add(domain) | ||||
|             print("Added " + str(domain_config)) | ||||
|         else: | ||||
|             domain.max_users = max_users | ||||
|             domain.max_aliases = max_aliases | ||||
|             domain.max_quota_bytes = max_quota_bytes | ||||
|             db.session.add(domain) | ||||
|             print("Updated " + str(domain_config)) | ||||
|  | ||||
|     users = new_config.get('users', []) | ||||
|     tracked_users = set() | ||||
|     user_optional_params = ('comment', 'quota_bytes', 'global_admin', | ||||
|                             'enable_imap', 'enable_pop', 'forward_enabled', | ||||
|                             'forward_destination', 'reply_enabled', | ||||
|                             'reply_subject', 'reply_body', 'displayed_name', | ||||
|                             'spam_enabled', 'email', 'spam_threshold') | ||||
|     for user_config in users: | ||||
|         if verbose: | ||||
|             print(str(user_config)) | ||||
|         localpart = user_config['localpart'] | ||||
|         domain_name = user_config['domain'] | ||||
|         password_hash = user_config.get('password_hash', None) | ||||
|         hash_scheme = user_config.get('hash_scheme', None) | ||||
|         domain = models.Domain.query.get(domain_name) | ||||
|         email = '{0}@{1}'.format(localpart, domain_name) | ||||
|         optional_params = {} | ||||
|         for k in user_optional_params: | ||||
|             if k in user_config: | ||||
|                 optional_params[k] = user_config[k] | ||||
|         if not domain: | ||||
|             domain = models.Domain(name=domain_name) | ||||
|             db.session.add(domain) | ||||
|         user = models.User.query.get(email) | ||||
|         tracked_users.add(email) | ||||
|         tracked_domains.add(domain_name) | ||||
|         if not user: | ||||
|             user = models.User( | ||||
|                 localpart=localpart, | ||||
|                 domain=domain, | ||||
|                 **optional_params | ||||
|             ) | ||||
|         else: | ||||
|             for k in optional_params: | ||||
|                 setattr(user, k, optional_params[k]) | ||||
|         user.set_password(password_hash, hash_scheme=hash_scheme, raw=True) | ||||
|         db.session.add(user) | ||||
|  | ||||
|     aliases = new_config.get('aliases', []) | ||||
|     tracked_aliases = set() | ||||
|     for alias_config in aliases: | ||||
|         if verbose: | ||||
|             print(str(alias_config)) | ||||
|         localpart = alias_config['localpart'] | ||||
|         domain_name = alias_config['domain'] | ||||
|         if type(alias_config['destination']) is str: | ||||
|             destination = alias_config['destination'].split(',') | ||||
|         else: | ||||
|             destination = alias_config['destination'] | ||||
|         wildcard = alias_config.get('wildcard', False) | ||||
|         domain = models.Domain.query.get(domain_name) | ||||
|         email = '{0}@{1}'.format(localpart, domain_name) | ||||
|         if not domain: | ||||
|             domain = models.Domain(name=domain_name) | ||||
|             db.session.add(domain) | ||||
|         alias = models.Alias.query.get(email) | ||||
|         tracked_aliases.add(email) | ||||
|         tracked_domains.add(domain_name) | ||||
|         if not alias: | ||||
|             alias = models.Alias( | ||||
|                 localpart=localpart, | ||||
|                 domain=domain, | ||||
|                 wildcard=wildcard, | ||||
|                 destination=destination, | ||||
|                 email=email | ||||
|             ) | ||||
|         else: | ||||
|             alias.destination = destination | ||||
|             alias.wildcard = wildcard | ||||
|         db.session.add(alias) | ||||
|  | ||||
|     db.session.commit() | ||||
|  | ||||
|     managers = new_config.get('managers', []) | ||||
|     # tracked_managers=set() | ||||
|     for manager_config in managers: | ||||
|         if verbose: | ||||
|             print(str(manager_config)) | ||||
|         domain_name = manager_config['domain'] | ||||
|         user_name = manager_config['user'] | ||||
|         domain = models.Domain.query.get(domain_name) | ||||
|         manageruser = models.User.query.get(user_name + '@' + domain_name) | ||||
|         if manageruser not in domain.managers: | ||||
|             domain.managers.append(manageruser) | ||||
|         db.session.add(domain) | ||||
|  | ||||
|     db.session.commit() | ||||
|  | ||||
|     if delete_objects: | ||||
|         for user in db.session.query(models.User).all(): | ||||
|             if not (user.email in tracked_users): | ||||
|                 if verbose: | ||||
|                     print("Deleting user: " + str(user.email)) | ||||
|                 db.session.delete(user) | ||||
|         for alias in db.session.query(models.Alias).all(): | ||||
|             if not (alias.email in tracked_aliases): | ||||
|                 if verbose: | ||||
|                     print("Deleting alias: " + str(alias.email)) | ||||
|                 db.session.delete(alias) | ||||
|         for domain in db.session.query(models.Domain).all(): | ||||
|             if not (domain.name in tracked_domains): | ||||
|                 if verbose: | ||||
|                     print("Deleting domain: " + str(domain.name)) | ||||
|                 db.session.delete(domain) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def user_delete(email): | ||||
|     """delete user""" | ||||
|     user = models.User.query.get(email) | ||||
|     if user: | ||||
|         db.session.delete(user) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def alias_delete(email): | ||||
|     """delete alias""" | ||||
|     alias = models.Alias.query.get(email) | ||||
|     if alias: | ||||
|         db.session.delete(alias) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def alias(localpart, domain_name, destination): | ||||
|     """ Create an alias | ||||
|     """ | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     if not domain: | ||||
|         domain = models.Domain(name=domain_name) | ||||
|         db.session.add(domain) | ||||
|     alias = models.Alias( | ||||
|         localpart=localpart, | ||||
|         domain=domain, | ||||
|         destination=destination.split(','), | ||||
|         email="%s@%s" % (localpart, domain_name) | ||||
|     ) | ||||
|     db.session.add(alias) | ||||
|     db.session.commit() | ||||
|  | ||||
| # Set limits to a domain | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def setlimits(domain_name, max_users, max_aliases, max_quota_bytes): | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     domain.max_users = max_users | ||||
|     domain.max_aliases = max_aliases | ||||
|     domain.max_quota_bytes = max_quota_bytes | ||||
|  | ||||
|     db.session.add(domain) | ||||
|     db.session.commit() | ||||
|  | ||||
| # Make the user manager of a domain | ||||
|  | ||||
|  | ||||
| @manager.command | ||||
| def setmanager(domain_name, user_name='manager'): | ||||
|     domain = models.Domain.query.get(domain_name) | ||||
|     manageruser = models.User.query.get(user_name + '@' + domain_name) | ||||
|     domain.managers.append(manageruser) | ||||
|     db.session.add(domain) | ||||
|     db.session.commit() | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     manager.run() | ||||
		Reference in New Issue
	
	Block a user
	 kaiyou
					kaiyou