def admin(localpart, domain_name, password, mode='create'): """ Create an admin user 'mode' can be: - 'create' (default) Will try to create user and will raise an exception if present - 'ifmissing': if user exists, nothing happens, else it will be created - 'update': user is created or, if it exists, its password gets updated """ domain = models.Domain.query.get(domain_name) if not domain: domain = models.Domain(name=domain_name) db.session.add(domain) user = None if mode == 'ifmissing' or mode == 'update': email = '{}@{}'.format(localpart, domain_name) user = models.User.query.get(email) if user and mode == 'ifmissing': print('user %s exists, not updating' % email) return if not user: user = models.User(localpart=localpart, domain=domain, global_admin=True) user.set_password(password) db.session.add(user) db.session.commit() print("created admin user") elif mode == 'update': user.set_password(password) db.session.commit() print("updated admin password")
def domain(domain_name, max_users=-1, max_aliases=-1, max_quota_bytes=0): """ Create a domain """ 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) db.session.commit()
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()
def user_import(localpart, domain_name, password_hash): """ Import a user along with password hash """ 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, raw=True) db.session.add(user) db.session.commit()
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()
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) 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()
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) 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()
def alias(localpart, domain_name, destination, wildcard=False): """ 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, wildcard=wildcard, destination=destination.split(','), email=f'{localpart}@{domain_name}') db.session.add(alias) db.session.commit()
def domain_create(): form = forms.DomainForm() if form.validate_on_submit(): conflicting_domain = models.Domain.query.get(form.name.data) conflicting_alternative = models.Alternative.query.get(form.name.data) conflicting_relay = models.Relay.query.get(form.name.data) if conflicting_domain or conflicting_alternative or conflicting_relay: flask.flash('Domain %s is already used' % form.name.data, 'error') else: domain = models.Domain() form.populate_obj(domain) db.session.add(domain) db.session.commit() flask.flash('Domain %s created' % domain) return flask.redirect(flask.url_for('.domain_list')) return flask.render_template('domain/create.html', form=form)
def domain_signup(domain_name=None): if not app.config['DOMAIN_REGISTRATION']: flask.abort(403) form = forms.DomainSignupForm() if flask_login.current_user.is_authenticated: del form.localpart del form.pw del form.pw2 if form.validate_on_submit(): conflicting_domain = models.Domain.query.get(form.name.data) conflicting_alternative = models.Alternative.query.get(form.name.data) conflicting_relay = models.Relay.query.get(form.name.data) hostnames = app.config['HOSTNAMES'].split(',') if conflicting_domain or conflicting_alternative or conflicting_relay: flask.flash('Domain %s is already used' % form.name.data, 'error') else: # Check if the domain MX actually points to this server try: mxok = any(str(rset).split()[-1][:-1] in hostnames for rset in dns.resolver.query(form.name.data, 'MX')) except Exception as e: mxok = False if mxok: # Actually create the domain domain = models.Domain() form.populate_obj(domain) domain.max_quota_bytes = app.config['DEFAULT_QUOTA'] domain.max_users = 10 domain.max_aliases = 10 db.session.add(domain) if flask_login.current_user.is_authenticated: user = models.User.query.get(flask_login.current_user.email) else: user = models.User() user.domain = domain form.populate_obj(user) user.set_password(form.pw.data) user.quota_bytes = domain.max_quota_bytes db.session.add(user) domain.managers.append(user) db.session.commit() flask.flash('Domain %s created' % domain) return flask.redirect(flask.url_for('.domain_list')) else: flask.flash('The MX record was not properly set', 'error') return flask.render_template('domain/signup.html', form=form)
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()
def domain_signup(domain_name=None): if not app.config['DOMAIN_REGISTRATION']: flask.abort(403) form = forms.DomainSignupForm() if flask_login.current_user.is_authenticated: del form.localpart del form.pw del form.pw2 if form.validate_on_submit(): conflicting_domain = models.Domain.query.get(form.name.data) conflicting_alternative = models.Alternative.query.get(form.name.data) conflicting_relay = models.Relay.query.get(form.name.data) if conflicting_domain or conflicting_alternative or conflicting_relay: flask.flash('Domain %s is already used' % form.name.data, 'error') else: domain = models.Domain() form.populate_obj(domain) domain.max_quota_bytes = app.config['DEFAULT_QUOTA'] domain.max_users = 10 domain.max_aliases = 10 if domain.check_mx(): models.db.session.add(domain) if flask_login.current_user.is_authenticated: user = models.User.query.get( flask_login.current_user.email) else: user = models.User() user.domain = domain form.populate_obj(user) user.set_password(form.pw.data) user.quota_bytes = domain.max_quota_bytes models.db.session.add(user) domain.managers.append(user) models.db.session.commit() flask.flash('Domain %s created' % domain) return flask.redirect(flask.url_for('.domain_list')) else: flask.flash('The MX record was not properly set', 'error') return flask.render_template('domain/signup.html', form=form)
def admin(localpart, domain_name, password, mode): """ Create an admin user """ if not mode in ('create', 'update', 'ifmissing'): raise click.ClickException(f'invalid mode: {mode!r}') domain = models.Domain.query.get(domain_name) if not domain: domain = models.Domain(name=domain_name) db.session.add(domain) email = f'{localpart}@{domain_name}' if user := models.User.query.get(email): if mode == 'ifmissing': print(f'user {email!r} exists, not updating') return elif mode == 'update': user.set_password(password) db.session.commit() print("updated admin password") else: raise click.ClickException(f'user {email!r} exists, not created')
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: "******"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()
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()
def config_update(verbose=False, delete_objects=False): """ Sync configuration with data from YAML (deprecated) """ new_config = yaml.safe_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', -1) max_aliases = domain_config.get('max_aliases', -1) 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(f'Added {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(f'Updated {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) domain = models.Domain.query.get(domain_name) email = f'{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, 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 isinstance(alias_config['destination'], 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 = f'{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(f'{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(f'Deleting user: {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(f'Deleting alias: {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(f'Deleting domain: {domain.name}') db.session.delete(domain) db.session.commit()