2020-04-24 21:18:31 +00:00
|
|
|
package onepassword
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Client is the 1Password client
|
2024-09-28 08:40:41 +00:00
|
|
|
type Client struct{}
|
2020-04-24 21:18:31 +00:00
|
|
|
|
|
|
|
// Secret contains the credentials from a 1Password secret
|
|
|
|
type Secret struct {
|
|
|
|
ID string `json:"id"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
Username string `json:"username"`
|
|
|
|
Password string `json:"password"`
|
|
|
|
SecretText string `json:"secretText"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// New authenticates with the provided values and returns a new 1Password client
|
2024-09-28 08:40:41 +00:00
|
|
|
func New() (*Client, error) {
|
|
|
|
client := &Client{}
|
2020-04-24 21:18:31 +00:00
|
|
|
if err := client.authenticate(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return client, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (op *Client) authenticate() error {
|
2024-09-28 08:40:41 +00:00
|
|
|
cmd := exec.Command("op", "user", "get", "--me")
|
2020-04-24 21:18:31 +00:00
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
2024-09-28 08:40:41 +00:00
|
|
|
return fmt.Errorf("Cannot verify auth: %s\n%s", err, output)
|
2020-04-24 21:18:31 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (op Client) runCmd(args ...string) ([]byte, error) {
|
2024-09-28 08:40:41 +00:00
|
|
|
args = append(args, "--format=json")
|
2020-04-24 21:18:31 +00:00
|
|
|
cmd := exec.Command("op", args...)
|
|
|
|
res, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
err = fmt.Errorf("error calling 1Password: %s\n%s", err, res)
|
|
|
|
}
|
|
|
|
return res, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetSecret returns the values from the secret stored in 1Password with a UUID matching the secretID
|
|
|
|
func (op *Client) GetSecret(vault, secretID string) (*Secret, error) {
|
2024-09-28 08:40:41 +00:00
|
|
|
res, err := op.runCmd("item", "get", secretID, "--reveal", fmt.Sprintf("--vault=%s", vault))
|
2020-04-24 21:18:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
item := response{}
|
|
|
|
if err := json.Unmarshal(res, &item); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
secret := &Secret{
|
|
|
|
ID: item.UUID,
|
2024-09-28 08:40:41 +00:00
|
|
|
Title: item.Title,
|
2020-04-24 21:18:31 +00:00
|
|
|
Username: "",
|
|
|
|
Password: "",
|
|
|
|
SecretText: "",
|
|
|
|
}
|
|
|
|
|
2024-09-28 08:40:41 +00:00
|
|
|
if len(item.Fields) > 0 {
|
|
|
|
for _, field := range item.Fields {
|
2020-04-24 21:18:31 +00:00
|
|
|
switch field.Name {
|
|
|
|
case "username":
|
|
|
|
secret.Username = field.Value
|
|
|
|
case "password":
|
|
|
|
secret.Password = field.Value
|
2024-09-28 08:40:41 +00:00
|
|
|
case "notesPlain":
|
|
|
|
secret.SecretText = field.Value
|
2020-04-24 21:18:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return secret, nil
|
|
|
|
}
|