def __init__(self, user=None, password=None): self.__hdelimiter = None self.quota_usage = -1 self.criterions = [] self.address = parameters.get_admin("IMAP_SERVER") self.port = int(parameters.get_admin("IMAP_PORT")) self.login(user, password)
def handle(self, *args, **options): Stats().load() if options["logfile"] is None: options["logfile"] = parameters.get_admin("LOGFILE", app="stats") p = LogParser(options, parameters.get_admin("RRD_ROOTDIR", app="stats")) p.process()
def delete(self, fromuser, keepdir=False): from modoboa.lib.permissions import \ ungrant_access_to_object, ungrant_access_to_objects if self.domainalias_set.count(): events.raiseEvent("DomainAliasDeleted", self.domainalias_set.all()) ungrant_access_to_objects(self.domainalias_set.all()) if self.mailbox_set.count(): Quota.objects.filter(username__contains='@%s' % self.name).delete() events.raiseEvent("DeleteMailbox", self.mailbox_set.all()) ungrant_access_to_objects(self.mailbox_set.all()) hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm == "yes" and not keepdir: for mb in self.mailbox_set.all(): mb.delete_dir() if self.alias_set.count(): events.raiseEvent("MailboxAliasDelete", self.alias_set.all()) ungrant_access_to_objects(self.alias_set.all()) if parameters.get_admin("AUTO_ACCOUNT_REMOVAL") == "yes": for account in User.objects.filter( mailbox__domain__name=self.name): account.delete(fromuser, keepdir) events.raiseEvent("DeleteDomain", self) ungrant_access_to_object(self) super(Domain, self).delete()
def __init__(self, user, recipient_db): """Constructor.""" self._sa_is_local = parameters.get_admin("SA_IS_LOCAL") self._default_username = parameters.get_admin("DEFAULT_USER") self._recipient_db = recipient_db self._setup_cache = {} self._username_cache = [] if user.role == "SimpleUsers": user_level_learning = parameters.get_admin("USER_LEVEL_LEARNING") if user_level_learning == "yes": self._username = user.email else: self._username = None self.error = None if self._sa_is_local == "yes": self._learn_cmd = "sa-learn --{0} --no-sync -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [0] else: self._learn_cmd = "spamc -d {0} -p {1}".format( parameters.get_admin("SPAMD_ADDRESS"), parameters.get_admin("SPAMD_PORT")) self._learn_cmd += " -L {0} -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [5, 6]
def handle(self, *args, **options): Stats().load() if options["logfile"] is None: options["logfile"] = parameters.get_admin("LOGFILE", app="stats") p = LogParser(options, parameters.get_admin("RRD_ROOTDIR", app="stats")) p.process() db.close_connection()
def _domains(request): sort_order, sort_dir = get_sort_order(request.GET, "name") filters = dict( (flt, request.GET.get(flt, None)) for flt in ['domfilter', 'searchquery'] + events.raiseQueryEvent('ExtraDomainFilters') ) request.session['domains_filters'] = filters domainlist = get_domains(request.user, **filters) if sort_order == 'name': domainlist = sorted( domainlist, key=lambda d: getattr(d, sort_order), reverse=sort_dir == '-' ) else: domainlist = sorted(domainlist, key=lambda d: d.tags[0], reverse=sort_dir == '-') context = { "handle_mailboxes": parameters.get_admin( "HANDLE_MAILBOXES", raise_error=False), "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL") } page = get_listing_page(domainlist, request.GET.get("page", 1)) if page is None: context["length"] = 0 else: context["rows"] = _render_to_string( request, "admin/domains_table.html", { 'domains': page.object_list, } ) context["pages"] = [page.number] return render_to_json_response(context)
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. """ hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return None if self.__mail_home is None: curuser = pwd.getpwuid(os.getuid()).pw_name mbowner = parameters.get_admin("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( _("Failed to retrieve mailbox location (%s)" % output)) self.__mail_home = output.strip() return self.__mail_home
def extra_static_content(user): if parameters.get_admin("USER_CAN_RELEASE") == "yes" \ or user.group == "SimpleUsers": return [] tpl = Template("""<script type="text/javascript"> $(document).ready(function() { var poller = new Poller("{{ url }}", { interval: {{ interval }}, success_cb: function(data) { var $link = $("#nbrequests"); if (data.requests > 0) { $link.html(data.requests + " " + "{{ text }}"); $link.parent().removeClass('hidden'); } else { $link.parent().addClass('hidden'); } } }); $(document).bind('domform_init', function() { activate_widget.call($('#id_spam_subject_tag2_act')); }); }); </script>""") url = reverse("modoboa.extensions.amavis.views.nbrequests") interval = int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000 return [ tpl.render( Context( dict(url=url, interval=interval, text=_("pending requests")))) ]
def _domains(request): sort_order, sort_dir = get_sort_order(request.GET, "name") filters = dict((flt, request.GET.get(flt, None)) for flt in ['domfilter', 'searchquery'] + events.raiseQueryEvent('ExtraDomainFilters')) request.session['domains_filters'] = filters domainlist = get_domains(request.user, **filters) if sort_order == 'name': domainlist = sorted(domainlist, key=lambda d: getattr(d, sort_order), reverse=sort_dir == '-') else: domainlist = sorted(domainlist, key=lambda d: d.tags[0], reverse=sort_dir == '-') context = { "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", raise_error=False), "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL") } page = get_listing_page(domainlist, request.GET.get("page", 1)) if page is None: context["length"] = 0 else: context["rows"] = _render_to_string(request, "admin/domains_table.html", { 'domains': page.object_list, }) context["pages"] = [page.number] return render_to_json_response(context)
def extra_static_content(user): if user.group == "SimpleUsers": return [] tpl = Template("""<script type="text/javascript"> $(document).ready(function() { {% if user_can_release == "no" %}var poller = new Poller("{{ url }}", { interval: {{ interval }}, success_cb: function(data) { var $link = $("#nbrequests"); if (data.requests > 0) { $link.html(data.requests + " " + "{{ text }}"); $link.parent().removeClass('hidden'); } else { $link.parent().addClass('hidden'); } } });{% endif %} $(document).bind('domform_init', function() { activate_widget.call($('#id_spam_subject_tag2_act')); }); }); </script>""") return [tpl.render( Context(dict( url=reverse("modoboa.extensions.amavis.views.nbrequests"), interval=int(parameters.get_admin("CHECK_REQUESTS_INTERVAL")) * 1000, text=_("pending requests"), user_can_release=parameters.get_admin("USER_CAN_RELEASE") )) )]
def delete(self, fromuser, keepdir=False): from modoboa.lib.permissions import \ ungrant_access_to_object, ungrant_access_to_objects if self.domainalias_set.count(): events.raiseEvent("DomainAliasDeleted", self.domainalias_set.all()) ungrant_access_to_objects(self.domainalias_set.all()) if self.mailbox_set.count(): Quota.objects.filter(username__contains='@%s' % self.name).delete() events.raiseEvent("DeleteMailbox", self.mailbox_set.all()) ungrant_access_to_objects(self.mailbox_set.all()) hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm == "yes" and not keepdir: for mb in self.mailbox_set.all(): MailboxOperation.objects.create( type='delete', argument=mb.mail_home ) if self.alias_set.count(): events.raiseEvent("MailboxAliasDelete", self.alias_set.all()) ungrant_access_to_objects(self.alias_set.all()) if parameters.get_admin("AUTO_ACCOUNT_REMOVAL") == "yes": for account in User.objects.filter(mailbox__domain__name=self.name): account.delete(fromuser, keepdir) events.raiseEvent("DeleteDomain", self) ungrant_access_to_object(self) super(Domain, self).delete()
def handle(self, *args, **options): if options["debug"]: import logging l = logging.getLogger("django.db.backends") l.setLevel(logging.DEBUG) l.addHandler(logging.StreamHandler()) self.verbose = options["verbose"] max_messages_age = int( parameters.get_admin("MAX_MESSAGES_AGE", app="amavis")) flags = ['D'] if parameters.get_admin("RELEASED_MSGS_CLEANUP", app="amavis") == "yes": 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..." % max_messages_age) limit = int(time.time()) - (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.""" self._sa_is_local = parameters.get_admin("SA_IS_LOCAL") self._default_username = parameters.get_admin("DEFAULT_USER") self._recipient_db = recipient_db self._setup_cache = {} self._username_cache = [] if user.group == "SimpleUsers": user_level_learning = parameters.get_admin("USER_LEVEL_LEARNING") if user_level_learning == "yes": self._username = user.email else: self._username = None self.error = None if self._sa_is_local == "yes": self._learn_cmd = "sa-learn --{0} --no-sync -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [0] else: self._learn_cmd = "spamc -d {0} -p {1}".format( parameters.get_admin("SPAMD_ADDRESS"), parameters.get_admin("SPAMD_PORT") ) self._learn_cmd += " -L {0} -u {1}" self._learn_cmd_kwargs = {} self._expected_exit_codes = [5, 6]
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. """ hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return None if self.__mail_home is None: curuser = pwd.getpwuid(os.getuid()).pw_name mbowner = parameters.get_admin("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( _("Failed to retrieve mailbox location (%s)" % output)) self.__mail_home = output.strip() return self.__mail_home
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"] max_messages_age = int(parameters.get_admin("MAX_MESSAGES_AGE", app="amavis")) flags = ['D'] if parameters.get_admin("RELEASED_MSGS_CLEANUP", app="amavis") == "yes": 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..." % max_messages_age) limit = int(time.time()) - (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 _find_user_dn(self, user): sbase = parameters.get_admin("LDAP_SEARCH_BASE", app="admin") sfilter = parameters.get_admin("LDAP_SEARCH_FILTER", app="admin") sfilter = sfilter % {"user": user} res = self.conn.search_s(sbase, ldap.SCOPE_SUBTREE, sfilter) try: dn = res[0][0] except IndexError: return None return dn
def _find_user_dn(self, user): sbase = parameters.get_admin("LDAP_SEARCH_BASE", app="core") sfilter = parameters.get_admin("LDAP_SEARCH_FILTER", app="core") sfilter = sfilter % {"user": user} res = self.conn.search_s(sbase, ldap.SCOPE_SUBTREE, sfilter) try: dn = res[0][0] except IndexError: return None return dn
def domains(request, tplname="admin/domains.html"): if not request.user.has_perm("admin.view_domains"): if request.user.has_perm("admin.view_mailboxes"): return HttpResponseRedirect(reverse("admin:identity_list")) return HttpResponseRedirect(reverse("core:user_index")) return render( request, tplname, { "selection": "domains", "enable_mx_checks": parameters.get_admin("ENABLE_MX_CHECKS"), "enable_dnsbl_checks": parameters.get_admin("ENABLE_DNSBL_CHECKS") })
def delete_dir(self): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return if not os.path.exists(self.mail_home): return code, output = exec_cmd( "rm -r %s" % self.mail_home, sudo_user=parameters.get_admin("MAILBOXES_OWNER")) if code: raise AdminError(_("Failed to remove mailbox: %s" % output))
def delete_dir(self): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return if not os.path.exists(self.mail_home): return code, output = exec_cmd( "rm -r %s" % self.mail_home, sudo_user=parameters.get_admin("MAILBOXES_OWNER") ) if code: raise AdminError(_("Failed to remove mailbox: %s" % output))
def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return self.__mail_home = None if not os.path.exists(old_mail_home): return code, output = exec_cmd( "mv %s %s" % (old_mail_home, self.mail_home), sudo_user=parameters.get_admin("MAILBOXES_OWNER")) if code: raise AdminError(_("Failed to rename mailbox: %s" % output))
def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return self.__mail_home = None if not os.path.exists(old_mail_home): return code, output = exec_cmd( "mv %s %s" % (old_mail_home, self.mail_home), sudo_user=parameters.get_admin("MAILBOXES_OWNER") ) if code: raise AdminError(_("Failed to rename mailbox: %s" % output))
def __init__(self): mode = parameters.get_admin("AM_PDP_MODE") try: if mode == "inet": host = parameters.get_admin('AM_PDP_HOST') port = parameters.get_admin('AM_PDP_PORT') self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, int(port))) else: path = parameters.get_admin('AM_PDP_SOCKET') self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(path) except socket.error, err: raise ModoboaException(_("Connection to amavis failed: %s" % str(err)))
def mail_home(self): """ """ hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return None if self.__mail_home is None: code, output = exec_cmd("doveadm user %s -f home" % self.full_address, sudo_user=parameters.get_admin("MAILBOXES_OWNER")) if code: raise AdminError(_("Failed to retrieve mailbox location (%s)" % output)) self.__mail_home = output.strip() return self.__mail_home
def index(request): """Default view.""" check_learning_rcpt = "false" if parameters.get_admin("MANUAL_LEARNING") == "yes": if request.user.group != "SimpleUsers": user_level_learning = parameters.get_admin( "USER_LEVEL_LEARNING") == "yes" domain_level_learning = parameters.get_admin( "DOMAIN_LEVEL_LEARNING") == "yes" if user_level_learning or domain_level_learning: check_learning_rcpt = "true" return render( request, "amavis/index.html", dict(selection="quarantine", check_learning_rcpt=check_learning_rcpt))
def index(request): """Default view.""" check_learning_rcpt = "false" if parameters.get_admin("MANUAL_LEARNING") == "yes": if request.user.group != "SimpleUsers": user_level_learning = parameters.get_admin( "USER_LEVEL_LEARNING") == "yes" domain_level_learning = parameters.get_admin( "DOMAIN_LEVEL_LEARNING") == "yes" if user_level_learning or domain_level_learning: check_learning_rcpt = "true" return render(request, "amavis/index.html", dict( selection="quarantine", check_learning_rcpt=check_learning_rcpt ))
def __init__(self, user, *args, **kwargs): """Constructor.""" super(LearningRecipientForm, self).__init__(*args, **kwargs) choices = [] if user.group == "SuperAdmins": choices.append(("global", _("Global database"))) domain_level_learning = parameters.get_admin( "DOMAIN_LEVEL_LEARNING") == "yes" user_level_learning = parameters.get_admin( "USER_LEVEL_LEARNING") == "yes" if domain_level_learning: choices.append(("domain", _("Domain's database"))) if user_level_learning: choices.append(("user", _("User's database"))) self.fields["recipient"].choices = choices
def __init__(self): mode = parameters.get_admin("AM_PDP_MODE") try: if mode == "inet": host = parameters.get_admin('AM_PDP_HOST') port = parameters.get_admin('AM_PDP_PORT') self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, int(port))) else: path = parameters.get_admin('AM_PDP_SOCKET') self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.sock.connect(path) except socket.error, err: raise InternalError(_("Connection to amavis failed: %s" % str(err)))
def _identities(request): filters = dict((fname, request.GET.get(fname, None)) for fname in ['searchquery', 'idtfilter', 'grpfilter']) request.session['identities_filters'] = filters idents_list = get_identities(request.user, **filters) sort_order, sort_dir = get_sort_order(request.GET, "identity", ["identity", "name_or_rcpt", "tags"]) if sort_order in ["identity", "name_or_rcpt"]: objects = sorted(idents_list, key=lambda o: getattr(o, sort_order), reverse=sort_dir == '-') else: objects = sorted(idents_list, key=lambda o: o.tags[0], reverse=sort_dir == '-') context = { "handle_mailboxes": parameters.get_admin( "HANDLE_MAILBOXES", raise_error=False) } page = get_listing_page(objects, request.GET.get("page", 1)) if page is None: context["length"] = 0 else: context["headers"] = _render_to_string( request, "admin/identity_headers.html", {}) context["rows"] = _render_to_string( request, "admin/identities_table.html", { "identities": page.object_list } ) context["pages"] = [page.number] return render_to_json_response(context)
def login(self, user, passwd): """Custom login method We connect to the server, issue a LOGIN command. If successfull, we try to record a eventuel CAPABILITY untagged response. Otherwise, we issue the command. :param user: username :param passwd: password """ import socket if isinstance(user, unicode): user = user.encode("utf-8") if isinstance(passwd, unicode): passwd = passwd.encode("utf-8") try: secured = parameters.get_admin("IMAP_SECURED") if secured == "yes": self.m = imaplib.IMAP4_SSL(self.address, self.port) else: self.m = imaplib.IMAP4(self.address, self.port) except (socket.error, imaplib.IMAP4.error, ssl.SSLError) as error: raise ImapError(_("Connection to IMAP server failed: %s" % error)) data = self._cmd("LOGIN", user, passwd) self.m.state = "AUTH" if "CAPABILITY" in self.m.untagged_responses: self.capabilities = \ self.m.untagged_responses.pop('CAPABILITY')[0].split() else: data = self._cmd("CAPABILITY") self.capabilities = data[0].split()
def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return MailboxOperation.objects.create( mailbox=self, type='rename', argument=old_mail_home )
def topredirection(request): """Simple view to redirect the request when no application is specified. The default "top redirection" can be specified in the *Admin > Settings* panel. It is the application that will be launched. Those not allowed to access the application will be redirected to their preferences page. This feature only applies to simple users. :param request: a Request object """ from modoboa.lib import parameters from modoboa.core.extensions import exts_pool if request.user.group == 'SimpleUsers': topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core") if topredir != "user": infos = exts_pool.get_extension_infos(topredir) path = infos["url"] if infos["url"] else infos["name"] else: path = reverse("core:user_index") else: # FIXME path = reverse("admin:domain_list") return HttpResponseRedirect(path)
def send_autoreply(sender, mailbox, armessage): if armessage.fromdate > timezone.now(): return if armessage.untildate is not None \ and armessage.untildate < timezone.now(): armessage.enabled = False armessage.save() return try: lastar = ARhistoric.objects.get(armessage=armessage.id, sender=sender) PostfixAutoreply().load() timeout = parameters.get_admin("AUTOREPLIES_TIMEOUT", app="postfix_autoreply") delta = datetime.timedelta(seconds=int(timeout)) now = timezone.make_aware(datetime.datetime.now(), timezone.get_default_timezone()) if lastar.last_sent + delta > now: sys.exit(0) except ARhistoric.DoesNotExist: lastar = ARhistoric() lastar.armessage = armessage lastar.sender = sender sendmail_simple(mailbox.user.encoded_address, sender, armessage.subject, armessage.content.encode('utf-8')) lastar.last_sent = datetime.datetime.now() lastar.save()
def account_auto_created(user): from modoboa.core.models import User from modoboa.lib.permissions import grant_access_to_object from .lib import check_if_domain_exists if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no": return localpart, domname = split_mailbox(user.username) if user.group != 'SimpleUsers' and domname is None: return sadmins = User.objects.filter(is_superuser=True) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: label = check_if_domain_exists( domname, [(DomainAlias, _('domain alias'))]) if label is not None: return domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox( address=localpart, domain=domain, user=user, use_domain_quota=True ) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def load_from_master_cf(self): """Load services from the master.cf file. Parse the configuration file to update the service table. New entries are saved and outdated ones (ie. present in the database but not in the file) are removed. """ with open(parameters.get_admin('MASTER_CF_PATH')) as fp: content = fp.read() services = [] for line in content.split('\n'): if not line or line.startswith('#'): continue parts = line.strip().split() if len(parts) != 8: continue if parts[7] != 'smtp': continue srv, created = self.get_or_create(name=parts[0]) services.append(parts[0]) to_delete = [] for service in self.all(): if service.name not in services: to_delete.append(service.name) Service.objects.filter(name__in=to_delete).delete()
def topredirection(request): """Simple view to redirect the request when no application is specified The default "top redirection" can be specified in the *Admin > Settings* panel. It is the application that will be launched by default. Users that are not allowed to access this application will be redirected to the "User preferences" application. :param request: a Request object """ from modoboa.lib import parameters from modoboa.core.extensions import exts_pool topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core") if not topredir in ["core"]: infos = exts_pool.get_extension_infos(topredir) path = infos["url"] if infos["url"] else infos["name"] else: path = "admin" # topredir if topredir in ["core", "stats"] and \ request.user.belongs_to_group('SimpleUsers'): path = "userprefs" return HttpResponseRedirect(path)
def attachments(request, tplname="webmail/attachments.html"): if request.method == "POST": csuploader = AttachmentUploadHandler() request.upload_handlers.insert(0, csuploader) error = None form = AttachmentForm(request.POST, request.FILES) if form.is_valid(): try: fobj = request.FILES["attachment"] tmpname = save_attachment(fobj) request.session["compose_mail"]["attachments"] \ += [{"fname": str(fobj), "content-type": fobj.content_type, "size": fobj.size, "tmpname": os.path.basename(tmpname)}] request.session.modified = True return render( request, "webmail/upload_done.html", { "status": "ok", "fname": request.FILES["attachment"], "tmpname": os.path.basename(tmpname) }) except WebmailError, inst: error = _("Failed to save attachment: ") + str(inst) if csuploader.toobig: error = _("Attachment is too big (limit: %s)" % parameters.get_admin("MAX_ATTACHMENT_SIZE")) return render(request, "webmail/upload_done.html", { "status": "ko", "error": error })
def __init__(self, user, *args, **kwargs): super(AccountFormGeneral, self).__init__(*args, **kwargs) self.fields.keyOrder = ['role', 'username', 'first_name', 'last_name', 'password1', 'password2', 'is_active'] self.fields["is_active"].label = _("Enabled") self.user = user if user.group == "DomainAdmins": self.fields["role"] = forms.CharField( label="", widget=forms.HiddenInput, required=False ) else: self.fields["role"].choices = [('', ugettext_lazy("Choose"))] self.fields["role"].choices += \ get_account_roles(user, kwargs['instance']) \ if 'instance' in kwargs else get_account_roles(user) if "instance" in kwargs: if args \ and (args[0].get("password1", "") == "" and args[0].get("password2", "") == ""): self.fields["password1"].required = False self.fields["password2"].required = False account = kwargs["instance"] self.fields["role"].initial = account.group if not account.is_local \ and parameters.get_admin("LDAP_AUTH_METHOD", app="core") == "directbind": del self.fields["password1"] del self.fields["password2"]
def account_auto_created(user): from modoboa.core.models import User from modoboa.lib.permissions import grant_access_to_object from .lib import check_if_domain_exists if parameters.get_admin("AUTO_CREATE_DOMAIN_AND_MAILBOX") == "no": return localpart, domname = split_mailbox(user.username) if user.group != 'SimpleUsers' and domname is None: return sadmins = User.objects.filter(is_superuser=True) try: domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: label = check_if_domain_exists(domname, [(DomainAlias, _('domain alias'))]) if label is not None: return domain = Domain(name=domname, enabled=True, quota=0) domain.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, domain) try: mb = Mailbox.objects.get(domain=domain, address=localpart) except Mailbox.DoesNotExist: mb = Mailbox(address=localpart, domain=domain, user=user, use_domain_quota=True) mb.set_quota(override_rules=True) mb.save(creator=sadmins[0]) for su in sadmins[1:]: grant_access_to_object(su, mb)
def rename_dir(self, old_mail_home): hm = parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) if hm is None or hm == "no": return MailboxOperation.objects.create(mailbox=self, type='rename', argument=old_mail_home)
def _identities(request): filters = dict((fname, request.GET.get(fname, None)) for fname in ['searchquery', 'idtfilter', 'grpfilter']) request.session['identities_filters'] = filters idents_list = get_identities(request.user, **filters) sort_order, sort_dir = get_sort_order(request.GET, "identity", ["identity", "name_or_rcpt", "tags"]) if sort_order in ["identity", "name_or_rcpt"]: objects = sorted(idents_list, key=lambda o: getattr(o, sort_order), reverse=sort_dir == '-') else: objects = sorted(idents_list, key=lambda o: o.tags[0], reverse=sort_dir == '-') context = { "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", raise_error=False) } page = get_listing_page(objects, request.GET.get("page", 1)) if page is None: context["length"] = 0 else: context["headers"] = _render_to_string(request, "admin/identity_headers.html", {}) context["rows"] = _render_to_string(request, "admin/identities_table.html", {"identities": page.object_list}) context["pages"] = [page.number] return render_to_json_response(context)
def attachments(request, tplname="webmail/attachments.html"): if request.method == "POST": csuploader = AttachmentUploadHandler() request.upload_handlers.insert(0, csuploader) error = None form = AttachmentForm(request.POST, request.FILES) if form.is_valid(): try: fobj = request.FILES["attachment"] tmpname = save_attachment(fobj) request.session["compose_mail"]["attachments"] \ += [{"fname" : str(fobj), "content-type" : fobj.content_type, "size" : fobj.size, "tmpname" : os.path.basename(tmpname)}] request.session.modified = True return _render(request, "webmail/upload_done.html", { "status" : "ok", "fname" : request.FILES["attachment"], "tmpname" : os.path.basename(tmpname) }) except WebmailError, inst: error = _("Failed to save attachment: ") + str(inst) if csuploader.toobig: error = _("Attachment is too big (limit: %s)" \ % parameters.get_admin("MAX_ATTACHMENT_SIZE")) return _render(request, "webmail/upload_done.html", { "status" : "ko", "error" : error })
def notify_admins_pending_requests(self): self.sender = parameters.get_admin("NOTIFICATIONS_SENDER", app="amavis") self.baseurl = self.options["baseurl"].strip("/") self.listingurl = self.baseurl \ + reverse("modoboa.extensions.amavis.views._listing") \ + "?viewrequests=1" for da in User.objects.filter(groups__name="DomainAdmins"): if not da.mailbox_set.count(): continue rcpt = da.mailbox_set.all()[0].full_address reqs = get_wrapper().get_domains_pending_requests( Domain.objects.get_for_admin(da)) if reqs.count(): self.send_pr_notification(rcpt, reqs) reqs = Msgrcpt.objects.filter(rs='p') if not reqs.count(): if self.options["verbose"]: print "No release request currently pending" return for su in User.objects.filter(is_superuser=True): if not su.mailbox_set.count(): continue rcpt = su.mailbox_set.all()[0].full_address self.send_pr_notification(rcpt, reqs)
def decrypt(ciph): obj = AES.new( parameters.get_admin("SECRET_KEY", app="admin"), AES.MODE_ECB ) ciph = base64.b64decode(ciph) clear = obj.decrypt(ciph) return clear.rstrip(' ')
def _crypt_password(self, raw_value): scheme = parameters.get_admin("PASSWORD_SCHEME") if type(raw_value) is unicode: raw_value = raw_value.encode("utf-8") if scheme == "crypt": salt = "".join(Random().sample(string.letters + string.digits, 2)) result = crypt.crypt(raw_value, salt) prefix = "{CRYPT}" elif scheme == "md5": obj = hashlib.md5(raw_value) result = obj.hexdigest() prefix = "{MD5}" # The md5crypt scheme is the only supported method that has both: # (a) a salt ("crypt" has this too), # (b) supports passwords lengths of more than 8 characters (all except # "crypt"). elif scheme == "md5crypt": # The salt may vary from 12 to 48 bits. (Using all six bytes here # with a subset of characters means we get only 35 random bits.) salt = "".join(Random().sample(string.letters + string.digits, 6)) result = md5crypt(raw_value, salt) prefix = "" # the result already has $1$ prepended to it to signify what this is elif scheme == "sha256": obj = hashlib.sha256(raw_value) result = base64.b64encode(obj.digest()) prefix = "{SHA256}" else: scheme = "plain" result = raw_value prefix = "{PLAIN}" return "%s%s" % (prefix, result)
def _generate_file(self, target): """ A user must not declare a rule for his direct admin! """ self._cfgfile = open(target, "w") self._cfgfile.write("""# Rights management file for Radicale # This file was generated by Modoboa on %s # DO NOT EDIT MANUALLY! """ % datetime.datetime.today()) allow_calendars_administration = parameters.get_admin( "ALLOW_CALENDARS_ADMINISTRATION", app="modoboa_radicale") if allow_calendars_administration == "yes": self._super_admin_rules() self._domain_admin_rules() self._generate_acr( "domain-shared-calendars", r"^(.+)@(.+)$", r"{1}/shared/.+$", comment="Access rule to domain shared calendars" ) self._generate_acr( "owners-access", r"^(.+)@(.+)$", r"{1}/user/{0}/.+$", comment="Read/Write permission for calendar owners" ) self._user_access_rules() self._cfgfile.close()
def _identities(request): filters = dict((fname, request.GET.get(fname, None)) for fname in ['searchquery', 'idtfilter', 'grpfilter']) request.session['identities_filters'] = filters idents_list = get_identities(request.user, **filters) sort_order, sort_dir = get_sort_order(request.GET, "identity", ["identity", "name_or_rcpt", "tags"]) if sort_order in ["identity", "name_or_rcpt"]: objects = sorted(idents_list, key=lambda o: getattr(o, sort_order), reverse=sort_dir == '-') else: objects = sorted(idents_list, key=lambda o: o.tags[0], reverse=sort_dir == '-') page = get_listing_page(objects, request.GET.get("page", 1)) return render_to_json_response({ "table": _render_to_string(request, "admin/identities_table.html", { "identities": page.object_list, "tableid": "objects_table" }), "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", raise_error=False), "page": page.number, "paginbar": pagination_bar(page) })
def create_limits(self): for ltpl in limits_tpl: l = Limit() l.name = ltpl[0] l.pool = self l.maxvalue = int(parameters.get_admin("DEFLT_%s" % ltpl[0].upper())) l.save()
def load_from_user(self, user): for lname in self.fields.keys(): self.fields[lname].initial = user.limitspool.getmaxvalue(lname) # The following lines will become useless in a near # future. if self.fields[lname].initial == -2: self.fields[lname].initial = parameters.get_admin("DEFLT_%s" % lname.upper())
def notify_admins_pending_requests(self): self.sender = parameters.get_admin("NOTIFICATIONS_SENDER", app="amavis") self.baseurl = self.options["baseurl"].strip("/") self.listingurl = self.baseurl \ + reverse("modoboa.extensions.amavis.views._listing") \ + "?viewrequests=1" for da in User.objects.filter(groups__name="DomainAdmins"): if not da.mailbox_set.count(): continue rcpt = da.mailbox_set.all()[0].full_address reqs = get_wrapper().get_domains_pending_requests( Domain.objects.get_for_admin(da) ) if reqs.count(): self.send_pr_notification(rcpt, reqs) reqs = Msgrcpt.objects.filter(rs='p') if not reqs.count(): if self.options["verbose"]: print "No release request currently pending" return for su in User.objects.filter(is_superuser=True): if not su.mailbox_set.count(): continue rcpt = su.mailbox_set.all()[0].full_address self.send_pr_notification(rcpt, reqs)
def topredirection(request): """Simple view to redirect the request when no application is specified. The default "top redirection" can be specified in the *Admin > Settings* panel. It is the application that will be launched. Those not allowed to access the application will be redirected to their preferences page. This feature only applies to simple users. :param request: a Request object """ from modoboa.lib import parameters from modoboa.core.extensions import exts_pool if request.user.group == 'SimpleUsers': topredir = parameters.get_admin("DEFAULT_TOP_REDIRECTION", app="core") if topredir != "user": infos = exts_pool.get_extension_infos(topredir) path = infos["url"] if infos["url"] else infos["name"] else: path = reverse("core:user_index") else: # FIXME path = reverse("modoboa_admin:domain_list") return HttpResponseRedirect(path)