mirror of https://github.com/jumpserver/jumpserver
120 lines
3.0 KiB
Go
120 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type APIClient struct {
|
|
Client *http.Client
|
|
APIURL string
|
|
KeyID string
|
|
KeySecret string
|
|
OrgID string
|
|
}
|
|
|
|
func NewAPIClient() *APIClient {
|
|
return &APIClient{
|
|
Client: &http.Client{},
|
|
APIURL: getEnv("API_URL", "http://127.0.0.1:8080"),
|
|
KeyID: getEnv("API_KEY_ID", "72b0b0aa-ad82-4182-a631-ae4865e8ae0e"),
|
|
KeySecret: getEnv("API_KEY_SECRET", "6fuSO7P1m4cj8SSlgaYdblOjNAmnxDVD7tr8"),
|
|
OrgID: getEnv("ORG_ID", "00000000-0000-0000-0000-000000000002"),
|
|
}
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return defaultValue
|
|
}
|
|
return value
|
|
}
|
|
|
|
func (c *APIClient) GetAccountSecret(asset, account string) (map[string]interface{}, error) {
|
|
u, err := url.Parse(c.APIURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to parse API URL: %v", err)
|
|
}
|
|
u.Path = "/api/v1/accounts/integration-applications/account-secret/"
|
|
|
|
q := u.Query()
|
|
q.Add("asset", asset)
|
|
q.Add("account", account)
|
|
u.RawQuery = q.Encode()
|
|
|
|
req, err := http.NewRequest("GET", u.String(), nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create request: %v", err)
|
|
}
|
|
|
|
date := time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT")
|
|
req.Header.Set("Accept", "application/json")
|
|
req.Header.Set("X-JMS-ORG", c.OrgID)
|
|
req.Header.Set("Date", date)
|
|
req.Header.Set("X-Source", "jms-pam")
|
|
|
|
headersList := []string{"(request-target)", "accept", "date", "x-jms-org"}
|
|
var signatureParts []string
|
|
|
|
for _, h := range headersList {
|
|
var value string
|
|
if h == "(request-target)" {
|
|
value = strings.ToLower(req.Method) + " " + req.URL.RequestURI()
|
|
} else {
|
|
canonicalKey := http.CanonicalHeaderKey(h)
|
|
value = req.Header.Get(canonicalKey)
|
|
}
|
|
signatureParts = append(signatureParts, fmt.Sprintf("%s: %s", h, value))
|
|
}
|
|
|
|
signatureString := strings.Join(signatureParts, "\n")
|
|
mac := hmac.New(sha256.New, []byte(c.KeySecret))
|
|
mac.Write([]byte(signatureString))
|
|
signatureB64 := base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
|
|
|
headersJoined := strings.Join(headersList, " ")
|
|
authHeader := fmt.Sprintf(
|
|
`Signature keyId="%s",algorithm="hmac-sha256",headers="%s",signature="%s"`,
|
|
c.KeyID,
|
|
headersJoined,
|
|
signatureB64,
|
|
)
|
|
req.Header.Set("Authorization", authHeader)
|
|
|
|
resp, err := c.Client.Do(req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("request failed: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("API returned non-200 status: %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
|
return nil, fmt.Errorf("failed to decode response: %v", err)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func main() {
|
|
client := NewAPIClient()
|
|
result, err := client.GetAccountSecret("ubuntu_docker", "root")
|
|
if err != nil {
|
|
log.Fatalf("Error: %v", err)
|
|
}
|
|
fmt.Printf("Result: %+v\n", result)
|
|
}
|