MCPcopy Index your code
hub / github.com/appleboy/CodeGPT / GetAPIKeyFromHelper

Function GetAPIKeyFromHelper

util/api_key_helper_unix.go:24–99  ·  view source on GitHub ↗

GetAPIKeyFromHelper executes a shell command to dynamically generate an API key. The command is executed in /bin/sh with a timeout controlled by the provided context. It returns the trimmed output from stdout, or an error if the command fails. On timeout, it kills the entire process group (shell an

(ctx context.Context, helperCmd string)

Source from the content-addressed store, hash-verified

22//
23// Security note: The returned API key is sensitive and should not be logged.
24func GetAPIKeyFromHelper(ctx context.Context, helperCmd string) (string, error) {
25 if helperCmd == "" {
26 return "", errors.New("api_key_helper command is empty")
27 }
28
29 // Create context with timeout if not already set
30 if _, hasDeadline := ctx.Deadline(); !hasDeadline {
31 var cancel context.CancelFunc
32 ctx, cancel = context.WithTimeout(ctx, HelperTimeout)
33 defer cancel()
34 }
35
36 // Execute command in /bin/sh
37 cmd := exec.CommandContext(ctx, "/bin/sh", "-c", helperCmd)
38
39 // Create a new process group so we can kill all descendants on timeout
40 cmd.SysProcAttr = &syscall.SysProcAttr{
41 Setpgid: true,
42 }
43
44 var stdout, stderr bytes.Buffer
45 cmd.Stdout = &stdout
46 cmd.Stderr = &stderr
47
48 // Start the command
49 if err := cmd.Start(); err != nil {
50 return "", fmt.Errorf("api_key_helper start failed: %w", err)
51 }
52
53 // Wait for command completion in a goroutine
54 done := make(chan error, 1)
55 go func() {
56 // Always Wait to avoid zombie processes
57 done <- cmd.Wait()
58 }()
59
60 select {
61 case err := <-done:
62 // Command completed normally
63 if err != nil {
64 // Don't include stderr in error message as it might contain sensitive info
65 return "", fmt.Errorf("api_key_helper command failed: %w", err)
66 }
67 apiKey := strings.TrimSpace(stdout.String())
68 if apiKey == "" {
69 return "", errors.New("api_key_helper command returned empty output")
70 }
71 return apiKey, nil
72
73 case <-ctx.Done():
74 // Timeout or cancellation: terminate the process group gracefully, then forcefully
75 if cmd.Process == nil {
76 // Process handle not initialized; wait for cleanup and report timeout
77 <-done
78 return "", fmt.Errorf("api_key_helper command timeout after %v", HelperTimeout)
79 }
80 pgid := cmd.Process.Pid
81

Calls 1

StringMethod · 0.45