security update
This commit is contained in:
1 parent
5b9f19e237
commit
4131345add
11 files changed
+424
-44
No files matched your search
@@ -0,0 +1,108 @@
|
||||
package vaultwarden
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/thijsherman/vaultwarden-api/pkg/logger"
|
||||
)
|
||||
|
||||
type BitwardenItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type int `json:"type"`
|
||||
Login *struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
} `json:"login,omitempty"`
|
||||
Notes string `json:"notes,omitempty"`
|
||||
Fields []struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
} `json:"fields,omitempty"`
|
||||
}
|
||||
|
||||
func (c *Client) FetchSecretViaCLI(name string) (string, error) {
|
||||
if len(name) == 0 || len(name) > 255 {
|
||||
return "", fmt.Errorf("invalid secret name length")
|
||||
}
|
||||
|
||||
for _, ch := range name {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '_' || ch == '.' || ch == '/') {
|
||||
return "", fmt.Errorf("invalid character in secret name")
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command("bw", "get", "item", name, "--session", c.token)
|
||||
output, err := cmd.Output()
|
||||
|
||||
if err != nil {
|
||||
logger.Info.Printf("Exact match failed, searching for: %s", name)
|
||||
|
||||
searchCmd := exec.Command("bw", "list", "items", "--search", name, "--session", c.token)
|
||||
searchOutput, searchErr := searchCmd.Output()
|
||||
if searchErr != nil {
|
||||
return "", fmt.Errorf("failed to search for item: %w", searchErr)
|
||||
}
|
||||
|
||||
var items []BitwardenItem
|
||||
if err := json.Unmarshal(searchOutput, &items); err != nil {
|
||||
return "", fmt.Errorf("failed to parse search results: %w", err)
|
||||
}
|
||||
|
||||
if len(items) == 0 {
|
||||
return "", fmt.Errorf("secret not found: %s", name)
|
||||
}
|
||||
|
||||
// Use the first matching item
|
||||
output, err = json.Marshal(items[0])
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to marshal item: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var item BitwardenItem
|
||||
if err := json.Unmarshal(output, &item); err != nil {
|
||||
return "", fmt.Errorf("failed to parse item: %w", err)
|
||||
}
|
||||
|
||||
return c.extractValueFromItem(item)
|
||||
}
|
||||
|
||||
func (c *Client) extractValueFromItem(item BitwardenItem) (string, error) {
|
||||
if item.Login != nil && item.Login.Password != "" {
|
||||
return item.Login.Password, nil
|
||||
}
|
||||
|
||||
for _, field := range item.Fields {
|
||||
fieldName := strings.ToLower(field.Name)
|
||||
if fieldName == "value" || fieldName == "secret" || fieldName == "api_key" {
|
||||
return field.Value, nil
|
||||
}
|
||||
}
|
||||
|
||||
if item.Notes != "" {
|
||||
return item.Notes, nil
|
||||
}
|
||||
|
||||
if len(item.Fields) > 0 {
|
||||
return item.Fields[0].Value, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no secret value found in item")
|
||||
}
|
||||
|
||||
func (c *Client) SyncVault() error {
|
||||
cmd := exec.Command("bw", "sync", "--session", c.token)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to sync vault: %w, output: %s", err, output)
|
||||
}
|
||||
logger.Info.Println("Vault synced successfully")
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user