def list_quotas(request): from modoboa.lib.dbutils import db_type sort_order, sort_dir = get_sort_order(request.GET, "address") mboxes = Mailbox.objects.get_for_admin( request.user, request.GET.get("searchquery", None)) mboxes = mboxes.exclude(quota=0) if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": where = "admin_mailbox.address||'@'||admin_domain.name" db_type = db_type() if db_type == "postgres": select = '(admin_quota.bytes::float / (CAST(admin_mailbox.quota AS BIGINT) * 1048576)) * 100' else: select = 'admin_quota.bytes / (admin_mailbox.quota * 1048576) * 100' if db_type == "mysql": where = "CONCAT(admin_mailbox.address,'@',admin_domain.name)" mboxes = mboxes.extra(select={'quota_usage': select}, where=["admin_quota.username=%s" % where], tables=["admin_quota", "admin_domain"], order_by=["%s%s" % (sort_dir, sort_order)]) else: raise BadRequest(_("Invalid request")) page = get_listing_page(mboxes, request.GET.get("page", 1)) context = {} if page is None: context["length"] = 0 else: context["headers"] = _render_to_string(request, "admin/quota_headers.html", {}) context["rows"] = _render_to_string(request, "admin/quotas.html", {"mboxes": page}) context["pages"] = [page.number] return render_to_json_response(context)
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 _identities(request): idents_list = request.user.get_identities(request.GET) 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 ajax_simple_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 _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 autoreply(request, tplname="postfix_autoreply/autoreply.html"): mb = Mailbox.objects.get(user=request.user.id) try: arm = ARmessage.objects.get(mbox=mb.id) except ARmessage.DoesNotExist: arm = None if request.method == "POST": if arm: form = ARmessageForm(request.POST, instance=arm) else: form = ARmessageForm(request.POST) if form.is_valid(): arm = form.save(commit=False) arm.fromdate = form.cleaned_data["fromdate"] arm.untildate = form.cleaned_data["untildate"] arm.mbox = mb arm.save() return render_to_json_response( _("Auto reply message updated successfully.") ) return render_to_json_response( {"form_errors": form.errors}, status=400 ) form = ARmessageForm(instance=arm) return render_to_json_response({ "content": _render_to_string(request, tplname, {"form": form}), "onload_cb": "autoreply_cb" })
def preferences(request): if request.method == "POST": for formdef in parameters.get_user_forms(request.user, request.POST)(): form = formdef["form"] if form.is_valid(): form.save() continue return ajax_simple_response({ "status": "ko", "prefix": form.app, "errors": form.errors }) return ajax_simple_response({ "status": "ok", "respmsg": _("Preferences saved") }) return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, "core/user_preferences.html", {"forms": parameters.get_user_forms(request.user)}) })
def viewparameters(request, tplname='core/parameters.html'): return render_to_json_response({ "left_selection": "parameters", "content": _render_to_string(request, tplname, { "forms": parameters.get_admin_forms }) })
def list_quotas(request, tplname="admin/quotas.html"): from modoboa.lib.dbutils import db_type sort_order, sort_dir = get_sort_order(request.GET, "address") mboxes = Mailbox.objects.get_for_admin( request.user, request.GET.get("searchquery", None) ) mboxes = mboxes.exclude(quota=0) if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": if db_type() == "postgres": select = '(admin_quota.bytes::float / (CAST(admin_mailbox.quota AS BIGINT) * 1048576)) * 100' else: select = 'admin_quota.bytes / (admin_mailbox.quota * 1048576) * 100' mboxes = mboxes.extra( select={'quota_usage': select}, where=["admin_quota.mbox_id=admin_mailbox.id"], tables=["admin_quota"], order_by=["%s%s" % (sort_dir, sort_order)] ) else: raise BadRequest(_("Invalid request")) page = get_listing_page(mboxes, request.GET.get("page", 1)) return render_to_json_response({ "page": page.number, "paginbar": pagination_bar(page), "table": _render_to_string(request, tplname, { "mboxes": page }) })
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 list_quotas(request, tplname="admin/quotas.html"): from modoboa.lib.dbutils import db_type sort_order, sort_dir = get_sort_order(request.GET, "address") mboxes = Mailbox.objects.get_for_admin( request.user, request.GET.get("searchquery", None)) mboxes = mboxes.exclude(quota=0) if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": if db_type() == "postgres": select = '(admin_quota.bytes::float / (CAST(admin_mailbox.quota AS BIGINT) * 1048576)) * 100' else: select = 'admin_quota.bytes / (admin_mailbox.quota * 1048576) * 100' mboxes = mboxes.extra(select={'quota_usage': select}, where=["admin_quota.mbox_id=admin_mailbox.id"], tables=["admin_quota"], order_by=["%s%s" % (sort_dir, sort_order)]) else: raise BadRequest(_("Invalid request")) page = get_listing_page(mboxes, request.GET.get("page", 1)) return render_to_json_response({ "page": page.number, "paginbar": pagination_bar(page), "table": _render_to_string(request, tplname, {"mboxes": page}) })
def profile(request, tplname='core/user_profile.html'): update_password = True if True in events.raiseQueryEvent("PasswordChange", request.user): update_password = False if request.method == "POST": form = ProfileForm(update_password, request.POST, instance=request.user) if form.is_valid(): form.save() if update_password and form.cleaned_data["confirmation"] != "": request.session["password"] = encrypt( form.cleaned_data["confirmation"]) return ajax_simple_response( dict(status="ok", respmsg=_("Profile updated"))) return ajax_simple_response({"status": "ko", "errors": form.errors}) form = ProfileForm(update_password, instance=request.user) return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, {"form": form}) })
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 == '-') page = get_listing_page(domainlist, request.GET.get("page", 1)) return render_to_json_response({ "table": _render_to_string(request, 'admin/domains_table.html', { 'domains': page.object_list, 'tableid': 'domains' }), "page": page.number, "paginbar": pagination_bar(page), "handle_mailboxes": parameters.get_admin("HANDLE_MAILBOXES", raise_error=False), "auto_account_removal": parameters.get_admin("AUTO_ACCOUNT_REMOVAL") })
def autoreply(request, tplname="postfix_autoreply/autoreply.html"): mb = Mailbox.objects.get(user=request.user.id) try: arm = ARmessage.objects.get(mbox=mb.id) except ARmessage.DoesNotExist: arm = None if request.method == "POST": if arm: form = ARmessageForm(request.POST, instance=arm) else: form = ARmessageForm(request.POST) if form.is_valid(): arm = form.save(commit=False) arm.fromdate = form.cleaned_data["fromdate"] arm.untildate = form.cleaned_data["untildate"] arm.mbox = mb arm.save() return render_to_json_response( _("Auto reply message updated successfully.")) return render_to_json_response({"form_errors": form.errors}, status=400) form = ARmessageForm(instance=arm) return render_to_json_response({ "content": _render_to_string(request, tplname, {"form": form}), "onload_cb": "autoreply_cb" })
def profile(request, tplname='core/user_profile.html'): update_password = True if True in events.raiseQueryEvent("PasswordChange", request.user): update_password = False if request.method == "POST": form = ProfileForm( update_password, request.POST, instance=request.user ) if form.is_valid(): form.save() if update_password and form.cleaned_data["confirmation"] != "": request.session["password"] = encrypt(form.cleaned_data["confirmation"]) return ajax_simple_response(dict( status="ok", respmsg=_("Profile updated") )) return ajax_simple_response({ "status": "ko", "errors": form.errors }) form = ProfileForm(update_password, instance=request.user) return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, { "form": form }) })
def viewparameters(request, tplname='admin/parameters.html'): return ajax_simple_response({ "status": "ok", "left_selection": "parameters", "content": _render_to_string(request, tplname, { "forms": parameters.get_admin_forms }) })
def viewparameters(request, tplname='core/parameters.html'): return render_to_json_response({ "left_selection": "parameters", "content": _render_to_string(request, tplname, {"forms": parameters.get_admin_forms}) })
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 = parameters.get_user(request.user, "EDITOR") listing = _render_to_string( request, "webmail/compose.html", { "form": form, "noerrors": True, "body": form.cleaned_data.get("body", "").strip(), "posturl": posturl }) return False, dict(status="ko", listing=listing, editor=editormode) msg = form.to_msg(request) rcpts = prepare_addresses(form.cleaned_data["to"], "envelope") for hdr in ["cc", "cci"]: if form.cleaned_data[hdr]: msg[hdr.capitalize()] = prepare_addresses(form.cleaned_data[hdr]) rcpts += prepare_addresses(form.cleaned_data[hdr], "envelope") try: secmode = parameters.get_admin("SMTP_SECURED_MODE") if secmode == "ssl": s = smtplib.SMTP_SSL(parameters.get_admin("SMTP_SERVER"), int(parameters.get_admin("SMTP_PORT"))) else: s = smtplib.SMTP(parameters.get_admin("SMTP_SERVER"), int(parameters.get_admin("SMTP_PORT"))) if secmode == "starttls": s.starttls() except Exception as text: raise WebmailInternalError(str(text)) if parameters.get_admin("SMTP_AUTHENTICATION") == "yes": try: s.login(request.user.username, get_password(request)) except smtplib.SMTPException as err: raise WebmailInternalError(str(err)) try: s.sendmail(request.user.email, rcpts, msg.as_string()) s.quit() except smtplib.SMTPException as err: raise WebmailInternalError(str(err)) sentfolder = parameters.get_user(request.user, "SENT_FOLDER") get_imapconnector(request).push_mail(sentfolder, msg) clean_attachments(request.session["compose_mail"]["attachments"]) del request.session["compose_mail"] return True, {}
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 = parameters.get_user(request.user, "EDITOR") listing = _render_to_string( request, "webmail/compose.html", {"form": form, "noerrors": True, "body": form.cleaned_data.get("body", "").strip(), "posturl": posturl} ) return False, dict(status="ko", listing=listing, editor=editormode) msg = form.to_msg(request) rcpts = prepare_addresses(form.cleaned_data["to"], "envelope") for hdr in ["cc", "cci"]: if form.cleaned_data[hdr]: msg[hdr.capitalize()] = prepare_addresses(form.cleaned_data[hdr]) rcpts += prepare_addresses(form.cleaned_data[hdr], "envelope") try: secmode = parameters.get_admin("SMTP_SECURED_MODE") if secmode == "ssl": s = smtplib.SMTP_SSL(parameters.get_admin("SMTP_SERVER"), int(parameters.get_admin("SMTP_PORT"))) else: s = smtplib.SMTP(parameters.get_admin("SMTP_SERVER"), int(parameters.get_admin("SMTP_PORT"))) if secmode == "starttls": s.starttls() except Exception as text: raise WebmailInternalError(str(text)) if parameters.get_admin("SMTP_AUTHENTICATION") == "yes": try: s.login(request.user.username, get_password(request)) except smtplib.SMTPException as err: raise WebmailInternalError(str(err)) try: s.sendmail(request.user.email, rcpts, msg.as_string()) s.quit() except smtplib.SMTPException as err: raise WebmailInternalError(str(err)) sentfolder = parameters.get_user(request.user, "SENT_FOLDER") get_imapconnector(request).push_mail(sentfolder, msg) clean_attachments(request.session["compose_mail"]["attachments"]) del request.session["compose_mail"] return True, {}
def viewparameters(request, tplname='admin/parameters.html'): return ajax_simple_response({ "status": "ok", "left_selection": "parameters", "content": _render_to_string(request, tplname, {"forms": parameters.get_admin_forms}) })
def dologin(request): error = None if request.method == "POST": form = LoginForm(request.POST) if form.is_valid(): logger = logging.getLogger('modoboa.auth') user = authenticate(username=form.cleaned_data["username"], password=form.cleaned_data["password"]) if user and user.is_active: login(request, user) if not form.cleaned_data["rememberme"]: request.session.set_expiry(0) if request.user.has_mailbox: request.session["password"] = encrypt( form.cleaned_data["password"]) request.session["django_language"] = \ parameters.get_user(request.user, "LANG", app="general") logger.info( _("User '%s' successfully logged in" % user.username)) events.raiseEvent("UserLogin", request, form.cleaned_data["username"], form.cleaned_data["password"]) nextlocation = request.POST.get("next", None) if nextlocation is None or nextlocation == "None": if user.group != "SimpleUsers": nextlocation = reverse( "modoboa.lib.webutils.topredirection") else: nextlocation = reverse("domains") return HttpResponseRedirect(nextlocation) error = _( "Your username and password didn't match. Please try again.") logger.warning("Failed connection attempt from '%(addr)s' as user '%(user)s'" \ % {"addr": request.META["REMOTE_ADDR"], "user": form.cleaned_data["username"]}) nextlocation = request.POST.get("next", None) httpcode = 401 else: form = LoginForm() nextlocation = request.GET.get("next", None) httpcode = 200 return HttpResponse(_render_to_string( request, "registration/login.html", { "form": form, "error": error, "next": nextlocation, "annoucements": events.raiseQueryEvent("GetAnnouncement", "loginpage") }), status=httpcode)
def dologin(request): error = None if request.method == "POST": form = LoginForm(request.POST) if form.is_valid(): logger = logging.getLogger("modoboa.auth") user = authenticate(username=form.cleaned_data["username"], password=form.cleaned_data["password"]) if user and user.is_active: login(request, user) if not form.cleaned_data["rememberme"]: request.session.set_expiry(0) if request.user.has_mailbox: request.session["password"] = encrypt(form.cleaned_data["password"]) request.session["django_language"] = parameters.get_user(request.user, "LANG", app="general") logger.info(_("User '%s' successfully logged in" % user.username)) events.raiseEvent("UserLogin", request, form.cleaned_data["username"], form.cleaned_data["password"]) nextlocation = request.POST.get("next", None) if nextlocation is None or nextlocation == "None": if user.group == "SimpleUsers": nextlocation = reverse("modoboa.lib.webutils.topredirection") else: nextlocation = reverse("domains") return HttpResponseRedirect(nextlocation) error = _("Your username and password didn't match. Please try again.") logger.warning( "Failed connection attempt from '%(addr)s' as user '%(user)s'" % {"addr": request.META["REMOTE_ADDR"], "user": form.cleaned_data["username"]} ) nextlocation = request.POST.get("next", None) httpcode = 401 else: form = LoginForm() nextlocation = request.GET.get("next", None) httpcode = 200 return HttpResponse( _render_to_string( request, "registration/login.html", { "form": form, "error": error, "next": nextlocation, "annoucements": events.raiseQueryEvent("GetAnnouncement", "loginpage"), }, ), status=httpcode, )
def render_mboxes_list(request, imapc): """Return the HTML representation of a mailboxes list :param request: a ``Request`` object :param imapc: an ``IMAPconnector` object :return: a string """ curmbox = WebmailNavigationParameters(request).get("mbox", "INBOX") return _render_to_string( request, "webmail/folders.html", {"selected": curmbox, "mboxes": imapc.getmboxes(request.user), "withunseen": True}, )
def render_mboxes_list(request, imapc): """Return the HTML representation of a mailboxes list :param request: a ``Request`` object :param imapc: an ``IMAPconnector` object :return: a string """ curmbox = request.session.get("mbox", "INBOX") return _render_to_string( request, "webmail/folders.html", { "selected": curmbox, "mboxes": imapc.getmboxes(request.user), "withunseen": True })
def listing_page(request): """Return a listing page.""" navparams = QuarantineNavigationParameters(request) previous_page_id = int(navparams["page"]) if "page" in navparams else None navparams.store() connector = get_connector(user=request.user, navparams=navparams) context = get_listing_pages(request, connector) if context is None: context = {"length": 0} navparams["page"] = previous_page_id else: context["rows"] = _render_to_string(request, "amavis/emails_page.html", {"email_list": context["rows"]}) return render_to_json_response(context)
def graphs(request): gset = request.GET.get("gset", None) gsets = events.raiseDictEvent("GetGraphSets") if not gset in gsets: raise ModoboaException(_("Unknown graphic set")) searchq = request.GET.get("searchquery", None) period = request.GET.get("period", "day") tplvars = dict(graphs=[], period=period) if searchq in [None, "global"]: if not request.user.is_superuser: if not Domain.objects.get_for_admin(request.user).count(): return ajax_simple_response({"status": "ok"}) tplvars.update( domain=Domain.objects.get_for_admin(request.user)[0].name ) else: tplvars.update(domain="global") else: domain = Domain.objects.filter(name__contains=searchq) if domain.count() != 1: return ajax_simple_response({"status": "ok"}) if not request.user.can_access(domain[0]): raise PermDeniedException tplvars.update(domain=domain[0].name) if period == "custom": if not "start" in request.GET or not "end" in request.GET: raise ModoboaException(_("Bad custom period")) start = request.GET["start"] end = request.GET["end"] G = Grapher() period_name = "%s_%s" % (start.replace('-', ''), end.replace('-', '')) for tpl in gsets[gset].get_graphs(): tplvars['graphs'].append(tpl.display_name) G.process( tplvars["domain"], period_name, str2Time(*start.split('-')), str2Time(*end.split('-')), tpl ) tplvars["period_name"] = period_name tplvars["start"] = start tplvars["end"] = end else: tplvars['graphs'] = gsets[gset].get_graph_names() return ajax_simple_response(dict( status="ok", content=_render_to_string(request, "stats/graphs.html", tplvars) ))
def graphs(request): gset = request.GET.get("gset", None) gsets = events.raiseDictEvent("GetGraphSets") if not gset in gsets: raise NotFound(_("Unknown graphic set")) searchq = request.GET.get("searchquery", None) period = request.GET.get("period", "day") tplvars = dict(graphs=[], period=period) if searchq in [None, "global"]: if not request.user.is_superuser: if not Domain.objects.get_for_admin(request.user).count(): return render_to_json_response({}) tplvars.update( domain=Domain.objects.get_for_admin(request.user)[0].name ) else: tplvars.update(domain="global") else: domain = Domain.objects.filter(name__contains=searchq) if domain.count() != 1: return render_to_json_response({}) if not request.user.can_access(domain[0]): raise PermDeniedException tplvars.update(domain=domain[0].name) if period == "custom": if not "start" in request.GET or not "end" in request.GET: raise BadRequest(_("Bad custom period")) start = request.GET["start"] end = request.GET["end"] G = Grapher() expr = re.compile(r'[:\- ]') period_name = "%s_%s" % (expr.sub('', start), expr.sub('', end)) for tpl in gsets[gset].get_graphs(): tplvars['graphs'].append(tpl.display_name) G.process( tplvars["domain"], period_name, str2Time(*expr.split(start)), str2Time(*expr.split(end)), tpl ) tplvars["period_name"] = period_name tplvars["start"] = start tplvars["end"] = end else: tplvars['graphs'] = gsets[gset].get_graph_names() return render_to_json_response({ 'content': _render_to_string(request, "stats/graphs.html", tplvars) })
def viewextensions(request, tplname="core/extensions.html"): from modoboa.core.extensions import exts_pool exts = exts_pool.list_all() for ext in exts: try: dbext = Extension.objects.get(name=ext["id"]) ext["selection"] = dbext.enabled except Extension.DoesNotExist: dbext = Extension() dbext.name = ext["id"] dbext.enabled = False dbext.save() ext["selection"] = False tbl = ExtensionsTable(request, exts) return ajax_simple_response({"status": "ok", "content": _render_to_string(request, tplname, {"extensions": tbl})})
def calendars_page(request, tplname="radicale/calendars_page.html"): """Return a page of calendars. The content depends on current user's role. """ page = get_calendar_page(request) if page is None: context = {"length": 0} else: context = { "rows": _render_to_string(request, tplname, { "calendars": page.object_list, "with_owner": request.user.group != "SimpleUsers" }), "page": page.number } return render_to_json_response(context)
def listmailbox(request, defmailbox="INBOX", update_session=True): """Mailbox content listing. Return a list of messages contained in the specified mailbox. The number of elements returned depends on the ``MESSAGES_PER_PAGE`` parameter. (user preferences) :param request: a ``Request`` object :param defmailbox: the default mailbox (when not present inside request arguments) :return: a dictionnary """ navparams = WebmailNavigationParameters(request, defmailbox) previous_page_id = int(navparams["page"]) if "page" in navparams else None if update_session: navparams.store() mbox = navparams.get('mbox') page_id = int(navparams["page"]) mbc = get_imapconnector(request) mbc.parse_search_parameters( navparams.get("criteria"), navparams.get("pattern")) paginator = Paginator( mbc.messages_count(folder=mbox, order=navparams.get("order")), int(parameters.get_user(request.user, "MESSAGES_PER_PAGE")) ) page = paginator.getpage(page_id) content = "" if page is not None: email_list = mbc.fetch(page.id_start, page.id_stop, mbox) content = _render_to_string(request, "webmail/email_list.html", { "email_list": email_list, "page": page_id, "with_top_div": request.GET.get("scroll", "false") == "false" }) length = len(content) else: if page_id == 1: content = "<div class='alert alert-info'>{0}</div>".format( _("Empty mailbox") ) length = 0 if previous_page_id is not None: navparams["page"] = previous_page_id return {"listing": content, "length": length, "pages": [page_id]}
def graphs(request): gset = request.GET.get("gset", None) gsets = events.raiseDictEvent("GetGraphSets") if not gset in gsets: raise NotFound(_("Unknown graphic set")) searchq = request.GET.get("searchquery", None) period = request.GET.get("period", "day") tplvars = dict(graphs=[], period=period) if searchq in [None, "global"]: if not request.user.is_superuser: if not Domain.objects.get_for_admin(request.user).count(): return render_to_json_response({}) tplvars.update( domain=Domain.objects.get_for_admin(request.user)[0].name) else: tplvars.update(domain="global") else: domain = Domain.objects.filter(name__contains=searchq) if domain.count() != 1: return render_to_json_response({}) if not request.user.can_access(domain[0]): raise PermDeniedException tplvars.update(domain=domain[0].name) if period == "custom": if not "start" in request.GET or not "end" in request.GET: raise BadRequest(_("Bad custom period")) start = request.GET["start"] end = request.GET["end"] G = Grapher() expr = re.compile(r'[:\- ]') period_name = "%s_%s" % (expr.sub('', start), expr.sub('', end)) for tpl in gsets[gset].get_graphs(): tplvars['graphs'].append(tpl.display_name) G.process(tplvars["domain"], period_name, str2Time(*expr.split(start)), str2Time(*expr.split(end)), tpl) tplvars["period_name"] = period_name tplvars["start"] = start tplvars["end"] = end else: tplvars['graphs'] = gsets[gset].get_graph_names() return render_to_json_response( {'content': _render_to_string(request, "stats/graphs.html", tplvars)})
def viewextensions(request, tplname='core/extensions.html'): from modoboa.core.extensions import exts_pool exts = exts_pool.list_all() for ext in exts: try: dbext = Extension.objects.get(name=ext["id"]) ext["selection"] = dbext.enabled except Extension.DoesNotExist: dbext = Extension() dbext.name = ext["id"] dbext.enabled = False dbext.save() ext["selection"] = False tbl = ExtensionsTable(request, exts) return render_to_json_response( {"content": _render_to_string(request, tplname, {"extensions": tbl})})
def preferences(request): if request.method == "POST": for formdef in parameters.get_user_forms(request.user, request.POST)(): form = formdef["form"] if form.is_valid(): form.save() continue return render_to_json_response({ "prefix": form.app, "form_errors": form.errors }, status=400) return render_to_json_response(_("Preferences saved")) return render_to_json_response({ "content": _render_to_string(request, "core/user_preferences.html", { "forms": parameters.get_user_forms(request.user) }) })
def listmailbox(request, defmailbox="INBOX", update_session=True): """Mailbox content listing. Return a list of messages contained in the specified mailbox. The number of elements returned depends on the ``MESSAGES_PER_PAGE`` parameter. (user preferences) :param request: a ``Request`` object :param defmailbox: the default mailbox (when not present inside request arguments) :return: a dictionnary """ navparams = WebmailNavigationParameters(request, defmailbox) previous_page_id = int(navparams["page"]) if "page" in navparams else None if update_session: navparams.store() mbox = navparams.get('mbox') page_id = int(navparams["page"]) mbc = get_imapconnector(request) mbc.parse_search_parameters(navparams.get("criteria"), navparams.get("pattern")) paginator = Paginator( mbc.messages_count(folder=mbox, order=navparams.get("order")), int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))) page = paginator.getpage(page_id) content = "" if page is not None: email_list = mbc.fetch(page.id_start, page.id_stop, mbox) content = _render_to_string( request, "webmail/email_list.html", { "email_list": email_list, "page": page_id, "with_top_div": request.GET.get("scroll", "false") == "false" }) length = len(content) else: if page_id == 1: content = "<div class='alert alert-info'>{0}</div>".format( _("Empty mailbox")) length = 0 if previous_page_id is not None: navparams["page"] = previous_page_id return {"listing": content, "length": length, "pages": [page_id]}
def forward(request, tplname='admin/forward.html'): mb = request.user.mailbox_set.all()[0] try: al = Alias.objects.get(address=mb.address, domain__name=mb.domain.name) except Alias.DoesNotExist: al = None if request.method == "POST": form = ForwardForm(request.POST) error = None if form.is_valid(): if al is None: al = Alias() al.address = mb.address al.domain = mb.domain al.enabled = mb.user.is_active intdests = [] if form.cleaned_data["keepcopies"]: intdests += [mb] form.parse_dest() al.save( int_rcpts=intdests, ext_rcpts=form.dests, creator=request.user ) return render_to_json_response(_("Forward updated")) return render_to_json_response( {'form_errors': form.errors}, status=400 ) form = ForwardForm() if al is not None: form.fields["dest"].initial = al.extmboxes try: al.mboxes.get(pk=mb.id) except Mailbox.DoesNotExist: pass else: form.fields["keepcopies"].initial = True return render_to_json_response({ "content": _render_to_string(request, tplname, { "form": form }) })
def render_compose(request, form, posturl, email=None, insert_signature=False): editor = parameters.get_user(request.user, "EDITOR") if email is None: body = "" textheader = "" else: body = email.body textheader = email.textheader if insert_signature: signature = EmailSignature(request.user) body += str(signature) randid = None if not "id" in request.GET: if "compose_mail" in request.session: clean_attachments(request.session["compose_mail"]["attachments"]) randid = set_compose_session(request) elif not "compose_mail" in request.session \ or request.session["compose_mail"]["id"] != request.GET["id"]: randid = set_compose_session(request) attachments = request.session["compose_mail"]["attachments"] if attachments: short_att_list = "(%s)" % ", ".join([ att['fname'] for att in (attachments[:2] + [{ "fname": "..." }] if len(attachments) > 2 else attachments) ]) else: short_att_list = "" content = _render_to_string( request, "webmail/compose.html", { "form": form, "bodyheader": textheader, "body": body, "posturl": posturl, "attachments": attachments, "short_att_list": short_att_list }) ctx = dict(listing=content, editor=editor) if randid is not None: ctx["id"] = randid return ctx
def render_compose(request, form, posturl, email=None, insert_signature=False): editor = parameters.get_user(request.user, "EDITOR") if email is None: body = "" textheader = "" else: body = email.body textheader = email.textheader if insert_signature: signature = EmailSignature(request.user) body += str(signature) randid = None if not "id" in request.GET: if "compose_mail" in request.session: clean_attachments(request.session["compose_mail"]["attachments"]) randid = set_compose_session(request) elif not "compose_mail" in request.session or request.session["compose_mail"]["id"] != request.GET["id"]: randid = set_compose_session(request) attachments = request.session["compose_mail"]["attachments"] if attachments: short_att_list = "(%s)" % ", ".join( [att["fname"] for att in (attachments[:2] + [{"fname": "..."}] if len(attachments) > 2 else attachments)] ) else: short_att_list = "" content = _render_to_string( request, "webmail/compose.html", { "form": form, "bodyheader": textheader, "body": body, "posturl": posturl, "attachments": attachments, "short_att_list": short_att_list, }, ) ctx = dict(listing=content, editor=editor) if randid is not None: ctx["id"] = randid return ctx
def calendars_page(request, tplname="radicale/calendars_page.html"): """Return a page of calendars. The content depends on current user's role. """ page = get_calendar_page(request) if page is None: context = {"length": 0} else: context = { "rows": _render_to_string( request, tplname, { "calendars": page.object_list, "with_owner": request.user.group != "SimpleUsers" }), "page": page.number } return render_to_json_response(context)
def viewextensions(request, tplname='core/extensions.html'): """List available extensions.""" from modoboa.core.extensions import exts_pool exts = exts_pool.list_all() for ext in exts: try: dbext = Extension.objects.get(name=ext["id"]) ext["selection"] = dbext.enabled except Extension.DoesNotExist: dbext = Extension() dbext.name = ext["id"] dbext.enabled = False dbext.save() ext["selection"] = False return render_to_json_response({ "callback": "extensions", "content": _render_to_string(request, tplname, {"extensions": exts}) })
def preferences(request): if request.method == "POST": for formdef in parameters.get_user_forms(request.user, request.POST)(): form = formdef["form"] if form.is_valid(): form.save() continue return render_to_json_response( { "prefix": form.app, "form_errors": form.errors }, status=400) return render_to_json_response(_("Preferences saved")) return render_to_json_response({ "content": _render_to_string(request, "core/user_preferences.html", {"forms": parameters.get_user_forms(request.user)}) })
def preferences(request): if request.method == "POST": for formdef in parameters.get_user_forms(request.user, request.POST)(): form = formdef["form"] if form.is_valid(): form.save() continue return ajax_simple_response({ "status": "ko", "prefix": form.app, "errors": form.errors }) return ajax_simple_response({ "status": "ok", "respmsg": _("Preferences saved") }) return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, "core/user_preferences.html", { "forms": parameters.get_user_forms(request.user) }) })
def render_compose(request, form, posturl, email=None, insert_signature=False): """Render the compose form.""" resp = {} if email is None: body = u"" textheader = u"" else: body = email.body textheader = email.textheader if insert_signature: signature = EmailSignature(request.user) body += unicode(signature) randid = None if not "id" in request.GET: if "compose_mail" in request.session: clean_attachments(request.session["compose_mail"]["attachments"]) randid = set_compose_session(request) elif not "compose_mail" in request.session \ or request.session["compose_mail"]["id"] != request.GET["id"]: randid = set_compose_session(request) attachment_list = request.session["compose_mail"]["attachments"] if attachment_list: resp["menuargs"] = {"attachment_counter": len(attachment_list)} content = _render_to_string(request, "webmail/compose.html", { "form": form, "bodyheader": textheader, "body": body, "posturl": posturl }) resp.update({ "listing": content, "editor": parameters.get_user(request.user, "EDITOR") }) if randid is not None: resp["id"] = randid return resp
def autoreply(request, tplname="postfix_autoreply/autoreply.html"): mb = Mailbox.objects.get(user=request.user.id) try: arm = ARmessage.objects.get(mbox=mb.id) except ARmessage.DoesNotExist: arm = None if request.method == "POST": if arm: form = ARmessageForm(request.POST, instance=arm) else: form = ARmessageForm(request.POST) if form.is_valid(): arm = form.save(commit=False) arm.untildate = form.cleaned_data["untildate"] arm.mbox = mb arm.save() return ajax_simple_response( dict(status="ok", respmsg=_("Auto reply message updated successfully."))) return ajax_simple_response({ "status": "ko", "errors": form.errors, "onload_cb": "autoreply_cb" }) form = ARmessageForm(instance=arm) if arm is not None: form.fields['untildate'].initial = arm.untildate else: form.fields['untildate'].initial = date.today() return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, {"form": form}), "onload_cb": "autoreply_cb" })
def editdomain(request, dom_id, tplname="admin/editdomainform.html"): domain = Domain.objects.get(pk=dom_id) if not request.user.can_access(domain): raise PermDeniedException domadmins = filter( lambda u: request.user.can_access(u) and not u.is_superuser, domain.admins ) if not request.user.is_superuser: domadmins = filter(lambda u: u.group == "DomainAdmins", domadmins) instances = dict(general=domain) events.raiseEvent("FillDomainInstances", request.user, domain, instances) commonctx = {"title": domain.name, "action_label": _("Update"), "action_classes": "submit", "action": reverse(editdomain, args=[dom_id]), "formid": "domform", "domain": domain} if request.method == "POST": error = None domain.oldname = domain.name form = DomainForm(request.user, request.POST, instances=instances) if form.is_valid(): try: form.save(request.user) except AdminError, e: error = str(e) else: events.raiseEvent("DomainModified", domain) return ajax_simple_response({"status": "ok", "respmsg": _("Domain modified")}) commonctx["tabs"] = form return ajax_simple_response({ "status": "ko", "respmsg": error, "content": _render_to_string(request, tplname, commonctx) })
def forward(request, tplname='admin/forward.html'): mb = request.user.mailbox_set.all()[0] try: al = Alias.objects.get(address=mb.address, domain__name=mb.domain.name) except Alias.DoesNotExist: al = None if request.method == "POST": form = ForwardForm(request.POST) error = None if form.is_valid(): if al is None: al = Alias() al.address = mb.address al.domain = mb.domain al.enabled = mb.user.is_active intdests = [] if form.cleaned_data["keepcopies"]: intdests += [mb] form.parse_dest() al.save(int_rcpts=intdests, ext_rcpts=form.dests, creator=request.user) return render_to_json_response(_("Forward updated")) return render_to_json_response({'form_errors': form.errors}, status=400) form = ForwardForm() if al is not None: form.fields["dest"].initial = al.extmboxes try: al.mboxes.get(pk=mb.id) except Mailbox.DoesNotExist: pass else: form.fields["keepcopies"].initial = True return render_to_json_response( {"content": _render_to_string(request, tplname, {"form": form})})
def _listing(request): """Listing initial view. Called the first time the listing page is displayed. """ if not request.user.is_superuser and request.user.group != 'SimpleUsers': if not Domain.objects.get_for_admin(request.user).count(): return empty_quarantine() navparams = QuarantineNavigationParameters(request) navparams.store() connector = get_connector(user=request.user, navparams=navparams) context = get_listing_pages(request, connector) if context is None: return empty_quarantine() context["listing"] = _render_to_string(request, "amavis/email_list.html", {"email_list": context["rows"]}) del context["rows"] if request.session.get('location', 'listing') != 'listing': context["menu"] = quar_menu(request.user) request.session["location"] = "listingx" return render_to_json_response(context)
def autoreply(request, tplname="postfix_autoreply/autoreply.html"): mb = Mailbox.objects.get(user=request.user.id) try: arm = ARmessage.objects.get(mbox=mb.id) except ARmessage.DoesNotExist: arm = None if request.method == "POST": if arm: form = ARmessageForm(request.POST, instance=arm) else: form = ARmessageForm(request.POST) if form.is_valid(): arm = form.save(commit=False) arm.untildate = form.cleaned_data["untildate"] arm.mbox = mb arm.save() return ajax_simple_response(dict( status="ok", respmsg=_("Auto reply message updated successfully.") )) return ajax_simple_response({ "status": "ko", "errors": form.errors, "onload_cb": "autoreply_cb" }) form = ARmessageForm(instance=arm) if arm is not None: form.fields['untildate'].initial = arm.untildate else: form.fields['untildate'].initial = date.today() return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, {"form": form}), "onload_cb": "autoreply_cb" })
def calendars(request, tplname="radicale/calendar_list.html"): """Display calendars list. The content depends on current user's role. """ sort_order, sort_dir = get_sort_order(request.GET, "name") calfilter = request.GET.get("calfilter", None) searchquery = request.GET.get("searchquery", None) if request.user.group == "SimpleUsers": mbox = request.user.mailbox_set.all()[0] cals = UserCalendar.objects.filter(mailbox=mbox) if searchquery is not None: cals = cals.filter(name__icontains=searchquery) cals = cals.select_related().all() with_owner = False else: ucals = [] if calfilter is None or calfilter == "user": ucals = UserCalendar.objects.get_for_admin(request.user) if searchquery is not None: ucals = ucals.filter(name__icontains=searchquery) scals = [] if calfilter is None or calfilter == "shared": scals = SharedCalendar.objects.get_for_admin(request.user) if searchquery is not None: scals = scals.filter(name__icontains=searchquery) cals = chain(ucals, scals) with_owner = True cals = sorted( cals, key=lambda c: getattr(c, sort_order), reverse=sort_dir == '-' ) return render_to_json_response({ "table": _render_to_string(request, tplname, { "calendars": cals, "with_owner": with_owner }) })
def list_quotas(request, tplname="admin/quotas.html"): sort_order, sort_dir = get_sort_order(request.GET, "address") mboxes = request.user.get_mailboxes(request.GET.get("searchquery", None)) mboxes = mboxes.exclude(quota=0) if sort_order in ["address", "quota", "quota_value__bytes"]: mboxes = mboxes.order_by("%s%s" % (sort_dir, sort_order)) elif sort_order == "quota_usage": mboxes = mboxes.extra( select={'quota_usage': 'admin_quota.bytes / (admin_mailbox.quota * 1048576) * 100'}, where=["admin_quota.mbox_id=admin_mailbox.id"], tables=["admin_quota"], order_by=["%s%s" % (sort_dir, sort_order)] ) else: raise AdminError(_("Invalid request")) page = get_listing_page(mboxes, request.GET.get("page", 1)) return ajax_simple_response({ "status": "ok", "page": page.number, "paginbar": pagination_bar(page), "table": _render_to_string(request, tplname, { "mboxes": page }) })
al.enabled = mb.user.is_active intdests = [] if form.cleaned_data["keepcopies"]: intdests += [mb] form.parse_dest() al.save(int_rcpts=intdests, ext_rcpts=form.dests) if request.user.group != "SimpleUsers": al.post_create(request.user) return ajax_response(request, respmsg=_("Forward updated")) except BadDestination, e: error = str(e) return ajax_simple_response( dict(status="ko", errors=form.errors, respmsg=error)) form = ForwardForm() if al is not None: form.fields["dest"].initial = al.extmboxes try: al.mboxes.get(pk=mb.id) except Mailbox.DoesNotExist: pass else: form.fields["keepcopies"].initial = True return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, {"form": form}) })
respmsg=error )) form = ForwardForm() if al is not None: form.fields["dest"].initial = al.extmboxes try: selfmb = al.mboxes.get(pk=mb.id) except Mailbox.DoesNotExist: pass else: form.fields["keepcopies"].initial = True return ajax_simple_response({ "status": "ok", "content": _render_to_string(request, tplname, { "form": form }) }) @login_required def profile(request, tplname='userprefs/profile.html'): update_password = True if True in events.raiseQueryEvent("PasswordChange", request.user): update_password = False if request.method == "POST": form = ProfileForm( update_password, request.POST, instance=request.user ) if form.is_valid():
raise WebmailError(str(e)) try: s.sendmail(request.user.email, rcpts, msg.as_string()) s.quit() except smtplib.SMTPException, e: raise WebmailError(str(e)) sentfolder = parameters.get_user(request.user, "SENT_FOLDER") IMAPconnector(user=request.user.username, password=request.session["password"]).push_mail(sentfolder, msg) clean_attachments(request.session["compose_mail"]["attachments"]) del request.session["compose_mail"] return True, dict(url=get_current_url(request)) listing = _render_to_string(request, "webmail/compose.html", {"form" : form, "noerrors" : True, "body" : request.POST["id_body"].strip(), "posturl" : posturl}) return False, dict(status="ko", listing=listing, editor=editormode) class AttachmentUploadHandler(FileUploadHandler): """ Simple upload handler to limit the size of the attachments users can upload. """ def __init__(self, request=None): super(AttachmentUploadHandler, self).__init__(request) self.total_upload = 0 self.toobig = False self.maxsize = size2integer(parameters.get_admin("MAX_ATTACHMENT_SIZE"))
s.quit() except smtplib.SMTPException, e: raise WebmailError(str(e)) sentfolder = parameters.get_user(request.user, "SENT_FOLDER") IMAPconnector(user=request.user.username, password=request.session["password"]).push_mail( sentfolder, msg) clean_attachments(request.session["compose_mail"]["attachments"]) del request.session["compose_mail"] return True, dict(url=get_current_url(request)) listing = _render_to_string( request, "webmail/compose.html", { "form": form, "noerrors": True, "body": request.POST["id_body"].strip(), "posturl": posturl }) return False, dict(status="ko", listing=listing, editor=editormode) class AttachmentUploadHandler(FileUploadHandler): """ Simple upload handler to limit the size of the attachments users can upload. """ def __init__(self, request=None): super(AttachmentUploadHandler, self).__init__(request) self.total_upload = 0 self.toobig = False