fix: fix: hire-an-agent fails — unbound user_pass, admin auth, silent repo creation failure, unauthenticated clone (#184)
This commit is contained in:
parent
3ca62fa96d
commit
0b0e8f8608
1 changed files with 106 additions and 69 deletions
175
bin/disinto
175
bin/disinto
|
|
@ -2634,38 +2634,54 @@ disinto_hire_an_agent() {
|
|||
echo "Step 1: Creating user '${agent_name}' (if not exists)..."
|
||||
|
||||
local user_exists=false
|
||||
local user_pass=""
|
||||
local admin_pass=""
|
||||
|
||||
# Read admin password from .env for standalone runs (#184)
|
||||
local env_file="${FACTORY_ROOT}/.env"
|
||||
if [ -f "$env_file" ] && grep -q '^FORGE_ADMIN_PASS=' "$env_file" 2>/dev/null; then
|
||||
admin_pass=$(grep '^FORGE_ADMIN_PASS=' "$env_file" | head -1 | cut -d= -f2-)
|
||||
fi
|
||||
|
||||
# Get admin token early (needed for both user creation and password reset)
|
||||
local admin_user="disinto-admin"
|
||||
admin_pass="${admin_pass:-admin}"
|
||||
local admin_token=""
|
||||
admin_token=$(curl -sf -X POST \
|
||||
-u "${admin_user}:${admin_pass}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/users/${admin_user}/tokens" \
|
||||
-d '{"name":"temp-token","scopes":["all"]}' 2>/dev/null \
|
||||
| jq -r '.sha1 // empty') || admin_token=""
|
||||
if [ -z "$admin_token" ]; then
|
||||
admin_token=$(curl -sf \
|
||||
-u "${admin_user}:${admin_pass}" \
|
||||
"${forge_url}/api/v1/users/${admin_user}/tokens" 2>/dev/null \
|
||||
| jq -r '.[0].sha1 // empty') || admin_token=""
|
||||
fi
|
||||
if [ -z "$admin_token" ]; then
|
||||
echo " Warning: could not obtain admin token, trying FORGE_TOKEN..."
|
||||
admin_token="${FORGE_TOKEN}"
|
||||
fi
|
||||
|
||||
if curl -sf --max-time 5 "${forge_url}/api/v1/users/${agent_name}" >/dev/null 2>&1; then
|
||||
user_exists=true
|
||||
echo " User '${agent_name}' already exists"
|
||||
else
|
||||
# Create user using admin token
|
||||
local admin_user="disinto-admin"
|
||||
local admin_pass="${_FORGE_ADMIN_PASS:-admin}"
|
||||
|
||||
# Try to get admin token first
|
||||
local admin_token
|
||||
admin_token=$(curl -sf -X POST \
|
||||
-u "${admin_user}:${admin_pass}" \
|
||||
# Reset user password so we can get a token (#184)
|
||||
user_pass="agent-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)"
|
||||
if curl -sf -X PATCH \
|
||||
-H "Authorization: token ${admin_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/users/${admin_user}/tokens" \
|
||||
-d '{"name":"temp-token","scopes":["all"]}' 2>/dev/null \
|
||||
| jq -r '.sha1 // empty') || admin_token=""
|
||||
|
||||
if [ -z "$admin_token" ]; then
|
||||
# Token might already exist — try listing
|
||||
admin_token=$(curl -sf \
|
||||
-u "${admin_user}:${admin_pass}" \
|
||||
"${forge_url}/api/v1/users/${admin_user}/tokens" 2>/dev/null \
|
||||
| jq -r '.[0].sha1 // empty') || admin_token=""
|
||||
"${forge_url}/api/v1/admin/users/${agent_name}" \
|
||||
-d "{\"password\":\"${user_pass}\"}" >/dev/null 2>&1; then
|
||||
echo " Reset password for existing user '${agent_name}'"
|
||||
else
|
||||
echo " Warning: could not reset password for existing user" >&2
|
||||
fi
|
||||
|
||||
if [ -z "$admin_token" ]; then
|
||||
echo " Warning: could not obtain admin token, trying FORGE_TOKEN..."
|
||||
admin_token="${FORGE_TOKEN}"
|
||||
fi
|
||||
|
||||
else
|
||||
# Create user using admin token (admin_token already obtained above)
|
||||
# Create the user
|
||||
local user_pass="agent-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)"
|
||||
user_pass="agent-$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 20)"
|
||||
if curl -sf -X POST \
|
||||
-H "Authorization: token ${admin_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
|
|
@ -2695,24 +2711,21 @@ disinto_hire_an_agent() {
|
|||
echo " Repo '${agent_name}/.profile' already exists"
|
||||
else
|
||||
# Get user token for creating repo
|
||||
# Always try to get token using user_pass (set in Step 1 for new users, reset for existing)
|
||||
local user_token=""
|
||||
if [ "$user_exists" = true ]; then
|
||||
# Try to get token for the new user
|
||||
# Note: user_pass was set in Step 1; for existing users this will fail (unknown password)
|
||||
user_token=$(curl -sf -X POST \
|
||||
-u "${agent_name}:${user_pass}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/users/${agent_name}/tokens" \
|
||||
-d "{\"name\":\".profile-repo-token\",\"scopes\":[\"repository\"]}" 2>/dev/null \
|
||||
| jq -r '.sha1 // empty') || user_token=""
|
||||
user_token=$(curl -sf -X POST \
|
||||
-u "${agent_name}:${user_pass}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/users/${agent_name}/tokens" \
|
||||
-d "{\"name\":\".profile-repo-token\",\"scopes\":[\"repository\"]}" 2>/dev/null \
|
||||
| jq -r '.sha1 // empty') || user_token=""
|
||||
|
||||
if [ -z "$user_token" ]; then
|
||||
# Try listing existing tokens
|
||||
user_token=$(curl -sf \
|
||||
-u "${agent_name}:${user_pass}" \
|
||||
"${forge_url}/api/v1/users/${agent_name}/tokens" 2>/dev/null \
|
||||
| jq -r '.[0].sha1 // empty') || user_token=""
|
||||
fi
|
||||
if [ -z "$user_token" ]; then
|
||||
# Try listing existing tokens
|
||||
user_token=$(curl -sf \
|
||||
-u "${agent_name}:${user_pass}" \
|
||||
"${forge_url}/api/v1/users/${agent_name}/tokens" 2>/dev/null \
|
||||
| jq -r '.[0].sha1 // empty') || user_token=""
|
||||
fi
|
||||
|
||||
# Fall back to admin token if user token not available
|
||||
|
|
@ -2721,26 +2734,45 @@ disinto_hire_an_agent() {
|
|||
user_token="${admin_token:-${FORGE_TOKEN}}"
|
||||
fi
|
||||
|
||||
# Create the repo
|
||||
if curl -sf -X POST \
|
||||
-H "Authorization: token ${user_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/user/repos" \
|
||||
-d "{\"name\":\".profile\",\"description\":\"${agent_name}'s .profile repo\",\"private\":true,\"auto_init\":false}" >/dev/null 2>&1; then
|
||||
echo " Created repo '${agent_name}/.profile'"
|
||||
else
|
||||
# Try with org path
|
||||
if curl -sf -X POST \
|
||||
# Create the repo using the user's namespace (user/repos with user_token creates in that user's namespace)
|
||||
# or use admin API to create in specific user's namespace
|
||||
local repo_created=false
|
||||
local create_output
|
||||
|
||||
if [ -n "$user_token" ]; then
|
||||
# Try creating as the agent user (user token creates in that user's namespace)
|
||||
create_output=$(curl -sf -X POST \
|
||||
-H "Authorization: token ${user_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/orgs/${agent_name}/repos" \
|
||||
-d "{\"name\":\".profile\",\"description\":\"${agent_name}'s .profile repo\",\"private\":true,\"auto_init\":false}" >/dev/null 2>&1; then
|
||||
echo " Created repo '${agent_name}/.profile' (in org)"
|
||||
else
|
||||
echo " Error: failed to create repo '${agent_name}/.profile'" >&2
|
||||
exit 1
|
||||
"${forge_url}/api/v1/user/repos" \
|
||||
-d "{\"name\":\".profile\",\"description\":\"${agent_name}'s .profile repo\",\"private\":true,\"auto_init\":false}" 2>&1) || true
|
||||
|
||||
if echo "$create_output" | grep -q '"id":\|[0-9]'; then
|
||||
repo_created=true
|
||||
echo " Created repo '${agent_name}/.profile'"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If user token failed or wasn't available, use admin API to create in agent's namespace
|
||||
if [ "$repo_created" = false ]; then
|
||||
echo " Using admin API to create repo in ${agent_name}'s namespace"
|
||||
create_output=$(curl -sf -X POST \
|
||||
-H "Authorization: token ${user_token}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${forge_url}/api/v1/admin/users/${agent_name}/repos" \
|
||||
-d "{\"name\":\".profile\",\"description\":\"${agent_name}'s .profile repo\",\"private\":true,\"auto_init\":false}" 2>&1) || true
|
||||
|
||||
if echo "$create_output" | grep -q '"id":\|[0-9]'; then
|
||||
repo_created=true
|
||||
echo " Created repo '${agent_name}/.profile' (via admin API)"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$repo_created" = false ]; then
|
||||
echo " Error: failed to create repo '${agent_name}/.profile'" >&2
|
||||
echo " Response: ${create_output}" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Step 3: Clone repo and create initial commit
|
||||
|
|
@ -2751,23 +2783,28 @@ disinto_hire_an_agent() {
|
|||
rm -rf "$clone_dir"
|
||||
mkdir -p "$clone_dir"
|
||||
|
||||
# Build clone URL (unauthenticated version for display)
|
||||
# Build authenticated clone URL
|
||||
# Use user_token if available, otherwise fall back to FORGE_TOKEN
|
||||
local clone_token="${user_token:-${FORGE_TOKEN}}"
|
||||
if [ -z "$clone_token" ]; then
|
||||
echo " Error: no authentication token available for cloning" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local clone_url="${forge_url}/${agent_name}/.profile.git"
|
||||
local auth_url
|
||||
auth_url=$(printf '%s' "$forge_url" | sed "s|://|://${agent_name}:${user_token:-${FORGE_TOKEN}}@|")
|
||||
clone_url="${auth_url}/.profile.git"
|
||||
auth_url=$(printf '%s' "$forge_url" | sed "s|://|://${agent_name}:${clone_token}@|")
|
||||
auth_url="${auth_url}/.profile.git"
|
||||
|
||||
# Display unauthenticated URL (auth token only in actual git clone command)
|
||||
echo " Cloning: ${forge_url}/${agent_name}/.profile.git"
|
||||
|
||||
if ! git clone --quiet "$clone_url" "$clone_dir" 2>/dev/null; then
|
||||
# Try without auth (might work for public repos or with FORGE_TOKEN)
|
||||
clone_url="${forge_url}/${agent_name}/.profile.git"
|
||||
if ! git clone --quiet "$clone_url" "$clone_dir" 2>/dev/null; then
|
||||
echo " Error: failed to clone repo" >&2
|
||||
rm -rf "$clone_dir"
|
||||
exit 1
|
||||
fi
|
||||
# Try authenticated clone first (required for private repos)
|
||||
if ! git clone --quiet "$auth_url" "$clone_dir" 2>/dev/null; then
|
||||
echo " Error: failed to clone repo with authentication" >&2
|
||||
echo " Note: Ensure the user has a valid API token with repository access" >&2
|
||||
rm -rf "$clone_dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure git
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue