change CLI to handle global lists
This commit is contained in:
@@ -23,6 +23,7 @@ import time
|
|||||||
|
|
||||||
from pyquarantine.config import get_milter_config, ActionConfig, ListConfig
|
from pyquarantine.config import get_milter_config, ActionConfig, ListConfig
|
||||||
from pyquarantine.storage import Quarantine
|
from pyquarantine.storage import Quarantine
|
||||||
|
from pyquarantine.list import DatabaseList
|
||||||
from pyquarantine import __version__ as version
|
from pyquarantine import __version__ as version
|
||||||
|
|
||||||
|
|
||||||
@@ -41,8 +42,6 @@ def _get_quarantine(cfg, name, debug):
|
|||||||
(q for q in _get_quarantines(cfg) if q["name"] == name))
|
(q for q in _get_quarantines(cfg) if q["name"] == name))
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
raise RuntimeError(f"invalid quarantine '{name}'")
|
raise RuntimeError(f"invalid quarantine '{name}'")
|
||||||
for name, lst in cfg["lists"].items():
|
|
||||||
cfg["lists"][name] = ListConfig(lst, {})
|
|
||||||
return Quarantine(ActionConfig(quarantine, cfg["lists"]), [], debug)
|
return Quarantine(ActionConfig(quarantine, cfg["lists"]), [], debug)
|
||||||
|
|
||||||
|
|
||||||
@@ -54,12 +53,17 @@ def _get_notification(cfg, name, debug):
|
|||||||
return notification
|
return notification
|
||||||
|
|
||||||
|
|
||||||
def _get_allowlist(cfg, name, debug):
|
def _get_list(cfg, name, debug):
|
||||||
allowlist = _get_quarantine(cfg, name, debug).allowlist
|
try:
|
||||||
if not allowlist:
|
list_cfg = ListConfig(cfg["lists"][name], {})
|
||||||
raise RuntimeError(
|
except KeyError:
|
||||||
"allowlist type is set to NONE")
|
raise RuntimeError(f"list '{name}' is not configured")
|
||||||
return allowlist
|
|
||||||
|
if list_cfg["type"] == "db":
|
||||||
|
list_cfg["loglevel"] = cfg["loglevel"]
|
||||||
|
return DatabaseList(list_cfg, debug)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("invalid lists type")
|
||||||
|
|
||||||
|
|
||||||
def print_table(columns, rows):
|
def print_table(columns, rows):
|
||||||
@@ -110,21 +114,21 @@ def list_quarantines(cfg, args):
|
|||||||
else:
|
else:
|
||||||
qlist = []
|
qlist = []
|
||||||
for q in quarantines:
|
for q in quarantines:
|
||||||
cfg = q["options"]
|
qcfg = q["options"]
|
||||||
storage_type = cfg["store"]["type"]
|
storage_type = qcfg["store"]["type"]
|
||||||
|
|
||||||
if "notify" in cfg:
|
if "notify" in cfg:
|
||||||
notification_type = cfg["notify"]["type"]
|
notification_type = qcfg["notify"]["type"]
|
||||||
else:
|
else:
|
||||||
notification_type = "NONE"
|
notification_type = "NONE"
|
||||||
|
|
||||||
if "allowlist" in cfg:
|
if "lists" in qcfg:
|
||||||
allowlist_type = cfg["allowlist"]["type"]
|
lists_type = qcfg["lists"]
|
||||||
else:
|
else:
|
||||||
allowlist_type = "NONE"
|
lists_type = "NONE"
|
||||||
|
|
||||||
if "milter_action" in cfg:
|
if "milter_action" in qcfg:
|
||||||
milter_action = cfg["milter_action"]
|
milter_action = qcfg["milter_action"]
|
||||||
else:
|
else:
|
||||||
milter_action = "NONE"
|
milter_action = "NONE"
|
||||||
|
|
||||||
@@ -132,14 +136,14 @@ def list_quarantines(cfg, args):
|
|||||||
"name": q["name"],
|
"name": q["name"],
|
||||||
"storage": storage_type,
|
"storage": storage_type,
|
||||||
"notification": notification_type,
|
"notification": notification_type,
|
||||||
"allowlist": allowlist_type,
|
"lists": lists_type,
|
||||||
"action": milter_action})
|
"action": milter_action})
|
||||||
|
|
||||||
print_table(
|
print_table(
|
||||||
[("Name", "name"),
|
[("Name", "name"),
|
||||||
("Storage", "storage"),
|
("Storage", "storage"),
|
||||||
("Notification", "notification"),
|
("Notification", "notification"),
|
||||||
("Allowlist", "allowlist"),
|
("Allowlist", "lists"),
|
||||||
("Action", "action")],
|
("Action", "action")],
|
||||||
qlist
|
qlist
|
||||||
)
|
)
|
||||||
@@ -193,16 +197,16 @@ def list_quarantine_emails(cfg, args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def list_allowlist(cfg, args):
|
def list_list(cfg, args):
|
||||||
allowlist = _get_allowlist(cfg, args.quarantine, args.debug)
|
lists = _get_list(cfg, args.list, args.debug)
|
||||||
|
|
||||||
# find allowlist entries
|
# find lists entries
|
||||||
entries = allowlist.find(
|
entries = lists.find(
|
||||||
mailfrom=args.mailfrom,
|
mailfrom=args.mailfrom,
|
||||||
recipients=args.recipients,
|
recipients=args.recipients,
|
||||||
older_than=args.older_than)
|
older_than=args.older_than)
|
||||||
if not entries:
|
if not entries:
|
||||||
print(f"allowlist of quarantine '{args.quarantine}' is empty")
|
print("list is empty")
|
||||||
return
|
return
|
||||||
|
|
||||||
# transform some values to strings
|
# transform some values to strings
|
||||||
@@ -223,12 +227,12 @@ def list_allowlist(cfg, args):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def add_allowlist_entry(cfg, args):
|
def add_list_entry(cfg, args):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
allowlist = _get_allowlist(cfg, args.quarantine, args.debug)
|
lists = _get_list(cfg, args.list, args.debug)
|
||||||
|
|
||||||
# check existing entries
|
# check existing entries
|
||||||
entries = allowlist.check(args.mailfrom, args.recipient, logger)
|
entries = lists.check(args.mailfrom, args.recipient, logger)
|
||||||
if entries:
|
if entries:
|
||||||
# check if the exact entry exists already
|
# check if the exact entry exists already
|
||||||
for entry in entries.values():
|
for entry in entries.values():
|
||||||
@@ -258,15 +262,15 @@ def add_allowlist_entry(cfg, args):
|
|||||||
"from/to combination is already covered by the entries above, "
|
"from/to combination is already covered by the entries above, "
|
||||||
"use --force to override.")
|
"use --force to override.")
|
||||||
|
|
||||||
# add entry to allowlist
|
# add entry to lists
|
||||||
allowlist.add(args.mailfrom, args.recipient, args.comment, args.permanent)
|
lists.add(args.mailfrom, args.recipient, args.comment, args.permanent)
|
||||||
print("allowlist entry added successfully")
|
print("list entry added successfully")
|
||||||
|
|
||||||
|
|
||||||
def delete_allowlist_entry(cfg, args):
|
def delete_list_entry(cfg, args):
|
||||||
allowlist = _get_allowlist(cfg, args.quarantine, args.debug)
|
lists = _get_list(cfg, args.list, args.debug)
|
||||||
allowlist.delete(args.allowlist_id)
|
lists.delete(args.lists_id)
|
||||||
print("allowlist entry deleted successfully")
|
print("list entry deleted successfully")
|
||||||
|
|
||||||
|
|
||||||
def notify(cfg, args):
|
def notify(cfg, args):
|
||||||
@@ -524,86 +528,86 @@ def main():
|
|||||||
help="Quarantine ID.")
|
help="Quarantine ID.")
|
||||||
quar_metadata_parser.set_defaults(func=metadata)
|
quar_metadata_parser.set_defaults(func=metadata)
|
||||||
|
|
||||||
# allowlist command group
|
# lists command group
|
||||||
allowlist_parser = subparsers.add_parser(
|
lists_parser = subparsers.add_parser(
|
||||||
"allowlist",
|
"lists",
|
||||||
description="Manage allowlists.",
|
description="Manage lists.",
|
||||||
help="Manage allowlists.",
|
help="Manage lists.",
|
||||||
formatter_class=formatter_class)
|
formatter_class=formatter_class)
|
||||||
allowlist_parser.add_argument(
|
lists_parser.add_argument(
|
||||||
"quarantine",
|
|
||||||
metavar="QUARANTINE",
|
|
||||||
help="Quarantine name.")
|
|
||||||
allowlist_subparsers = allowlist_parser.add_subparsers(
|
|
||||||
dest="command",
|
|
||||||
title="Allowlist commands")
|
|
||||||
allowlist_subparsers.required = True
|
|
||||||
# allowlist list command
|
|
||||||
allowlist_list_parser = allowlist_subparsers.add_parser(
|
|
||||||
"list",
|
"list",
|
||||||
description="List allowlist entries.",
|
metavar="LIST",
|
||||||
help="List allowlist entries.",
|
help="List name.")
|
||||||
|
lists_subparsers = lists_parser.add_subparsers(
|
||||||
|
dest="command",
|
||||||
|
title="Lists commands.")
|
||||||
|
lists_subparsers.required = True
|
||||||
|
# lists list command
|
||||||
|
lists_list_parser = lists_subparsers.add_parser(
|
||||||
|
"list",
|
||||||
|
description="List list entries.",
|
||||||
|
help="List list entries.",
|
||||||
formatter_class=formatter_class)
|
formatter_class=formatter_class)
|
||||||
allowlist_list_parser.add_argument(
|
lists_list_parser.add_argument(
|
||||||
"-f", "--from",
|
"-f", "--from",
|
||||||
dest="mailfrom",
|
dest="mailfrom",
|
||||||
help="Filter entries by from address.",
|
help="Filter entries by from address.",
|
||||||
default=None,
|
default=None,
|
||||||
nargs="+")
|
nargs="+")
|
||||||
allowlist_list_parser.add_argument(
|
lists_list_parser.add_argument(
|
||||||
"-t", "--to",
|
"-t", "--to",
|
||||||
dest="recipients",
|
dest="recipients",
|
||||||
help="Filter entries by recipient address.",
|
help="Filter entries by recipient address.",
|
||||||
default=None,
|
default=None,
|
||||||
nargs="+")
|
nargs="+")
|
||||||
allowlist_list_parser.add_argument(
|
lists_list_parser.add_argument(
|
||||||
"-o", "--older-than",
|
"-o", "--older-than",
|
||||||
dest="older_than",
|
dest="older_than",
|
||||||
help="Filter emails by last used date (days).",
|
help="Filter emails by last used date (days).",
|
||||||
default=None,
|
default=None,
|
||||||
type=float)
|
type=float)
|
||||||
allowlist_list_parser.set_defaults(func=list_allowlist)
|
lists_list_parser.set_defaults(func=list_list)
|
||||||
# allowlist add command
|
# lists add command
|
||||||
allowlist_add_parser = allowlist_subparsers.add_parser(
|
lists_add_parser = lists_subparsers.add_parser(
|
||||||
"add",
|
"add",
|
||||||
description="Add allowlist entry.",
|
description="Add list entry.",
|
||||||
help="Add allowlist entry.",
|
help="Add list entry.",
|
||||||
formatter_class=formatter_class)
|
formatter_class=formatter_class)
|
||||||
allowlist_add_parser.add_argument(
|
lists_add_parser.add_argument(
|
||||||
"-f", "--from",
|
"-f", "--from",
|
||||||
dest="mailfrom",
|
dest="mailfrom",
|
||||||
help="From address.",
|
help="From address.",
|
||||||
required=True)
|
required=True)
|
||||||
allowlist_add_parser.add_argument(
|
lists_add_parser.add_argument(
|
||||||
"-t", "--to",
|
"-t", "--to",
|
||||||
dest="recipient",
|
dest="recipient",
|
||||||
help="Recipient address.",
|
help="Recipient address.",
|
||||||
required=True)
|
required=True)
|
||||||
allowlist_add_parser.add_argument(
|
lists_add_parser.add_argument(
|
||||||
"-c", "--comment",
|
"-c", "--comment",
|
||||||
help="Comment.",
|
help="Comment.",
|
||||||
default="added by CLI")
|
default="added by CLI")
|
||||||
allowlist_add_parser.add_argument(
|
lists_add_parser.add_argument(
|
||||||
"-p", "--permanent",
|
"-p", "--permanent",
|
||||||
help="Add a permanent entry.",
|
help="Add a permanent entry.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
allowlist_add_parser.add_argument(
|
lists_add_parser.add_argument(
|
||||||
"--force",
|
"--force",
|
||||||
help="Force adding an entry, "
|
help="Force adding an entry, "
|
||||||
"even if already covered by another entry.",
|
"even if already covered by another entry.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
allowlist_add_parser.set_defaults(func=add_allowlist_entry)
|
lists_add_parser.set_defaults(func=add_list_entry)
|
||||||
# allowlist delete command
|
# lists delete command
|
||||||
allowlist_delete_parser = allowlist_subparsers.add_parser(
|
lists_delete_parser = lists_subparsers.add_parser(
|
||||||
"delete",
|
"delete",
|
||||||
description="Delete allowlist entry.",
|
description="Delete list entry.",
|
||||||
help="Delete allowlist entry.",
|
help="Delete list entry.",
|
||||||
formatter_class=formatter_class)
|
formatter_class=formatter_class)
|
||||||
allowlist_delete_parser.add_argument(
|
lists_delete_parser.add_argument(
|
||||||
"allowlist_id",
|
"lists_id",
|
||||||
metavar="ID",
|
metavar="ID",
|
||||||
help="List ID.")
|
help="List ID.")
|
||||||
allowlist_delete_parser.set_defaults(func=delete_allowlist_entry)
|
lists_delete_parser.set_defaults(func=delete_list_entry)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|||||||
@@ -299,7 +299,8 @@ class ActionConfig(BaseConfig):
|
|||||||
return
|
return
|
||||||
if "conditions" in self:
|
if "conditions" in self:
|
||||||
self["conditions"] = ConditionsConfig(self["conditions"], lists)
|
self["conditions"] = ConditionsConfig(self["conditions"], lists)
|
||||||
self["action"] = self.ACTION_TYPES[self["type"]](self["options"], lists)
|
self["action"] = self.ACTION_TYPES[self["type"]](
|
||||||
|
self["options"], lists)
|
||||||
|
|
||||||
|
|
||||||
class RuleConfig(BaseConfig):
|
class RuleConfig(BaseConfig):
|
||||||
|
|||||||
Reference in New Issue
Block a user