feat(bitdefender): complete Accounts module (build-out 1/N)

- Completed Accounts module for bitdefender skill (GravityZone Public API)
- Added 5 methods: getAccountDetails, createAccount, updateAccount, deleteAccount, configureNotificationsSettings
- Write methods require --confirm; raw also gates createAccount/updateAccount/configureNotificationsSettings
- Param shapes validated against official docs and safe validation probes
- configureNotificationsSettings is a setter with no required param; warning documented against empty payload on live tenant
- selftest 42 -> 49 passing

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-21 10:22:01 -07:00
parent 4cf34f5221
commit 8a64bc48e6
5 changed files with 217 additions and 9 deletions

View File

@@ -265,6 +265,88 @@ def cmd_notif_settings(client, args):
_emit(client.get_notifications_settings(), args.json, _print_kv)
def cmd_account(client, args):
_emit(client.get_account_details(args.account_id), args.json, _print_kv)
def _load_json_arg(raw, label):
"""Parse a JSON-object CLI arg; returns (obj, error_rc). error_rc is None on ok."""
if raw is None:
return {}, None
try:
obj = json.loads(raw)
except json.JSONDecodeError as exc:
print(f"[ERROR] --{label} is not valid JSON: {exc}", file=sys.stderr)
return None, 2
if not isinstance(obj, dict):
print(f"[ERROR] --{label} must be a JSON object.", file=sys.stderr)
return None, 2
return obj, None
def cmd_account_create(client, args):
rights, rc = _load_json_arg(args.rights_json, "rights-json")
if rc:
return rc
extra, rc = _load_json_arg(args.extra_json, "extra-json")
if rc:
return rc
profile = {}
if args.full_name:
profile["fullName"] = args.full_name
if args.language:
profile["language"] = args.language
if args.timezone:
profile["timezone"] = args.timezone
if not _gated(f"create account {args.email} (role={args.role})", args.confirm):
return 3
result = client.create_account(
email=args.email, password=args.password, username=args.username,
role=args.role, profile=profile or None, rights=rights or None,
extra=extra or None,
)
_emit({"createdAccount": args.email, "result": result}, args.json, _print_kv)
return 0
def cmd_account_update(client, args):
fields, rc = _load_json_arg(args.set_json, "set-json")
if rc:
return rc
if not fields:
print("[ERROR] --set-json (object of fields to change) is required.",
file=sys.stderr)
return 2
if not _gated(f"update account {args.id} fields={list(fields)}", args.confirm):
return 3
result = client.update_account(args.id, fields)
_emit({"updatedAccount": args.id, "result": result}, args.json, _print_kv)
return 0
def cmd_account_delete(client, args):
if not _gated(f"delete account {args.id}", args.confirm):
return 3
result = client.delete_account(args.id)
_emit({"deletedAccount": args.id, "result": result}, args.json, _print_kv)
return 0
def cmd_notif_configure(client, args):
settings, rc = _load_json_arg(args.settings_json, "settings-json")
if rc:
return rc
if not settings:
print("[ERROR] --settings-json (the settings object) is required.",
file=sys.stderr)
return 2
if not _gated(f"configure notification settings ({list(settings)})", args.confirm):
return 3
result = client.configure_notifications_settings(settings)
_emit({"notificationsConfigured": True, "result": result}, args.json, _print_kv)
return 0
def cmd_scan_tasks(client, args):
_emit(client.list_scan_tasks(page=args.page, per_page=args.per_page),
args.json, _print_scan_tasks_table)
@@ -395,7 +477,8 @@ def cmd_make_group(client, args):
DESTRUCTIVE_RAW_PATTERNS = ("delete", "createuninstall", "createremove",
"createreconfigure", "isolat", "addtoblocklist",
"removefromblocklist", "assignpolicy",
"setpushevent")
"setpushevent", "createaccount", "updateaccount",
"configurenotif")
def _is_destructive_method(method: str) -> bool:
@@ -545,6 +628,11 @@ def build_parser() -> argparse.ArgumentParser:
sub.add_parser("notif-settings", help="Show notification settings.",
parents=[common])
sp = sub.add_parser("account",
help="Account detail (no id = the API key's own account).",
parents=[common])
sp.add_argument("account_id", nargs="?", help="Account id (optional).")
sp = sub.add_parser("scan-tasks", help="List scan tasks.", parents=[common])
sp.add_argument("--page", type=int, default=1)
sp.add_argument("--per-page", type=int, default=100)
@@ -674,6 +762,36 @@ def build_parser() -> argparse.ArgumentParser:
help="Inherit the policy from the parent group.")
sp.add_argument("--confirm", action="store_true")
sp = sub.add_parser("account-create", help="Create a console account (gated).",
parents=[common])
sp.add_argument("--email", required=True)
sp.add_argument("--password")
sp.add_argument("--username")
sp.add_argument("--role", type=int, help="Numeric role id (see docs/console).")
sp.add_argument("--full-name")
sp.add_argument("--language", help="e.g. en_US")
sp.add_argument("--timezone", help="e.g. America/Phoenix")
sp.add_argument("--rights-json", help="JSON object of rights flags.")
sp.add_argument("--extra-json", help="JSON object of any extra documented fields.")
sp.add_argument("--confirm", action="store_true")
sp = sub.add_parser("account-update", help="Update a console account (gated).",
parents=[common])
sp.add_argument("--id", required=True, help="accountId.")
sp.add_argument("--set-json", required=True, help="JSON object of fields to change.")
sp.add_argument("--confirm", action="store_true")
sp = sub.add_parser("account-delete", help="Delete a console account (gated).",
parents=[common])
sp.add_argument("--id", required=True, help="accountId.")
sp.add_argument("--confirm", action="store_true")
sp = sub.add_parser("notif-configure",
help="Set notification settings (gated).", parents=[common])
sp.add_argument("--settings-json", required=True,
help="JSON object of the notification settings to apply.")
sp.add_argument("--confirm", action="store_true")
sp = sub.add_parser("push-set",
help="Configure the push event service (gated).",
parents=[common])
@@ -705,6 +823,11 @@ HANDLERS = {
"reports": cmd_reports,
"accounts": cmd_accounts,
"notif-settings": cmd_notif_settings,
"account": cmd_account,
"account-create": cmd_account_create,
"account-update": cmd_account_update,
"account-delete": cmd_account_delete,
"notif-configure": cmd_notif_configure,
"scan-tasks": cmd_scan_tasks,
"push-settings": cmd_push_settings,
"push-stats": cmd_push_stats,