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 }