2023-12-20 18:29:23 +00:00
|
|
|
package infisical
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"code.jhot.me/jhot/hats/internal/util"
|
|
|
|
"github.com/go-resty/resty/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type InfisicalClient struct {
|
|
|
|
restClient *resty.Client
|
|
|
|
host string
|
|
|
|
clientId string
|
|
|
|
clientSecret string
|
|
|
|
accessToken string
|
|
|
|
tokenExpiration time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(host string, clientId string, clientSecret string) *InfisicalClient {
|
|
|
|
return &InfisicalClient{
|
|
|
|
restClient: resty.New().SetBaseURL(fmt.Sprintf("%s/api", host)),
|
|
|
|
host: host,
|
|
|
|
clientId: clientId,
|
|
|
|
clientSecret: clientSecret,
|
|
|
|
accessToken: "",
|
|
|
|
tokenExpiration: time.Now(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *InfisicalClient) Login() error {
|
|
|
|
var result LoginResponse
|
|
|
|
_, err := util.CheckSuccess(c.restClient.R().SetFormData(map[string]string{
|
|
|
|
"clientId": c.clientId,
|
|
|
|
"clientSecret": c.clientSecret,
|
|
|
|
}).SetResult(&result).Post("v1/auth/universal-auth/login"))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
c.restClient.SetAuthScheme(result.TokenType).SetAuthToken(result.AccessToken)
|
|
|
|
c.accessToken = result.AccessToken
|
|
|
|
c.tokenExpiration = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *InfisicalClient) CheckToken() error {
|
|
|
|
if c.accessToken == "" {
|
|
|
|
return fmt.Errorf("access token empty, please login first")
|
|
|
|
}
|
|
|
|
|
|
|
|
if time.Now().Before(c.tokenExpiration) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var result LoginResponse
|
|
|
|
_, err := util.CheckSuccess(c.restClient.R().SetResult(&result).SetBody(map[string]interface{}{
|
|
|
|
"accessToken": c.accessToken,
|
|
|
|
}).Post("v1/auth/token/renew"))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("error renewing token: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
c.restClient.SetAuthScheme(result.TokenType).SetAuthToken(result.AccessToken)
|
|
|
|
c.accessToken = result.AccessToken
|
|
|
|
c.tokenExpiration = time.Now().Add(time.Duration(result.ExpiresIn) * time.Second)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-01-04 16:55:57 +00:00
|
|
|
func (c *InfisicalClient) ListSecrets(workspaceId string, environment string, optFuncs ...RetrieveSecretOptionFunc) ([]Secret, error) {
|
2024-01-04 16:38:38 +00:00
|
|
|
opts := DefaultRetrieveSecretOptions()
|
2024-01-04 16:55:57 +00:00
|
|
|
optFuncs = append(optFuncs, WithWorkspaceID(workspaceId), WithEnvironment(environment))
|
2024-01-04 16:38:38 +00:00
|
|
|
for _, f := range optFuncs {
|
|
|
|
f(opts)
|
|
|
|
}
|
|
|
|
|
2023-12-20 18:29:23 +00:00
|
|
|
err := c.CheckToken()
|
|
|
|
if err != nil {
|
|
|
|
return []Secret{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var result SecretsResponse
|
|
|
|
_, err = util.CheckSuccess(c.restClient.R().SetResult(&result).SetQueryParams(map[string]string{
|
|
|
|
"workspaceId": opts.WorkspaceID,
|
|
|
|
"environment": opts.Environment,
|
|
|
|
"secretPath": opts.SecretPath,
|
|
|
|
"include_imports": fmt.Sprintf("%t", opts.IncludeImports),
|
|
|
|
}).Get("v3/secrets/raw"))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return []Secret{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.Secrets, nil
|
|
|
|
}
|
|
|
|
|
2024-01-04 16:55:57 +00:00
|
|
|
func (c *InfisicalClient) GetSecret(name string, workspaceId string, environment string, optFuncs ...RetrieveSecretOptionFunc) (Secret, error) {
|
|
|
|
opts := DefaultRetrieveSecretOptions()
|
|
|
|
optFuncs = append(optFuncs, WithWorkspaceID(workspaceId), WithEnvironment(environment))
|
|
|
|
for _, f := range optFuncs {
|
|
|
|
f(opts)
|
|
|
|
}
|
|
|
|
|
2023-12-20 18:29:23 +00:00
|
|
|
err := c.CheckToken()
|
|
|
|
if err != nil {
|
|
|
|
return Secret{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var result SecretResponse
|
|
|
|
_, err = util.CheckSuccess(c.restClient.R().SetResult(&result).SetQueryParams(map[string]string{
|
|
|
|
"workspaceId": opts.WorkspaceID,
|
|
|
|
"environment": opts.Environment,
|
|
|
|
"secretPath": opts.SecretPath,
|
|
|
|
"include_imports": fmt.Sprintf("%t", opts.IncludeImports),
|
|
|
|
"type": "shared",
|
|
|
|
}).Get("v3/secrets/raw/" + name))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return Secret{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.Secret, nil
|
|
|
|
}
|