audit-labs/audit-tools

A collection of scripts, queries, and other goodies you can use in an audit.

clone: git clone https://gitbay.org/audit-labs/audit-tools.git

main: applications/gitlab/collectors/approvals.py · raw

 1"""
 2Collect merge-request approval rules for every project in the group.
 3
 4Approval rules require a GitLab Premium or Ultimate subscription. Projects that
 5return 403/404 (feature unavailable) are skipped with a warning.
 6"""
 7
 8import sys
 9
10import requests
11
12from .api import paginate
13
14
15def approval_rules(_group, cfg, projects):
16    rows = []
17    for p in projects:
18        try:
19            rules = paginate(
20                f"{cfg['base_url']}/projects/{p['id']}/approval_rules", cfg
21            )
22        except requests.HTTPError as e:
23            if e.response is not None and e.response.status_code in (403, 404):
24                print(
25                    f"  Skipping {p.get('path_with_namespace', p['id'])}: "
26                    f"approval_rules returned {e.response.status_code}",
27                    file=sys.stderr,
28                )
29                continue
30            raise
31        for rule in rules:
32            approvers = ", ".join(
33                a.get("name", "") for a in rule.get("eligible_approvers", [])
34            )
35            branches = ", ".join(
36                b.get("name", "") for b in rule.get("protected_branches", [])
37            )
38            rows.append(
39                {
40                    "project": p.get("path_with_namespace", ""),
41                    "rule": rule.get("name", ""),
42                    "rule_type": rule.get("rule_type", ""),
43                    "approvals_required": rule.get("approvals_required", 0),
44                    "protected_branches": branches or "(all)",
45                    "eligible_approvers": approvers or "(none)",
46                }
47            )
48    return rows