@profoundlogic/coderflow-server 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +322 -0
- package/README.md +158 -0
- package/dist/LICENSE.txt +322 -0
- package/dist/README.md +158 -0
- package/dist/base-image/Dockerfile +184 -0
- package/dist/base-image/agent-wrapper.sh +143 -0
- package/dist/base-image/apply-local-state.sh +357 -0
- package/dist/base-image/coder-git-credential-helper +307 -0
- package/dist/base-image/entrypoint.sh +942 -0
- package/dist/base-image/ssh_config_template +41 -0
- package/dist/base-image/start-code-server.sh +76 -0
- package/dist/base-image/sync-repos.sh +170 -0
- package/dist/base-image/vscode-extensions.txt +10 -0
- package/dist/base-image/vscode-settings.json +41 -0
- package/dist/coder-server.js +2 -0
- package/dist/config/cli-models.json +45 -0
- package/dist/config/imported-skills.schema.json +83 -0
- package/dist/config/skill-catalog.json +18 -0
- package/dist/config/skill-catalog.schema.json +140 -0
- package/dist/config.js +1 -0
- package/dist/examples/oidc.json.example +11 -0
- package/dist/lib/agent-keepalive.js +1 -0
- package/dist/lib/api-keys.js +1 -0
- package/dist/lib/apiKeys.js +1 -0
- package/dist/lib/auto-judge.js +1 -0
- package/dist/lib/basic-auth.js +1 -0
- package/dist/lib/build-history.js +1 -0
- package/dist/lib/build-output-service.js +1 -0
- package/dist/lib/build-scheduler.js +1 -0
- package/dist/lib/build-service.js +1 -0
- package/dist/lib/claude-oauth-refresh.js +1 -0
- package/dist/lib/cli/build.js +1 -0
- package/dist/lib/cli/config-command.js +1 -0
- package/dist/lib/cli/config.js +1 -0
- package/dist/lib/cli/create-user.js +1 -0
- package/dist/lib/cli/init.js +1 -0
- package/dist/lib/cli/jira.js +1 -0
- package/dist/lib/cli/license.js +1 -0
- package/dist/lib/cli/server-manager.js +1 -0
- package/dist/lib/container-tokens.js +1 -0
- package/dist/lib/data-dir.js +1 -0
- package/dist/lib/deployment-history.js +1 -0
- package/dist/lib/deployment-service.js +1 -0
- package/dist/lib/docker-utils.js +1 -0
- package/dist/lib/email.js +1 -0
- package/dist/lib/emailTemplates.js +1 -0
- package/dist/lib/entitlement.js +1 -0
- package/dist/lib/fetch-utils.js +1 -0
- package/dist/lib/git-provider-service.js +1 -0
- package/dist/lib/git-provider-setup/assets/coderflow_github_app.png +0 -0
- package/dist/lib/git-provider-setup/github-setup-handler.js +1 -0
- package/dist/lib/git-provider-setup/index.js +1 -0
- package/dist/lib/git-provider-setup/setup-factory.js +1 -0
- package/dist/lib/git-provider-setup/setup-interface.js +1 -0
- package/dist/lib/git-providers/azure-devops-provider.js +1 -0
- package/dist/lib/git-providers/github-app-provider.js +1 -0
- package/dist/lib/git-providers/index.js +1 -0
- package/dist/lib/git-providers/provider-factory.js +1 -0
- package/dist/lib/git-providers/provider-interface.js +1 -0
- package/dist/lib/jira-client.js +1 -0
- package/dist/lib/logger.js +1 -0
- package/dist/lib/model-fetcher.js +1 -0
- package/dist/lib/notifications.js +1 -0
- package/dist/lib/oidc-auth.js +1 -0
- package/dist/lib/oidc-device-flow.js +1 -0
- package/dist/lib/passwordTokens.js +1 -0
- package/dist/lib/pin-cascade.js +1 -0
- package/dist/lib/provider-accounts.js +1 -0
- package/dist/lib/provider-oauth.js +1 -0
- package/dist/lib/provider-profile.js +1 -0
- package/dist/lib/provider-token-refresh.js +1 -0
- package/dist/lib/roles.js +1 -0
- package/dist/lib/secrets.js +1 -0
- package/dist/lib/state-capture.js +1 -0
- package/dist/lib/static-files.js +1 -0
- package/dist/lib/task-name-generator.js +1 -0
- package/dist/lib/users.js +1 -0
- package/dist/middleware/requireAuth.js +1 -0
- package/dist/middleware/requireInit.js +1 -0
- package/dist/middleware/requirePermission.js +1 -0
- package/dist/package-lock.json +4151 -0
- package/dist/package.json +50 -0
- package/dist/routes/apiKeys.js +1 -0
- package/dist/routes/auth-oidc.js +1 -0
- package/dist/routes/auth.js +1 -0
- package/dist/routes/build.js +1 -0
- package/dist/routes/containers.js +1 -0
- package/dist/routes/deploy-task.js +1 -0
- package/dist/routes/environment-management.js +1 -0
- package/dist/routes/environments.js +1 -0
- package/dist/routes/external-skills.js +1 -0
- package/dist/routes/git-credentials.js +1 -0
- package/dist/routes/git-provider-setup.js +1 -0
- package/dist/routes/health.js +1 -0
- package/dist/routes/jira.js +1 -0
- package/dist/routes/objective-management.js +1 -0
- package/dist/routes/password.js +1 -0
- package/dist/routes/prompt.js +1 -0
- package/dist/routes/provider-auth.js +1 -0
- package/dist/routes/qa.js +1 -0
- package/dist/routes/settings.js +1 -0
- package/dist/routes/skill-management.js +1 -0
- package/dist/routes/skills.js +1 -0
- package/dist/routes/tasks.js +2 -0
- package/dist/routes/templates.js +1 -0
- package/dist/routes/test-task.js +1 -0
- package/dist/routes/test.js +1 -0
- package/dist/routes/users.js +1 -0
- package/dist/routes/visualizations.js +1 -0
- package/dist/schemas/template-metadata.schema.json +178 -0
- package/dist/scripts/create-user.js +2 -0
- package/dist/shipped-skills/environment-instructions/SKILL.md +154 -0
- package/dist/shipped-skills/environment-templates/SKILL.md +282 -0
- package/dist/shipped-skills/objective-management/SKILL.md +238 -0
- package/dist/shipped-skills/skill-editor/SKILL.md +326 -0
- package/dist/start.js +2 -0
- package/dist/web-ui/public/activity-detail-modal.js +1 -0
- package/dist/web-ui/public/activity-feed.js +1 -0
- package/dist/web-ui/public/activity-formatters.js +1 -0
- package/dist/web-ui/public/agent-event-parser.js +1 -0
- package/dist/web-ui/public/app.js +1 -0
- package/dist/web-ui/public/approve-dialog.js +1 -0
- package/dist/web-ui/public/coderflow-logo-reversed.svg +46 -0
- package/dist/web-ui/public/coderflow-logo.svg +46 -0
- package/dist/web-ui/public/comments-widget.js +1 -0
- package/dist/web-ui/public/docs/.nojekyll +0 -0
- package/dist/web-ui/public/docs/README.md +26 -0
- package/dist/web-ui/public/docs/_sidebar.md +47 -0
- package/dist/web-ui/public/docs/admin/ai-providers.md +132 -0
- package/dist/web-ui/public/docs/admin/email-notifications.md +69 -0
- package/dist/web-ui/public/docs/admin/environments.md +215 -0
- package/dist/web-ui/public/docs/admin/git-providers.md +147 -0
- package/dist/web-ui/public/docs/admin/installation.md +313 -0
- package/dist/web-ui/public/docs/admin/skills.md +35 -0
- package/dist/web-ui/public/docs/admin/sso.md +241 -0
- package/dist/web-ui/public/docs/admin/users-and-roles.md +57 -0
- package/dist/web-ui/public/docs/code/cli.md +102 -0
- package/dist/web-ui/public/docs/code/files-and-editing.md +86 -0
- package/dist/web-ui/public/docs/code/terminal-access.md +110 -0
- package/dist/web-ui/public/docs/code/vscode-extension.md +58 -0
- package/dist/web-ui/public/docs/getting-started/core-concepts.md +129 -0
- package/dist/web-ui/public/docs/getting-started/overview.md +46 -0
- package/dist/web-ui/public/docs/index.html +151 -0
- package/dist/web-ui/public/docs/integrations/custom.md +58 -0
- package/dist/web-ui/public/docs/integrations/ibmi/overview.md +58 -0
- package/dist/web-ui/public/docs/integrations/overview.md +48 -0
- package/dist/web-ui/public/docs/objectives/qa-mode.md +90 -0
- package/dist/web-ui/public/docs/objectives/staged-tasks.md +60 -0
- package/dist/web-ui/public/docs/objectives/working-with-objectives.md +102 -0
- package/dist/web-ui/public/docs/tasks/approval-and-deployment.md +83 -0
- package/dist/web-ui/public/docs/tasks/creating-tasks.md +111 -0
- package/dist/web-ui/public/docs/tasks/judging.md +114 -0
- package/dist/web-ui/public/docs/tasks/providing-feedback.md +41 -0
- package/dist/web-ui/public/docs/tasks/task-groups.md +73 -0
- package/dist/web-ui/public/docs/tasks/winner-selection.md +75 -0
- package/dist/web-ui/public/docs/templates/batch-processing.md +152 -0
- package/dist/web-ui/public/docs/templates/task-templates.md +44 -0
- package/dist/web-ui/public/docs/templates/template-examples.md +93 -0
- package/dist/web-ui/public/docs/testing/profound-automated-testing.md +77 -0
- package/dist/web-ui/public/docs/testing/task-visualizations.md +42 -0
- package/dist/web-ui/public/docs/testing/testing-menu.md +118 -0
- package/dist/web-ui/public/environments.css +3942 -0
- package/dist/web-ui/public/environments.html +1791 -0
- package/dist/web-ui/public/environments.js +1 -0
- package/dist/web-ui/public/favicon-16.png +0 -0
- package/dist/web-ui/public/favicon-32.png +0 -0
- package/dist/web-ui/public/favicon.ico +0 -0
- package/dist/web-ui/public/feedback-widget.css +3133 -0
- package/dist/web-ui/public/feedback-widget.js +1 -0
- package/dist/web-ui/public/git-history.css +2663 -0
- package/dist/web-ui/public/git-history.html +272 -0
- package/dist/web-ui/public/git-history.js +1 -0
- package/dist/web-ui/public/git-status.js +1 -0
- package/dist/web-ui/public/index.html +1459 -0
- package/dist/web-ui/public/index.js +1 -0
- package/dist/web-ui/public/login.html +346 -0
- package/dist/web-ui/public/login.js +1 -0
- package/dist/web-ui/public/markdown-editor.js +1 -0
- package/dist/web-ui/public/markdown-file-editor.js +1 -0
- package/dist/web-ui/public/modal-maximize.js +1 -0
- package/dist/web-ui/public/notifications.js +1 -0
- package/dist/web-ui/public/server-health.js +1 -0
- package/dist/web-ui/public/settings.css +761 -0
- package/dist/web-ui/public/settings.html +1044 -0
- package/dist/web-ui/public/settings.js +1 -0
- package/dist/web-ui/public/setup-password.html +355 -0
- package/dist/web-ui/public/setup-password.js +1 -0
- package/dist/web-ui/public/skills.css +1949 -0
- package/dist/web-ui/public/skills.html +820 -0
- package/dist/web-ui/public/skills.js +1 -0
- package/dist/web-ui/public/sse-client.js +1 -0
- package/dist/web-ui/public/sse-shared-worker.js +1 -0
- package/dist/web-ui/public/styles.css +18614 -0
- package/dist/web-ui/public/task.html +1779 -0
- package/dist/web-ui/public/task.js +1 -0
- package/dist/web-ui/public/terminal.html +45 -0
- package/dist/web-ui/public/terminal.js +1 -0
- package/dist/web-ui/public/theme.js +1 -0
- package/dist/web-ui/public/users.html +298 -0
- package/dist/web-ui/public/users.js +1 -0
- package/dist/web-ui/public/variant-grouping.js +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Git credential helper that fetches fresh tokens from server
|
|
3
|
+
# Only responds for repo URLs in CODER_MANAGED_REPOS; others fall through to store helper
|
|
4
|
+
#
|
|
5
|
+
# This helper is configured first in the credential helper chain:
|
|
6
|
+
# [credential]
|
|
7
|
+
# helper = /usr/local/bin/coder-git-credential-helper
|
|
8
|
+
# helper = store
|
|
9
|
+
#
|
|
10
|
+
# Behavior:
|
|
11
|
+
# - get: Check if URL is managed; if so, return credentials (from cache or server)
|
|
12
|
+
# If not managed, exit silently to fall through to store helper
|
|
13
|
+
# - store/erase: Ignore (we don't persist, store helper handles non-managed repos)
|
|
14
|
+
|
|
15
|
+
set -o pipefail
|
|
16
|
+
|
|
17
|
+
OPERATION="$1"
|
|
18
|
+
CACHE_DIR="/home/coder/.cache/coder-git-credentials"
|
|
19
|
+
CACHE_FILE="$CACHE_DIR/cache.json"
|
|
20
|
+
SERVER_URL="${CODER_CREDENTIAL_SERVER:-}"
|
|
21
|
+
CONTAINER_TOKEN="${CODER_CONTAINER_TOKEN:-}"
|
|
22
|
+
MANAGED_REPOS="${CODER_MANAGED_REPOS:-[]}"
|
|
23
|
+
CACHE_BUFFER_SECONDS=300 # Refresh 5 minutes before expiry
|
|
24
|
+
|
|
25
|
+
# Log function (only logs when CODER_CREDENTIAL_DEBUG is set)
|
|
26
|
+
debug_log() {
|
|
27
|
+
if [ -n "${CODER_CREDENTIAL_DEBUG:-}" ]; then
|
|
28
|
+
echo "[coder-git-credential-helper] $*" >&2
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Normalize a URL for comparison (strip .git suffix, lowercase host)
|
|
33
|
+
normalize_url() {
|
|
34
|
+
local url="$1"
|
|
35
|
+
# Remove trailing .git
|
|
36
|
+
url="${url%.git}"
|
|
37
|
+
# Remove trailing slash
|
|
38
|
+
url="${url%/}"
|
|
39
|
+
# Lowercase the host part (everything up to the third slash)
|
|
40
|
+
# e.g., https://GITHUB.COM/owner/repo -> https://github.com/owner/repo
|
|
41
|
+
echo "$url" | sed -E 's|^(https?://[^/]+)|\L\1|'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Check if a URL is in the managed repos list
|
|
45
|
+
is_managed_repo() {
|
|
46
|
+
local url="$1"
|
|
47
|
+
local normalized_url
|
|
48
|
+
normalized_url=$(normalize_url "$url")
|
|
49
|
+
|
|
50
|
+
# Check if URL is in MANAGED_REPOS array
|
|
51
|
+
# MANAGED_REPOS is a JSON array of URLs
|
|
52
|
+
if echo "$MANAGED_REPOS" | jq -e --arg url "$normalized_url" 'map(. | gsub("\\.git$"; "") | gsub("/$"; "")) | index($url) != null' > /dev/null 2>&1; then
|
|
53
|
+
return 0
|
|
54
|
+
fi
|
|
55
|
+
return 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Get cached credentials for a URL
|
|
59
|
+
get_cached_credentials() {
|
|
60
|
+
local url="$1"
|
|
61
|
+
local normalized_url
|
|
62
|
+
normalized_url=$(normalize_url "$url")
|
|
63
|
+
|
|
64
|
+
# Check if cache file exists
|
|
65
|
+
if [ ! -f "$CACHE_FILE" ]; then
|
|
66
|
+
return 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# Try to get cached entry for this URL
|
|
70
|
+
local cached_entry
|
|
71
|
+
cached_entry=$(jq -r --arg url "$normalized_url" '.[$url] // empty' "$CACHE_FILE" 2>/dev/null)
|
|
72
|
+
|
|
73
|
+
if [ -z "$cached_entry" ] || [ "$cached_entry" = "null" ]; then
|
|
74
|
+
debug_log "Cache miss for $normalized_url"
|
|
75
|
+
return 1
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Check if cache is still valid (not expired)
|
|
79
|
+
local expires_at
|
|
80
|
+
expires_at=$(echo "$cached_entry" | jq -r '.expires_at // empty')
|
|
81
|
+
|
|
82
|
+
if [ -z "$expires_at" ]; then
|
|
83
|
+
debug_log "Cache entry missing expires_at for $normalized_url"
|
|
84
|
+
return 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Convert ISO timestamp to epoch seconds
|
|
88
|
+
local expires_epoch
|
|
89
|
+
expires_epoch=$(date -d "$expires_at" +%s 2>/dev/null)
|
|
90
|
+
|
|
91
|
+
if [ -z "$expires_epoch" ]; then
|
|
92
|
+
debug_log "Failed to parse expires_at: $expires_at"
|
|
93
|
+
return 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
local now_epoch
|
|
97
|
+
now_epoch=$(date +%s)
|
|
98
|
+
|
|
99
|
+
# Check if expired (with buffer)
|
|
100
|
+
local effective_expires=$((expires_epoch - CACHE_BUFFER_SECONDS))
|
|
101
|
+
if [ "$now_epoch" -ge "$effective_expires" ]; then
|
|
102
|
+
debug_log "Cache expired for $normalized_url (expires: $expires_at, buffer: ${CACHE_BUFFER_SECONDS}s)"
|
|
103
|
+
return 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Cache is valid - extract credentials
|
|
107
|
+
local username password
|
|
108
|
+
username=$(echo "$cached_entry" | jq -r '.username // empty')
|
|
109
|
+
password=$(echo "$cached_entry" | jq -r '.password // empty')
|
|
110
|
+
|
|
111
|
+
if [ -z "$username" ] || [ -z "$password" ]; then
|
|
112
|
+
debug_log "Cache entry missing username or password for $normalized_url"
|
|
113
|
+
return 1
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
debug_log "Cache hit for $normalized_url (expires: $expires_at)"
|
|
117
|
+
echo "$username"
|
|
118
|
+
echo "$password"
|
|
119
|
+
return 0
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
# Update cache with new credentials
|
|
123
|
+
update_cache() {
|
|
124
|
+
local url="$1"
|
|
125
|
+
local username="$2"
|
|
126
|
+
local password="$3"
|
|
127
|
+
local expires_at="$4"
|
|
128
|
+
local normalized_url
|
|
129
|
+
normalized_url=$(normalize_url "$url")
|
|
130
|
+
|
|
131
|
+
# Ensure cache directory exists with proper permissions
|
|
132
|
+
mkdir -p "$CACHE_DIR"
|
|
133
|
+
chmod 700 "$CACHE_DIR"
|
|
134
|
+
|
|
135
|
+
# Read existing cache or start fresh
|
|
136
|
+
local existing_cache="{}"
|
|
137
|
+
if [ -f "$CACHE_FILE" ]; then
|
|
138
|
+
existing_cache=$(cat "$CACHE_FILE" 2>/dev/null || echo "{}")
|
|
139
|
+
# Validate it's valid JSON
|
|
140
|
+
if ! echo "$existing_cache" | jq . > /dev/null 2>&1; then
|
|
141
|
+
existing_cache="{}"
|
|
142
|
+
fi
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Add/update entry for this URL
|
|
146
|
+
local new_cache
|
|
147
|
+
new_cache=$(echo "$existing_cache" | jq --arg url "$normalized_url" \
|
|
148
|
+
--arg username "$username" \
|
|
149
|
+
--arg password "$password" \
|
|
150
|
+
--arg expires_at "$expires_at" \
|
|
151
|
+
'.[$url] = {username: $username, password: $password, expires_at: $expires_at}')
|
|
152
|
+
|
|
153
|
+
# Write to cache file with secure permissions
|
|
154
|
+
echo "$new_cache" > "$CACHE_FILE"
|
|
155
|
+
chmod 600 "$CACHE_FILE"
|
|
156
|
+
|
|
157
|
+
debug_log "Cache updated for $normalized_url (expires: $expires_at)"
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
# Fetch credentials from server
|
|
161
|
+
fetch_from_server() {
|
|
162
|
+
local url="$1"
|
|
163
|
+
|
|
164
|
+
# Check if server is configured
|
|
165
|
+
if [ -z "$SERVER_URL" ]; then
|
|
166
|
+
debug_log "No CODER_CREDENTIAL_SERVER configured"
|
|
167
|
+
return 1
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
if [ -z "$CONTAINER_TOKEN" ]; then
|
|
171
|
+
debug_log "No CODER_CONTAINER_TOKEN configured"
|
|
172
|
+
return 1
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# URL-encode the repo URL for the query parameter
|
|
176
|
+
local encoded_url
|
|
177
|
+
encoded_url=$(printf '%s' "$url" | jq -sRr @uri)
|
|
178
|
+
|
|
179
|
+
local api_url="${SERVER_URL}/api/git/credentials?repo_url=${encoded_url}"
|
|
180
|
+
|
|
181
|
+
debug_log "Fetching credentials from: $api_url"
|
|
182
|
+
|
|
183
|
+
# Make HTTP request to server
|
|
184
|
+
local response http_code
|
|
185
|
+
response=$(curl -s -w "\n%{http_code}" \
|
|
186
|
+
-H "Authorization: Bearer $CONTAINER_TOKEN" \
|
|
187
|
+
-H "Accept: application/json" \
|
|
188
|
+
--connect-timeout 10 \
|
|
189
|
+
--max-time 30 \
|
|
190
|
+
"$api_url" 2>/dev/null)
|
|
191
|
+
|
|
192
|
+
# Extract HTTP status code (last line)
|
|
193
|
+
http_code=$(echo "$response" | tail -n1)
|
|
194
|
+
# Extract response body (all but last line)
|
|
195
|
+
response=$(echo "$response" | sed '$d')
|
|
196
|
+
|
|
197
|
+
if [ "$http_code" != "200" ]; then
|
|
198
|
+
debug_log "Server returned HTTP $http_code"
|
|
199
|
+
debug_log "Response: $response"
|
|
200
|
+
return 1
|
|
201
|
+
fi
|
|
202
|
+
|
|
203
|
+
# Parse response JSON
|
|
204
|
+
local username password expires_at
|
|
205
|
+
username=$(echo "$response" | jq -r '.username // empty')
|
|
206
|
+
password=$(echo "$response" | jq -r '.password // empty')
|
|
207
|
+
expires_at=$(echo "$response" | jq -r '.expires_at // empty')
|
|
208
|
+
|
|
209
|
+
if [ -z "$username" ] || [ -z "$password" ]; then
|
|
210
|
+
debug_log "Server response missing username or password"
|
|
211
|
+
return 1
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
debug_log "Got credentials from server (expires: $expires_at)"
|
|
215
|
+
|
|
216
|
+
# Update cache with new credentials
|
|
217
|
+
if [ -n "$expires_at" ]; then
|
|
218
|
+
update_cache "$url" "$username" "$password" "$expires_at"
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
echo "$username"
|
|
222
|
+
echo "$password"
|
|
223
|
+
return 0
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
# Handle 'get' operation
|
|
227
|
+
handle_get() {
|
|
228
|
+
local protocol="" host="" path_part=""
|
|
229
|
+
|
|
230
|
+
# Parse stdin (git credential protocol format)
|
|
231
|
+
while IFS='=' read -r key value; do
|
|
232
|
+
case "$key" in
|
|
233
|
+
protocol) protocol="$value" ;;
|
|
234
|
+
host) host="$value" ;;
|
|
235
|
+
path) path_part="$value" ;;
|
|
236
|
+
esac
|
|
237
|
+
done
|
|
238
|
+
|
|
239
|
+
debug_log "Received: protocol=$protocol host=$host path=$path_part"
|
|
240
|
+
|
|
241
|
+
# Validate we have required fields
|
|
242
|
+
if [ -z "$protocol" ] || [ -z "$host" ]; then
|
|
243
|
+
debug_log "Missing protocol or host, exiting"
|
|
244
|
+
exit 0
|
|
245
|
+
fi
|
|
246
|
+
|
|
247
|
+
# Reconstruct URL (strip .git suffix for matching)
|
|
248
|
+
local repo_url="${protocol}://${host}/${path_part%.git}"
|
|
249
|
+
|
|
250
|
+
debug_log "Reconstructed URL: $repo_url"
|
|
251
|
+
|
|
252
|
+
# Check if this repo is managed by us
|
|
253
|
+
if ! is_managed_repo "$repo_url"; then
|
|
254
|
+
debug_log "Not a managed repo, falling through to next helper"
|
|
255
|
+
exit 0
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
debug_log "Repo is managed, looking for credentials"
|
|
259
|
+
|
|
260
|
+
# Try to get cached credentials
|
|
261
|
+
local cached_result
|
|
262
|
+
cached_result=$(get_cached_credentials "$repo_url")
|
|
263
|
+
|
|
264
|
+
if [ -n "$cached_result" ]; then
|
|
265
|
+
local username password
|
|
266
|
+
username=$(echo "$cached_result" | head -1)
|
|
267
|
+
password=$(echo "$cached_result" | tail -1)
|
|
268
|
+
|
|
269
|
+
echo "username=$username"
|
|
270
|
+
echo "password=$password"
|
|
271
|
+
exit 0
|
|
272
|
+
fi
|
|
273
|
+
|
|
274
|
+
# Cache miss - fetch from server
|
|
275
|
+
local server_result
|
|
276
|
+
server_result=$(fetch_from_server "$repo_url")
|
|
277
|
+
|
|
278
|
+
if [ -n "$server_result" ]; then
|
|
279
|
+
local username password
|
|
280
|
+
username=$(echo "$server_result" | head -1)
|
|
281
|
+
password=$(echo "$server_result" | tail -1)
|
|
282
|
+
|
|
283
|
+
echo "username=$username"
|
|
284
|
+
echo "password=$password"
|
|
285
|
+
exit 0
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
# Failed to get credentials - exit silently to fall through
|
|
289
|
+
debug_log "Failed to get credentials, falling through to next helper"
|
|
290
|
+
exit 0
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
# Main operation switch
|
|
294
|
+
case "$OPERATION" in
|
|
295
|
+
get)
|
|
296
|
+
handle_get
|
|
297
|
+
;;
|
|
298
|
+
store|erase)
|
|
299
|
+
# Ignore store/erase - we don't persist credentials
|
|
300
|
+
# The store helper in the chain handles non-managed repos
|
|
301
|
+
exit 0
|
|
302
|
+
;;
|
|
303
|
+
*)
|
|
304
|
+
# Unknown operation - exit silently
|
|
305
|
+
exit 0
|
|
306
|
+
;;
|
|
307
|
+
esac
|