export: skip resource on error

This commit is contained in:
Samuel Lorch 2024-03-21 22:42:36 +01:00
parent a535a832c2
commit c595eca741

View file

@ -91,73 +91,15 @@ func KeepassExport(cmd *cobra.Command, args []string) error {
return fmt.Errorf("Progress: %w", err) return fmt.Errorf("Progress: %w", err)
} }
for i, resource := range resources { for _, resource := range resources {
_, _, _, _, pass, desc, err := helper.GetResourceFromData(client, resource, resource.Secrets[0], resource.ResourceType) entry, err := GetKeepassEntry(client, resource, resource.Secrets[0], resource.ResourceType)
if err != nil { if err != nil {
return fmt.Errorf("Get Resource %v, %v %w", i, resource.ID, err) fmt.Printf("Skipping Export of Resource %v %v Because of: %v\n", resource.ID, resource.Name, err)
progressbar.Increment()
continue
} }
entry := gokeepasslib.NewEntry() rootGroup.Entries = append(rootGroup.Entries, *entry)
entry.Values = append(
entry.Values,
gokeepasslib.ValueData{Key: "Title", Value: gokeepasslib.V{Content: resource.Name}},
gokeepasslib.ValueData{Key: "UserName", Value: gokeepasslib.V{Content: resource.Username}},
gokeepasslib.ValueData{Key: "URL", Value: gokeepasslib.V{Content: resource.URI}},
gokeepasslib.ValueData{Key: "Password", Value: gokeepasslib.V{Content: pass, Protected: w.NewBoolWrapper(true)}},
gokeepasslib.ValueData{Key: "Notes", Value: gokeepasslib.V{Content: desc}},
)
if resource.ResourceType.Slug == "password-description-totp" || resource.ResourceType.Slug == "totp" {
var totpData api.SecretDataTOTP
rawSecretData, err := client.DecryptMessage(resource.Secrets[0].Data)
if err != nil {
return fmt.Errorf("Decrypting Secret Data: %w", err)
}
if resource.ResourceType.Slug == "password-description-totp" {
var secretData api.SecretDataTypePasswordDescriptionTOTP
err = json.Unmarshal([]byte(rawSecretData), &secretData)
if err != nil {
return fmt.Errorf("Parsing Decrypted Secret Data: %w", err)
}
totpData = secretData.TOTP
} else {
var secretData api.SecretDataTOTP
err = json.Unmarshal([]byte(rawSecretData), &secretData)
if err != nil {
return fmt.Errorf("Parsing Decrypted Secret Data: %w", err)
}
totpData = secretData
}
var alg otp.Algorithm
switch totpData.Algorithm {
case "SHA1":
alg = otp.AlgorithmSHA1
case "SHA256":
alg = otp.AlgorithmSHA256
default:
return fmt.Errorf("Unsuported TOTP Algorithm: %v ", totpData.Algorithm)
}
totpKey, err := totp.Generate(totp.GenerateOpts{
Issuer: resource.URI,
AccountName: resource.Username,
Secret: []byte(totpData.SecretKey),
Algorithm: alg,
Period: uint(totpData.Period),
Digits: otp.Digits(totpData.Digits),
})
if err != nil {
return fmt.Errorf("Generating TOTP Key: %w", err)
}
entry.Values = append(entry.Values, gokeepasslib.ValueData{Key: "otp", Value: gokeepasslib.V{Content: totpKey.URL(), Protected: w.NewBoolWrapper(true)}})
}
rootGroup.Entries = append(rootGroup.Entries, entry)
progressbar.Increment() progressbar.Increment()
} }
@ -184,3 +126,72 @@ func KeepassExport(cmd *cobra.Command, args []string) error {
return nil return nil
} }
func GetKeepassEntry(client *api.Client, resource api.Resource, secret api.Secret, rType api.ResourceType) (*gokeepasslib.Entry, error) {
_, _, _, _, pass, desc, err := helper.GetResourceFromData(client, resource, resource.Secrets[0], resource.ResourceType)
if err != nil {
return nil, fmt.Errorf("Get Resource %v: %w", resource.ID, err)
}
entry := gokeepasslib.NewEntry()
entry.Values = append(
entry.Values,
gokeepasslib.ValueData{Key: "Title", Value: gokeepasslib.V{Content: resource.Name}},
gokeepasslib.ValueData{Key: "UserName", Value: gokeepasslib.V{Content: resource.Username}},
gokeepasslib.ValueData{Key: "URL", Value: gokeepasslib.V{Content: resource.URI}},
gokeepasslib.ValueData{Key: "Password", Value: gokeepasslib.V{Content: pass, Protected: w.NewBoolWrapper(true)}},
gokeepasslib.ValueData{Key: "Notes", Value: gokeepasslib.V{Content: desc}},
)
if resource.ResourceType.Slug == "password-description-totp" || resource.ResourceType.Slug == "totp" {
var totpData api.SecretDataTOTP
rawSecretData, err := client.DecryptMessage(resource.Secrets[0].Data)
if err != nil {
return nil, fmt.Errorf("Decrypting Secret Data: %w", err)
}
if resource.ResourceType.Slug == "password-description-totp" {
var secretData api.SecretDataTypePasswordDescriptionTOTP
err = json.Unmarshal([]byte(rawSecretData), &secretData)
if err != nil {
return nil, fmt.Errorf("Parsing Decrypted Secret Data: %w", err)
}
totpData = secretData.TOTP
} else {
var secretData api.SecretDataTOTP
err = json.Unmarshal([]byte(rawSecretData), &secretData)
if err != nil {
return nil, fmt.Errorf("Parsing Decrypted Secret Data: %w", err)
}
totpData = secretData
}
var alg otp.Algorithm
switch totpData.Algorithm {
case "SHA1":
alg = otp.AlgorithmSHA1
case "SHA256":
alg = otp.AlgorithmSHA256
default:
return nil, fmt.Errorf("Unsuported TOTP Algorithm: %v ", totpData.Algorithm)
}
totpKey, err := totp.Generate(totp.GenerateOpts{
Issuer: resource.URI,
AccountName: resource.Username,
Secret: []byte(totpData.SecretKey),
Algorithm: alg,
Period: uint(totpData.Period),
Digits: otp.Digits(totpData.Digits),
})
if err != nil {
return nil, fmt.Errorf("Generating TOTP Key: %w", err)
}
entry.Values = append(entry.Values, gokeepasslib.ValueData{Key: "otp", Value: gokeepasslib.V{Content: totpKey.URL(), Protected: w.NewBoolWrapper(true)}})
}
return &entry, nil
}