Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mailinabox
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
mailinabox
Commits
443b084a
Commit
443b084a
authored
Oct 07, 2014
by
Joshua Tauberer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
in the admin, group aliases by domain, fixes #211
parent
990649af
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
28 deletions
+69
-28
daemon.py
management/daemon.py
+3
-3
mailconfig.py
management/mailconfig.py
+49
-16
aliases.html
management/templates/aliases.html
+17
-9
No files found.
management/daemon.py
View file @
443b084a
...
...
@@ -7,9 +7,9 @@ from functools import wraps
from
flask
import
Flask
,
request
,
render_template
,
abort
,
Response
import
auth
,
utils
from
mailconfig
import
get_mail_users_ex
,
get_admins
,
add_mail_user
,
set_mail_password
,
remove_mail_user
from
mailconfig
import
get_mail_users
,
get_mail_users
_ex
,
get_admins
,
add_mail_user
,
set_mail_password
,
remove_mail_user
from
mailconfig
import
get_mail_user_privileges
,
add_remove_mail_user_privilege
from
mailconfig
import
get_mail_aliases
,
get_mail_domains
,
add_mail_alias
,
remove_mail_alias
from
mailconfig
import
get_mail_aliases
,
get_mail_
aliases_ex
,
get_mail_
domains
,
add_mail_alias
,
remove_mail_alias
env
=
utils
.
load_environment
()
...
...
@@ -146,7 +146,7 @@ def mail_user_privs_remove():
@
authorized_personnel_only
def
mail_aliases
():
if
request
.
args
.
get
(
"format"
,
""
)
==
"json"
:
return
json_response
(
get_mail_aliases
(
env
,
as_json
=
True
))
return
json_response
(
get_mail_aliases
_ex
(
env
))
else
:
return
""
.
join
(
x
+
"
\t
"
+
y
+
"
\n
"
for
x
,
y
in
get_mail_aliases
(
env
))
...
...
management/mailconfig.py
View file @
443b084a
...
...
@@ -139,29 +139,62 @@ def get_admins(env):
users
.
add
(
user
[
"email"
])
return
users
def
get_mail_aliases
(
env
,
as_json
=
False
):
def
get_mail_aliases
(
env
):
# Returns a sorted list of tuples of (alias, forward-to string).
c
=
open_database
(
env
)
c
.
execute
(
'SELECT source, destination FROM aliases'
)
aliases
=
{
row
[
0
]:
row
[
1
]
for
row
in
c
.
fetchall
()
}
# make dict
# put in a canonical order: sort by domain, then by email address lexicographically
aliases
=
[
(
source
,
aliases
[
source
])
for
source
in
utils
.
sort_email_addresses
(
aliases
.
keys
(),
env
)
]
# sort
# but put automatic aliases to administrator@ last
aliases
.
sort
(
key
=
lambda
x
:
x
[
1
]
==
get_system_administrator
(
env
))
if
as_json
:
required_aliases
=
get_required_aliases
(
env
)
aliases
=
[
{
"source"
:
alias
[
0
],
"destination"
:
[
d
.
strip
()
for
d
in
alias
[
1
]
.
split
(
","
)],
"required"
:
alias
[
0
]
in
required_aliases
or
alias
[
0
]
==
get_system_administrator
(
env
),
}
for
alias
in
aliases
]
aliases
=
[
(
source
,
aliases
[
source
])
for
source
in
utils
.
sort_email_addresses
(
aliases
.
keys
(),
env
)
]
return
aliases
def
get_mail_aliases_ex
(
env
):
# Returns a complex data structure of all mail aliases, similar
# to get_mail_users_ex.
#
# [
# {
# domain: "domain.tld",
# alias: [
# {
# source: "name@domain.tld",
# destination: ["target1@domain.com", "target2@domain.com", ...],
# required: True|False
# },
# ...
# ]
# },
# ...
# ]
required_aliases
=
get_required_aliases
(
env
)
domains
=
{}
for
source
,
destination
in
get_mail_aliases
(
env
):
# get alias info
domain
=
get_domain
(
source
)
required
=
((
source
in
required_aliases
)
or
(
source
==
get_system_administrator
(
env
)))
# add to list
if
not
domain
in
domains
:
domains
[
domain
]
=
{
"domain"
:
domain
,
"aliases"
:
[],
}
domains
[
domain
][
"aliases"
]
.
append
({
"source"
:
source
,
"destination"
:
[
d
.
strip
()
for
d
in
destination
.
split
(
","
)],
"required"
:
required
,
})
# Sort domains.
domains
=
[
domains
[
domain
]
for
domain
in
utils
.
sort_domains
(
domains
.
keys
(),
env
)]
# Sort aliases within each domain first by required-ness then lexicographically by source address.
for
domain
in
domains
:
domain
[
"aliases"
]
.
sort
(
key
=
lambda
alias
:
(
alias
[
"required"
],
alias
[
"source"
]))
return
domains
def
get_mail_alias_map
(
env
):
aliases
=
{
}
for
alias
,
targets
in
get_mail_aliases
(
env
):
...
...
management/templates/aliases.html
View file @
443b084a
...
...
@@ -82,15 +82,23 @@ function show_aliases() {
function
(
r
)
{
$
(
'
#alias_table tbody
'
).
html
(
""
);
for
(
var
i
=
0
;
i
<
r
.
length
;
i
++
)
{
var
n
=
$
(
"
#alias-template
"
).
clone
();
n
.
attr
(
'
id
'
,
''
);
if
(
r
[
i
].
required
)
n
.
addClass
(
'
alias-required
'
);
n
.
attr
(
'
data-email
'
,
r
[
i
].
source
);
n
.
find
(
'
td.email
'
).
text
(
r
[
i
].
source
)
for
(
var
j
=
0
;
j
<
r
[
i
].
destination
.
length
;
j
++
)
n
.
find
(
'
td.target
'
).
append
(
$
(
"
<div></div>
"
).
text
(
r
[
i
].
destination
[
j
]))
$
(
'
#alias_table tbody
'
).
append
(
n
);
var
hdr
=
$
(
"
<tr><td colspan='3'><h4/></td></tr>
"
);
hdr
.
find
(
'
h4
'
).
text
(
r
[
i
].
domain
);
$
(
'
#alias_table tbody
'
).
append
(
hdr
);
for
(
var
k
=
0
;
k
<
r
[
i
].
aliases
.
length
;
k
++
)
{
var
alias
=
r
[
i
].
aliases
[
k
];
var
n
=
$
(
"
#alias-template
"
).
clone
();
n
.
attr
(
'
id
'
,
''
);
if
(
alias
.
required
)
n
.
addClass
(
'
alias-required
'
);
n
.
attr
(
'
data-email
'
,
alias
.
source
);
n
.
find
(
'
td.email
'
).
text
(
alias
.
source
)
for
(
var
j
=
0
;
j
<
alias
.
destination
.
length
;
j
++
)
n
.
find
(
'
td.target
'
).
append
(
$
(
"
<div></div>
"
).
text
(
alias
.
destination
[
j
]))
$
(
'
#alias_table tbody
'
).
append
(
n
);
}
}
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment