From 97a7651397480bb18d1fc6d5c9f125294607f923 Mon Sep 17 00:00:00 2001 From: Kitty Chiu <42864823+KittyChiu@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:17:45 +0000 Subject: [PATCH 1/5] added 4 scripts --- gh-cli/check-enterprise-owner.sh | 163 +++++++++++++++++++++ gh-cli/check-enterprise-team-membership.sh | 87 +++++++++++ gh-cli/check-org-team-membership.sh | 48 ++++++ gh-cli/check-repo-admin.sh | 83 +++++++++++ 4 files changed, 381 insertions(+) create mode 100644 gh-cli/check-enterprise-owner.sh create mode 100644 gh-cli/check-enterprise-team-membership.sh create mode 100644 gh-cli/check-org-team-membership.sh create mode 100644 gh-cli/check-repo-admin.sh diff --git a/gh-cli/check-enterprise-owner.sh b/gh-cli/check-enterprise-owner.sh new file mode 100644 index 0000000..d212623 --- /dev/null +++ b/gh-cli/check-enterprise-owner.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +# Check if a user is an enterprise admin +# API: https://docs.github.com/en/enterprise-cloud@latest/graphql/reference/objects#enterpriseownerinfo +# Reference: https://docs.github.com/en/enterprise-cloud@latest/graphql/reference/queries#enterprise + +# Usage: ./check-enterprise-owner.sh +# Example: ./check-enterprise-owner.sh octocat johndoe + +set -e + +# Check if required parameters are provided +if [ $# -lt 2 ]; then + echo "Usage: $0 " + echo "Example: $0 octocat johndoe" + echo "" + echo "Note: Requires 'gh' CLI to be installed and authenticated" + exit 1 +fi + +ENTERPRISE_SLUG="$1" +TARGET_USER="$2" + +# Check if gh CLI is available +if ! command -v gh &> /dev/null; then + echo "Error: GitHub CLI (gh) is required but not installed." + echo "Install it from: https://cli.github.com/" + exit 1 +fi + +# Check if gh is authenticated +if ! gh auth status &> /dev/null; then + echo "Error: GitHub CLI is not authenticated." + echo "Run 'gh auth login' to authenticate." + exit 1 +fi + +# Check if jq is available for JSON parsing +if ! command -v jq &> /dev/null; then + echo "Error: jq is required for JSON parsing but not installed." + echo "Install it with: brew install jq (on macOS) or your package manager" + exit 1 +fi + +USER_FOUND=false +CURSOR="" +HAS_NEXT_PAGE=true + +echo "Checking if user '$TARGET_USER' is an enterprise admin for '$ENTERPRISE_SLUG'..." + +while [ "$HAS_NEXT_PAGE" = "true" ]; do + # Build the GraphQL query with optional cursor + if [ -z "$CURSOR" ]; then + QUERY=' + query CheckEnterpriseAdmin($slug: String!) { + enterprise(slug: $slug) { + id + name + slug + ownerInfo { + admins(first: 100) { + totalCount + pageInfo { + hasNextPage + endCursor + } + nodes { + login + name + } + } + } + } + }' + RESPONSE=$(gh api graphql -f query="$QUERY" -f slug="$ENTERPRISE_SLUG" 2>/dev/null) + else + QUERY=' + query CheckEnterpriseAdmin($slug: String!, $cursor: String!) { + enterprise(slug: $slug) { + id + name + slug + ownerInfo { + admins(first: 100, after: $cursor) { + totalCount + pageInfo { + hasNextPage + endCursor + } + nodes { + login + name + } + } + } + } + }' + RESPONSE=$(gh api graphql -f query="$QUERY" -f slug="$ENTERPRISE_SLUG" -f cursor="$CURSOR" 2>/dev/null) + fi + + # Check for errors in the response + if [ $? -ne 0 ] || echo "$RESPONSE" | jq -e '.errors' > /dev/null 2>&1; then + ERROR_MSG=$(echo "$RESPONSE" | jq -r '.errors[0].message // "Unknown error"' 2>/dev/null || echo "API call failed") + echo "✗ Error accessing enterprise '$ENTERPRISE_SLUG': $ERROR_MSG" + + # Check for common error types + if echo "$ERROR_MSG" | grep -q "Could not resolve to an Enterprise"; then + echo " Enterprise slug '$ENTERPRISE_SLUG' not found or not accessible" + elif echo "$ERROR_MSG" | grep -q "Must have admin access"; then + echo " Current user does not have admin access to view enterprise admins" + fi + exit 1 + fi + + # Check if enterprise data exists + if ! echo "$RESPONSE" | jq -e '.data.enterprise' > /dev/null 2>&1; then + echo "✗ Enterprise '$ENTERPRISE_SLUG' not found or not accessible" + exit 1 + fi + + # Extract data from response + TOTAL_COUNT=$(echo "$RESPONSE" | jq -r '.data.enterprise.ownerInfo.admins.totalCount') + HAS_NEXT_PAGE=$(echo "$RESPONSE" | jq -r '.data.enterprise.ownerInfo.admins.pageInfo.hasNextPage') + CURSOR=$(echo "$RESPONSE" | jq -r '.data.enterprise.ownerInfo.admins.pageInfo.endCursor') + + # Check if target user is in current page + ADMINS=$(echo "$RESPONSE" | jq -r '.data.enterprise.ownerInfo.admins.nodes[].login') + + PAGE_COUNT=$(echo "$RESPONSE" | jq -r '.data.enterprise.ownerInfo.admins.nodes | length') + echo "Checking page with $PAGE_COUNT admins..." + + for admin in $ADMINS; do + # Case-insensitive comparison + if [ "$(echo "$admin" | tr '[:upper:]' '[:lower:]')" = "$(echo "$TARGET_USER" | tr '[:upper:]' '[:lower:]')" ]; then + USER_FOUND=true + echo "✓ User '$TARGET_USER' found as enterprise admin!" + + # Get full admin details + ADMIN_NAME=$(echo "$RESPONSE" | jq -r --arg login "$admin" '.data.enterprise.ownerInfo.admins.nodes[] | select(.login == $login) | .name') + echo " Login: $admin" + echo " Name: $ADMIN_NAME" + break 2 # Break out of both loops + fi + done + + # If no next page, break + if [ "$HAS_NEXT_PAGE" = "false" ]; then + break + fi +done + +# Final result +echo "" +echo "=== SUMMARY ===" +echo "Enterprise: $ENTERPRISE_SLUG" +echo "Total admins checked: $TOTAL_COUNT" +if [ "$USER_FOUND" = "true" ]; then + echo "Result: ✓ '$TARGET_USER' IS an enterprise admin" + exit 0 +else + echo "Result: ✗ '$TARGET_USER' is NOT an enterprise admin" + exit 1 +fi diff --git a/gh-cli/check-enterprise-team-membership.sh b/gh-cli/check-enterprise-team-membership.sh new file mode 100644 index 0000000..cdd66be --- /dev/null +++ b/gh-cli/check-enterprise-team-membership.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# API GET /enterprises/{enterprise}/teams/{enterprise-team}/memberships/{username} +# NOTE: Enterprise Teams is a private preview feature, API may subject to change without notice +# +# Check if a user is a member of an enterprise team +# Response Code: 200 if user is a member, otherwise not + +# Function to display usage +usage() { + echo "Usage: $0 " + echo "" + echo "Parameters:" + echo " enterprise - The enterprise slug" + echo " team-slug - The enterprise team slug" + echo " username - The username to check" + echo "" + echo "Example:" + echo " $0 my-enterprise dev-team octocat" + exit 1 +} + +# Check if required parameters are provided +if [ $# -ne 3 ]; then + echo "Error: Missing required parameters" + usage +fi + +ENTERPRISE="$1" +TEAM_SLUG="$2" +USERNAME="$3" + +echo "Checking if user '$USERNAME' is a member of enterprise team '$TEAM_SLUG' in enterprise '$ENTERPRISE'..." + +# Make the API call using gh api and capture both response and HTTP status code +TEMP_DIR=$(mktemp -d) +RESPONSE_FILE="$TEMP_DIR/response.json" +HEADERS_FILE="$TEMP_DIR/headers.txt" + +# Use gh api with --include flag to get headers, then parse status code +gh api "/enterprises/$ENTERPRISE/teams/$TEAM_SLUG/memberships/$USERNAME" \ + --include > "$TEMP_DIR/full_response.txt" 2>&1 +API_EXIT_CODE=$? + +# Extract HTTP status code from the response headers +if [ $API_EXIT_CODE -eq 0 ]; then + # Split headers and body + sed '/^$/q' "$TEMP_DIR/full_response.txt" > "$HEADERS_FILE" + sed '1,/^$/d' "$TEMP_DIR/full_response.txt" > "$RESPONSE_FILE" + + # Extract status code from first line of headers + HTTP_STATUS=$(head -n1 "$HEADERS_FILE" | grep -o '[0-9]\{3\}' | head -n1) + RESPONSE=$(cat "$RESPONSE_FILE") +else + # If gh api failed, set status as non-200 + RESPONSE=$(cat "$TEMP_DIR/full_response.txt") + HTTP_STATUS="non-200" +fi + +echo "HTTP Status Code: $HTTP_STATUS" + +# Check response based on HTTP status code - only 200 indicates membership +if [ "$HTTP_STATUS" = "200" ]; then + # 200 OK - User is a member + TYPE=$(echo "$RESPONSE" | jq -r '.type // "unknown"' 2>/dev/null) + + echo "✅ User '$USERNAME' is a member of team '$TEAM_SLUG'" + if [ "$TYPE" != "null" ] && [ "$TYPE" != "unknown" ]; then + echo " Type: $TYPE" + fi + + # Display full response if verbose + if [ "$VERBOSE" = "true" ]; then + echo "" + echo "Full response:" + echo "$RESPONSE" | jq . 2>/dev/null || echo "$RESPONSE" + fi + + # Cleanup + rm -rf "$TEMP_DIR" + exit 0 +else + # Any non-200 status code means user is not a member + echo "❌ User '$USERNAME' is not a member of team '$TEAM_SLUG' in enterprise '$ENTERPRISE'" + rm -rf "$TEMP_DIR" + exit 1 +fi diff --git a/gh-cli/check-org-team-membership.sh b/gh-cli/check-org-team-membership.sh new file mode 100644 index 0000000..243b61e --- /dev/null +++ b/gh-cli/check-org-team-membership.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Check if a user is a member of a specific team in an organization +# API https://api.github.com/orgs/ORG/teams/TEAM_SLUG/memberships/USERNAME +# Response code 200 if user is a member, 404 if not + +# Usage: ./check-org-team-membership.sh +# Example: ./check-org-team-membership.sh myorg security johndoe + +set -e + +# Check if required parameters are provided +if [ $# -lt 3 ]; then + echo "Usage: $0 " + echo "Example: $0 myorg security johndoe" + echo "" + echo "Note: Requires 'gh' CLI to be installed and authenticated" + exit 1 +fi + +ORG="$1" +TEAM_SLUG="$2" +USERNAME="$3" + +# Check if gh CLI is available +if ! command -v gh &> /dev/null; then + echo "Error: GitHub CLI (gh) is required but not installed." + echo "Install it from: https://cli.github.com/" + exit 1 +fi + +# Check if gh is authenticated +if ! gh auth status &> /dev/null; then + echo "Error: GitHub CLI is not authenticated." + echo "Run 'gh auth login' to authenticate." + exit 1 +fi + +echo "Checking if user '$USERNAME' is a member of team '$TEAM_SLUG' in organization '$ORG'..." + +# Check team membership +if gh api "orgs/$ORG/teams/$TEAM_SLUG/memberships/$USERNAME" --silent 2>/dev/null; then + echo "✓ User '$USERNAME' is a member of team '$TEAM_SLUG' in organization '$ORG'" + exit 0 +else + echo "✗ User '$USERNAME' is NOT a member of team '$TEAM_SLUG' in organization '$ORG'" + exit 1 +fi \ No newline at end of file diff --git a/gh-cli/check-repo-admin.sh b/gh-cli/check-repo-admin.sh new file mode 100644 index 0000000..9a3b6ef --- /dev/null +++ b/gh-cli/check-repo-admin.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Check if user is a collaborator in the given repo +# API https://api.github.com/repos/OWNER/REPO/collaborators/USERNAME +# Response code 204 if user is a collaborator, 404 if not +# +# If a collaborator, check if user is a repo admin in the given repo +# API https://api.github.com/repos/OWNER/REPO/collaborators/USERNAME/permission +# Response code 200 if user has repo access permissions, otherwise not +# Response body will include "permission": "admin" if user is a repo admin + +# Usage: ./check-repo-admin.sh +# Example: ./check-repo-admin.sh octocat Hello-World johndoe + +set -e + +# Check if required parameters are provided +if [ $# -lt 3 ]; then + echo "Usage: $0 " + echo "Example: $0 octocat Hello-World johndoe" + echo "" + echo "Note: Requires 'gh' CLI to be installed and authenticated" + exit 1 +fi + +OWNER="$1" +REPO="$2" +USERNAME="$3" + +# Check if gh CLI is available +if ! command -v gh &> /dev/null; then + echo "Error: GitHub CLI (gh) is required but not installed." + echo "Install it from: https://cli.github.com/" + exit 1 +fi + +# Check if gh is authenticated +if ! gh auth status &> /dev/null; then + echo "Error: GitHub CLI is not authenticated." + echo "Run 'gh auth login' to authenticate." + exit 1 +fi + +echo "Checking if user '$USERNAME' is a collaborator in repository '$OWNER/$REPO'..." + +# Step 1: Check if user is a collaborator +# Using --silent and --include flags to capture HTTP status +if gh api "repos/$OWNER/$REPO/collaborators/$USERNAME" --silent 2>/dev/null; then + echo "✓ User '$USERNAME' is a collaborator in '$OWNER/$REPO'" + + # Step 2: Check user's permission level + echo "Checking permission level..." + PERM_RESPONSE=$(gh api "repos/$OWNER/$REPO/collaborators/$USERNAME/permission" 2>/dev/null) + + # Extract permission from JSON response using jq if available, otherwise use grep + if command -v jq &> /dev/null; then + PERMISSION=$(echo "$PERM_RESPONSE" | jq -r '.permission') + else + PERMISSION=$(echo "$PERM_RESPONSE" | grep -o '"permission":"[^"]*"' | cut -d'"' -f4) + fi + + if [ -z "$PERMISSION" ] || [ "$PERMISSION" = "null" ]; then + echo "⚠ Could not determine permission level" + echo "API Response: $PERM_RESPONSE" + exit 1 + fi + + echo "Permission level: $PERMISSION" + + # Check if user has admin permission + if [ "$PERMISSION" = "admin" ]; then + echo "✓ User '$USERNAME' has ADMIN access to '$OWNER/$REPO'" + exit 0 + else + echo "✗ User '$USERNAME' does NOT have admin access to '$OWNER/$REPO' (has '$PERMISSION' permission)" + exit 1 + fi + +else + # User is not a collaborator or an error occurred + echo "✗ User '$USERNAME' is NOT a collaborator in '$OWNER/$REPO' or an error occurred" + exit 1 +fi \ No newline at end of file From 5b05f90f6b388a6088bb51c58cacdac79edeffe3 Mon Sep 17 00:00:00 2001 From: Kitty Chiu <42864823+KittyChiu@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:27:48 +0000 Subject: [PATCH 2/5] listed to README --- gh-cli/README.md | 97 ++++++++++++++++++- gh-cli/check-org-team-membership.sh | 44 +++++---- ...epo-admin.sh => check-repository-admin.sh} | 52 +++++----- 3 files changed, 147 insertions(+), 46 deletions(-) rename gh-cli/{check-repo-admin.sh => check-repository-admin.sh} (56%) diff --git a/gh-cli/README.md b/gh-cli/README.md index 999dbba..9ce4a7a 100644 --- a/gh-cli/README.md +++ b/gh-cli/README.md @@ -230,6 +230,101 @@ octocat/octocat Change a repository visibility to internal, for example +### check-enterprise-owner.sh + +Checks if a user is an enterprise admin (owner) using the GitHub GraphQL API. + +Usage: + +```shell +./check-enterprise-owner.sh +``` + +Example: + +```shell +./check-enterprise-owner.sh my-enterprise johndoe +``` + +> [!NOTE] +> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GraphQL API and requires permission to view enterprise admins. Your token must have appropriate enterprise-level scopes. `jq` is required for JSON parsing. + +### check-organization-admin.sh + +Checks if a user is an admin in a given organization. + +Usage: + +```shell +./check-organization-admin.sh +``` + +Example: + +```shell +./check-organization-admin.sh octo-org johndoe +``` + +> [!NOTE] +> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GitHub API and requires appropriate permissions to view organization members and their roles. + +### check-repository-admin.sh + +Checks if a user is a collaborator in a given repository and determines if they have admin access. + +Usage: + +```shell +./check-repository-admin.sh +``` + +Example: + +```shell +./check-repository-admin.sh octocat Hello-World johndoe +``` + +> [!NOTE] +> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GitHub API and requires appropriate permissions to view collaborators and permissions for the repository. For private repositories, your token must have the `repo` scope. + +### check-enterprise-team-membership.sh + +Checks if a user is a member of an enterprise team using the GitHub API (private preview feature). + +Usage: + +```shell +./check-enterprise-team-membership.sh +``` + +Example: + +```shell +./check-enterprise-team-membership.sh my-enterprise dev-team octocat +``` + +> [!NOTE] +> This script uses a private preview API for enterprise teams, which may change without notice. Requires GitHub CLI (`gh`) to be installed and authenticated. You may need special permissions or token scopes to access enterprise team membership information. + +### check-org-team-membership.sh + +Checks if a user is a member of a specific team in an organization using the GitHub API. + +Usage: + +```shell +./check-org-team-membership.sh +``` + +Example: + +```shell +./check-org-team-membership.sh my-organization security johndoe +``` + +> [!NOTE] +> Requires GitHub CLI (`gh`) to be installed and authenticated. Your token must have the `read:org` scope to view team membership. + ### copy-organization-members.sh Copy organization members from one organization to the other, the member will **retain** the source role (owner or member), member cannot be demoted, if they already exist at the target with an owner role they cannot be demoted to member. @@ -1016,7 +1111,7 @@ Gets the list of organization secrets that are available by repository (all repo Public repositories are ignored and not listed. -A repository can only use a max of [100 organization secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#limits-for-secrets) that are available to it. The purpose of this script is to get list of repositories and the number of organization secrets available to them mostly to figure out if you are hitting the limit and not all secrets are really available to the repository (only first 100 secrets sorted by secret name are available). +A repository can only use a max of [100 organization secrets](https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#limits-for-secrets) that are available to it. The purpose of this script is to get list of repositories and the number of organization secrets available to them mostly to figure out if you are hitting the limit and not all secrets are really available. usage: diff --git a/gh-cli/check-org-team-membership.sh b/gh-cli/check-org-team-membership.sh index 243b61e..11f6382 100644 --- a/gh-cli/check-org-team-membership.sh +++ b/gh-cli/check-org-team-membership.sh @@ -1,48 +1,54 @@ #!/bin/bash -# Check if a user is a member of a specific team in an organization -# API https://api.github.com/orgs/ORG/teams/TEAM_SLUG/memberships/USERNAME -# Response code 200 if user is a member, 404 if not - -# Usage: ./check-org-team-membership.sh -# Example: ./check-org-team-membership.sh myorg security johndoe +# Checks if a user is a member of a specific team in an organization using the GitHub API. +# +# Usage: +# ./check-org-team-membership.sh +# +# Example: +# ./check-org-team-membership.sh my-organization security johndoe +# +# Requirements: +# - GitHub CLI (`gh`) must be installed and authenticated +# - Token must have `read:org` scope to view team membership +# - Uses GitHub API endpoint: /orgs/{organization}/teams/{team-slug}/memberships/{username} +# - This script does not paginate as the endpoint is for a single user/team +# +# Notes: +# - Organization, team-slug, and username must be provided as input parameters set -e -# Check if required parameters are provided if [ $# -lt 3 ]; then - echo "Usage: $0 " - echo "Example: $0 myorg security johndoe" + echo "Usage: $0 " + echo "Example: $0 my-organization security johndoe" echo "" echo "Note: Requires 'gh' CLI to be installed and authenticated" exit 1 fi -ORG="$1" -TEAM_SLUG="$2" -USERNAME="$3" +organization="$1" +team_slug="$2" +username="$3" -# Check if gh CLI is available if ! command -v gh &> /dev/null; then echo "Error: GitHub CLI (gh) is required but not installed." echo "Install it from: https://cli.github.com/" exit 1 fi -# Check if gh is authenticated if ! gh auth status &> /dev/null; then echo "Error: GitHub CLI is not authenticated." echo "Run 'gh auth login' to authenticate." exit 1 fi -echo "Checking if user '$USERNAME' is a member of team '$TEAM_SLUG' in organization '$ORG'..." +echo "Checking if user '$username' is a member of team '$team_slug' in organization '$organization'..." -# Check team membership -if gh api "orgs/$ORG/teams/$TEAM_SLUG/memberships/$USERNAME" --silent 2>/dev/null; then - echo "✓ User '$USERNAME' is a member of team '$TEAM_SLUG' in organization '$ORG'" +if gh api "orgs/$organization/teams/$team_slug/memberships/$username" --silent 2>/dev/null; then + echo "✓ User '$username' is a member of team '$team_slug' in organization '$organization'" exit 0 else - echo "✗ User '$USERNAME' is NOT a member of team '$TEAM_SLUG' in organization '$ORG'" + echo "✗ User '$username' is NOT a member of team '$team_slug' in organization '$organization'" exit 1 fi \ No newline at end of file diff --git a/gh-cli/check-repo-admin.sh b/gh-cli/check-repository-admin.sh similarity index 56% rename from gh-cli/check-repo-admin.sh rename to gh-cli/check-repository-admin.sh index 9a3b6ef..42689ca 100644 --- a/gh-cli/check-repo-admin.sh +++ b/gh-cli/check-repository-admin.sh @@ -1,22 +1,21 @@ #!/bin/bash -# Check if user is a collaborator in the given repo -# API https://api.github.com/repos/OWNER/REPO/collaborators/USERNAME -# Response code 204 if user is a collaborator, 404 if not +# Checks if a user is a collaborator in a given repository and determines if they have admin access. # -# If a collaborator, check if user is a repo admin in the given repo -# API https://api.github.com/repos/OWNER/REPO/collaborators/USERNAME/permission -# Response code 200 if user has repo access permissions, otherwise not -# Response body will include "permission": "admin" if user is a repo admin - -# Usage: ./check-repo-admin.sh -# Example: ./check-repo-admin.sh octocat Hello-World johndoe +# Usage: +# ./check-repository-admin.sh +# Example: +# ./check-repository-admin.sh octocat Hello-World johndoe +# +# Requirements: +# - GitHub CLI (`gh`) must be installed and authenticated +# - Token must have `repo` scope for private repositories +# - The script uses the GitHub API and requires permission to view collaborators and permissions for the repository set -e -# Check if required parameters are provided if [ $# -lt 3 ]; then - echo "Usage: $0 " + echo "Usage: $0 " echo "Example: $0 octocat Hello-World johndoe" echo "" echo "Note: Requires 'gh' CLI to be installed and authenticated" @@ -24,35 +23,31 @@ if [ $# -lt 3 ]; then fi OWNER="$1" -REPO="$2" +REPOSITORY="$2" USERNAME="$3" -# Check if gh CLI is available if ! command -v gh &> /dev/null; then echo "Error: GitHub CLI (gh) is required but not installed." echo "Install it from: https://cli.github.com/" exit 1 fi -# Check if gh is authenticated if ! gh auth status &> /dev/null; then echo "Error: GitHub CLI is not authenticated." echo "Run 'gh auth login' to authenticate." exit 1 fi -echo "Checking if user '$USERNAME' is a collaborator in repository '$OWNER/$REPO'..." +echo "Checking if user '$USERNAME' is a collaborator in repository '$OWNER/$REPOSITORY'..." # Step 1: Check if user is a collaborator -# Using --silent and --include flags to capture HTTP status -if gh api "repos/$OWNER/$REPO/collaborators/$USERNAME" --silent 2>/dev/null; then - echo "✓ User '$USERNAME' is a collaborator in '$OWNER/$REPO'" +if gh api --paginate "repos/$OWNER/$REPOSITORY/collaborators/$USERNAME" --silent 2>/dev/null; then + echo "✓ User '$USERNAME' is a collaborator in '$OWNER/$REPOSITORY'" # Step 2: Check user's permission level echo "Checking permission level..." - PERM_RESPONSE=$(gh api "repos/$OWNER/$REPO/collaborators/$USERNAME/permission" 2>/dev/null) + PERM_RESPONSE=$(gh api --paginate "repos/$OWNER/$REPOSITORY/collaborators/$USERNAME/permission" 2>/dev/null) - # Extract permission from JSON response using jq if available, otherwise use grep if command -v jq &> /dev/null; then PERMISSION=$(echo "$PERM_RESPONSE" | jq -r '.permission') else @@ -67,17 +62,22 @@ if gh api "repos/$OWNER/$REPO/collaborators/$USERNAME" --silent 2>/dev/null; the echo "Permission level: $PERMISSION" - # Check if user has admin permission if [ "$PERMISSION" = "admin" ]; then - echo "✓ User '$USERNAME' has ADMIN access to '$OWNER/$REPO'" + echo "✓ User '$USERNAME' has ADMIN access to '$OWNER/$REPOSITORY'" exit 0 else - echo "✗ User '$USERNAME' does NOT have admin access to '$OWNER/$REPO' (has '$PERMISSION' permission)" + echo "✗ User '$USERNAME' does NOT have admin access to '$OWNER/$REPOSITORY' (has '$PERMISSION' permission)" exit 1 fi +else + echo "✗ User '$USERNAME' is NOT a collaborator in '$OWNER/$REPOSITORY' or an error occurred" + exit 1 +fi + fi + else # User is not a collaborator or an error occurred - echo "✗ User '$USERNAME' is NOT a collaborator in '$OWNER/$REPO' or an error occurred" + echo "✗ User '$USERNAME' is NOT a collaborator in '$OWNER/$REPOSITORY' or an error occurred" exit 1 -fi \ No newline at end of file +fi From 80717fda5eb01066ac3d67a0378ddfd3b9de2d32 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 12 Aug 2025 19:41:25 -0500 Subject: [PATCH 3/5] chore: chmod +x *.sh --- gh-cli/check-enterprise-owner.sh | 0 gh-cli/check-enterprise-team-membership.sh | 0 gh-cli/check-org-team-membership.sh | 0 gh-cli/check-repository-admin.sh | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gh-cli/check-enterprise-owner.sh mode change 100644 => 100755 gh-cli/check-enterprise-team-membership.sh mode change 100644 => 100755 gh-cli/check-org-team-membership.sh mode change 100644 => 100755 gh-cli/check-repository-admin.sh diff --git a/gh-cli/check-enterprise-owner.sh b/gh-cli/check-enterprise-owner.sh old mode 100644 new mode 100755 diff --git a/gh-cli/check-enterprise-team-membership.sh b/gh-cli/check-enterprise-team-membership.sh old mode 100644 new mode 100755 diff --git a/gh-cli/check-org-team-membership.sh b/gh-cli/check-org-team-membership.sh old mode 100644 new mode 100755 diff --git a/gh-cli/check-repository-admin.sh b/gh-cli/check-repository-admin.sh old mode 100644 new mode 100755 From 3d961e7c4715ccf255900527ddf4fe8e785c3c57 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 12 Aug 2025 19:42:04 -0500 Subject: [PATCH 4/5] chore: spell out organization --- gh-cli/README.md | 7 ++++--- ...membership.sh => check-organization-team-membership.sh} | 0 2 files changed, 4 insertions(+), 3 deletions(-) rename gh-cli/{check-org-team-membership.sh => check-organization-team-membership.sh} (100%) diff --git a/gh-cli/README.md b/gh-cli/README.md index 9ce4a7a..c893bda 100644 --- a/gh-cli/README.md +++ b/gh-cli/README.md @@ -306,20 +306,21 @@ Example: > [!NOTE] > This script uses a private preview API for enterprise teams, which may change without notice. Requires GitHub CLI (`gh`) to be installed and authenticated. You may need special permissions or token scopes to access enterprise team membership information. -### check-org-team-membership.sh + +### check-organization-team-membership.sh Checks if a user is a member of a specific team in an organization using the GitHub API. Usage: ```shell -./check-org-team-membership.sh +./check-organization-team-membership.sh ``` Example: ```shell -./check-org-team-membership.sh my-organization security johndoe +./check-organization-team-membership.sh my-organization security johndoe ``` > [!NOTE] diff --git a/gh-cli/check-org-team-membership.sh b/gh-cli/check-organization-team-membership.sh similarity index 100% rename from gh-cli/check-org-team-membership.sh rename to gh-cli/check-organization-team-membership.sh From b8cf5d44cf5d913e5f7fce09ff7f378fb0f7ad74 Mon Sep 17 00:00:00 2001 From: Josh Johanning Date: Tue, 12 Aug 2025 19:47:21 -0500 Subject: [PATCH 5/5] refactor: clean up README --- gh-cli/README.md | 70 +++++++----------------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/gh-cli/README.md b/gh-cli/README.md index c893bda..b2455f0 100644 --- a/gh-cli/README.md +++ b/gh-cli/README.md @@ -240,53 +240,6 @@ Usage: ./check-enterprise-owner.sh ``` -Example: - -```shell -./check-enterprise-owner.sh my-enterprise johndoe -``` - -> [!NOTE] -> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GraphQL API and requires permission to view enterprise admins. Your token must have appropriate enterprise-level scopes. `jq` is required for JSON parsing. - -### check-organization-admin.sh - -Checks if a user is an admin in a given organization. - -Usage: - -```shell -./check-organization-admin.sh -``` - -Example: - -```shell -./check-organization-admin.sh octo-org johndoe -``` - -> [!NOTE] -> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GitHub API and requires appropriate permissions to view organization members and their roles. - -### check-repository-admin.sh - -Checks if a user is a collaborator in a given repository and determines if they have admin access. - -Usage: - -```shell -./check-repository-admin.sh -``` - -Example: - -```shell -./check-repository-admin.sh octocat Hello-World johndoe -``` - -> [!NOTE] -> Requires GitHub CLI (`gh`) to be installed and authenticated. The script uses the GitHub API and requires appropriate permissions to view collaborators and permissions for the repository. For private repositories, your token must have the `repo` scope. - ### check-enterprise-team-membership.sh Checks if a user is a member of an enterprise team using the GitHub API (private preview feature). @@ -297,15 +250,8 @@ Usage: ./check-enterprise-team-membership.sh ``` -Example: - -```shell -./check-enterprise-team-membership.sh my-enterprise dev-team octocat -``` - > [!NOTE] -> This script uses a private preview API for enterprise teams, which may change without notice. Requires GitHub CLI (`gh`) to be installed and authenticated. You may need special permissions or token scopes to access enterprise team membership information. - +> This script uses a private preview API for enterprise teams, which may change without notice. ### check-organization-team-membership.sh @@ -317,15 +263,19 @@ Usage: ./check-organization-team-membership.sh ``` -Example: +> [!NOTE] +> Your token must have the `read:org` scope to view team membership. + +### check-repository-admin.sh + +Checks if a user is a collaborator in a given repository and determines if they have admin access. + +Usage: ```shell -./check-organization-team-membership.sh my-organization security johndoe +./check-repository-admin.sh ``` -> [!NOTE] -> Requires GitHub CLI (`gh`) to be installed and authenticated. Your token must have the `read:org` scope to view team membership. - ### copy-organization-members.sh Copy organization members from one organization to the other, the member will **retain** the source role (owner or member), member cannot be demoted, if they already exist at the target with an owner role they cannot be demoted to member.