113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
|
package vault
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"io"
|
||
|
|
||
|
"git.anthrove.art/Anthrove/otter-cage/internal/utils"
|
||
|
"git.anthrove.art/Anthrove/otter-space-sdk/v5/pkg/models"
|
||
|
"github.com/tobischo/gokeepasslib/v3"
|
||
|
w "github.com/tobischo/gokeepasslib/v3/wrappers"
|
||
|
)
|
||
|
|
||
|
func AddAPIKey(file io.Writer, masterKey string, userID models.UserID, userSourceID models.UserSourceID, apiKey string) gokeepasslib.Group {
|
||
|
// demonstrate creating sub group (we'll leave it empty because we're lazy)
|
||
|
subGroup := gokeepasslib.NewGroup()
|
||
|
subGroup.Name = string(userID)
|
||
|
|
||
|
// add api key to the user group
|
||
|
entry := gokeepasslib.NewEntry()
|
||
|
entry.Values = append(entry.Values, mkValue("Title", string(userSourceID)))
|
||
|
entry.Values = append(entry.Values, mkProtectedValue("Password", apiKey))
|
||
|
|
||
|
subGroup.Entries = append(subGroup.Entries, entry)
|
||
|
|
||
|
return subGroup
|
||
|
|
||
|
}
|
||
|
|
||
|
func mkValue(key string, value string) gokeepasslib.ValueData {
|
||
|
return gokeepasslib.ValueData{Key: key, Value: gokeepasslib.V{Content: value}}
|
||
|
}
|
||
|
|
||
|
func mkProtectedValue(key string, value string) gokeepasslib.ValueData {
|
||
|
return gokeepasslib.ValueData{
|
||
|
Key: key,
|
||
|
Value: gokeepasslib.V{Content: value, Protected: w.NewBoolWrapper(true)},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func CreateDatabase(ctx context.Context, file string, password string) error {
|
||
|
createdFile, err := utils.CreateFile(ctx, file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
rootGroup := gokeepasslib.NewGroup()
|
||
|
rootGroup.Name = "API Keys"
|
||
|
|
||
|
// now create the database containing the root group
|
||
|
db := &gokeepasslib.Database{
|
||
|
Header: gokeepasslib.NewHeader(),
|
||
|
Credentials: gokeepasslib.NewPasswordCredentials(password),
|
||
|
Content: &gokeepasslib.DBContent{
|
||
|
Meta: gokeepasslib.NewMetaData(),
|
||
|
Root: &gokeepasslib.RootData{
|
||
|
Groups: []gokeepasslib.Group{rootGroup},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// Lock entries using stream cipher
|
||
|
err = db.LockProtectedEntries()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// and encode it into the file
|
||
|
keepassEncoder := gokeepasslib.NewEncoder(createdFile)
|
||
|
if err := keepassEncoder.Encode(db); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func AppendData(ctx context.Context, file string, masterKey string, subGroups gokeepasslib.Group) error {
|
||
|
openFile, err := utils.OpenFile(ctx, file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
db := gokeepasslib.NewDatabase()
|
||
|
db.Credentials = gokeepasslib.NewPasswordCredentials(masterKey)
|
||
|
_ = gokeepasslib.NewDecoder(openFile).Decode(db)
|
||
|
|
||
|
err = db.UnlockProtectedEntries()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
db.Content.Root.Groups[0].Groups = append(db.Content.Root.Groups[0].Groups, subGroups)
|
||
|
|
||
|
// Lock entries using stream cipher
|
||
|
err = db.LockProtectedEntries()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
writeFile, err := utils.CreateFile(ctx, file)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// and encode it into the file
|
||
|
keepassEncoder := gokeepasslib.NewEncoder(writeFile)
|
||
|
if err := keepassEncoder.Encode(db); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
|
||
|
}
|