def handle(self, *args, **options): Amavis().load() if options["debug"]: import logging l = logging.getLogger("django.db.backends") l.setLevel(logging.DEBUG) l.addHandler(logging.StreamHandler()) self.verbose = options["verbose"] conf = dict(param_tools.get_global_parameters("modoboa_amavis")) flags = ["D"] if conf["released_msgs_cleanup"]: flags += ["R"] self.__vprint("Deleting marked messages...") ids = Msgrcpt.objects.filter(rs__in=flags).values("mail_id").distinct() for msg in Msgs.objects.filter(mail_id__in=ids): if not msg.msgrcpt_set.exclude(rs__in=flags).count(): msg.delete() self.__vprint("Deleting messages older than %d days...".format( conf["max_messages_age"])) limit = int(time.time()) - (conf["max_messages_age"] * 24 * 3600) Msgs.objects.filter(time_num__lt=limit).delete() self.__vprint("Deleting unreferenced e-mail addresses...") for maddr in Maddr.objects.all(): if not maddr.msgs_set.count() and not maddr.msgrcpt_set.count(): maddr.delete() self.__vprint("Done.")
def __init__(self, user, recipient_db): """Constructor.""" conf = dict(param_tools.get_global_parameters("modoboa_amavis")) self._sa_is_local = conf["sa_is_local"] self._default_username = conf["default_user"] self._recipient_db = recipient_db self._setup_cache = {} self._username_cache = [] if user.role == "SimpleUsers": if conf["user_level_learning"]: self._username = user.email else: self._username = None self.error = None if self._sa_is_local: self._learn_cmd = self._find_binary("sa-learn") self._learn_cmd += " --{0} --no-sync -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [0] self._sync_cmd = self._find_binary("sa-learn") self._sync_cmd += " -u {0} --sync" else: self._learn_cmd = self._find_binary("spamc") self._learn_cmd += " -d {0} -p {1}".format(conf["spamd_address"], conf["spamd_port"]) self._learn_cmd += " -L {0} -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [5, 6]
def authenticate(self, username=None, password=None): """Check the username/password and return a User.""" if type(username) is unicode: username = username.encode("utf-8") if type(password) is unicode: password = password.encode("utf-8") conf = dict( param_tools.get_global_parameters("modoboa_imap_migration")) address = conf["server_address"] port = conf["server_port"] try: if conf["secured"]: conn = imaplib.IMAP4_SSL(address, port) else: conn = imaplib.IMAP4(address, port) except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error: raise ModoboaException( _("Connection to IMAP server failed: %s" % error)) try: typ, data = conn.login(username, password) except imaplib.IMAP4.error: typ = "NO" conn.logout() if typ != "OK": return None return self.get_or_create_user(username, password)
def mail_home(self): """Retrieve the home directory of this mailbox. The home directory refers to the place on the file system where the mailbox data is stored. We ask dovecot to give us this information because there are several patterns to understand and we don't want to implement them. """ admin_params = dict(param_tools.get_global_parameters("admin")) if not admin_params.get("handle_mailboxes"): return None if self.__mail_home is None: curuser = pwd.getpwuid(os.getuid()).pw_name mbowner = admin_params["mailboxes_owner"] options = {} if curuser != mbowner: options["sudo_user"] = mbowner code, output = exec_cmd( "doveadm user -f home %s" % self.full_address, **options) if code: raise lib_exceptions.InternalError( _("Failed to retrieve mailbox location (%s)") % output) self.__mail_home = output.strip() return self.__mail_home
def make_query_args(address, exact_extension=True, wildcard=None, domain_search=False): assert isinstance(address, six.text_type),\ "address should be of type %s" % six.text_type.__name__ conf = dict(param_tools.get_global_parameters("modoboa_amavis")) local_part, domain = split_address(address) if not conf["localpart_is_case_sensitive"]: local_part = local_part.lower() if domain: domain = domain.lstrip("@").rstrip(".") domain = domain.lower() orig_domain = domain domain = idna.encode(domain, uts46=True).decode("ascii") delimiter = conf["recipient_delimiter"] local_part, extension = split_local_part(local_part, delimiter=delimiter) query_args = [] if (conf["localpart_is_case_sensitive"] or (domain and domain != orig_domain)): query_args.append(address) if extension: query_args.append("%s%s%s@%s" % (local_part, delimiter, extension, domain)) if delimiter and not exact_extension and wildcard: query_args.append("%s%s%s@%s" % (local_part, delimiter, wildcard, domain)) query_args.append("%s@%s" % (local_part, domain)) if domain_search: query_args.append("@%s" % domain) query_args.append("@.") return query_args
def to_django_settings(self): """Apply LDAP related parameters to Django settings. Doing so, we can use the django_auth_ldap module. """ try: import ldap from django_auth_ldap.config import ( LDAPSearch, PosixGroupType, GroupOfNamesType) ldap_available = True except ImportError: ldap_available = False values = dict(param_tools.get_global_parameters("core")) if not ldap_available or values["authentication_type"] != "ldap": return if not hasattr(settings, "AUTH_LDAP_USER_ATTR_MAP"): setattr(settings, "AUTH_LDAP_USER_ATTR_MAP", { "first_name": "givenName", "email": "mail", "last_name": "sn" }) ldap_uri = "ldaps://" if values["ldap_secured"] else "ldap://" ldap_uri += "%s:%s" % ( values["ldap_server_address"], values["ldap_server_port"]) setattr(settings, "AUTH_LDAP_SERVER_URI", ldap_uri) if values["ldap_group_type"] == "groupofnames": setattr(settings, "AUTH_LDAP_GROUP_TYPE", GroupOfNamesType()) searchfilter = "(objectClass=groupOfNames)" else: setattr(settings, "AUTH_LDAP_GROUP_TYPE", PosixGroupType()) searchfilter = "(objectClass=posixGroup)" setattr(settings, "AUTH_LDAP_GROUP_SEARCH", LDAPSearch( values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, searchfilter )) if values["ldap_auth_method"] == "searchbind": setattr(settings, "AUTH_LDAP_BIND_DN", values["ldap_bind_dn"]) setattr( settings, "AUTH_LDAP_BIND_PASSWORD", values["ldap_bind_password"] ) search = LDAPSearch( values["ldap_search_base"], ldap.SCOPE_SUBTREE, values["ldap_search_filter"] ) setattr(settings, "AUTH_LDAP_USER_SEARCH", search) else: setattr( settings, "AUTH_LDAP_USER_DN_TEMPLATE", values["ldap_user_dn_template"] ) if values["ldap_is_active_directory"]: if not hasattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS"): setattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS", { ldap.OPT_REFERRALS: False }) else: settings.AUTH_LDAP_GLOBAL_OPTIONS[ldap.OPT_REFERRALS] = False
def __init__(self, user, *args, **kwargs): self.oldname = None if "instance" in kwargs: self.old_dkim_key_length = kwargs["instance"].dkim_key_length self.oldname = kwargs["instance"].name super(DomainFormGeneral, self).__init__(*args, **kwargs) params = dict(param_tools.get_global_parameters("admin")) self.fields["quota"].initial = params["default_domain_quota"] if params["default_domain_message_limit"] is not None: self.fields["message_limit"].initial = ( params["default_domain_message_limit"]) self.fields["default_mailbox_quota"].initial = ( params["default_mailbox_quota"]) self.fields["type"].choices = constants.DOMAIN_TYPES self.field_widths = { "quota": 3, "default_mailbox_quota": 3 } self.user = user if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict(args[0], "aliases", DomainNameField) elif "instance" in kwargs: d = kwargs["instance"] for pos, dalias in enumerate(d.domainalias_set.all()): name = "aliases_%d" % (pos + 1) self._create_field(forms.CharField, name, dalias.name, 3)
def __init__(self, user=None, password=None): self.__hdelimiter = None self.conf = dict( param_tools.get_global_parameters("modoboa_sievefilters")) self.address = self.conf["imap_server"] self.port = self.conf["imap_port"] self.login(user, password)
def __init__(self, user, *args, **kwargs): self.oldname = None if "instance" in kwargs: self.oldname = kwargs["instance"].name super(DomainFormGeneral, self).__init__(*args, **kwargs) params = dict(param_tools.get_global_parameters("admin")) self.fields["quota"].initial = params["default_domain_quota"] self.fields["default_mailbox_quota"].initial = ( params["default_mailbox_quota"]) extra_domain_types = reduce( lambda a, b: a + b, [result[1] for result in signals.extra_domain_types.send( sender=self.__class__)] ) self.fields["type"].choices = DOMAIN_TYPES + extra_domain_types self.field_widths = { "quota": 3, "default_mailbox_quota": 3 } self.user = user if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict(args[0], "aliases", DomainNameField) elif "instance" in kwargs: d = kwargs["instance"] for pos, dalias in enumerate(d.domainalias_set.all()): name = "aliases_%d" % (pos + 1) self._create_field(forms.CharField, name, dalias.name, 3)
def mail_home(self): """Retrieve the home directory of this mailbox. The home directory refers to the place on the file system where the mailbox data is stored. We ask dovecot to give us this information because there are several patterns to understand and we don't want to implement them. """ admin_params = dict(param_tools.get_global_parameters("admin")) if not admin_params.get("handle_mailboxes"): return None if self.__mail_home is None: curuser = pwd.getpwuid(os.getuid()).pw_name mbowner = admin_params["mailboxes_owner"] options = {} if curuser != mbowner: options["sudo_user"] = mbowner code, output = exec_cmd( "doveadm user %s -f home" % self.full_address, **options ) if code: raise lib_exceptions.InternalError( _(u"Failed to retrieve mailbox location (%s)") % output) self.__mail_home = output.strip() return self.__mail_home
def to_django_settings(self): """Apply LDAP related parameters to Django settings. Doing so, we can use the django_auth_ldap module. """ try: import ldap from django_auth_ldap.config import ( LDAPSearch, PosixGroupType, GroupOfNamesType) ldap_available = True except ImportError: ldap_available = False values = dict(param_tools.get_global_parameters("core")) if not ldap_available or values["authentication_type"] != "ldap": return if not hasattr(settings, "AUTH_LDAP_USER_ATTR_MAP"): setattr(settings, "AUTH_LDAP_USER_ATTR_MAP", { "first_name": "givenName", "email": "mail", "last_name": "sn" }) ldap_uri = "ldaps://" if values["ldap_secured"] else "ldap://" ldap_uri += "%s:%s" % ( values["ldap_server_address"], values["ldap_server_port"]) setattr(settings, "AUTH_LDAP_SERVER_URI", ldap_uri) if values["ldap_group_type"] == "groupofnames": setattr(settings, "AUTH_LDAP_GROUP_TYPE", GroupOfNamesType()) searchfilter = "(objectClass=groupOfNames)" else: setattr(settings, "AUTH_LDAP_GROUP_TYPE", PosixGroupType()) searchfilter = "(objectClass=posixGroup)" setattr(settings, "AUTH_LDAP_GROUP_SEARCH", LDAPSearch( values["ldap_groups_search_base"], ldap.SCOPE_SUBTREE, searchfilter )) if values["ldap_auth_method"] == "searchbind": setattr(settings, "AUTH_LDAP_BIND_DN", values["ldap_bind_dn"]) setattr( settings, "AUTH_LDAP_BIND_PASSWORD", values["ldap_bind_password"] ) search = LDAPSearch( values["ldap_search_base"], ldap.SCOPE_SUBTREE, values["ldap_search_filter"] ) setattr(settings, "AUTH_LDAP_USER_SEARCH", search) else: setattr( settings, "AUTH_LDAP_USER_DN_TEMPLATE", values["ldap_user_dn_template"] ) if values["ldap_is_active_directory"]: if not hasattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS"): setattr(settings, "AUTH_LDAP_GLOBAL_OPTIONS", { ldap.OPT_REFERRALS: False }) else: settings.AUTH_LDAP_GLOBAL_OPTIONS[ldap.OPT_REFERRALS] = False
def handle(self, *args, **options): """Entry point.""" load_admin_settings() ImapMigration().load() conf = dict( param_tools.get_global_parameters("modoboa_imap_migration")) context = { "imap_server_address": conf["server_address"], "imap_server_port": conf["server_port"], "imap_server_secured": conf["secured"], "imap_create_folders": conf["create_folders"], "imap_folder_filter_exclude": conf["folder_filter_exclude"], "imap_folder_filter_include": ", ".join("'{0}'".format(w) for w in conf["folder_filter_include"].split(",")), "migrations": Migration.objects.select_related("mailbox"), } with open(options["output"], "w") as fpo: content = render_to_string( "modoboa_imap_migration/offlineimap.conf", context) fpo.write(content)
def dns_global_status(self) -> str: """Return global DNS status.""" if not self.enable_dns_checks or self.uses_a_reserved_tld: return "disabled" elif self.awaiting_checks(): return "pending" config = dict(param_tools.get_global_parameters("admin")) errors = [] if config["enable_mx_checks"] and not self.mxrecord_set.has_valids(): errors.append("mx") if config["enable_dnsbl_checks"] and self.dnsblresult_set.blacklisted( ).exists(): errors.append("dnsbl") if config["enable_spf_checks"]: if self.spf_record is None or not self.spf_record.is_valid: errors.append("spf") if self.dkim_record is None or not self.dkim_record.is_valid: errors.append("dkim") if self.dmarc_record is None or not self.dmarc_record.is_valid: errors.append("dmarc") if config["enable_autoconfig_checks"]: if self.autoconfig_record is None: errors.append("autoconfig") if self.autodiscover_record is None: errors.append("autodiscover") if len(errors) == 0: return "ok" return "critical"
def __init__(self, user=None, password=None): self.__hdelimiter = None self.quota_usage = -1 self.criterions = [] self.conf = dict(param_tools.get_global_parameters("modoboa_webmail")) self.address = self.conf["imap_server"] self.port = self.conf["imap_port"] self.login(user, password)
def delete_ldap_account(sender, instance, **kwargs): """Delete LDAP account if needed.""" config = dict(param_tools.get_global_parameters("core")) if not config["ldap_enable_sync"]: return if instance.role != "SimpleUsers": return lib.delete_ldap_account(instance, config)
def create_domain_limits(sender, instance, **kwargs): """Create limits for new domain.""" if not kwargs.get("created"): return global_params = dict(param_tools.get_global_parameters("limits")) for name, _definition in utils.get_domain_limit_templates(): max_value = global_params["deflt_domain_{0}_limit".format(name)] models.DomainObjectLimit.objects.create( domain=instance, name=name, max_value=max_value)
def __init__(self): param_tools.apply_to_django_settings() self.global_params = dict(param_tools.get_global_parameters("core")) self.server_uri = self._setting("AUTH_LDAP_SERVER_URI", "ldap://localhost") self.pwd_attr = self._setting("LDAP_PASSWORD_ATTR", "userPassword") self.ldap_ad = self._setting("LDAP_ACTIVE_DIRECTORY", False) self.conn = None self.user_filter = self._setting("LDAP_USER_FILTER", "")
def create_domain_limits(sender, instance, **kwargs): """Create limits for new domain.""" if not kwargs.get("created"): return global_params = dict(param_tools.get_global_parameters("limits")) for name, definition in utils.get_domain_limit_templates(): max_value = global_params["deflt_domain_{0}_limit".format(name)] models.DomainObjectLimit.objects.create( domain=instance, name=name, max_value=max_value)
def __init__(self): param_tools.apply_to_django_settings() self.global_params = dict(param_tools.get_global_parameters("core")) self.server_uri = self._setting( "AUTH_LDAP_SERVER_URI", "ldap://localhost" ) self.pwd_attr = self._setting("LDAP_PASSWORD_ATTR", "userPassword") self.ldap_ad = self._setting("LDAP_ACTIVE_DIRECTORY", False) self.conn = None self.user_filter = self._setting("LDAP_USER_FILTER", "")
def handle(self, *args, **options): Amavis().load() if options["debug"]: import logging log = logging.getLogger("django.db.backends") log.setLevel(logging.DEBUG) log.addHandler(logging.StreamHandler()) self.verbose = options["verbose"] conf = dict(param_tools.get_global_parameters("modoboa_amavis")) flags = ["D"] if conf["released_msgs_cleanup"]: flags += ["R"] self.__vprint("Deleting marked messages...") ids = Msgrcpt.objects.filter(rs__in=flags).values("mail_id").distinct() for msg in Msgs.objects.filter(mail_id__in=ids): if not msg.msgrcpt_set.exclude(rs__in=flags).count(): msg.delete() self.__vprint("Deleting messages older than {} days...".format( conf["max_messages_age"])) limit = int(time.time()) - (conf["max_messages_age"] * 24 * 3600) # Delete older messages in batches. # This would avoid consuming too much RAM when # having to delete many thousands of messages # leading to process OOM kill or soft crash. res = Msgs.objects.filter(time_num__lt=limit)[:5000] while res.count() != 0: for item in res: item.delete() res = Msgs.objects.filter(time_num__lt=limit)[:5000] self.__vprint("Deleting unreferenced e-mail addresses...") # Delete unreferenced email addresses in batches. # This would avoid consuming too much RAM when # having to delete many thousands of messages # leading to process OOM kill or soft crash. res = Maddr.objects.annotate(msgs_count=Count("msgs"), msgrcpt_count=Count("msgrcpt")).filter( msgs_count=0, msgrcpt_count=0)[:100000] while res.count() != 0: for item in res: item.delete() res = Maddr.objects.annotate( msgs_count=Count("msgs"), msgrcpt_count=Count("msgrcpt")).filter( msgs_count=0, msgrcpt_count=0)[:100000] self.__vprint("Done.")
def handle(self, *args, **options): """Command entry point.""" localconfig = models.LocalConfig.objects.first() if not localconfig.need_dovecot_update: return config = dict(param_tools.get_global_parameters("core")) condition = (config["authentication_type"] == "ldap" and config["ldap_dovecot_sync"]) if condition: lib.update_dovecot_config_file(config) localconfig.need_dovecot_update = False localconfig.save(update_fields=["need_dovecot_update"])
def __init__(self): conf = dict(param_tools.get_global_parameters("modoboa_amavis")) try: if conf["am_pdp_mode"] == "inet": self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((conf["am_pdp_host"], conf["am_pdp_port"])) else: self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(conf["am_pdp_socket"]) except socket.error as err: raise InternalError(_("Connection to amavis failed: %s" % str(err)))
def __init__(self, user, *args, **kwargs): """Constructor.""" super(LearningRecipientForm, self).__init__(*args, **kwargs) choices = [] if user.role == "SuperAdmins": choices.append(("global", _("Global database"))) conf = dict(param_tools.get_global_parameters("modoboa_amavis")) if conf["domain_level_learning"]: choices.append(("domain", _("Domain's database"))) if conf["user_level_learning"]: choices.append(("user", _("User's database"))) self.fields["recipient"].choices = choices
def send_mail(request, form, posturl=None): """Email verification and sending. If the form does not present any error, a new MIME message is constructed. Then, a connection is established with the defined SMTP server and the message is finally sent. :param request: a Request object :param posturl: the url to post the message form to :return: a 2-uple (True|False, HttpResponse) """ if not form.is_valid(): editormode = request.user.parameters.get_value("editor") listing = render_to_string( "modoboa_webmail/compose.html", { "form": form, "noerrors": True, "body": form.cleaned_data.get("body", "").strip(), "posturl": posturl }, request) return False, { "status": "ko", "listing": listing, "editor": editormode } msg = form.to_msg(request) conf = dict(param_tools.get_global_parameters("modoboa_webmail")) options = {"host": conf["smtp_server"], "port": conf["smtp_port"]} if conf["smtp_secured_mode"] == "ssl": options.update({"use_ssl": True}) elif conf["smtp_secured_mode"] == "starttls": options.update({"use_tls": True}) if conf["smtp_authentication"]: options.update({ "username": request.user.username, "password": get_password(request) }) try: with mail.get_connection(**options) as connection: msg.connection = connection msg.send() except Exception as inst: raise WebmailInternalError(str(inst)) # Copy message to sent folder sentfolder = request.user.parameters.get_value("sent_folder") get_imapconnector(request).push_mail(sentfolder, msg.message()) clean_attachments(request.session["compose_mail"]["attachments"]) del request.session["compose_mail"] return True, {}
def sync_ldap_account(sender, instance, created, **kwargs): """Create/modify a new LDAP account if needed.""" config = dict(param_tools.get_global_parameters("core")) if not config["ldap_enable_sync"]: return if created: return if instance.role != "SimpleUsers": return update_fields = kwargs.get("update_fields") if update_fields and "last_login" in update_fields: return lib.update_ldap_account(instance, config)
def index(request): """Default view.""" check_learning_rcpt = "false" conf = dict(param_tools.get_global_parameters("modoboa_amavis")) if conf["manual_learning"]: if request.user.role != "SimpleUsers": if conf["user_level_learning"] or conf["domain_level_learning"]: check_learning_rcpt = "true" context = { "selection": "quarantine", "check_learning_rcpt": check_learning_rcpt } return render(request, "modoboa_amavis/index.html", context)
def setUp(self): super().setUp() self.set_global_parameters({ "ldap_enable_import": True, "ldap_server_port": settings.LDAP_SERVER_PORT, "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", "ldap_sync_bind_password": "******", "ldap_import_search_base": "ou=users,dc=example,dc=com", "ldap_import_search_filter": "(objectClass=person)", "ldap_groups_search_base": "ou=groups,dc=example,dc=com", "ldap_admin_groups": "admins", }, app="core") self.config = dict(param_tools.get_global_parameters("core")) self.conn = lib.get_connection(self.config)
def setUp(self): super(LDAPSyncTestCase, self).setUp() self.set_global_parameters({ "ldap_enable_sync": True, "ldap_server_port": 3389, "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", "ldap_sync_bind_password": "******", "ldap_sync_account_dn_template": ( "cn=%(user)s,ou=users,dc=example,dc=com"), }, app="core") self.config = dict(param_tools.get_global_parameters("core")) self.conn = lib.get_connection(self.config) self.username = "******" self.dn = self.config["ldap_sync_account_dn_template"] % { "user": self.username}
def create(self, validated_data): """Set permissions.""" params = dict(param_tools.get_global_parameters("admin")) domain = models.Domain(**validated_data) condition = (params["default_domain_message_limit"] is not None and "message_limit" not in validated_data) if condition: domain.message_limit = params["default_domain_message_limit"] creator = self.context["request"].user core_signals.can_create_object.send(sender=self.__class__, context=creator, klass=models.Domain, instance=domain) domain.save(creator=creator) return domain
def update_rspamd_dkim_maps(sender, domains, **kwargs): """Update config maps.""" qset = admin_models.Domain.objects.filter(enable_dkim=True) config = dict(param_tools.get_global_parameters("modoboa_rspamd")) if not config["path_map_path"] or not config["selector_map_path"]: return dkim_path_map = open(config["path_map_path"], "w") dkim_selector_map = open(config["selector_map_path"], "w") for domain in qset: dkim_path_map.write("{} {}\n".format(domain.name, domain.dkim_private_key_path)) dkim_selector_map.write("{} {}\n".format(domain.name, domain.dkim_key_selector)) dkim_path_map.close() dkim_selector_map.close()
def setUp(self): super().setUp() self.set_global_parameters({ "ldap_enable_sync": True, "ldap_server_port": settings.LDAP_SERVER_PORT, "ldap_sync_bind_dn": "cn=admin,dc=example,dc=com", "ldap_sync_bind_password": "******", "ldap_sync_account_dn_template": ( "cn=%(user)s,ou=users,dc=example,dc=com"), }, app="core") self.config = dict(param_tools.get_global_parameters("core")) self.conn = lib.get_connection(self.config) self.username = "******" self.dn = self.config["ldap_sync_account_dn_template"] % { "user": self.username}
def create_user_limits(sender, instance, **kwargs): """Create limits for new user.""" if not kwargs.get("created"): return request = lib_signals.get_request() creator = request.user if request else None global_params = dict(param_tools.get_global_parameters("limits")) for name, definition in utils.get_user_limit_templates(): ct = ContentType.objects.get_by_natural_key( *definition["content_type"].split(".")) max_value = 0 # creator can be None if user was created by a factory if not creator or creator.is_superuser: max_value = global_params["deflt_user_{0}_limit".format(name)] models.UserObjectLimit.objects.create( user=instance, name=name, content_type=ct, max_value=max_value)
def handle(self, *args, **options): """Entry point.""" load_admin_settings() ImapMigration().load() conf = dict( param_tools.get_global_parameters("modoboa_imap_migration")) context = { "imap_server_address": conf["server_address"], "imap_server_port": conf["server_port"], "imap_server_secured": conf["secured"], "migrations": Migration.objects.select_related("mailbox").all(), } with open(options["output"], "w") as fpo: content = render_to_string( "modoboa_imap_migration/offlineimap.conf", context) fpo.write(content)
def create_user_limits(sender, instance, **kwargs): """Create limits for new user.""" if not kwargs.get("created"): return request = lib_signals.get_request() creator = request.user if request else None global_params = dict(param_tools.get_global_parameters("limits")) for name, definition in utils.get_user_limit_templates(): ct = ContentType.objects.get_by_natural_key( *definition["content_type"].split(".")) max_value = 0 # creator can be None if user was created by a factory if not creator or creator.is_superuser: max_value = global_params["deflt_user_{0}_limit".format(name)] models.UserObjectLimit.objects.create( user=instance, name=name, content_type=ct, max_value=max_value)
def manual_learning_enabled(user): """Check if manual learning is enabled or not. Also check for :kw:`user` if necessary. :return: True if learning is enabled, False otherwise. """ conf = dict(param_tools.get_global_parameters("modoboa_amavis")) if not conf["manual_learning"]: return False if user.role != "SuperAdmins": if user.has_perm("admin.view_domains"): manual_learning = (conf["domain_level_learning"] or conf["user_level_learning"]) else: manual_learning = conf["user_level_learning"] return manual_learning return True
def login(self, user, password): conf = dict(param_tools.get_global_parameters("modoboa_sievefilters")) self.msc = managesieve.Client( conf["server"], conf["port"], debug=False) authmech = conf["authentication_mech"] if authmech == "AUTO": authmech = None try: ret = self.msc.connect(user, password, starttls=conf["starttls"], authmech=authmech) except managesieve.Error: ret = False if not ret: return False, _( "Connection to MANAGESIEVE server failed, check your " "configuration" ) return True, None
def __init__(self, user, *args, **kwargs): self.mb = kwargs.pop("instance", None) self.user = user super().__init__(*args, **kwargs) self.field_widths = { "quota": 3 } params = dict(param_tools.get_global_parameters("admin")) if self.mb is not None: self.fields["email"].required = True qset = self.mb.aliasrecipient_set.filter(alias__internal=False) for cpt, ralias in enumerate(qset): name = "aliases_{}".format(cpt + 1) self._create_field( lib_fields.UTF8AndEmptyUserEmailField, name, ralias.alias.address) for cpt, saddress in enumerate(self.mb.senderaddress_set.all()): name = "senderaddress_{}".format(cpt + 1) self._create_field( lib_fields.UTF8AndEmptyUserEmailField, name, saddress.address) self.fields["email"].initial = self.mb.full_address self.fields["quota_act"].initial = self.mb.use_domain_quota if not self.mb.use_domain_quota and self.mb.quota: self.fields["quota"].initial = self.mb.quota if self.mb.message_limit: self.fields["message_limit"].initial = self.mb.message_limit self.fields["create_alias_with_old_address"].initial = ( params["create_alias_on_mbox_rename"] ) else: del self.fields["create_alias_with_old_address"] self.fields["quota_act"].initial = True if params["default_mailbox_message_limit"] is not None: self.fields["message_limit"].initial = ( params["default_mailbox_message_limit"]) if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict( args[0], "aliases", lib_fields.UTF8AndEmptyUserEmailField) self._load_from_qdict( args[0], "senderaddress", lib_fields.UTF8AndEmptyUserEmailField)
def handle(self, *args, **options): """Entry point.""" load_admin_settings() ImapMigration().load() conf = dict( param_tools.get_global_parameters("modoboa_imap_migration")) context = { "imap_create_folders": conf["create_folders"], "imap_folder_filter_exclude": conf["folder_filter_exclude"], "imap_folder_filter_include": ", ".join( "'{0}'".format(w) for w in conf["folder_filter_include"].split(",")), "migrations": Migration.objects.select_related( "provider", "mailbox__domain"), } with open(options["output"], "w") as fpo: content = render_to_string( "modoboa_imap_migration/offlineimap.conf", context) fpo.write(content)
def __init__(self, user, *args, **kwargs): self.oldname = None if "instance" in kwargs: self.old_dkim_key_length = kwargs["instance"].dkim_key_length self.oldname = kwargs["instance"].name super(DomainFormGeneral, self).__init__(*args, **kwargs) params = dict(param_tools.get_global_parameters("admin")) self.fields["quota"].initial = params["default_domain_quota"] self.fields["default_mailbox_quota"].initial = ( params["default_mailbox_quota"]) self.fields["type"].choices = constants.DOMAIN_TYPES self.field_widths = { "quota": 3, "default_mailbox_quota": 3 } self.user = user if len(args) and isinstance(args[0], QueryDict): self._load_from_qdict(args[0], "aliases", DomainNameField) elif "instance" in kwargs: d = kwargs["instance"] for pos, dalias in enumerate(d.domainalias_set.all()): name = "aliases_%d" % (pos + 1) self._create_field(forms.CharField, name, dalias.name, 3)
def __init__(self, *args, **kwargs): """Load LDAP settings.""" param_tools.apply_to_django_settings() super(LDAPBackend, self).__init__(*args, **kwargs) self.global_params = dict( param_tools.get_global_parameters("core"))
def credentials(account, password): """Generate a PDF document containing account credentials.""" def page_template(canvas, doc): canvas.setTitle(_("Personal account information")) canvas.setAuthor(account.fullname) canvas.setCreator("Modoboa") footer = [Paragraph(_("Powered by Modoboa - Mail hosting made simple"), styles["Footer"])] Frame(0, 0, 21 * cm, 2 * cm).addFromList(footer, canvas) conf = dict( param_tools.get_global_parameters("modoboa_pdfcredentials")) filename = lib.get_creds_filename(account) buff = BytesIO() doc = SimpleDocTemplate(buff, pagesize=A4) story = [] story.append(resized_image(lib.get_document_logo(), 8*cm)) story.append(Spacer(1, 1 * cm)) story.append(Paragraph(conf["title"], styles["Title"])) story.append(Spacer(1, 1 * cm)) story.append(Paragraph(_(""" Dear %s, this document contains the credentials you will need to connect to Modoboa. Learn the content and destroy the document as soon as possible. """) % account.fullname, styles["Normal"])) story.append(Spacer(1, 0.2 * cm)) story.append(Paragraph(_("Web panel:"), styles["h3"])) data = [ ["URL", conf["webpanel_url"]], [_("Username"), account.username], [_("Password"), password] ] table = Table(data) table.setStyle(TableStyle([ ('TEXTCOLOR', (1, 0), (1, 0), colors.blue), ('GRID', (0, 0), (-1, -1), 1, colors.black), ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey), ])) story.append(table) story.append(Spacer(1, 0.5 * cm)) story.append(Paragraph(_(""" Here you can view your emails anytime online, create filters or manage your contacts. """), styles["Normal"])) story.append(Spacer(1, 0.2 * cm)) story.append(Paragraph( _("Please change your password!"), styles["Warning"])) if conf["include_connection_settings"]: story.append(Spacer(1, 1 * cm)) story.append(Paragraph( _("PC/Tablet/Smartphone configuration:"), styles["h3"])) story.append(Spacer(1, 0.2 * cm)) data = [ [_("SMTP server address"), conf["smtp_server_address"]], [_("SMTP server port"), conf["smtp_server_port"]], [_("SMTP connection security"), conf["smtp_connection_security"]], [_("IMAP server address"), conf["imap_server_address"]], [_("IMAP server port"), conf["imap_server_port"]], [_("IMAP connection security"), conf["imap_connection_security"]], ] table = Table(data) table.setStyle(TableStyle([ ('GRID', (0, 0), (-1, -1), 1, colors.black), ('BACKGROUND', (0, 0), (0, -1), colors.lightgrey), ])) story.append(table) story.append(Spacer(1, 0.5 * cm)) story.append(Paragraph( _("Use those settings for your computer, tablet or phone."), styles["Normal"]) ) if conf["custom_message"]: story.append(Spacer(1, 2 * cm)) story.append(Paragraph(conf["custom_message"], styles["Greeting"])) doc.build(story, onFirstPage=page_template, onLaterPages=page_template) length = len(buff.getvalue()) buff.seek(0) lib.crypt_and_save_to_file(buff, filename, length)