diff --git a/docker/edge/dispatcher.sh b/docker/edge/dispatcher.sh index 109978a..9282b97 100755 --- a/docker/edge/dispatcher.sh +++ b/docker/edge/dispatcher.sh @@ -56,7 +56,7 @@ log() { # Forge API helpers for admin verification # ----------------------------------------------------------------------------- -# Check if a user has admin role +# Check if a user has admin role in the org/repo # Usage: is_user_admin # Returns: 0=yes, 1=no is_user_admin() { @@ -67,11 +67,13 @@ is_user_admin() { user_json=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \ "${FORGE_URL}/api/v1/users/${username}" 2>/dev/null) || return 1 - # Forgejo uses .is_admin for site-wide admin users - local is_admin - is_admin=$(echo "$user_json" | jq -r '.is_admin // false' 2>/dev/null) || return 1 + # Check if user has admin role (org-level) or admin permission (repo-level) + local is_org_admin is_repo_admin + is_org_admin=$(echo "$user_json" | jq -r '.role_name // empty' 2>/dev/null) || return 1 + is_repo_admin=$(echo "$user_json" | jq -r '.permissions.admin // false' 2>/dev/null) || return 1 - if [[ "$is_admin" == "true" ]]; then + # User is admin if role is 'Admin' or has admin permission + if [[ "$is_org_admin" == "Admin" ]] || [[ "$is_repo_admin" == "true" ]]; then return 0 fi @@ -101,17 +103,16 @@ is_allowed_admin() { return 1 } -# Get the PR that introduced a specific file to vault/actions +# Get the PR that introduced a file to vault/actions # Usage: get_pr_for_file # Returns: PR number or empty if not found via PR get_pr_for_file() { local file_path="$1" - local file_name - file_name=$(basename "$file_path") + local actions_dir="${file_path%/*}" - # Get recent commits that added this specific file + # Get recent commits that touched the vault/actions directory local commits - commits=$(git -C "$OPS_REPO_ROOT" log --oneline --diff-filter=A -- "vault/actions/${file_name}" 2>/dev/null | head -20) || true + commits=$(git -C "$OPS_REPO_ROOT" log --oneline --diff-filter=A -- "${actions_dir}/*" 2>/dev/null | head -20) || true if [ -z "$commits" ]; then return 1 @@ -237,6 +238,35 @@ validate_action() { return 0 } +# Get vault secrets for a specific action +# Usage: get_action_secrets +# Returns: space-separated list of KEY=VALUE pairs +get_action_secrets() { + local action_id="$1" + local secrets_list="$2" + local result="" + + for secret in $secrets_list; do + secret=$(echo "$secret" | xargs) # trim whitespace + if [ -z "$secret" ]; then + continue + fi + + # Check if secret is defined in decrypted vault + local secret_value + secret_value="${!secret:-}" + + if [ -z "$secret_value" ]; then + log "ERROR: Secret '${secret}' not found in .env.vault.enc for action ${action_id}" + return 1 + fi + + result="${result} ${secret}=${secret_value}" + done + + echo "$result" +} + # Write result file for an action # Usage: write_result write_result() {