Skip to content

Commit

Permalink
Check write permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Apr 23, 2024
1 parent 2ad5a02 commit 93bd4e6
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
name: GitHub CODEOWNERS Validator
runs-on: ubuntu-latest
steps:
- uses: cachix/install-nix-action@v26

- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -55,3 +56,12 @@ jobs:

# Specifies whether only teams are allowed as owners of files.
owner_checker_owners_must_be_teams: "false"

# The above validator doesn't currently ensure that people have write access: https://github.com/mszostok/codeowners-validator/issues/157
# So we're doing it manually instead
- name: Check that codeowners have write access
# Important that we run the script from the base branch,
# because otherwise a PR from a fork could change it to extract the secret
run: trusted-base/scripts/unprivileged-owners.sh untrusted-pr ${{ github.repository }}
env:
GH_TOKEN: "${{ secrets.OWNERS_VALIDATOR_GITHUB_SECRET }}"
50 changes: 50 additions & 0 deletions scripts/unprivileged-owners.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash --pure -p codeowners github-cli

set -euo pipefail

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' exit

if (( $# != 2 )); then
echo "Usage: $0 PATH OWNER/REPO"
exit 1
fi

root=$1
repo=$2

# Writes all code owners into $tmp/codeowners, one user per line (without @)
while read -r -a fields; do
# The first field is the filename
unset 'fields[0]'
if [[ "${fields[1]}" != "(unowned)" ]]; then
(IFS=$'\n'; echo "${fields[*]##@}")
fi
done < <(codeowners --file "$root/.github/CODEOWNERS") |
sort -u > "$tmp/codeowners"

# Get all users with push access
gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
--method GET \
-f permission=push \
/repos/"$repo"/collaborators \
-F per_page=100 \
--paginate \
--jq '.[].login' |
sort > "$tmp/collaborators"

# Figure out all the owners that aren't collaborators
readarray -t unprivilegedOwners < <(comm -23 "$tmp/codeowners" "$tmp/collaborators")

if (( "${#unprivilegedOwners[@]}" == 0 )); then
echo "All code owners have write permission"
else
echo "These code owners don't have write permission:"
for handle in "${unprivilegedOwners[@]}"; do
echo "- [ ] @$handle"
done
exit 1
fi

0 comments on commit 93bd4e6

Please sign in to comment.