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

v1.0.0: 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