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/branch_protections.py · raw
1"""Collect protected-branch settings for every project in the group."""
2
3import sys
4
5import requests
6
7from .api import paginate
8
9
10def _levels(entries):
11 """Summarize an access-level list (push/merge/unprotect) into one string."""
12 return ", ".join(e.get("access_level_description", "") for e in entries) or "(none)"
13
14
15def branch_protections(_group, cfg, projects):
16 rows = []
17 for p in projects:
18 try:
19 protected = paginate(
20 f"{cfg['base_url']}/projects/{p['id']}/protected_branches", 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"protected_branches returned {e.response.status_code}",
27 file=sys.stderr,
28 )
29 continue
30 raise
31 for b in protected:
32 rows.append(
33 {
34 "project": p.get("path_with_namespace", ""),
35 "branch": b.get("name", ""),
36 "push_access": _levels(b.get("push_access_levels", [])),
37 "merge_access": _levels(b.get("merge_access_levels", [])),
38 "allow_force_push": b.get("allow_force_push"),
39 "code_owner_approval_required": b.get(
40 "code_owner_approval_required"
41 ),
42 }
43 )
44 return rows