Add files via upload

This commit is contained in:
Harold Finch
2023-04-10 07:23:44 +02:00
committed by GitHub
parent 047f85e92d
commit ae35dc5986
56 changed files with 11982 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_random_password,
display_preferred_language,
display_add_admin,
display_domain_creation_options_of_normal_admin
with context %}
{% from "macros/msg_handlers.html" import admin_msg_handler with context %}
{% block navlinks_create %}class="active"{% endblock %}
{% block title %}{{ _('Add admin') }}{% endblock title %}
{% block main %}
{# Show system message #}
{% if msg %}
{% if msg.startswith('PW_') %}
{% set _pw_errors = msg.split(',') %}
{% for _err in _pw_errors %}
{{ admin_msg_handler(_err) }}
{% endfor %}
{% else %}
{{ admin_msg_handler(msg) }}
{% endif %}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
{# -- Tabs -- #}
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/admins">{{ _('All admins') }}</a></li>
<li class="active"><a href="{{ctx.homepath}}/create/admin"><i class="fa fa-plus"></i>&nbsp;{{ _('Add admin') }}</a></li>
</ul>
<h2>{{ _('Add admin') }}</h2>
</div>
<div class="columns clear">
<div class="col2-3">
<div id="admin_add" class="box-wrap clear">
<form name="create" method="post" action="{{ctx.homepath}}/create/admin">
{{ input_csrf_token() }}
{{ display_add_admin(min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
lang=default_language,
languagemaps=languagemaps) }}
{{ display_domain_creation_options_of_normal_admin(admin_settings={}) }}
{{ input_submit(label=_('Add')) }}
</form>
</div>
</div>
<div class="box-wrap clear">
<div class="col1-3 lastcol">
{{ display_random_password(password_length=min_passwd_length,
password_policies=password_policies) }}
</div>
</div>
</div>
</div>
</div>
{% endblock main %}

View File

@@ -0,0 +1,118 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
set_account_status_img,
highlight_username_in_mail,
set_admin_type_img,
show_pages
with context
%}
{% from "macros/msg_handlers.html" import admin_msg_handler with context %}
{% block title %}{{ _('Domain Admins') }}{% endblock %}
{% block navlinks_admins %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{{ admin_msg_handler(msg) }}
{# List admins #}
{#{% if admins|length > 0 %}#}
{% if admins is not string %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
{% if session.get('is_global_admin') %}
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/admin"><i class="fa fa-plus"></i>&nbsp;{{ _('Add admin') }}</a></li>
</ul>
{% endif %}
<h2>{{ _('All admins') }}
{% if total is defined and admins|length > 0 %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + admins|length}}/{{ total }})
{% endif %}
</h2>
</div>
<form name="admins" id="list_table" method="post" action="{{ctx.homepath}}/admins">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('Global Admin') }}</th>
</tr>
</thead>
<tbody>
{% for r in admins %}
{% set mail = r.username |e %}
{% set name = r.name |e %}
<tr>
<td class="checkbox">
<input type="checkbox"
name="mail"
class="checkbox"
value="{{ mail }}"
{% if mail == session.get('username') %}disabled="disabled"{% endif %}
/>
</td>
<td>
<a href="{{ctx.homepath}}/profile/{% if r.get('isadmin') is not sameas none %}user{% else %}admin{% endif %}/general/{{ mail }}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(r.active) }}
{# -- Show name -- #}
<a href="{{ctx.homepath}}/profile/{% if r.get('isadmin') is not sameas none %}user{% else %}admin{% endif %}/general/{{ mail }}" title="{{ _('Edit account profile') }}">{% if name == '' %}{{ mail.split('@', 1)[0] }}{% else %}{{ name |cut_string }}{% endif %}</a>
</td>
<td>{{ mail }}</td>
{% if r.get('isglobaladmin') is not sameas none %}
{# users marked as admin #}
{% if r.get('isglobaladmin') == 1 %}
<td>{{ set_admin_type_img('yes') }}</td>
{% else %}
<td>{{ set_admin_type_img('no') }}</td>
{% endif %}
{% else %}
{# Separate admin accounts #}
{% if mail in allGlobalAdmins %}
<td>{{ set_admin_type_img('yes') }}</td>
{% else %}
<td>{{ set_admin_type_img('no') }}</td>
{% endif %}
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
{{ show_pages(baseurl=ctx.homepath + '/admins', total=total, cur_page=cur_page) }}
</div>
</form>
</div>{# -- box body -- #}
</div>{# -- content box -- #}
{% endif %}
{% endblock main %}

View File

@@ -0,0 +1,165 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
display_account_status,
display_input_cn,
display_preferred_language,
display_timezones,
display_reset_password,
display_random_password,
display_input_global_admin,
display_domain_creation_options_of_normal_admin
with context
%}
{% from "macros/sql.html" import
display_all_domains
with context
%}
{% from "macros/msg_handlers.html" import admin_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_admins %}class="active"{% endblock %}
{% block breadcrumb %}
{% if session.get('is_global_admin') %}
{% set crumbs = [(ctx.homepath + '/admins', _('All admins')),
('active', ctx.homepath + '/profile/admin/general/' + mail, _('Profile of admin:') + '&nbsp;' + mail)] %}
{% else %}
{% set crumbs = [('active', ctx.homepath + '/profile/admin/general/' + mail, _('Profile of admin:') + '&nbsp;' + mail)] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{% if msg %}
{% if msg.startswith('PW_') %}
{% set _pw_errors = msg.split(',') %}
{% for _err in _pw_errors %}
{{ admin_msg_handler(_err) }}
{% endfor %}
{% else %}
{{ admin_msg_handler(msg) }}
{% endif %}
{% endif %}
{% set navlinks = [
('general', _('General'), []),
('password', _('Password'), []),
]
%}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{ nav[0] }}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>{{ _('Profile of admin:') }} {{ mail }}</h2>
</div>
<div class="box-wrap clear">
<div id="profile_general">
<form name="general" method="post" action="{{ctx.homepath}}/profile/admin/general/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3">
{% if session.get('is_global_admin') %}
{{ display_account_status(profile.active) }}
{% endif %}
{{ display_input_cn(value=profile.name, account_type='admin') }}
{{ display_preferred_language(value=profile.get('language', 'en_US') |e,
languagemaps=languagemaps) }}
{{ display_timezones(value=admin_settings.get('timezone'), timezones=timezones) }}
{% if session.get('is_global_admin') %}
<div class="rule"></div>
{{ display_input_global_admin(value=is_global_admin) }}
{% endif %}
</div>
{% if session.get('is_global_admin') %}
<div class="col2-3">
{{ display_domain_creation_options_of_normal_admin(admin_settings=admin_settings) }}
</div>
<div class="col1-3 lastcol normal_admin_create_domain_options">
<div class="mark_blue bt-space10">
<p>{{ _('All domains managed by this admin share the mailbox quota and limit of mail accounts.') }}</p>
</div>
</div>{# .col1-3 #}
{% endif %}
{% if session.get('is_global_admin') %}
{{ display_all_domains(managedDomains=managedDomains, allDomains=allDomains) }}
{% endif %}
</div>{# .columns #}
{{ input_submit() }}
</form>
</div>
<div id="profile_password">
<form name="password" method="post" action="{{ctx.homepath}}/profile/admin/password/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col3-4">
{% if session.get('is_global_admin') %}
{{ display_reset_password(
min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
show_confirmpw=true,
store_password_in_plain_text=store_password_in_plain_text) }}
{% else %}
{{ display_reset_password(
min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
show_oldpw=true,
show_confirmpw=true,
store_password_in_plain_text=store_password_in_plain_text) }}
{% endif %}
</div>
<div class="col1-4 lastcol">
{{ display_random_password(password_length=min_passwd_length,
password_policies=password_policies) }}
</div>
</div>
{{ input_submit() }}
</form>
</div>
</div>{# .box-wrap #}
</div>{# .box-body #}
</div>{#-- .content-box --#}
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$(".tabs li").idTabs("profile_{{ profile_type }}");
$('#domain_search').quickfilter('#all_domains tr');
});
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,135 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import input_csrf_token with context %}
{% from "macros/general.html" import
display_subnav,
display_input_cn,
display_list_access_policies
with context %}
{% from "macros/msg_handlers.html" import alias_msg_handler, warning_info with context %}
{% block title %}{{ _('Add mail alias') }}{% endblock title %}
{% block navlinks_create %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ alias_msg_handler(msg) }}
{% set createNewAccount = true %}
{% set numberOfSpareAccounts = profile.aliases - num_existing_aliases %}
{% if profile.aliases == -1 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Not allowed to create mail alias under this domain.') %}
{% elif profile.aliases > 0 and numberOfSpareAccounts <= 0 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Already exceed max number of account limit (%d).') |format(profile.aliases |int) %}
{% endif %}
{% if not createNewAccount %}
<div class="notification note-error">
<p>
<strong>{{ _('Error:') }}</strong> {{ _("You can't create mail aliases under domain %s.") |format('<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '#accountLimit"><strong>' + cur_domain + '</strong></a>') }}
{{ whyDisabledCreation }}
</p>
</div>
{% else %}
{% if profile.aliases > 0 and numberOfSpareAccounts > 0 %}
<div class="notification note-info">
<p>{{ _('You can create <strong>%d</strong> more mail alias(es) under domain %s.') |format(numberOfSpareAccounts |int, '<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '"><strong>' + cur_domain + '</strong></a>') }}</p>
</div>
{% endif %}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/user/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li class="active"><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>
{{ _('Add mail alias') }}
<a href="{{ctx.homepath}}/profile/domain/general/{{cur_domain}}"><i class="fa fa-cog fa-lg" title="{{ _('Edit domain profile') }}"></i></a>
</h2>
</div>
<div id="alias_add" class="box-wrap clear">
<div class="columns clear">
{{ warning_info( _("It's better create a subscribable mailing list, so that you can restrict the mail posting and delivery.") ) }}
<form name="create" method="post" action="{{ctx.homepath}}/create/alias/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Add mail alias under domain') }} <span class="required">*</span></h4>
<span class="clean-padding">
<select name="domainName" onchange="change_url(this, baseurl='{{ctx.homepath}}/create/alias/');">
{% for d in allDomains %}
<option value="{{ d |e }}" {% if d == cur_domain %}selected{%endif%}>{{ d |e }}</option>
{% endfor %}
</select>
</span>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Mail Address') }} <span class="required">*</span></h4>
<span class="clean-padding">
<input type="text" size="35"
name="listname"
value="{{ listname |e }}"
class="text fl-space {% if not createNewAccount %}disabled{% endif %}"
{% if not createNewAccount %}disabled="disabled"{% endif %}
/>@{{ cur_domain }}
</span>
</div>
{{ display_input_cn(value=cn, enable_input=createNewAccount) }}
<div class="rule"></div>
{{ display_list_access_policies(policy=None, enable_input=createNewAccount) }}
<div class="rule2"></div>
<div class="form-field clear">
<h4 class="size-250 fl-space">&nbsp;</h4>
<span class="clean-padding bt-space20">
<input type="submit"
value="{{ _('Add') }}"
{% if not createNewAccount %}
class="button color-grey" disabled="disabled"
{% else %}
class="button green"
{% endif %}
/>
</span>
</div>
</form>
</div>{# .columns #}
</div>{# .box-wrap #}
</div>{# .content-box #}
</div>{# .box-body #}
{% endblock main %}

View File

@@ -0,0 +1,152 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
set_account_activity_img,
highlight_username_in_mail,
display_filter_by_first_char,
display_list_access_policy_name,
show_pages
with context
%}
{% from "macros/msg_handlers.html" import alias_msg_handler with context %}
{% block title %}{{ _('Mail Aliases') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
('active', ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
] %}
{% if session.get('is_global_admin') %}
{% set crumbs = crumbs + [(ctx.homepath + '/admins/' + cur_domain, _('Admins'))] %}
{% endif %}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ alias_msg_handler(msg) }}
{% if aliases is defined %}
{% if aliases or (not aliases and first_char) %}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/aliases/' + cur_domain,
available_chars=all_first_chars,
first_char=first_char,
disabled_only=disabled_only) }}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/user/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>
{{ _('Aliases under domain: %s.') |format(cur_domain) }}
{% if total is defined and aliases %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + aliases|length}}/{{total}})
{% endif %}
<a href="{{ctx.homepath}}/profile/domain/general/{{cur_domain}}"><i class="fa fa-cog fa-lg" title="{{ _('Edit domain profile') }}"></i></a>
{{ set_account_activity_img('sent', 'domain', cur_domain, float=false) }}
</h2>
</div>{# -- box-header -- #}
{# List all aliases. #}
<form name="aliases" id="list_table" action="{{ctx.homepath}}/aliases/{{cur_domain}}" method="post">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('Mail Deliver Restriction') }}</th>
</tr>
</thead>
{# List alias attributes/avalues. #}
<tbody>
{% if aliases |length > 0 %}
{% for r in aliases %}
{% set address = r.address |e %}
{% set name = r.name |e %}
<tr>
<td class="checkbox"><input type="checkbox" class="checkbox" name="mail" value="{{ address }}" /></td>
<td>
<a href="{{ctx.homepath}}/profile/alias/general/{{address}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(r.active) }}
<a href="{{ctx.homepath}}/profile/alias/general/{{address}}" title="{{ _('Edit account profile') }}">{% if name %}{{ name |cut_string |e }}{% else %}{{ address.split('@', 1)[0] }}{% endif %}</a>
</td>
<td>{{ highlight_username_in_mail(address) }}</td>
<td>{{ display_list_access_policy_name(policy=r.accesspolicy) }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td class="checkbox"></td>
<td colspan="3">{{ _('No mail alias available.') }}
{% if not first_char %}
<a href="{{ctx.homepath}}/create/alias/{{ cur_domain }}">{{ _('Add one') }}</a>?
{% endif %}
</td>
</tr>
{% endif %}
</tbody>
</table>
{% if aliases %}
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
{% set baseurl = ctx.homepath + '/aliases/' + cur_domain %}
{% if disabled_only %}
{% set baseurl = baseurl + '/disabled' %}
{% endif %}
{% set url_suffix = '' %}
{% if first_char %}
{% set url_suffix = '?starts_with=' + first_char %}
{% endif %}
{{ show_pages(baseurl=baseurl, total=total, cur_page=cur_page, url_suffix=url_suffix) }}
</div>
{% endif %}
</form>
</div>{# -- box-body -- #}
</div>{# -- content-body -- #}
{% endif %}
{% endblock main %}

View File

@@ -0,0 +1,142 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
display_input_cn,
display_change_email_address,
display_migrate_alias_to_ml,
display_account_status,
set_account_status_img,
display_list_access_policies
with context
%}
{% from "macros/msg_handlers.html" import alias_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
('active', ctx.homepath + '/profile/alias/general/' + mail, _('Profile of alias:') + '&nbsp;' + mail),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ alias_msg_handler(msg) }}
{% set navlinks = [
('general', _('General'), [true,]),
]
%}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _('Profile of alias:') }} {{ mail }}</h2>
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{nav[0]}}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>{# -- box-header -- #}
{# modal window used to change email address #}
{{ display_change_email_address(current_domain=cur_domain,
post_url=ctx.homepath + '/profile/alias/rename/' + mail ) }}
{{ display_migrate_alias_to_ml(mail=mail) }}
<div class="box-wrap clear">
<div id="profile_general">
<form name="general" id="list_table" method="post" action="{{ctx.homepath}}/profile/alias/{{profile_type}}/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 clear">
{{ display_account_status(profile.active) }}
{{ display_input_cn(value=profile.name) }}
</div>
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li><a href="#change_email_address" class="modal-link"><span class="text">{{ _('Change email address') }}</span></a></li>
<li><a href="#migrate_alias_to_ml" class="modal-link"><span class="text">{{ _('Migrate to subscribable mailing list') }}</span></a></li>
</ul>
</div>
</div>
</div>
<div class="columns clear">
<div class="col3-4 clear">
<div class="bt-space20"></div>
{# -- Access policy -- #}
{% set accessPolicy = profile.get('accesspolicy', 'public').lower() |e %}
{% if accessPolicy == '' %}
{% set accessPolicy = 'public' %}
{% endif %}
{{ display_list_access_policies(policy=accessPolicy) }}
</div>{# col3-4 #}
</div>{# .columns #}
<div class="bt-space0">&nbsp;</div>
{# List all members. #}
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Members') }}<a name="members">&nbsp;</a></h4>
<small>{{ _('One mail address per line. Invalid address will be discarded.') }}</small>
<textarea name="members"
class="textarea"
rows="6"
style="width: 40%;">{% for addr in profile.members %}{{ addr }}
{% endfor -%}
</textarea>
</div>{#-- .form-field --#}
<div class="bt-space0">&nbsp;</div>
{# List all moderators. #}
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Moderators') }}<a name="moderators">&nbsp;</a></h4>
<small>{{ _('One mail address per line. Invalid address will be discarded.') }}</small>
<textarea name="moderators"
class="textarea"
rows="6"
style="width: 40%;">{% for addr in profile.moderators %}{{ addr }}
{% endfor -%}
</textarea>
</div>{#-- .form-field --#}
{{ input_submit() }}
</form>
</div>{# #profile_general #}
</div>{#-- .box-wrap --#}
</div>{#-- .box-body --#}
</div>{#-- .content-box --#}
{% endblock main %}

View File

@@ -0,0 +1,62 @@
{% extends "layout.html" %}
{% from "macros/general.html" import display_add_domain with context %}
{% from "macros/msg_handlers.html" import
domain_msg_handler,
creation_limit_msg_handler
with context %}
{% block title %}{{ _('Add domain') }}{% endblock title %}
{% block navlinks_create %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{{ domain_msg_handler(msg) }}
{% if creation_limits['error_code'] %}
{% for err in creation_limits['error_code'] %}
{{ creation_limit_msg_handler(err) }}
{% endfor %}
{% endif %}
{% if creation_limits['create_new_domain'] %}
{# num_spare_domains: -1 means no limit #}
{% if creation_limits['num_spare_domains'] > 0 %}
<div class="notification note-info">
<p>{{ _('You can create <strong>%d</strong> more mail domains (Existing: %d, Max: %d)') |format(creation_limits['num_spare_domains'], creation_limits['num_managed_domains'], creation_limits['num_max_domains']) }}</p>
</div>
<div class="bt-space0"></div>
{% endif %}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _('Add domain') }}</h2>
</div>
{{ display_add_domain(label=false,
preferred_language=preferred_language,
languagemaps=languagemaps,
timezones=timezones,
create_new_domain=creation_limits['create_new_domain'],
num_max_domains=creation_limits['num_max_domains'],
num_managed_domains=creation_limits['num_managed_domains'],
num_spare_domains=creation_limits['num_spare_domains'],
num_max_quota=creation_limits['num_max_quota'],
num_allocated_quota=creation_limits['num_allocated_quota'],
num_spare_quota=creation_limits['num_spare_quota'],
num_max_users=creation_limits['num_max_users'],
num_allocated_users=creation_limits['num_allocated_users'],
num_spare_users=creation_limits['num_spare_users'],
num_max_aliases=creation_limits['num_max_aliases'],
num_allocated_aliases=creation_limits['num_allocated_aliases'],
num_spare_aliases=creation_limits['num_spare_aliases'],
num_max_lists=creation_limits['num_max_lists'],
num_allocated_lists=creation_limits['num_allocated_lists'],
num_spare_lists=creation_limits['num_spare_lists']) }}
</div>
</div>
{% endblock main %}

View File

@@ -0,0 +1,286 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
set_account_status_img,
set_account_activity_img,
set_alias_domain_img,
display_number_of_account_limited,
display_progress_bar,
display_filter_by_first_char,
display_add_domain,
show_pages,
display_remove_mailbox_days
with context
%}
{% from "macros/msg_handlers.html" import domain_msg_handler with context %}
{% block title %}{{ _('Domains and Accounts') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{{ domain_msg_handler(msg) }}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/domains',
first_char=first_char,
available_chars=all_first_chars,
account_type='domain',
disabled_only=disabled_only) }}
{# List all domains under control. #}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/domain"><i class="fa fa-plus"></i> {{ _('Add domain') }}</a></li>
</ul>
{% endif %}
<h2>
{{ _('All domains under your control.') }} {% if disabled_only %}({{ _('Disabled') }}){% endif %}
{% if total is defined and all_domain_profiles | length > 0 %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + all_domain_profiles | length}}/{{ total }})
{% endif %}
</h2>
</div>
<form id="form_domains" method="post" action="{{ctx.homepath}}/domains">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
{% endif %}
<th data-sort="string-ins">{{ _('Domain') }}</th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="int">{{ _('Quota') }}</th>
<th data-sort="int">{{ _('Users') }}</th>
<th data-sort="int">{{ _('Mailing Lists') }}</th>
<th data-sort="int">{{ _('Aliases') }}</th>
</tr>
</thead>
<tbody>
{% if all_domain_profiles %}
{% for r in all_domain_profiles %}
{% set domain = r.domain |e %}
<tr>
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<td class="checkbox vcenter">
<input type="checkbox"
class="checkbox"
name="domainName"
value="{{ domain }}" />
</td>
{% endif %}
<td class="vcenter">
<a href="{{ctx.homepath}}/profile/domain/general/{{ domain }}"
title="{{ _('Edit domain profile') }}"
>{{ domain }}</a>
<a href="{{ctx.homepath}}/profile/domain/general/{{ domain }}">
<i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit domain profile') }}"></i>
</a>
<a href="{{ctx.homepath}}/export/domain/{{domain}}"><i class="fas fa-download fr-space" title="{{ _('Export accounts') }}"></i></a>
{% set _alias_domains = all_alias_domains.get(domain, []) %}
{% set _pending_alias_domains = [] %}
{% for d in _alias_domains %}
{% if d in pending_domains %}
{% do _pending_alias_domains.append(d) %}
{% endif %}
{% endfor %}
{{ set_account_activity_img('sent', 'domain', domain) }}
{# Check whether domain is a real backup mx #}
{% set is_real_backupmx = false %}
{% if r.backupmx == 1 and r.transport.startswith('relay:') %}
{% set is_real_backupmx = true %}
{% endif %}
{{ set_account_status_img(status=r.active,
account_type='domain',
is_relay=r.transport not in local_transports,
relay=r.transport,
backupmx=r.backupmx,
is_backupmx=is_real_backupmx) }}
{{ set_alias_domain_img(alias_domains=_alias_domains) }}
{% if (domain in pending_domains) or _pending_alias_domains %}
<span class="fr-space small_label bgcolor-red"
style="vertical-align: middle;"
><a href="{{ctx.homepath}}/verify/domain_ownership"
style="text-decoration: none; color: white;"
>{{ _('PLEASE VERIFY OWNERSHIP') }}</a>
</span>
{% endif %}
</td>
<td class="vcenter">{% if r.description %}{{ r.description |cut_string |e }}{% endif %}</td>
{#-- Domain Quota --#}
<td class="vcenter" data-sort-value="{{ r.maxquota }}">
{% set used_quota = domain_used_quota.get(domain, {}).get('size', 0) %}
{% if r.maxquota > 0 %}
{% set percent_allocated = r.quota_count |convert_to_percentage(r.maxquota) %}
{% set percent_used_quota = (used_quota/1024/1024) |convert_to_percentage(r.maxquota) %}
{% if session.get('is_global_admin') %}
{#-- Link to domain profile page. --#}
<a href="{{ctx.homepath}}/profile/domain/general/{{domain}}" style="text-decoration: none;"><span title="{{ _('Edit quota setting') }}">{{ percent_allocated }}%</span> <span class="color-grey"><span title="{{ _('Used') }}">({{ used_quota | file_size_format }}</span> / <span title="{{ _('Allocated') }}">{{ r.quota_count |file_size_format(base_mb=True) }}</span>) <span title="{{ _('Total') }}">{{ display_number_of_account_limited(r.maxquota |file_size_format(base_mb=True)) }}</span></a>
{% else %}
<span>{{ percent_allocated }}%</span> <span class="color-grey"><span title="{{ _('Used') }}">({{ used_quota | file_size_format }}</span> / <span title="{{ _('Allocated') }}">{{ r.quota_count |file_size_format(base_mb=True) }}</span>) <span title="{{ _('Total') }}">{{ display_number_of_account_limited(r.maxquota |file_size_format(base_mb=True)) }}</span></span>
{% endif %}
{{ display_progress_bar(percent_used_quota, tooltip=_('Used'), style='thin') }}
{{ display_progress_bar(percent_allocated, tooltip=_('Allocated'), style='thin') }}
{% else %}
{% if session.get('is_global_admin') %}
<span title="{{ _('Used') }}">{{ used_quota | file_size_format }}</span> / <span title="{{ _('Allocated') }}">{{ r.quota_count |file_size_format(base_mb=True) }}</span> / <a href="{{ctx.homepath}}/profile/domain/general/{{domain}}" title="{{ _('Edit quota setting') }}" style="text-decoration: none;">{{ _('Unlimited') }}</a>
{% else %}
<span title="{{ _('Used') }}">{{ used_quota | file_size_format }}</span> / <span title="{{ _('Allocated') }}">{{ r.quota_count |file_size_format(base_mb=True) }}</span> / <span title="{{ _('Total') }}">{{ _('Unlimited') }}</span>
{% endif %}
{% endif %}
</td>
{#-- Users --#}
<td class="vcenter" data-sort-value="{{ r.mailboxes }}">
{% if r.num_existing_users %}
{% set num_existing_users = r.num_existing_users | int %}
{% else %}
{% set num_existing_users = 0 %}
{% endif %}
{% if r.mailboxes > 0 %}
{% set percentOfNumberOfUsers = num_existing_users |convert_to_percentage(r.mailboxes) %}
<a href="{{ctx.homepath}}/users/{{domain}}" title="{{ _('List all mail users.') }}" style="text-decoration: none; display: block; padding: 0 10px 0 10px;">{{ percentOfNumberOfUsers }}% <span class="color-grey">({% if num_existing_users is not sameas none %}{{ num_existing_users }}{% else %}0{% endif %} {{ display_number_of_account_limited(r.mailboxes) }})</span></a>
{{ display_progress_bar(percentOfNumberOfUsers, style='thin') }}
{% elif r.mailboxes == -1 %}
<span class="color-grey"><em>{{ _('DISABLED') }}</em></span>
{% else %}
<a href="{{ctx.homepath}}/users/{{domain}}" title="{{ _('List all mail users.') }}" style="text-decoration: none; display: block; padding: 0 10px 0 10px;">{% if num_existing_users is not sameas none %}{{ num_existing_users }}{% else %}0{% endif %}</a>
{% endif %}
</td>
{#-- Mailing list --#}
<td class="vcenter" data-sort-value="{{ r.maillists }}">
{% if r.num_existing_maillists %}
{% set num_existing_maillists = r.num_existing_maillists | int %}
{% else %}
{% set num_existing_maillists = 0 %}
{% endif %}
{% if r.maillists > 0 %}
{% set percentOfNumberOfMaillists= num_existing_maillists |convert_to_percentage(r.maillists) %}
<a href="{{ctx.homepath}}/mls/{{domain}}"
title="{{ _('List all mailing lists.') }}"
style="text-decoration: none; display: block; padding: 0 10px 0 10px;"
>{{ percentOfNumberOfMaillists }}% <span class="color-grey">({{ num_existing_maillists }} {{ display_number_of_account_limited(r.maillists) }})</span></a>
{{ display_progress_bar(percentOfNumberOfMaillists, style='thin') }}
{% elif r.maillists == -1 %}
<span class="color-grey"><em>{{ _('DISABLED') }}</em></span>
{% else %}
<a href="{{ctx.homepath}}/mls/{{domain}}"
title="{{ _('List all mailing lists.') }}"
style="text-decoration: none; display: block; padding: 0 10px 0 10px;">{% if num_existing_maillists is not sameas none %}{{ num_existing_maillists }}{% else %}0{% endif %}</a>
{% endif %}
</td>
{#-- Aliases --#}
<td class="vcenter" data-sort-value="{{ r.aliases }}">
{% if r.num_existing_aliases %}
{% set num_existing_aliases = r.num_existing_aliases | int %}
{% else %}
{% set num_existing_aliases = 0 %}
{% endif %}
{% if r.aliases > 0 %}
{% set percentOfNumberOfAliases = num_existing_aliases |convert_to_percentage(r.aliases) %}
<a href="{{ctx.homepath}}/aliases/{{domain}}" title="{{ _('List all mail aliases.') }}" style="text-decoration: none; display: block; padding: 0 10px 0 10px;">{{ percentOfNumberOfAliases }}% <span class="color-grey">({{ num_existing_aliases }} {{ display_number_of_account_limited(r.aliases) }})</span></a>
{{ display_progress_bar(percentOfNumberOfAliases, style='thin') }}
{% elif r.aliases == -1 %}
<span class="color-grey"><em>{{ _('DISABLED') }}</em></span>
{% else %}
<a href="{{ctx.homepath}}/aliases/{{domain}}" title="{{ _('List all mail aliases.') }}" style="text-decoration: none; display: block; padding: 0 10px 0 10px;">{% if num_existing_aliases is not sameas none %}{{ num_existing_aliases }}{% else %}0{% endif %}</a>
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<td class="checkbox"></td>
<td class="vcenter" colspan="5">{{ _('No mail domain available.') }}
{% if not (first_char or disabled_only) %}
<a href="{{ctx.homepath}}/create/domain">{{ _('Add one') }}</a>?
{% endif %}
</td>
{% else %}
<td class="vcenter" colspan="5">{{ _('No mail domain available.') }}</td>
{% endif %}
</tr>
{% endif %}
</tbody>
</table>
<div class="tab-footer clear f1">
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<div class="fl">
<select name="action" class="fl-space" id="account_list_actions" >
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<select name="keep_mailbox_days" class="fl-space" id="account_delete_date">
{% for _day in days_to_keep_removed_mailbox %}
<option value="{{ _day }}">{{ display_remove_mailbox_days(_day) }}</option>
{% endfor %}
</select>
<input type="submit" name="submit_domains" value="{{ _('Apply') }}" class="button fl-space" />
</div>
{% endif %}
{% set baseurl = ctx.homepath + '/domains' %}
{% if disabled_only %}
{% set baseurl = ctx.homepath + '/domains/disabled' %}
{% endif %}
{% set url_suffix = '' %}
{% if first_char %}
{% set url_suffix = url_suffix + '?starts_with=' + first_char %}
{% endif %}
{{ show_pages(baseurl=baseurl,
total=total,
cur_page=cur_page,
url_suffix=url_suffix) }}
</div>
</form>
</div>
</div>
{% endblock main %}

View File

@@ -0,0 +1,773 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token,
input_text
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
set_account_activity_img,
display_domain_cn,
display_preferred_language,
display_timezones,
display_account_status,
display_domain_backupmx,
display_relay,
display_sender_relayhost,
display_domain_quota,
display_domain_default_userquota,
display_domain_max_user_quota,
display_recipient_bcc,
display_sender_bcc,
display_disabled_account_profiles,
display_disabled_domain_mail_services,
display_per_account_wblist_all
with context
%}
{% from "macros/sql.html" import
display_enabled_domain_services
with context %}
{% from "macros/iredapd.html" import
display_throttle_setting,
display_greylisting_setting,
display_greylisting_whitelists
with context
%}
{% from "macros/amavisd.html" import display_spam_policy with context %}
{% from "macros/msg_handlers.html" import domain_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
('active', ctx.homepath + '/profile/domain/general/' + cur_domain, _('Profile of domain:') + '&nbsp;' + cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{# Domain profile. #}
{% block main %}
{% if pending_domains %}
<div class="notification note-attention">
<p><strong>{{ _('Mail services are disabled for domain(s): %s, please <a href="%s/verify/domain_ownership">verify domain ownership</a> first.' | format(pending_domains |join(', '), ctx.homepath)) }}</strong></p>
</div>
{% endif %}
{# Show system message #}
{{ domain_msg_handler(msg) }}
{% set enabled_services = domain_settings.get('enabled_services', []) %}
{% set disabled_mail_services = domain_settings.get('disabled_mail_services', []) %}
{% set disabled_domain_profiles = domain_settings.get('disabled_domain_profiles', []) %}
{% set disabled_user_profiles = domain_settings.get('disabled_user_profiles', []) %}
{% set disabled_user_preferences = domain_settings.get('disabled_user_preferences', []) %}
{% if session.get('is_global_admin') %}
{% set navlinks = [
('general', _('General'), [true]),
('bcc', _('BCC'), [true]),
('relay', _('Relay'), [true]),
('catchall', _('Catch-all'), [true]),
('aliases', _('Aliases'), [true]),
('throttle', _('Throttling'), [session.get('iredapd_enabled')]),
('greylisting', _('Greylisting'), [session.get('iredapd_enabled')]),
('wblist', _('White/Blacklist'), [session.get('amavisd_enable_policy_lookup')]),
('spampolicy', _('Spam Policy'), [session.get('amavisd_enable_policy_lookup')]),
('backupmx', _('Backup MX'), [true]),
('advanced', _('Advanced'), [true]),
]
%}
{% else %}
{% set navlinks = [
('general', _('General'), [true]),
('bcc', _('BCC'), ['bcc' not in disabled_domain_profiles]),
('relay', _('Relay'), ['relay' not in disabled_domain_profiles]),
('catchall', _('Catch-all'), ['catchall' not in disabled_domain_profiles]),
('aliases', _('Aliases'), ['aliases' not in disabled_domain_profiles]),
('throttle', _('Throttling'), ['throttle' not in disabled_domain_profiles, session.get('iredapd_enabled')]),
('greylisting', _('Greylisting'), ['greylisting' not in disabled_domain_profiles, session.get('iredapd_enabled')]),
('wblist', _('White/Blacklist'), [(session.get('amavisd_enable_policy_lookup') and 'wblist' not in disabled_domain_profiles)]),
('spampolicy', _('Spam Policy'), [(session.get('amavisd_enable_policy_lookup') and 'spampolicy' not in disabled_domain_profiles)]),
('backupmx', _('Backup MX'), ['backupmx' not in disabled_domain_profiles]),
('advanced', _('Advanced'), [true]),
]
%}
{% endif %}
<div class="content-box">
<div class="box-body">
{#-- Links --#}
<div class="box-header clear">
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{ nav[0] }}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>{{ set_account_activity_img('sent', 'domain', cur_domain, float=false) }}</h2>
</div>{# .box-header #}
<div class="box-wrap clear">
{# profile_type: general #}
<div id="profile_general">
<form name="general" method="post" action="{{ctx.homepath}}/profile/domain/general/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col3-4 ">
{% if cur_domain not in pending_domains %}
{# normal admin, and not domain ownership verification required #}
{{ display_account_status(profile.active, account_type='domain') }}
{% endif %}
{{ display_domain_cn(cn=profile.description) }}
</div>{# .col2-3 #}
</div>
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<div class="columns clear">
<div class="col2-3">
{{ display_domain_quota(
quota=profile.maxquota | int,
required=(session.get('create_new_domains') and (creation_limits['num_max_quota'] > 0)),
num_allocated_quota=creation_limits['num_allocated_quota'],
num_max_quota=creation_limits['num_max_quota'],
num_spare_quota=creation_limits['num_spare_quota'],
) }}
</div>{# .col2-3 #}
{% if session.get('is_global_admin') %}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Set to 0 for unlimited.') }}</li>
</ul>
</div>
</div>
{% endif %}
</div>{# .columns #}
{% endif %}
<div class="rule">&nbsp;</div>
<div class="columns clear">
<div class="col2-3">
{% set default_user_quota = domain_settings.get('default_user_quota', '0') | int %}
{% set max_user_quota = domain_settings.get('max_user_quota', 0) | int %}
{{ display_domain_default_userquota(default_user_quota, max_user_quota=max_user_quota) }}
{% if session.get('is_global_admin') %}
{{ display_domain_max_user_quota(max_user_quota) }}
{% endif %}
</div>{# .col2-3 #}
{% if session.get('is_global_admin') %}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Domain admin cannot assign more than max quota to a mail user.') }}</li>
</ul>
</div>
</div>{# .col1-3 #}
{% endif %}
</div>{# .columns #}
{{ input_submit() }}
</form>
</div><!-- . profile_general -->
{# profile_type: bcc #}
{% if session.get('is_global_admin') or 'bcc' not in disabled_domain_profiles %}
<div id="profile_bcc">
<form name="bcc" method="post" action="{{ctx.homepath}}/profile/domain/bcc/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 ">
{{ display_recipient_bcc(address=profile.rbcc_addr) }}
{{ display_sender_bcc(address=profile.sbcc_addr) }}
</div>{#-- .col2-3 --#}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Multiple addresses are NOT supported.') }}</li>
<li class="bt-space5">{{ _('Per-user bcc settings has higher priority than per-domain bcc settings.') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{#-- .columns --#}
{{ input_submit() }}
</form>
</div><!-- #profile_bcc -->
{% endif %}
{# profile_type: relay #}
{% if session.get('is_global_admin') or 'relay' not in disabled_domain_profiles %}
<div id="profile_relay">
<form name="relay" method="post" action="{{ctx.homepath}}/profile/domain/relay/{{cur_domain}}">
{{ input_csrf_token() }}
{{ display_relay(transport=profile.transport |string,
default_mta_transport=default_mta_transport,
is_backupmx=profile.backupmx) }}
<div class="rule"></div>
{{ display_sender_relayhost(relayhost=profile.relayhost) }}
{{ input_submit() }}
</form>
</div><!-- #profile_relay -->
{% endif %}
{# profile_type: catchall #}
{% if session.get('is_global_admin') or 'catchall' not in disabled_domain_profiles %}
<div id="profile_catchall">
<form name="catchall" method="post" action="{{ctx.homepath}}/profile/domain/catchall/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Catch-all Addresses') }}</h4>
<small>{{ _('One mail address per line. Invalid address will be discarded.') }}</small>
<textarea name="catchall_addresses"
rows="6"
style="width: 50%"
class="textarea" >{%- for addr in profile.catchall |sort %}{{ addr |e }}
{% endfor -%}
</textarea>
</div>
</div>{#-- .col2-3 --#}
<div class="col1-3 lastcol">
<div class="notification note-attention">
<p>{{ _('Catch-all address may receive many spam emails.') }}</p>
</div>
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Emails delivered to non-exist mail accounts will be forwarded to catch-all address(es).') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{#-- .columns --#}
{{ input_submit() }}
</form>
</div><!-- #profile_catchall -->
{% endif %}
{# profile_type: aliases #}
{% if session.get('is_global_admin') or 'aliases' not in disabled_domain_profiles %}
<div id="profile_aliases">
<form name="aliases" method="post" action="{{ctx.homepath}}/profile/domain/aliases/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Alias domains') }}</h4>
{% if alias_domains %}
{% for d in alias_domains |sort %}
{% if not loop.first %}
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">&nbsp;</h4>
{% endif %}
<input type="text" name="domainAliasName" value="{{ d |e }}" size="35" class="text" />
{% if d in pending_domains %}<small>&nbsp;{{ _('Domain ownership verification required') }}</small>{% endif %}
{% endfor %}
{% else %}
<input type="text" name="domainAliasName" value="" size="35" class="text" />
{% endif %}
</div>
{#-- Always display an empty input field to add new value --#}
<div class="form-field clear">
{% if domainAliasName |length == 0 %}
<h4 class="size-250 fl-space">&nbsp;</h4>
{% else %}
<h4 class="size-250 fl-space">&nbsp;</h4>
{% endif %}
<input type="text" name="domainAliasName" value="{{ d |e }}" size="35" class="text" />
</div>
</div>{# .col2-3 #}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Emails sent to <em><strong>user@[ALIAS_DOMAIN]</strong></em> will be delivered to <em><strong>user@%s</strong></em>.') |format(cur_domain) }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{#-- .columns --#}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# profile_type: throttling #}
{% if session.get('is_global_admin') or 'throttle' not in disabled_domain_profiles %}
<div id="profile_throttle">
<form name="throttle" method="post" action="{{ctx.homepath}}/profile/domain/throttle/{{cur_domain}}">
{{ input_csrf_token() }}
{% if session.get('iredapd_enabled') %}
{# Throttling with iRedAPD #}
<div class="columns clear">
{{ input_csrf_token() }}
{{ display_throttle_setting(account='@' + cur_domain,
setting=outbound_throttle_setting,
inout_type='outbound') }}
{{ display_throttle_setting(account='@' + cur_domain,
setting=inbound_throttle_setting,
inout_type='inbound',
with_left_border=true) }}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('This throttle setting will be applied to all individual accounts under domain %s.') |format(cur_domain) }}</li>
<li class="bt-space5">{{ _('You can set per-user throttling in account profile page.') }}</li>
<li class="bt-space5">{{ _('Per-user throttle setting has higher priority.') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{# .columns #}
{% endif %}
{{ input_submit() }}
</form>
</div>{# #profile_throttle #}
{% endif %}
{# profile_type: greylisting, with iRedAPD #}
{% if session.get('is_global_admin') or 'greylisting' not in disabled_domain_profiles %}
{% if session.get('iredapd_enabled') %}
<div id="profile_greylisting">
<form name="greylisting" method="post" action="{{ctx.homepath}}/profile/domain/greylisting/{{cur_domain}}">
{{ input_csrf_token() }}
{{ display_greylisting_setting(account='@' + cur_domain, gl_setting=gl_setting) }}
{{ display_greylisting_whitelists(account='@' + cur_domain, gl_whitelists=gl_whitelists) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{% endif %}
{# wblist #}
{% if session.get('amavisd_enable_policy_lookup') and (session.get('is_global_admin') or ('wblist' not in disabled_domain_profiles)) %}
<div id="profile_wblist">
<form name="wblist" method="post" action="{{ctx.homepath}}/profile/domain/wblist/{{cur_domain}}">
{{ input_csrf_token() }}
{{ display_per_account_wblist_all(inbound_whitelists=whitelists,
inbound_blacklists=blacklists,
outbound_whitelists=outbound_whitelists,
outbound_blacklists=outbound_blacklists) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# profile_type: spampolicy #}
{% if session.get('amavisd_enable_policy_lookup') and (session.get('is_global_admin') or ('spampolicy' not in disabled_domain_profiles)) %}
<div id="profile_spampolicy">
<form name="spampolicy" method="post" action="{{ctx.homepath}}/system/spampolicy/{{cur_domain}}">
{{ input_csrf_token() }}
{{ display_spam_policy(account_type='domain',
spampolicy=spampolicy,
custom_ban_rules=custom_ban_rules,
global_spam_score=global_spam_score) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# profile_type: advanced #}
<div id="profile_advanced">
<form name="advanced" method="post" action="{{ctx.homepath}}/profile/domain/advanced/{{cur_domain}}">
{{ input_csrf_token() }}
{% if session.get('is_global_admin') or session.get('create_new_domains') %}
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<a name="accountLimit">&nbsp;</a>
<h4 class="size-250 fl-space">{{ _('Number of max mail users') }}
{% if session.get('create_new_domains') %}
{% if creation_limits['num_max_users'] > 0 -%}<span class="required">*</span>{% endif %}
{% endif %}
</h4>
<span class="clean-padding fl-space">
<input type="text" size="8"
name="numberOfUsers"
value="{% if profile.mailboxes != 0 %}{{ profile.mailboxes |e }}{% endif %}"
class="text fl-space" />
{% if session.get('is_global_admin') %}
<label>{{ _('%s account(s) exist.') |format(profile.num_existing_users |e) }}</label>
{% elif session.get('create_new_domains') %}
{% if creation_limits['num_max_users'] > 0 %}
<label>{{ _('Max:') }} {{ profile.mailboxes |int + creation_limits['num_spare_users'] }}</label>
{% endif %}
{% endif %}
</span>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Number of max mail aliases') }}
{% if session.get('create_new_domains') %}
{% if creation_limits['num_max_aliases'] > 0 -%}<span class="required">*</span>{% endif %}
{% endif %}
</h4>
<span class="clean-padding">
<input type="text" size="8"
name="numberOfAliases"
value="{% if profile.aliases != 0 %}{{ profile.aliases |e }}{% endif %}"
class="text fl-space" />
{% if session.get('is_global_admin') %}
<label>{{ _('%s account(s) exist.') |format(all_alias_accounts |length |string) }}</label>
{% elif session.get('create_new_domains') %}
{% if creation_limits['num_max_aliases'] > 0 %}
<label>{{ _('Max:') }} {{ profile.aliases |int + creation_limits['num_spare_aliases'] }}</label>
{% endif %}
{% endif %}
</span>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Number of max mailing lists') }}
{% if session.get('create_new_domains') %}
{% if creation_limits['num_max_lists'] > 0 -%}<span class="required">*</span>{% endif %}
{% endif %}
</h4>
<span class="clean-padding">
<input type="text" size="8"
name="numberOfLists"
value="{% if profile.maillists != 0 %}{{ profile.maillists |e }}{% endif %}"
class="text fl-space" />
{% if session.get('is_global_admin') %}
<label>{{ _('%s account(s) exist.') |format(mails_of_all_mailing_lists |length |string) }}</label>
{% elif session.get('create_new_domains') %}
{% if creation_limits['num_max_lists'] > 0 %}
<label>{{ _('Max:') }} {{ profile.maillists |int + creation_limits['num_spare_lists'] }}</label>
{% endif %}
{% endif %}
</span>
</div>
<div class="clear bt-space">&nbsp;</div>
</div><!-- .col2-3 -->
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
{% if session.get('is_global_admin') %}
<li class="bt-space5">{{ _('Set value to 0 or leave it empty for unlimited.') }}</li>
<li class="bt-space5">{{ _('Set value to -1 means not allowed to create this kind of account.') }}</li>
{% elif session.get('create_new_domains') %}
<li class="bt-space5">{{ _('Leave it empty to use max value.') }}</li>
{% endif %}
</ul>
</div>
</div><!-- .col1-3 -->
</div><!-- .columns -->
{% endif %}
{# Password length #}
{% if session.get('is_global_admin') or ('password_policies' not in disabled_domain_profiles) %}
<div class="columns clear">
<div class="col2-3 ">
{% set min_passwd_length = domain_settings.get('min_passwd_length') %}
{% set max_passwd_length = domain_settings.get('max_passwd_length') %}
{% if session.get('is_global_admin') %}
{% set comment_min_passwd_length = none %}
{% set comment_max_passwd_length = none %}
{% else %}
{% if global_min_passwd_length > 0 %}
{% set comment_min_passwd_length = _('Can not be shorter than') + ' ' + (global_min_passwd_length | string ) %}
{% else %}
{% set comment_min_passwd_length = none %}
{% endif %}
{% if global_max_passwd_length > 0 %}
{% if global_min_passwd_length > 0 %}
{% set comment_max_passwd_length = _('Can not be shorter than') + ' ' + (global_min_passwd_length | string ) + ' ' + _('or longer than') + ' ' + (global_max_passwd_length | string) %}
{% else %}
{% set comment_max_passwd_length = _('Can not be longer than') + ' ' + (global_max_passwd_length | string) %}
{% endif %}
{% else %}
{% if global_min_passwd_length > 0 %}
{% set comment_max_passwd_length = _('Can not be shorter than') + ' ' + (global_min_passwd_length | string ) %}
{% else %}
{% set comment_max_passwd_length = none %}
{% endif %}
{% endif %}
{% endif %}
{{ input_text(label=_('Minimum password length'),
input_name='minPasswordLength',
value=min_passwd_length,
size=8,
comment=comment_min_passwd_length,
comment_as_text=True) }}
{{ input_text(label=_('Maximum password length'),
input_name='maxPasswordLength',
value=max_passwd_length,
size=8,
comment=comment_max_passwd_length,
comment_as_text=True) }}
</div>{# .col2-3 #}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Leave it empty to use server-wide default setting.') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{#-- .columns --#}
{% endif %}
<div class="rule"></div>
<div class="columns clear">
<div class="col2-3 ">
{{ display_preferred_language(
value=domain_settings.get('default_language'),
languagemaps=languagemaps,
label=_('Default language for new user')) }}
{{ display_timezones(value=domain_settings.get('timezone'), timezones=timezones) }}
</div>
</div>
{% if session.get('is_global_admin') or 'bcc' not in disabled_domain_profiles %}
<div class="rule"></div>
<div class="columns clear">
<div class="col2-3 ">
{{ display_recipient_bcc(address=domain_settings.get('default_recipient_bcc', ''), label=_('Default bcc address for incoming emails for new user')) }}
{{ display_sender_bcc(address=domain_settings.get('default_sender_bcc', ''), label=_('Default bcc address for outgoing emails for new user')) }}
</div><!-- .col2-3 -->
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('These addresses will be assigned to newly created mail user as per-user bcc address.') }}</li>
</ul>
</div>
</div><!-- .col1-3 -->
</div>
{% endif %}
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Default mailing list(s) of new user') }}</h4>
<div class="checklist clear">
<fieldset>
{% if domain_settings.get('default_mailing_lists', []) %}
{% set default_mailing_lists = domain_settings.get('default_mailing_lists') %}
{% else %}
{% set default_mailing_lists = [] %}
{% endif %}
{# Show non-exist lists which still stored in default_mailing_lists #}
{% for addr in default_mailing_lists |sort %}
{% if addr and addr not in mails_of_all_mailing_lists %}
<div class="checklist-item">
<span class="clean-padding">
<input type="checkbox"
name="default_mail_list"
class="checkbox fl-space"
rel="checkboxhorizont"
checked="checked"
value="{{ addr |e }}"
/>
</span>
<label>{{ addr |e }} (<span class="required">{{ _('Warning') }}: {{ _('Account does not exist.') }}</span>)</label>
</div>
<div class="clear"></div>
{% endif %}
{% endfor %}
{% for rcd in all_mailing_lists %}
<div class="checklist-item">
<span class="clean-padding">
<input type="checkbox"
name="default_mail_list"
class="checkbox fl-space"
rel="checkboxhorizont"
value="{{ rcd.address |e }}"
{% if rcd.address in default_mailing_lists %}checked="checked"{% endif %}
/>
</span>
<label>
<a href="{{ctx.homepath}}/profile/ml/general/{{ rcd.address |e }}">{% if rcd.name %}{{ rcd.name |e }}{% else %}{{ rcd.address.split('@', 1)[0] }}{% endif %}</a>&nbsp;({{ rcd.address |e }})
</label>
</div>
<div class="clear"></div>
{% endfor %}
</fieldset>
</div>
</div><!-- .form-field -->
</div><!-- .col2-3 -->
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5"><a href="{{ctx.homepath}}/create/ml/{{ cur_domain }}" class="action_add">{{ _('Add mailing list') }}</a></li>
</ul>
</div>
</div><!-- .col1-3 -->
</div><!-- .columns -->
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Default mail alias(es) of new user') }}</h4>
<div class="checklist clear">
<fieldset>
{% if domain_settings.get('default_groups', []) %}
{% set default_groups = domain_settings.get('default_groups') %}
{% else %}
{% set default_groups = [] %}
{% endif %}
{# Show non-exist lists which still stored in default_groups #}
{% for addr in default_groups |sort %}
{% if addr and addr not in mails_of_all_alias_accounts %}
<div class="checklist-item">
<span class="clean-padding">
<input type="checkbox"
name="defaultList"
class="checkbox fl-space"
rel="checkboxhorizont"
checked="checked"
value="{{ addr |e }}"
/>
</span>
<label>{{ addr |e }} (<span class="required">{{ _('Warning') }}: {{ _('Account does not exist.') }}</span>)</label>
</div>
<div class="clear"></div>
{% endif %}
{% endfor %}
{% for rcd in all_alias_accounts %}
<div class="checklist-item">
<span class="clean-padding">
<input type="checkbox"
name="defaultList"
class="checkbox fl-space"
rel="checkboxhorizont"
value="{{ rcd.address |e }}"
{% if rcd.address in default_groups %}checked="checked"{% endif %}
/>
</span>
<label>
<a href="{{ctx.homepath}}/profile/alias/general/{{ rcd.address |e }}">{% if rcd.name %}{{ rcd.name |e }}{% else %}{{ rcd.address.split('@', 1)[0] }}{% endif %}</a>&nbsp;({{ rcd.address |e }})
</label>
</div>
<div class="clear"></div>
{% endfor %}
</fieldset>
</div>
</div><!-- .form-field -->
</div><!-- .col2-3 -->
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5"><a href="{{ctx.homepath}}/create/alias/{{ cur_domain }}" class="action_add">{{ _('Add mail alias') }}</a></li>
</ul>
</div>
</div><!-- .col1-3 -->
</div><!-- .columns -->
<div class="rule"></div>
{# Enabled services #}
{{ display_enabled_domain_services(enabled_services=enabled_services) }}
{# Disabled per-domain mail services #}
{% if session.get('is_global_admin') or 'disabled_mail_services' not in disabled_domain_profiles %}
<div class="rule"></div>
{{ display_disabled_domain_mail_services(disabled_mail_services=disabled_mail_services) }}
{% endif %}
{% if session.get('is_global_admin') %}
<div class="rule"></div>
{# Disabled domain profiles #}
{{ display_disabled_account_profiles(account_type='domain',
disabled_profiles=disabled_domain_profiles) }}
<div class="rule"></div>
{# Disabled user profiles #}
{{ display_disabled_account_profiles(account_type='user',
disabled_profiles=disabled_user_profiles) }}
{% endif %}
<div class="rule"></div>
{# Disabled user profiles #}
{{ display_disabled_account_profiles(account_type='user_preference',
disabled_profiles=disabled_user_preferences) }}
{{ input_submit() }}
</form>
</div><!-- #profile_advanced -->
{# profile_type: backupmx #}
{% if session.get('is_global_admin') or 'backupmx' not in disabled_domain_profiles %}
<div id="profile_backupmx">
<form name="backupmx" method="post" action="{{ctx.homepath}}/profile/domain/backupmx/{{cur_domain}}">
{{ input_csrf_token() }}
{{ display_domain_backupmx(domain=cur_domain,
backupmx=profile.backupmx,
transport=profile.transport) }}
{{ input_submit() }}
</form>
</div><!-- #profile_backupmx -->
{% endif %}
</div><!-- .box-wrap -->
</div><!-- .box-body -->
</div><!-- .content-box -->
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$(".tabs li").idTabs("profile_{{ profile_type }}")
});
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,131 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import input_csrf_token with context %}
{% from "macros/general.html" import
display_subnav,
display_input_cn
with context
%}
{% from "macros/mlmmj.html" import display_maillist_basic_profile with context %}
{% from "macros/msg_handlers.html" import maillist_msg_handler with context %}
{% block title %}{{ _('Add mailing list') }}{% endblock title %}
{% block navlinks_create %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ maillist_msg_handler(msg) }}
{% set createNewAccount = true %}
{% set numberOfSpareAccounts = profile.maillists - num_existing_maillists %}
{% if profile.maillists == -1 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Not allowed to create mailing list under this domain.') %}
{% elif profile.maillists > 0 and numberOfSpareAccounts <= 0 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Already exceed max number of account limit (%d).') |format(profile.maillists |int) %}
{% endif %}
{% if not createNewAccount %}
<div class="notification note-error">
<p>
<strong>{{ _('Error:') }}</strong> {{ _("You can't create mailing lists under domain %s.") |format('<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '#accountLimit"><strong>' + cur_domain + '</strong></a>') }}
{{ whyDisabledCreation }}
</p>
</div>
{% else %}
{% if profile.maillists > 0 and numberOfSpareAccounts > 0 %}
<div class="notification note-info">
<p>{{ _('You can create <strong>%d</strong> more mailing list(s) under domain %s.') |format(numberOfSpareAccounts |int, '<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '"><strong>' + cur_domain + '</strong></a>') }}</p>
</div>
{% endif %}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/user/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li class="active"><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>{{ _('Add mailing list') }}</h2>
</div>
<div id="maillist_add" class="box-wrap clear">
<div class="columns clear">
<form name="create" method="post" action="{{ctx.homepath}}/create/ml/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Add mailing list under domain') }} <span class="required">*</span></h4>
<span class="clean-padding">
<select name="domainName" onchange="change_url(this, baseurl='{{ctx.homepath}}/create/ml/');">
{% for d in allDomains %}
<option value="{{ d |e }}" {% if d == cur_domain %}selected{%endif%}>{{ d |e }}</option>
{% endfor %}
</select>
</span>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Mail Address') }} <span class="required">*</span></h4>
<span class="clean-padding">
<input type="text" size="35"
name="listname"
value="{{ listname |e }}"
class="text fl-space {% if not createNewAccount %}disabled{% endif %}"
{% if not createNewAccount %}disabled="disabled"{% endif %}
/>@{{ cur_domain }}
</span>
</div>
{{ display_input_cn(value=cn, input_name='name', enable_input=createNewAccount) }}
{{ display_maillist_basic_profile(profile=default_creation_settings) }}
<div class="rule2"></div>
<div class="form-field clear">
<h4 class="size-250 fl-space">&nbsp;</h4>
<span class="clean-padding bt-space20">
<input type="submit"
value="{{ _('Add') }}"
{% if not createNewAccount %}
class="button color-grey" disabled="disabled"
{% else %}
class="button green"
{% endif %}
/>
</span>
</div>
</form>
</div>{# .columns #}
</div>{# .box-wrap #}
</div>{# .content-box #}
</div>{# .box-body #}
{% endblock main %}

View File

@@ -0,0 +1,155 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
set_account_activity_img,
highlight_username_in_mail,
display_filter_by_first_char,
display_list_access_policy_name,
show_pages
with context
%}
{% from "macros/msg_handlers.html" import maillist_msg_handler with context %}
{% block title %}{{ _('Mailing Lists') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
('active', ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
] %}
{% if session.get('is_global_admin') %}
{% set crumbs = crumbs + [(ctx.homepath + '/admins/' + cur_domain, _('Admins'))] %}
{% endif %}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ maillist_msg_handler(msg) }}
{% if maillists is defined %}
{% if maillists or (not maillists and first_char) %}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/mls/' + cur_domain,
available_chars=all_first_chars,
first_char=first_char,
disabled_only=disabled_only) }}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/user/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>
{{ _('Mailing lists under domain: %s.') |format(cur_domain) }}
{% if total is defined and maillists %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + maillists |length}}/{{total}})
{% endif %}
<a href="{{ctx.homepath}}/profile/domain/general/{{cur_domain}}"><i class="fa fa-cog fa-lg" title="{{ _('Edit domain profile') }}"></i></a>
{{ set_account_activity_img('sent', 'domain', cur_domain, float=false) }}
</h2>
</div>{# -- box-header -- #}
{# List all mailing lists. #}
<form name="maillists" id="list_table" action="{{ctx.homepath}}/mls/{{cur_domain}}" method="post">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('Mail Deliver Restriction') }}</th>
</tr>
</thead>
<tbody>
{% if maillists|length > 0 %}
{% for r in maillists %}
{% set address = r.address |e %}
{% set name = r.name |e %}
{% set access_policy = r.accesspolicy |e %}
<tr>
<td class="checkbox"><input type="checkbox" class="checkbox" name="mail" value="{{ address }}" /></td>
<td>
<a href="{{ctx.homepath}}/profile/ml/members/{{address}}"><i class="fa fa-users fa-lg fr-space" title="{{ _('View members') }}"></i></a>
<a href="{{ctx.homepath}}/profile/ml/general/{{address}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(r.active) }}
<a href="{{ctx.homepath}}/profile/ml/general/{{address}}" title="{{ _('Edit account profile') }}">{% if name %}{{ name |cut_string |e }}{% else %}{{ address.split('@', 1)[0] }}{% endif %}</a>
</td>
<td>{{ highlight_username_in_mail(address) }}</td>
<td>{{ display_list_access_policy_name(policy=access_policy) }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td class="checkbox"></td>
<td colspan="4">{{ _('No mailing list available.') }}
{% if not first_char %}
<a href="{{ctx.homepath}}/create/ml/{{ cur_domain }}">{{ _('Add one') }}</a>?
{% endif %}
</td>
</tr>
{% endif %}
</tbody>
</table>
{% if maillists %}
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete and archive') }}</option>
<option disabled>----</option>
<option value="delete_without_archiving">{{ _('Delete without archiving') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
{% set baseurl = ctx.homepath + '/mls/' + cur_domain %}
{% if disabled_only %}
{% set baseurl = baseurl + '/disabled' %}
{% endif %}
{% set url_suffix = '' %}
{% if first_char %}
{% set url_suffix = '?starts_with=' + first_char %}
{% endif %}
{{ show_pages(baseurl=baseurl, total=total, cur_page=cur_page, url_suffix=url_suffix) }}
</div>
{% endif %}
</form>
</div>{# -- box-body -- #}
</div>{# -- content-body -- #}
{% endif %}
{% endblock main %}

View File

@@ -0,0 +1,185 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
display_input_cn,
display_change_email_address,
display_account_status,
display_per_account_alias_addresses,
set_account_status_img
with context
%}
{% from "macros/mlmmj.html" import
display_maillist_basic_profile,
display_maillist_owners,
display_maillist_moderators,
display_maillist_subscription_moderators,
display_modal_add_subscribers,
display_maillist_subscribers,
display_modal_newsletter_html_code,
display_maillist_newsletter_profile
with context
%}
{% from "macros/msg_handlers.html" import maillist_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
('active', ctx.homepath + '/profile/ml/general/' + mail, _('Profile of mailing list:') + '&nbsp;' + mail),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ maillist_msg_handler(msg) }}
{% set navlinks = [
('general', _('General'), [true]),
('aliases', _('Aliases'), [true]),
('members', _('Members'), [true]),
('owners', _('Owners and Moderators'), [true]),
('newsletter', _('Newsletter'), [true]),
]
%}
{# modal window used to add subscriber #}
{% set form_post_url = ctx.homepath + "/profile/ml/add_subscribers/" + mail %}
{{ display_modal_add_subscribers(form_post_url=form_post_url) }}
{% if profile.mlid %}
{{ display_modal_newsletter_html_code(mlid=profile.mlid) }}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _('Profile of mailing list:') }} {{ mail }} ({{ subscribers | length }} {{ _('Members') }})</h2>
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{ nav[0] }}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>{# -- box-header -- #}
<div class="box-wrap clear">
<div id="profile_general">
<form name="general" method="post" action="{{ctx.homepath}}/profile/ml/general/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 clear">
{{ display_account_status(profile.active) }}
{{ display_input_cn(value=profile.name, input_name='name') }}
</div>
<div class="col1-3 lastcol">
{% if profile.active %}
<div class="mark_blue bt-space10">
<p class="bt-space"><i class="fa fa-plus fa-lg"></i> <a href="#add_subscribers" class="modal-link"><span class="text">{{ _('Add new members') }}</span></a></p>
</div>
{% else %}
<div class="notification note-attention">
<p class="bt-space"> {{ _('To add new members, please enable mailing list account first.') }}</p>
</div>
{% endif %}
</div>
</div>
<div class="columns clear">
{{ display_maillist_basic_profile(profile=profile, access_policy=profile.accesspolicy, mail=mail) }}
</div>
{{ input_submit() }}
</form>
</div>{# #profile_general #}
{# Aliases #}
<div id="profile_aliases">
<form name="aliases" method="post" action="{{ctx.homepath}}/profile/ml/aliases/{{mail}}">
{{ input_csrf_token() }}
{{ display_per_account_alias_addresses(mail=mail, alias_addresses=alias_addresses) }}
{{ input_submit() }}
</form>
</div>
{#
# Members
#}
<div id="profile_members" style="margin-left: -10px; margin-right: -10px; margin-bottom: -10px;">
<form name="members" method="post" action="{{ctx.homepath}}/profile/ml/members/{{mail}}">
{{ input_csrf_token() }}
{{ display_maillist_subscribers(mail=mail, subscribers=subscribers, account_is_enabled=profile.active) }}
</form>
</div>{# #profile_general #}
<div id="profile_owners">
<form name="owners" method="post" action="{{ctx.homepath}}/profile/ml/owners/{{mail}}">
{{ input_csrf_token() }}
{# parameter name is 'owner', not 'owners' #}
{{ display_maillist_owners(mail=mail, addresses=profile.get('owner')) }}
<div class="rule"></div>
{{ display_maillist_moderators(mail=mail, addresses=profile.get('moderators')) }}
<div class="rule"></div>
{{ display_maillist_subscription_moderators(mail=mail,
profile=profile,
addresses=profile.get('subscription_moderators')) }}
{{ input_submit() }}
</form>
</div>{# #profile_owners #}
<div id="profile_newsletter">
<form name="newsletter" method="post" action="{{ctx.homepath}}/profile/ml/newsletter/{{mail}}">
{{ input_csrf_token() }}
{{ display_maillist_newsletter_profile(is_newsletter=profile.is_newsletter,
description=profile.description) }}
{{ input_submit() }}
</form>
</div>{# #profile_newsletter #}
</div>{#-- .box-wrap --#}
</div>{#-- .box-body --#}
</div>{#-- .content-box --#}
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function(){
$(".tabs li").idTabs("profile_{{ profile_type }}");
$('#subscriber_search').quickfilter('#subscribers_tbody tr');
});
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,469 @@
{#
@queryResult List which stores LDAP query results
#}
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_progress_bar,
set_account_status_img,
set_account_activity_img,
set_alias_address_img,
set_forwarding_address_img,
set_assigned_groups_img,
set_admin_type_img,
highlight_username_in_mail,
display_number_of_account_limited,
display_remove_mailbox_days
with context %}
{% from "macros/msg_handlers.html" import search_msg_handler with context %}
{% block title %}{{ _('Search') }}{% endblock %}
{% block navlinks_active_search %}class="active"{% endblock %}
{% block main %}
{{ search_msg_handler(msg) }}
<div class="content-box">
<div class="box-body">
<div class="box-wrap clear">
<form name="search" method="post" action="{{ctx.homepath}}/search">
{{ input_csrf_token() }}
<div class="form-field clear">
<h4 class="size-150 fl-space">{{ _('Keyword') }} <span class="required">*</span></h4>
<input type="text" name="searchString" value="{{ searchString |e }}" size="30" class="text" />
<input type="submit" value="{{ _('Search') }}" size="30" class="button green" />
</div>
<div class="form-field clear">
<h4 class="size-150 fl-space">{{ _('Account type') }}</h4>
<input type="checkbox" name="account_type" value="user" rel="checkboxvert" class="checkbox" checked="checked" /> <label>{{ _('User') }}</label>
<input type="checkbox" name="account_type" value="alias" rel="checkboxvert" class="checkbox" checked="checked" /> <label>{{ _('Alias') }}</label>
<input type="checkbox" name="account_type" value="ml" rel="checkboxvert" class="checkbox" checked="checked" /> <label>{{ _('Mailing List') }}</label>
{% if session.get('is_global_admin') %}
<input type="checkbox" name="account_type" value="domain" rel="checkboxvert" class="checkbox" /> <label>{{ _('Domain') }}</label>
<input type="checkbox" name="account_type" value="admin" rel="checkboxvert" class="checkbox" /> <label>{{ _('Admin') }}</label>
{% endif %}
</div>
<div class="form-field clear">
<h4 class="size-150 fl-space">{{ _('Account status') }}</h4>
<input type="checkbox"
name="accountStatus"
value="active"
rel="checkboxvert"
class="checkbox"
checked="checked"
/>
<label>{{ _('Active') }}</label>
<input type="checkbox"
name="accountStatus"
value="disabled"
rel="checkboxvert"
class="checkbox"
checked="checked"
/>
<label>{{ _('Disabled') }}</label>
</div>
</form>
</div>
</div>
</div>
{% if total_results is defined %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _('Search results.') }}</h2>
</div>
<div class="box-wrap clear">
{% if total_results > 0 %}
{% if session.get('is_global_admin') %}
{% if domains |length > 0 %}
<h2>{{ _('%d domain(s) found.') |format(domains |length) }}</h2>
<form name="domains" id="domain_table" method="post" action="{{ctx.homepath}}/domains">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Domain') }}</th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="int">{{ _('Quota') }}</th>
<th data-sort="int">{{ _('Users') }}</th>
<th data-sort="int">{{ _('Aliases') }}</th>
</tr>
</thead>
<tbody>
{% for r in domains %}
{% set domain = r.domain |e %}
<tr>
<td class="checkbox"><input type="checkbox" class="checkbox " name="domainName" value="{{ domain }}" /></td>
<td>
<a href="{{ctx.homepath}}/profile/domain/general/{{domain}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_activity_img('sent', 'domain', domain) }}
{{ set_account_status_img(r.active) }}
<a href="{{ctx.homepath}}/profile/domain/general/{{domain}}" title="{{ _('Edit account profile') }}">{{ domain }}</a>
</td>
{% if r.description %}
<td class="vcenter">{{ r.description |cut_string |e }}</td>
{% else %}
<td class="vcenter">&nbsp;</td>
{% endif %}
{# Quota #}
<td class="vcenter">
{{ display_number_of_account_limited(r.maxquota |file_size_format(base_mb=True), hide_unlimited=false, hide_slash=true) }}
</td>
{# Mailboxes #}
<td class="vcenter" data-sort-value="{{ r.mailboxes |e }}">
{% if (r.mailboxes |int) >= 0 %}
<a href="{{ctx.homepath}}/users/{{domain}}" title="{{ _('List all mail users.') }}" style="text-decoration: none;">{{ display_number_of_account_limited(r.mailboxes, hide_unlimited=false, hide_slash=true) }}</a>
{% elif (r.mailboxes |int) == -1 %}
<span class="color-grey"><em>{{ _('DISABLED') }}</em></span>
{% endif %}
</td>
{# Aliases #}
<td class="vcenter" data-sort-value="{{ r.aliases |e }}">
{% if (r.aliases |int) >= 0 %}
<a href="{{ctx.homepath}}/aliases/{{domain}}" title="{{ _('List all mail aliases.') }}" style="text-decoration: none;">{{ display_number_of_account_limited(r.aliases, hide_unlimited=false, hide_slash=true) }}</a>
{% elif (r.aliases |int) == -1 %}
<span class="color-grey"><em>{{ _('DISABLED') }}</em></span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space" id="domain_list_actions">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<select name="keep_mailbox_days" class="fl-space" id="domain_delete_date">
{% for _day in days_to_keep_removed_mailbox %}
<option value="{{ _day }}">{{ display_remove_mailbox_days(_day) }}</option>
{% endfor %}
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
</div>
</form>
<div class="bt-space20"></div>
{% endif %} {# domains #}
{% if admins |length > 0 %}
<h2>{{ _('%d admin(s) found.') |format(admins |length) }}</h2>
<form name="admins" id="admin_table" method="post" action="{{ctx.homepath}}/admins">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('Global Admin') }}</th>
</tr>
</thead>
<tbody>
{% for r in admins %}
{% set username = r.username |e %}
{% set name = r.name |e %}
<tr>
<td class="checkbox"><input type="checkbox" name="mail" value="{{ username }}" {% if username == session.get('username') %}disabled="disabled"{% endif %}/></td>
<td>
<a href="{{ctx.homepath}}/profile/admin/general/{{ username }}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(r.active) }}
{# -- Show name -- #}
{% if name == '' %}
{{ username.split('@', 1)[0] }}
{% else %}
{{ name |cut_string }}
{% endif %}
</td>
<td><a href="{{ctx.homepath}}/profile/admin/general/{{username}}" title="{{ _('Edit account profile') }}">{{ username }}</a></td>
{% if username in allGlobalAdmins %}
<td>{{ set_admin_type_img('yes') }}</td>
{% else %}
<td>{{ set_admin_type_img('no') }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
</div>
</form>
<div class="bt-space20"></div>
{% endif %} {# admins #}
{% endif %} {# domainGlobalAdmin #}
{# List all users. #}
{% if users %}
<h2>{{ _('%d user(s) found.') |format( users |length ) }}</h2>
<form name="users" id="user_table" method="post" action="{{ctx.homepath}}/action/user">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('User/Employee ID') }}</th>
<th data-sort="int">{{ _('Quota') }}</th>
{% if last_logins %}
<th data-sort="int">{{ _('Last Login') }}</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for r in users %}
{% set mail = r.username |e %}
<tr>
<td class="checkbox"><input type="checkbox" name="mail" value="{{mail}}" /></td>
<td class="vcenter">
<a href="{{ctx.homepath}}/profile/user/general/{{mail}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_activity_img('sent', 'user', mail) }}
{{ set_account_status_img(r.active) }}
{{ set_assigned_groups_img(addresses=user_assigned_groups.get(mail, [])) }}
{{ set_forwarding_address_img(user=mail, addresses=user_forwarding_addresses.get(mail, [])) }}
{{ set_alias_address_img(addresses=user_alias_addresses.get(mail, [])) }}
<a href="{{ctx.homepath}}/profile/user/general/{{mail}}" title="{{ _('Edit account profile') }}">{% if r.name %}{{ r.name |cut_string |e }}{% else %}{{ mail.split('@', 1)[0] }}{% endif %}</a>
</td>
<td class="vcenter">{{ highlight_username_in_mail(mail) }}</td>
<td class="vcenter">{% if r.employeeid %}{{ r.employeeid |e }}{% endif %}</td>
{% if (r.quota |int) == 0 %}
<td class="vcenter" data-sort-value="0">{{ _('Unlimited') }}</td>
{% else %}
<td class="vcenter" data-sort-value="{{ r.quota |e }}">{{ r.quota | file_size_format(base_mb=True) }}</td>
{% endif %}
{# last login #}
{% if last_logins %}
{% if mail in last_logins %}
{% set _times = last_logins.get(mail, {}) %}
{# values may be None, so we use `or 0` to set it to `0` #}
{% set _imap = _times.get('imap', 0) or 0 %}
{% set _pop3 = _times.get('pop3', 0) or 0 %}
{% set _lda = _times.get('lda', 0) or 0 %}
{# imap or pop3 login time #}
{% set _login_time = 0 %}
{% set _login_service = None %}
{% if (_imap > 0) and (_pop3 > 0) %}
{% if _imap > _pop3 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% else %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
{% elif _imap > 0 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% elif _pop3 > 0 %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
<td data-sort-value="{{ _login_time }}">
{% if _login_time %}
<span title="{% if _imap %}{{ _('IMAP Login:') }} {{ _imap | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}<br/>{% endif %}{% if _pop3 %}{{ _('POP3 Login:') }} {{ _pop3 | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}<br/>{% endif %}{% if _lda %}{{ _('New Mail Delivered:') }} {{ _lda | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}{% endif %}">
{{ _login_time | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}
{% if _login_service %}
{{ _login_service | upper }}
{% endif %}
</span>
{% endif %}
</td>
{% else %}
<td data-sort-value="0"></td>
{% endif %}
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space" id="account_list_actions">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<select name="keep_mailbox_days" class="fl-space" id="account_delete_date">
{% for _day in days_to_keep_removed_mailbox %}
<option value="{{ _day }}">{{ display_remove_mailbox_days(_day) }}</option>
{% endfor %}
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
</div>
</form>
<div class="bt-space20"></div>
{% endif %}
{# List all mailing lists. #}
{% if mls |length > 0 %}
<h2>{{ _('%d mailing list(s) found.') |format( mls |length ) }}</h2>
<form name="mls" id="ml_table" method="post" action="{{ctx.homepath}}/action/ml">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
</tr>
</thead>
<tbody>
{% for r in mls %}
{% set address = r.address |e %}
{% set name = r.name |e %}
{% set active = r.active |int %}
<tr>
<td class="checkbox"><input type="checkbox" name="mail" value="{{ address }}" /></td>
<td>
<a href="{{ctx.homepath}}/profile/ml/general/{{address}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(active) }}
<a href="{{ctx.homepath}}/profile/ml/general/{{address}}">{% if name %}{{ name |cut_string |e }}{% else %}{{ address.split('@', 1)[0] }}{% endif %}</a>
</td>
<td><a href="{{ctx.homepath}}/profile/ml/general/{{address}}">{{ highlight_username_in_mail(address) }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
</div>
</form>
{% endif %}
{# List all mail aliases. #}
{% if aliases |length > 0 %}
<h2>{{ _('%d mail alias(es) found.') |format( aliases |length ) }}</h2>
<form name="aliases" id="alias_table" method="post" action="{{ctx.homepath}}/action/alias">
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins">{{ _('Display Name') }}</th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
</tr>
</thead>
{# List alias attributes/avalues. #}
<tbody>
{% for r in aliases %}
{% set address = r.address |e %}
{% set name = r.name |e %}
<tr>
<td class="checkbox"><input type="checkbox" name="mail" value="{{ address }}" /></td>
<td>
<a href="{{ctx.homepath}}/profile/alias/general/{{address}}"><i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}"></i></a>
{{ set_account_status_img(r.active) }}
<a href="{{ctx.homepath}}/profile/alias/general/{{address}}">{% if name %}{{ name |cut_string |e }}{% else %}{{ address.split('@', 1)[0] }}{% endif %}</a>
</td>
<td><a href="{{ctx.homepath}}/profile/alias/general/{{address}}">{{ highlight_username_in_mail(address) }}</a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space">
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
</select>
<input type="submit" value="{{ _('Apply') }}" class="button fl-space" />
</div>
</div>
</form>
{% endif %}
{% else %}
<p>{{ _('Your search returned no hits.') }}</p>
{% endif %}
</div>{# .box-wrap #}
</div>{# .box-body #}
</div>{# .content-box #}
{% endif %}
{% endblock main %}

View File

@@ -0,0 +1,74 @@
{% extends "layout_user.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
highlight_username_in_mail,
display_filter_by_first_char,
display_list_access_policy_name,
show_pages
with context
%}
{% from "macros/sql.html" import
display_mls
with context
%}
{% from "macros/msg_handlers.html" import maillist_msg_handler with context %}
{% block title %}{{ _('Mailing Lists') }}{% endblock %}
{% block navlinks_manageml %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{{ maillist_msg_handler(msg) }}
{% if maillists %}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/self-service/mls',
account_type="managed_ml",
available_chars=all_first_chars,
first_char=first_char,
disabled_only=False) }}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>
{{ _('Managed mailing lists.') }}
{% if total > 0 %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + (maillists |length) }}/{{total}})
{% endif %}
</h2>
</div>
{# List all mailing lists. #}
<form name="maillists" id="list_table" action="{{ctx.homepath}}/self-service/mls" method="post">
{{ input_csrf_token() }}
{{ display_mls(maillists=maillists,
profile_base_url=ctx.homepath + "/self-service/ml/profile",
domain=None) }}
{% if maillists %}
<div class="tab-footer clear f1">
{% set baseurl = ctx.homepath + '/self-service/mls' %}
{% set url_suffix = '' %}
{% if first_char %}
{% set url_suffix = '?starts_with=' + first_char %}
{% endif %}
{{ show_pages(baseurl=baseurl, total=total, cur_page=cur_page, url_suffix=url_suffix) }}
</div>
{% endif %}
</form>
</div>{# -- box-body -- #}
</div>{# -- content-body -- #}
{% endblock main %}

View File

@@ -0,0 +1,127 @@
{% extends "layout_user.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
display_input_cn,
with context
%}
{% from "macros/mlmmj.html" import
display_maillist_basic_profile,
display_modal_add_subscribers,
display_maillist_subscribers,
display_modal_newsletter_html_code,
display_maillist_newsletter_profile
with context
%}
{% from "macros/msg_handlers.html" import maillist_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_manageml %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{{ maillist_msg_handler(msg) }}
{% set navlinks = [
('general', _('General'), [true]),
('members', _('Members'), [true]),
('newsletter', _('Newsletter'), [true]),
]
%}
{# modal window used to add subscriber #}
{% set form_post_url = ctx.homepath + "/self-service/ml/profile/add_subscribers/" + mail %}
{{ display_modal_add_subscribers(form_post_url=form_post_url) }}
{% if profile.mlid %}
{{ display_modal_newsletter_html_code(mlid=profile.mlid) }}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _('Profile of mailing list:') }} {{ mail }} ({{ subscribers | length }} {{ _('Members') }})</h2>
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{ nav[0] }}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
</div>{# -- box-header -- #}
<div class="box-wrap clear">
<div id="profile_general">
<form name="general" method="post" action="{{ctx.homepath}}/self-service/ml/profile/general/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3 clear">
{{ display_input_cn(value=profile.name, input_name='name') }}
</div>
<div class="col1-3 lastcol">
{% if profile.active %}
<div class="mark_blue bt-space10">
<p class="bt-space"><i class="fa fa-plus fa-lg"></i> <a href="#add_subscribers" class="modal-link"><span class="text">{{ _('Add new members') }}</span></a></p>
</div>
{% else %}
<div class="notification note-attention">
<p class="bt-space"> {{ _('To add new members, please enable mailing list account first.') }}</p>
</div>
{% endif %}
</div>
</div>
<div class="columns clear">
{{ display_maillist_basic_profile(profile=profile, access_policy=profile.accesspolicy, mail=mail) }}
</div>
{{ input_submit() }}
</form>
</div>{# #profile_general #}
{#
# Members
#}
<div id="profile_members" style="margin-left: -10px; margin-right: -10px; margin-bottom: -10px;">
<form name="members" method="post" action="{{ctx.homepath}}/self-service/ml/profile/members/{{mail}}">
{{ input_csrf_token() }}
{{ display_maillist_subscribers(mail=mail, subscribers=subscribers, account_is_enabled=profile.active) }}
</form>
</div>{# #profile_general #}
<div id="profile_newsletter">
<form name="newsletter" method="post" action="{{ctx.homepath}}/self-service/ml/profile/newsletter/{{mail}}">
{{ input_csrf_token() }}
{{ display_maillist_newsletter_profile(is_newsletter=profile.is_newsletter,
description=profile.description) }}
{{ input_submit() }}
</form>
</div>{# #profile_newsletter #}
</div>{#-- .box-wrap --#}
</div>{#-- .box-body --#}
</div>{#-- .content-box --#}
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function(){
$(".tabs li").idTabs("profile_{{ profile_type }}");
$('#subscriber_search').quickfilter('#subscribers_tbody tr');
});
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,138 @@
{% extends "layout_user.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_activity_img,
display_progress_bar,
display_input_cn,
display_preferred_language,
display_timezones,
display_account_status,
display_reset_password,
display_random_password,
display_user_forwarding
with context
%}
{% from "macros/msg_handlers.html" import user_msg_handler with context %}
{% block title %}{{ _('Preferences') }}{% endblock %}
{% block navlinks_preferences %}class="active"{% endblock %}
{% block main %}
{# Show system message #}
{% if msg %}
{% if msg.startswith('PW_') %}
{% set _pw_errors = msg.split(',') %}
{% for _err in _pw_errors %}
{{ user_msg_handler(_err) }}
{% endfor %}
{% else %}
{{ user_msg_handler(msg) }}
{% endif %}
{% endif %}
{% set navlinks = [('general', _('General'), [true]),
('forwarding', _('Forwarding'), ['forwarding' not in disabled_user_preferences]),
('password', _('Password'), ['password' not in disabled_user_preferences])]
%}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{nav[0]}}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>{{ _('Preferences') }}</h2>
</div>
<div class="box-wrap clear">
<div id="profile_general">
<form name="profile" method="post" action="{{ctx.homepath}}/preferences/general">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3">
{% if 'personal_info' not in disabled_user_preferences %}
{{ display_input_cn(value=profile.name) }}
{% endif %}
{{ display_preferred_language(value=profile.get('language'), languagemaps=languagemaps) }}
{{ display_timezones(value=user_settings.get('timezone'), timezones=timezones) }}
</div>
{% if profile.quota %}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
{% set percent = used_quota_bytes |convert_to_percentage(profile.quota |int * 1024 * 1024) %}
<h4>{{ _('Mailbox Quota') }} ({{ profile.quota | file_size_format(base_mb=True) }}, {{ percent }}% {{ _('Used') }})</h4>
{{ display_progress_bar(percent, style='thin', show_zero=true, width='70%') }}
<div>&nbsp;</div>
</div>
</div>
{% endif %}
</div>
{{ input_submit() }}
</form>
</div>
{% if 'forwarding' not in disabled_user_preferences %}
<div id="profile_forwarding">
<form name="profile" method="post" action="{{ctx.homepath}}/preferences/forwarding">
{{ input_csrf_token() }}
<div class="columns clear">
{{ display_user_forwarding(mail=mail,
enabled=profile.alias_active,
forwarding_addresses=profile.forwardings) }}
</div>{#-- .columns --#}
{{ input_submit() }}
</form>
</div>
{% endif %}
{% if 'password' not in disabled_user_preferences %}
<div id="profile_password">
<form name="profile" method="post" action="{{ctx.homepath}}/preferences/password">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3">
{{ display_reset_password(show_confirmpw=true,
min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
store_password_in_plain_text=store_password_in_plain_text) }}
</div>
<div class="col1-3 lastcol">
{{ display_random_password(password_length=min_passwd_length,
password_policies=password_policies) }}
</div>
</div>
{{ input_submit() }}
</form>
</div>
{% endif %}
</div>
</div>
</div>
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$(".tabs li").idTabs("profile_{{ profile_type }}")
});
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,167 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
set_forwarding_address_img,
with context
%}
{% from "macros/msg_handlers.html" import user_msg_handler with context %}
{% block title %}{{ _('Last Logins') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% if all_are_admins %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% else %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
] %}
{% if session.get('is_global_admin') %}
{% set crumbs = crumbs + [(ctx.homepath + '/admins/' + cur_domain, _('Admins'))] %}
{% endif %}
{% endif %}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [('active', ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ user_msg_handler(msg) }}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<h2>{{ _("Last Logins") }}</h2>
</div>
<div class="box-wrapper clear">
<div id="all_last_logins">
<table class="style1">
<thead>
<tr>
<th data-sort="string-ins">{{ _("Display Name") }}</th>
<th data-sort="string-ins">{{ _("Mail Address") }}</th>
<th data-sort="int" data-sort-default="desc" data-sort-onload="yes">IMAP</th>
<th data-sort="int" data-sort-default="desc">POP3</th>
<th data-sort="int" data-sort-default="desc">{{ _("Last Email Delivery") }}</th>
<th></th>
</tr>
</thead>
<tbody>
{% if last_logins %}
{% for email in last_logins %}
{% set active = last_logins[email]["active"] %}
{% set forwardings = last_logins[email]["forwardings"] %}
{% set name = last_logins[email]["name"] %}
{% set imap = last_logins[email]["imap"] %}
{% set pop3 = last_logins[email]["pop3"] %}
{% set lda = last_logins[email]["lda"] %}
<tr id="row_{{ loop.index }}">
<td>{% if name %}{{ name | e }}{% endif %}</td>
<td id="td_status_{{ loop.index }}">
<a href="{{ ctx.homepath }}/profile/user/general/{{ email }}"
title="{{ _('Edit account profile') }}"
>{{ email }}</a>
<a href="{{ ctx.homepath }}/profile/user/general/{{ email }}" title="{{ _('Edit account profile') }}"><i class="fa fa-cog fa-lg fr-space"></i></a>
{{ set_account_status_img(active) }}
{% if forwardings %}
{{ set_forwarding_address_img(email, forwardings) }}
{% endif %}
</td>
<td data-sort-value="{{ imap }}">
{% if imap > 0 %}
{{ imap | epoch_seconds_to_gmt | utc_to_timezone(timezone=session['timezone']) }}
{% endif %}
</td>
<td data-sort-value="{{ pop3 }}">
{% if pop3 > 0 %}
{{ pop3 | epoch_seconds_to_gmt | utc_to_timezone(timezone=session['timezone']) }}
{% endif %}
</td>
<td data-sort-value="{{ lda }}">
{% if lda > 0 %}
{{ lda | epoch_seconds_to_gmt | utc_to_timezone(timezone=session['timezone']) }}
{% endif %}
</td>
<td>
{% if active %}
<span
id="btn_disable_{{ loop.index }}"
class="button"
onclick='disable_user("{{ loop.index }}", "{{ email }}")'
>{{ _("Disable") }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="5">{{ _("No any login or mail delivery yet.") }}</td>
</tr>
{% endif %}
</tbody>
</table>
</div>{# .all_last_logins #}
</div>{# .box-wrapper #}
</div>{# .box-body #}
</div>{# .content-box #}
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
function disable_user(id, email) {
$.ajax({
type: "PUT",
url: '{{ ctx.homepath }}/apiproxy/user/' + email,
data: "accountStatus=disabled",
success: function (ret) {
if (ret._success) {
$('#td_status_' + id + ' i').
attr("title", '{{ _("Disabled") }}').
removeClass().
toggleClass("fas fa-times-circle fa-lg color-red fr-space");
$('#btn_disable_' + id).
text('{{ _("Disabled") }}').
addClass("grey").
attr('disabled','disabled');
} else {
alert(ret._msg);
}
}
});
};
</script>
{% endblock extra_js %}

View File

@@ -0,0 +1,186 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import input_csrf_token with context %}
{% from "macros/general.html" import
display_subnav,
display_input_cn,
display_preferred_language,
display_reset_password,
display_random_password,
display_quota
with context
%}
{% from "macros/msg_handlers.html" import user_msg_handler with context %}
{% block title %}{{ _('Add mail user') }}{% endblock title %}
{% block navlinks_create %}class="active"{% endblock %}
{% block breadcrumb %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
(ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{% if msg %}
{% if msg.startswith('PW_') %}
{% set _pw_errors = msg.split(',') %}
{% for _err in _pw_errors %}
{{ user_msg_handler(_err) }}
{% endfor %}
{% else %}
{{ user_msg_handler(msg) }}
{% endif %}
{% endif %}
{# -- Allow to create new account --#}
{% set createNewAccount = true %}
{% set numberOfSpareAccounts = profile.mailboxes - num_existing_users %}
{% set spareQuotaBytes = (profile.maxquota - usedQuotaSize) * 1024 * 1024 %}
{% if profile.mailboxes == -1 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Not allowed to create mail alias under this domain.') %}
{% elif profile.mailboxes > 0 and numberOfSpareAccounts <= 0 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('Already exceed max number of account limit (%d).') |format(profile.mailboxes |int) %}
{% endif %}
{% if profile.maxquota > 0 and spareQuotaBytes <= 0 %}
{% set createNewAccount = false %}
{% set whyDisabledCreation = _('No free domain quota left.') %}
{% endif %}
{# Display input field for adding new user. #}
{% if not createNewAccount %}
<div class="notification note-error">
<p>
<strong>{{ _('Error:') }}</strong> {{ _('You can NOT create more users under domain %s.') |format('<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '"><strong>' + cur_domain + '</strong></a>') }} {{ whyDisabledCreation }}
{# Show link to change limit #}
{% if session.get('is_global_admin') %}
{% if profile.mailboxes > 0 and numberOfSpareAccounts <= 0 %}
<a href='{{ctx.homepath}}/profile/domain/advanced/{{cur_domain}}#domainQuota'>{{ _('Increase it now?') }}</a>
{% endif %}
{% endif %}
</p>
</div>
{% else %}
{% if profile.mailboxes > 0 and numberOfSpareAccounts > 0 %}
<div class="notification note-info">
<p>{{ _('You can create <strong>%d</strong> more mail user(s) under domain %s.') |format(numberOfSpareAccounts, '<a href="' + ctx.homepath + '/profile/domain/general/' + cur_domain + '"><strong>' + cur_domain + '</strong></a>') }}</p>
</div>
<div class="bt-space0"></div>
{% endif %}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li class="active"><a href="#user_add"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>{{ _('Add mail user') }}</h2>
</div>
<div id="user_add" class="box-wrap clear">
<form name="form_add_user" method="post" action="{{ctx.homepath}}/create/user/{{cur_domain}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col3-4">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Add mail user under domain') }} <span class="required">*</span></h4>
<span class="clean-padding">
<select
name="domainName"
onchange="change_url(this, baseurl='{{ctx.homepath}}/create/user/');"
{% if not createNewAccount %}disabled{% endif %}
>
{% for d in all_domains %}
<option value="{{ d |e }}" {% if d == cur_domain %}selected{%endif%}>{{ d |e }}</option>
{% endfor %}
</select>
</span>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Mail Address') }} <span class="required">*</span></h4>
<span class="clean-padding">
<input type="text" size="35"
name="username"
autocomplete="off"
value=""
class="text fl-space {% if not createNewAccount %}disabled{% endif %}"
{% if not createNewAccount %}disabled="disabled"{% endif %} />@{{ cur_domain }}
</span>
</div>
<div class="bt-space5">&nbsp;</div>
{{ display_reset_password(
min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
store_password_in_plain_text=store_password_in_plain_text,
enable_input=createNewAccount,
) }}
<div class="bt-space5">&nbsp;</div>
{{ display_input_cn(
value=cn,
account_type='user',
enable_input=createNewAccount,
) }}
{{ display_preferred_language(
value=domain_settings.get('default_language', 'en_US'),
languagemaps=languagemaps,
enable_input=createNewAccount,
) }}
{{ display_quota(value=domain_settings.get('default_user_quota', 0),
spare_quota_bytes=spareQuotaBytes,
show_spare_quota=true,
show_value_in_input=true,
show_used_quota=false,
enable_input=createNewAccount) }}
</div>{# .col2-3 #}
<div class="col1-4 lastcol">
{{ display_random_password(password_length=min_passwd_length,
password_policies=password_policies) }}
</div>
</div>{# .columns #}
<div class="rule2"></div>
<div class="form-field clear">
<h4 class="size-250 fl-space">&nbsp;</h4>
<span>
<input type="submit" name="submit_add_user" value="{{ _('Add') }}" {% if not createNewAccount %}class="button color-grey" disabled="disabled"{% else %}class="button green"{% endif %} />
</span>
</div>
</form>
</div>{# -- End box-wrap -- #}
</div>{# -- End content-box -- #}
</div>{# -- End box-body -- #}
{% endblock main %}

View File

@@ -0,0 +1,332 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_status_img,
set_account_activity_img,
set_forwarding_address_img,
set_alias_address_img,
set_assigned_groups_img,
set_user_admin_type_img,
highlight_username_in_mail,
display_progress_bar,
display_filter_by_first_char,
show_pages,
display_remove_mailbox_days
with context
%}
{% from "macros/msg_handlers.html" import user_msg_handler with context %}
{% block title %}{{ _('Mail Users') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% if all_are_admins %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
('active', ctx.homepath + '/admins/' + cur_domain, _('Admins')),
]
%}
{% else %}
{% set crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
('active', ctx.homepath + '/users/' + cur_domain, _('Users')),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
] %}
{% if session.get('is_global_admin') %}
{% set crumbs = crumbs + [(ctx.homepath + '/admins/' + cur_domain, _('Admins'))] %}
{% endif %}
{% endif %}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{{ user_msg_handler(msg) }}
{% if users is defined %}
{% if users or (not users and first_char) %}
{% if all_are_admins %}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/admins/' + cur_domain,
first_char=first_char,
account_type='admin',
disabled_only=disabled_only) }}
{% else %}
{{ display_filter_by_first_char(baseurl=ctx.homepath + '/users/' + cur_domain,
available_chars=all_first_chars,
first_char=first_char,
account_type='user',
disabled_only=disabled_only) }}
{% endif %}
{% endif %}
{# List all users. #}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
<li><a href="{{ctx.homepath}}/create/user/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('User') }}</a>
<li><a href="{{ctx.homepath}}/create/ml/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Mailing List') }}</a>
<li><a href="{{ctx.homepath}}/create/alias/{{cur_domain}}"><i class="fa fa-plus"></i> {{ _('Alias') }}</a>
</ul>
<h2>
{% if all_are_admins %}
{{ _('Admins under domain: %s') |format(cur_domain) }}
{% else %}
{{ _('Users under domain: %s') |format(cur_domain) }}
{% endif %}
{% if total is defined and users|length > 0 %}
({{ (cur_page-1) * page_size_limit + 1 }}-{{ (cur_page-1) * page_size_limit + users|length}}/{{ total }})
{% endif %}
<a href="{{ctx.homepath}}/profile/domain/general/{{cur_domain}}"><i class="fa fa-cog fa-lg" title="{{ _('Edit domain profile') }}"></i></a>
{{ set_account_activity_img('sent', 'domain', cur_domain, float=false) }}
</h2>
</div>
<div class="box-wrapper clear">
<div id="user_list">
<form name="form_users" id="account_list" method="post" action="{{ctx.homepath}}/users/{{cur_domain}}/page/{{ cur_page }}">
{# Control whether we should redirect to /admins/[domain] or /usrs/[domain] #}
{% if all_are_admins %}
<input type="hidden" name="redirect_to_admin_list" value="yes">
{% endif %}
{{ input_csrf_token() }}
<table class="style1">
<thead>
<tr>
<th class="checkbox"><input type="checkbox" class="checkbox select-all" /></th>
<th data-sort="string-ins"><a href="{{ctx.homepath}}/users/{{cur_domain}}?order_name=name&order_by={% if order_name == 'name' and not order_by_desc %}desc{% else %}asc{% endif %}">{{ _('Display Name') }}</a></th>
<th data-sort="string-ins">{{ _('Mail Address') }}</th>
<th data-sort="string-ins">{{ _('User/Employee ID') }}</th>
{#
<th data-sort="string-ins">{{ _('Job Title') }}</th>
#}
{% if all_are_admins %}
<th data-sort="int">{{ _('Quota') }}</th>
{% else %}
<th data-sort="int"><a href="{{ctx.homepath}}/users/{{cur_domain}}?order_name=quota&order_by={% if order_name == 'quota' and order_by_desc %}asc{% else %}desc{% endif %}">{{ _('Quota') }}</a></th>
{% endif %}
{% if last_logins %}
<th data-sort="int">
{{ _('Last Login') }}
{% if backend != "pgsql" %}
(<a href="{{ ctx.homepath }}/users/{{ cur_domain }}/last_logins">{{ _("All users") }}</a>)
{% endif %}
</th>
{% endif %}
</tr>
</thead>
<tbody>
{% if users %}
{% for r in users %}
{% set mail = r.username |e %}
<tr>
<td class="checkbox">
<input type="checkbox"
name="mail"
class="checkbox"
value="{{ mail }}"
alt="{% if r.active %}active{% else %}disabled{% endif %}"
{% if session.get('is_global_admin') %}
{% if mail == session.get('username') %}disabled="disabled"{% endif %}
{% else %}
{# Normal admin is NOT allowed to enable/disable/delete itself and global admin accounts. #}
{% if mail == session.get('username') or r.isglobaladmin == 1 %}disabled="disabled"{% endif %}
{% endif %}
/>
</td>
<td class="vcenter">
<a href="{{ctx.homepath}}/profile/user/general/{{mail}}">
<i class="fa fa-cog fa-lg fr-space" title="{{ _('Edit account profile') }}{% if r.passwordlastchange %}<br/>{{ _('Password last change:') }} {{ r.passwordlastchange | utc_to_timezone(timezone=session.get('timezone')) }}{% endif %}"></i>
</a>
{{ set_account_activity_img('sent', 'user', mail) }}
{{ set_account_status_img(r.active) }}
{% if r.isglobaladmin %}
{{ set_user_admin_type_img('globaladmin') }}
{% elif r.isadmin %}
{{ set_user_admin_type_img('domainadmin') }}
{% endif %}
{{ set_assigned_groups_img(addresses=user_assigned_groups.get(mail, [])) }}
{{ set_forwarding_address_img(user=mail, addresses=user_forwardings.get(mail, [])) }}
{{ set_alias_address_img(addresses=user_alias_addresses.get(mail, [])) }}
<a href="{{ctx.homepath}}/profile/user/general/{{mail}}" title="{{ _('Edit account profile') }}">{% if r.name %}{{ r.name |cut_string |e }}{% else %}{{ mail.split('@', 1)[0] }}{% endif %}</a>
</td>
<td class="vcenter">{{ highlight_username_in_mail(mail) }}</td>
<td class="vcenter">{% if r.employeeid %}{{ r.employeeid |e }}{% endif %}</td>
{# mail quota #}
{% set usedQuotaBytes = used_quotas.get(mail, {}).get('bytes', 0) %}
{% set usedQuotaMessages = used_quotas.get(mail, {}).get('messages', 0) %}
{% if r.quota == 0 %}
{% if session.get('show_used_quota') %}
<td class="vcenter" data-sort-value="0">{{ usedQuotaBytes |file_size_format }} / {{ _('Unlimited') }}</td>
{% else %}
<td class="vcenter" data-sort-value="0">{{ _('Unlimited') }}</td>
{% endif %}
{% else %}
{% set percent = usedQuotaBytes |convert_to_percentage(r.quota |int * 1024 * 1024) %}
<td class="vcenter" data-sort-value="{{ r.quota }}">
<div>
<span title="{{ _('Edit quota setting') }}"><a href="{{ctx.homepath}}/profile/user/general/{{mail}}">{{ percent }}%</a></span>
<span class="color-grey">(<span title="{{ _('Stored') }}">{{ usedQuotaMessages }} {{_('Emails') }} / {{ usedQuotaBytes |file_size_format }}</span>) / <span title="{{ _('Allocated') }}">{{ r.quota |file_size_format(base_mb=True) }}</span></span>
</div>
{{ display_progress_bar(percent, show_zero=true, width='60%', style='thin') }}
</td>
{% endif %}
{% if last_logins %}
{% if mail in last_logins %}
{% set _times = last_logins.get(mail, {}) %}
{% set _imap = _times.get('imap') or 0 %}
{% set _pop3 = _times.get('pop3') or 0 %}
{% set _lda = _times.get('lda') or 0 %}
{# imap or pop3 login time #}
{% set _login_time = 0 %}
{% set _login_service = None %}
{% if (_imap > 0) and (_pop3 > 0) %}
{% if _imap > _pop3 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% else %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
{% elif _imap > 0 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% elif _pop3 > 0 %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
<td data-sort-value="{{ _login_time }}">
{% if _login_time %}
<span title="{% if _imap %}{{ _('IMAP Login:') }} {{ _imap | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}<br/>{% endif %}{% if _pop3 %}{{ _('POP3 Login:') }} {{ _pop3 | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}<br/>{% endif %}{% if _lda %}{{ _('New Mail Delivered:') }} {{ _lda | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}{% endif %}">
{{ _login_time | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}
{% if _login_service %}
{{ _login_service | upper }}
{% endif %}
</span>
{% endif %}
</td>
{% else %}
<td data-sort-value="0"></td>
{% endif %}
{% endif %}
</tr>
{% endfor %}
{% else %}
<tr>
<td class="checkbox"></td>
{% if all_are_admins %}
<td colspan="4">{{ _('No mail admin assigned.') }}</td>
{% else %}
<td colspan="4">{{ _('No mail user available.') }}
{% if not (first_char or disabled_only) %}
<a href="{{ctx.homepath}}/create/user/{{ cur_domain }}">{{ _('Add one') }}</a>?
{% endif %}
</td>
{% endif %}
</tr>
{% endif %}
</tbody>
</table>
<input type="hidden" name="cur_page" value="{{cur_page}}" />
{% if users %}
<div class="tab-footer clear f1">
<div class="fl">
<select name="action" class="fl-space" id="account_list_actions" >
<option>{{ _('Choose Action') }}</option>
<option disabled>----</option>
<option value="enable">{{ _('Enable') }}</option>
<option value="disable">{{ _('Disable') }}</option>
<option value="delete">{{ _('Delete') }}</option>
<option disabled>----</option>
<option value="markasadmin">{{ _('Mark as domain admin') }}</option>
<option value="unmarkasadmin">{{ _('Unmark as domain admin') }}</option>
{% if session.get('is_global_admin') %}
<option disabled>----</option>
<option value="markasglobaladmin">{{ _('Mark as global admin') }}</option>
<option value="unmarkasglobaladmin">{{ _('Unmark as global admin') }}</option>
{% endif %}
</select>
<select name="keep_mailbox_days" class="fl-space" id="account_delete_date">
{% for _day in days_to_keep_removed_mailbox %}
<option value="{{ _day }}">{{ display_remove_mailbox_days(_day) }}</option>
{% endfor %}
</select>
<input type="submit" name="submit_users" value="{{ _('Apply') }}" class="button fl-space" />
</div>
{% if all_are_admins %}
{% set baseurl = ctx.homepath + '/admins/' + cur_domain %}
{% else %}
{% set baseurl = ctx.homepath + '/users/' + cur_domain %}
{% endif %}
{% if disabled_only %}
{% set baseurl = baseurl + '/disabled' %}
{% endif %}
{% if all_are_admins %}
{{ show_pages(baseurl=baseurl,
total=total,
cur_page=cur_page) }}
{% else %}
{{ show_pages(baseurl=baseurl,
total=total,
cur_page=cur_page,
url_suffix=ctx.query) }}
{% endif %}
</div>
{% endif %}
</form>
</div>{# #user_list #}
</div>{# .box-wrapper #}
</div>{# -- End id=user_list -- #}
</div>
{% endif %}
{% endblock main %}

View File

@@ -0,0 +1,606 @@
{% extends "layout.html" %}
{% from "macros/form_inputs.html" import
input_submit,
input_csrf_token
with context
%}
{% from "macros/general.html" import
display_subnav,
set_account_activity_img,
display_input_cn,
display_preferred_language,
display_timezones,
display_quota,
display_change_email_address,
display_input_employeeid,
display_account_status,
display_mark_user_as_admin,
display_reset_password,
display_random_password,
display_user_forwarding,
display_recipient_bcc,
display_sender_bcc,
display_relay,
display_sender_relayhost,
display_per_account_wblist_all,
display_allow_nets
with context
%}
{% from "macros/sql.html" import
display_enabled_user_services,
display_all_domains
with context
%}
{% from "macros/iredapd.html" import
display_throttle_setting,
display_greylisting_setting,
display_greylisting_whitelists
with context
%}
{% from "macros/amavisd.html" import display_spam_policy with context %}
{% from "macros/msg_handlers.html" import warning_info, user_msg_handler with context %}
{% block title %}{{ _('Edit account profile') }}{% endblock %}
{% block navlinks_domains %}class="active"{% endblock %}
{% block breadcrumb %}
{% set tmp_crumbs = [
(ctx.homepath + '/domains', _('All domains')),
(ctx.homepath + '/profile/domain/general/' + cur_domain, cur_domain),
(ctx.homepath + '/users/' + cur_domain, _('Users')),
('active', ctx.homepath + '/profile/user/general/' + mail, _('Profile of user:') + '&nbsp;' + mail),
(ctx.homepath + '/mls/' + cur_domain, _('Mailing Lists')),
(ctx.homepath + '/aliases/' + cur_domain, _('Aliases')),
] %}
{% if session.get('is_global_admin') %}
{% set crumbs = tmp_crumbs + [(ctx.homepath + '/admins/' + cur_domain, _('Admins'))] %}
{% else %}
{% set crumbs = tmp_crumbs %}
{% endif %}
{% if backend != "pgsql" %}
{% set crumbs = crumbs + [(ctx.homepath + '/users/' + cur_domain + '/last_logins', _('Last Logins'))] %}
{% endif %}
{{ display_subnav(crumbs) }}
{% endblock %}
{% block main %}
{# Show system message #}
{% if msg %}
{% if msg.startswith('PW_') %}
{% set _pw_errors = msg.split(',') %}
{% for _err in _pw_errors %}
{{ user_msg_handler(_err) }}
{% endfor %}
{% else %}
{{ user_msg_handler(msg) }}
{% endif %}
{% endif %}
{% if discarded_aliases %}
{% set _msg = _('Some addresses have been discarded because they have been used: %s.') |format(discarded_aliases | join(', ')) %}
{{ warning_info(msg=_msg, removable=true) }}
{% endif %}
{% if session.get('is_global_admin') %}
{% set navlinks = [
('general', _('General'), [true]),
('forwarding', _('Forwarding'), [true]),
('bcc', _('BCC'), [true]),
('relay', _('Relay'), [true]),
('aliases', _('Aliases'), [true]),
('throttle', _('Throttling'), [session.get('iredapd_enabled')]),
('greylisting', _('Greylisting'), [session.get('iredapd_enabled')]),
('wblist', _('White/Blacklists'), [session.get('amavisd_enable_policy_lookup')]),
('spampolicy', _('Spam Policy'), [session.get('amavisd_enable_policy_lookup')]),
('password', _('Password'), [true]),
('advanced', _('Advanced'), [true]),
]
%}
{% else %}
{% set navlinks = [
('general', _('General'), [true]),
('forwarding', _('Forwarding'), ['forwarding' not in disabled_user_profiles]),
('bcc', _('BCC'), ['bcc' not in disabled_user_profiles]),
('relay', _('Relay'), ['relay' not in disabled_user_profiles]),
('aliases', _('Aliases'), ['aliases' not in disabled_user_profiles]),
('throttle', _('Throttling'), ['throttle' not in disabled_user_profiles, session.get('iredapd_enabled')]),
('greylisting', _('Greylisting'), ['greylisting' not in disabled_user_profiles, session.get('iredapd_enabled')]),
('wblist', _('White/Blacklists'), [session.get('amavisd_enable_policy_lookup'), 'wblist' not in disabled_user_profiles]),
('spampolicy', _('Spam Policy'), [session.get('amavisd_enable_policy_lookup'), 'spampolicy' not in disabled_user_profiles]),
('password', _('Password'), [true]),
('advanced', _('Advanced'), [true]),
]
%}
{% endif %}
<div class="content-box">
<div class="box-body">
<div class="box-header clear">
<ul class="tabs clear">
{% for nav in navlinks %}
{% if not false in nav[2] and not none in nav[2] %}
<li><a href="#profile_{{nav[0]}}">{{ nav[1] }}</a></li>
{% endif %}
{% endfor %}
</ul>
<h2>{{ set_account_activity_img('sent', 'user', mail, float=false) }}</h2>
</div>
{# modal window used to change email address #}
{{ display_change_email_address(current_domain=cur_domain,
post_url=ctx.homepath + '/profile/user/rename/' + mail ) }}
<div class="box-wrap clear">
<div id="profile_general">
<form name="general" method="post" action="{{ctx.homepath}}/profile/user/general/{{mail}}">
{{ input_csrf_token() }}
{# imap or pop3 login time #}
{% set _login_time = 0 %}
{% set _login_service = None %}
{% set _times = last_logins.get(mail, {}) %}
{# values may be None, so we use `or 0` to set it to `0` #}
{% set _imap = _times.get('imap', 0) or 0 %}
{% set _pop3 = _times.get('pop3', 0) or 0 %}
{% set _lda = _times.get('lda', 0) or 0 %}
{% if (_imap > 0) and (_pop3 > 0) %}
{% if _imap > _pop3 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% else %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
{% elif _imap > 0 %}
{% set _login_time = _imap %}
{% set _login_service = 'imap' %}
{% elif _pop3 > 0 %}
{% set _login_time = _pop3 %}
{% set _login_service = 'pop3' %}
{% endif %}
<div class="columns clear">
<div class="col2-3">
{{ display_account_status(profile.active,
last_login_epoch_seconds=_login_time,
last_login_service=_login_service) }}
<div class="bt-space10"></div>
{{ display_input_cn(value=profile.name, email=mail, empty_if_equal_to_username=true) }}
{% set stored_mailbox_size = used_quota.get(mail, {}).get('bytes', 0) %}
{% set stored_mailbox_messages = used_quota.get(mail, {}).get('messages', 0) %}
{{ display_quota(value=profile.quota,
show_value_in_input=true,
used_quota=stored_mailbox_size,
stored_messages=stored_mailbox_messages,
show_used_quota=true) }}
{{ display_preferred_language(value=profile.get('language'), languagemaps=languagemaps) }}
{{ display_timezones(value=user_settings.get('timezone'), timezones=timezones) }}
<div class="bt-space10"></div>
{{ display_input_employeeid(profile.employeeid) }}
</div>{#-- .col2-3 --#}
<div class="col1-3 lastcol">
{% if _login_time or _lda %}
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
{% if _imap %}
<li class="bt-space5">{{ _('IMAP Login:') }} {{ _imap | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}</li>
{% endif %}
{% if _pop3 %}
<li class="bt-space5">{{ _('POP3 Login:') }} {{ _pop3 | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}</li>
{% endif %}
{% if _lda %}
<li class="bt-space5">{{ _('New Mail Delivered:') }} {{ _lda | epoch_seconds_to_gmt | utc_to_timezone(timezone=session.get('timezone')) }}</li>
{% endif %}
</ul>
</div>
{% endif %}
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li><a href="#change_email_address" class="modal-link"><span class="text">{{ _('Change email address') }}</span></a></li>
<li class="bt-space5">{{ _('You can enable self-service (per-domain setting) to allow users to manage their own preferences and more.') }}</li>
</ul>
</div>
</div>{# .col1-3 #}
</div>{#-- .columns --#}
<div class="rule"></div>
<div class="columns clear">
<div class="col2-3">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Member of Mailing Lists') }}</h4>
<div class="checklist clear">
<fieldset>
{% for ml_profile in all_maillist_profiles %}
{% set ml_mail = ml_profile.address |e %}
{% set ml_name = ml_profile.name |e %}
<div class="checklist-item">
<span class="fl-space">
<input type="checkbox" name="subscribed_list" value="{{ ml_mail }}" {% if ml_mail in all_subscribed_lists %}checked="checked"{% endif %} />
</span>
<label>
{%- if ml_name -%}
<a href="{{ctx.homepath}}/profile/ml/general/{{ ml_mail }}">{{ ml_name }}</a>&nbsp;({{ ml_mail }})
{%- else -%}
<a href="{{ctx.homepath}}/profile/ml/general/{{ ml_mail }}">{{ ml_mail }}</a>
{%- endif -%}
</label>
</div>
<div class="clear"></div>
{% endfor %}
</fieldset>
</div>{#-- .checklist --#}
</div>{#-- form-field --#}
</div>{#-- End col2-3 -- #}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5"><a href="{{ctx.homepath}}/create/ml/{{ cur_domain }}">{{ _('Add mailing list') }}</a></li>
</ul>
</div>
</div>{# .col1-3 #}
</div>{#-- .columns --#}
<div class="rule"></div>
<div class="columns clear">
<div class="col2-3">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Member of Mail Aliases') }}</h4>
<div class="checklist clear">
<fieldset>
{% for _profile in all_aliases %}
{% set _name = _profile.name |e %}
{% set _mail = _profile.address |e %}
<div class="checklist-item">
<span class="fl-space">
<input type="checkbox" name="memberOfGroup" value="{{ _mail }}" {% if _mail in assigned_aliases %}checked="checked"{% endif %} />
</span>
<label><a href="{{ctx.homepath}}/profile/alias/general/{{ _mail }}">{{ _name }}</a>&nbsp;({{ _mail }})</label>
</div>
<div class="clear"></div>
{% endfor %}
{# Display assigned aliases which is not in same domain as current user #}
{% for _mail in assigned_aliases %}
{% if not _mail.endswith('@' + cur_domain) %}
<div class="checklist-item">
<span class="fl-space">
<input type="checkbox" name="memberOfGroup" value="{{ _mail }}" checked="checked" />
</span>
<label><a href="{{ctx.homepath}}/profile/alias/general/{{ _mail }}">{{ _mail }}</a></label>
</div>
<div class="clear"></div>
{% endif %}
{% endfor %}
</fieldset>
</div>{#-- .checklist --#}
</div>{#-- form-field --#}
</div>{#-- End col2-3 -- #}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5"><a href="{{ctx.homepath}}/create/alias/{{ cur_domain }}">{{ _('Add mail alias') }}</a></li>
</ul>
</div>
</div>{# .col1-3 #}
</div>{#-- .columns --#}
{% if session.get('is_global_admin') or session.get('allowed_to_grant_admin') %}
<div class="rule"></div>
<div class="columns clear">
<div class="col2-3">
{{ display_mark_user_as_admin(is_domain_admin=profile.get('isadmin', 0),
is_global_admin=profile.get('isglobaladmin', 0),
allowed_to_grant_admin=user_settings.get('grant_admin', 'no'),
user_settings=user_settings) }}
</div>
{% if session.get('is_global_admin') %}
<div class="col1-3 lastcol normal_admin_options">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li>{{ _('All domains managed by this admin share the mailbox quota and limit of mail accounts.') }}</li>
<li>{{ _('Domain ownership verification is recommended if you can not fully trust this admin, because if domains like gmail.com, hotmail.com were added locally, all emails sent to gmail.com/hotmail.com will be delivered locally on your server instead of the real Gmail/Hotmail servers.') }}</li>
</ul>
</div>
</div>{# .col1-3 #}
{% endif %}
</div>
{{ display_all_domains(managedDomains=managed_domains, allDomains=all_domains) }}
{% endif %}
{{ input_submit() }}
</form>
</div>{# #profile_general #}
{# profile_type == 'forwarding' #}
{% if session.get('is_global_admin') or 'forwarding' not in disabled_user_profiles %}
<div id="profile_forwarding">
<form name="forwarding" method="post" action="{{ctx.homepath}}/profile/user/forwarding/{{mail}}">
{{ input_csrf_token() }}
{{ display_user_forwarding(mail=mail,
enabled=none,
forwarding_addresses=profile.forwardings) }}
{{ input_submit() }}
</form>
</div>{# #profile_forwarding #}
{% endif %}
{# profile_type: bcc #}
{% if session.get('is_global_admin') or 'bcc' not in disabled_user_profiles %}
<div id="profile_bcc">
<form name="bcc" method="post" action="{{ctx.homepath}}/profile/user/bcc/{{mail}}">
{{ input_csrf_token() }}
{# BCC #}
<div class="columns clear">
<div class="col2-3 ">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Monitor incoming emails via BCC') }}</h4>
<div class="clear">
<input type="checkbox"
name="recipientbcc"
class="checkbox"
rel="checkboxhorizont"
{% if profile.rbcc_active in [1, '1'] %}checked="checked"{%endif%}
/>
</div>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Monitor outgoing emails via BCC') }}</h4>
<div class="clear">
<input type="checkbox"
name="senderbcc"
{% if profile.sbcc_active in [1, '1'] %}checked="checked"{%endif%}
class="checkbox"
rel="checkboxhorizont"
/>
</div>
</div>
{{ display_recipient_bcc(address=profile.recipient_bcc_address) }}
{{ display_sender_bcc(address=profile.sender_bcc_address) }}
</div>
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Multiple addresses are NOT supported.') }}</li>
<li class="bt-space5">{{ _('Per-user bcc settings has higher priority than per-domain bcc settings.') }}</li>
<li class="bt-space5">{{ _('Invalid email addresses will be silently discarded.') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>
{{ input_submit() }}
</form>
</div>
{% endif %}
{# Relay #}
{% if session.get('is_global_admin') or 'relay' not in disabled_user_profiles %}
<div id="profile_relay">
<form name="relay" method="post" action="{{ctx.homepath}}/profile/user/relay/{{mail}}">
{{ input_csrf_token() }}
{{ display_relay(profile.transport |default('') |e,
account_type='user',
url=ctx.homepath + '/profile/domain/relay/' + cur_domain) }}
<div class="rule"></div>
{{ display_sender_relayhost(relayhost=relayhost) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# Aliases #}
{% if session.get('is_global_admin') or 'aliases' not in disabled_user_profiles %}
<div id="profile_aliases">
<form name="aliases" method="post" action="{{ctx.homepath}}/profile/user/aliases/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col2-3">
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Email addresses of alias accounts') }}</h4>
<small>{{ _('One mail address per line. Invalid address will be discarded.') }}</small>
</div>
<div class="form-field clear">
<h4 class="size-250 fl-space"></h4>
<textarea name="user_alias_addresses"
rows="6"
style="width: 50%"
class="textarea"
>{%- for addr in user_alias_addresses %}{{ addr |e }}
{% endfor -%}
</textarea>
</div>
</div>{#-- .col2-3 --#}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('Emails sent to alias addresses will be delivered to %s.') |format('<strong>' + mail + '</strong>') }}</li>
{% if user_alias_cross_all_domains is sameas false %}
<li class="bt-space5">{{ _('Email address of alias account must end with domain name(s): %s.') |format('<strong>' + cur_domain + '</strong>') }}</li>
{% endif %}
</ul>
</div>
</div>
</div>{#-- .columns --#}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# Throttling #}
{% if session.get('iredapd_enabled') and (session.get('is_global_admin') or ('throttle' not in disabled_user_profiles)) %}
<div id="profile_throttle">
<form name="throttle" method="post" action="{{ctx.homepath}}/profile/user/throttle/{{mail}}">
{{ input_csrf_token() }}
{# Throttling in iRedAPD#}
<div class="columns clear">
{{ display_throttle_setting(account=mail,
setting=outbound_throttle_setting,
inout_type='outbound') }}
{{ display_throttle_setting(account=mail,
setting=inbound_throttle_setting,
inout_type='inbound',
with_left_border=true) }}
<div class="col1-3 lastcol">
<div class="mark_blue bt-space10">
<ul class="standard clean-padding bt-space10">
<li class="bt-space5">{{ _('You can set per-domain throttling in domain profile page.') }}</li>
</ul>
</div>
</div>{#-- .col1-3 --#}
</div>{# .columns #}
{{ input_submit() }}
</form>
</div>{# #profile_throttle #}
{% endif %}
{# profile_type: greylisting, with iRedAPD #}
{% if 'greylisting' not in disabled_user_profiles %}
{% if session.get('iredapd_enabled') %}
<div id="profile_greylisting">
<form name="greylisting" method="post" action="{{ctx.homepath}}/profile/user/greylisting/{{mail}}">
{{ input_csrf_token() }}
{{ display_greylisting_setting(account=mail, gl_setting=gl_setting) }}
{{ display_greylisting_whitelists(account=mail, gl_whitelists=gl_whitelists) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{% endif %}
{# wblist #}
{% if session.get('amavisd_enable_policy_lookup') and (session.get('is_global_admin') or ('wblist' not in disabled_user_profiles)) %}
<div id="profile_wblist">
<form name="wblist" method="post" action="{{ctx.homepath}}/profile/user/wblist/{{mail}}">
{{ input_csrf_token() }}
{{ display_per_account_wblist_all(inbound_whitelists=whitelists,
inbound_blacklists=blacklists,
outbound_whitelists=outbound_whitelists,
outbound_blacklists=outbound_blacklists) }}
{{ input_submit() }}
</form>
</div>
{% endif %}
{# Spam Policy#}
{% if session.get('amavisd_enable_policy_lookup') and (session.get('is_global_admin') or ('spampolicy' not in disabled_user_profiles)) %}
<div id="profile_spampolicy">
<form name="spampolicy" method="post" action="{{ctx.homepath}}/profile/user/spampolicy/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
{{ display_spam_policy(account_type='user',
spampolicy=spampolicy,
custom_ban_rules=custom_ban_rules,
global_spam_score=global_spam_score) }}
{{ input_submit() }}
</div>
</form>
</div>
{% endif %}
{# Password #}
<div id="profile_password">
<form name="password" method="post" action="{{ctx.homepath}}/profile/user/password/{{mail}}">
{{ input_csrf_token() }}
<div class="columns clear">
<div class="col3-4">
{{ display_reset_password(show_confirmpw=true,
min_passwd_length=min_passwd_length,
max_passwd_length=max_passwd_length,
store_password_in_plain_text=store_password_in_plain_text) }}
</div>
<div class="col1-4 lastcol">
{{ display_random_password(password_length=min_passwd_length,
password_policies=password_policies,
password_last_change_date=profile.passwordlastchange) }}
</div>
</div>
{{ input_submit() }}
</form>
</div>
<div id="profile_advanced">
<form name="advanced" method="post" action="{{ctx.homepath}}/profile/user/advanced/{{mail}}">
{{ input_csrf_token() }}
{{ display_enabled_user_services(profile=profile, greylisted=greylisted) }}
<div class="rule"></div>
{{ display_allow_nets(allow_nets=allow_nets) }}
<div class="rule"></div>
{% if session.get('is_global_admin') %}
{# Maildir path #}
<div class="form-field clear">
<h4 class="size-250 fl-space">{{ _('Path to mailbox') }}</h4>
<input type="text" name="storageBaseDirectory" value="{{ profile.storagebasedirectory |default('') |e }}" size="{{ storageBaseDirectory |length}}" class="fl-space text" />
<span class="vcenter">/</span>
<input type="text" name="storageNode" value="{{ profile.storagenode |default('') |e }}" />
<span class="vcenter">/</span>
<input type="text" name="mailMessageStore" value="{{ profile.maildir |default('') }}" size="{{ profile.maildir |length }}" class="text" />
</div>
{% endif %}
{{ input_submit() }}
</form>
</div>
</div>
</div>
</div>
{% endblock main %}
{% block extra_js %}
<script type="text/javascript">
$(document).ready(function() {
$(".tabs li").idTabs("profile_{{ profile_type }}");
$('#domain_search').quickfilter('#all_domains tr');
});
</script>
{% endblock extra_js %}