oficina / calendar Public

Clone
git clone https://amadan.net/oficina/calendar

Plain git — no account needed to clone.

Download

Download this file

1package calendar
2
3import (
4 "encoding/base64"
5 "errors"
6 "fmt"
7
8 "amadan.net/oficina/calendar/internal/calendar/seal"
9 "gorm.io/gorm"
10)
11
12const keyCheckMeta = "sealed_key_check_v1"
13const keyCheckPurpose = "key.check.v1"
14const keyCheckValue = "oficina/calendar key check v1"
15
16func checkDataKey(g *gorm.DB, sealer *seal.Sealer) error {
17 return g.Transaction(func(tx *gorm.DB) error {
18 var row Meta
19 err := tx.Where("key = ?", keyCheckMeta).First(&row).Error
20 if err == nil {
21 sealed, err := base64.StdEncoding.DecodeString(row.Value)
22 if err != nil {
23 return errors.New("calendar: invalid data key check")
24 }
25 plain, err := sealer.OpenString(keyCheckPurpose, sealed)
26 if err != nil || plain != keyCheckValue {
27 return errors.New("calendar: data key does not match database")
28 }
29 return nil
30 }
31 if !errors.Is(err, gorm.ErrRecordNotFound) {
32 return err
33 }
34 var calendars []Calendar
35 if err := tx.Find(&calendars).Error; err != nil {
36 return err
37 }
38 for _, c := range calendars {
39 if _, err := sealer.OpenString(seal.PurposeCalendarName, c.NameSealed); err != nil {
40 return fmt.Errorf("calendar: data key cannot open existing calendar: %w", err)
41 }
42 }
43 sealed, err := sealer.SealString(keyCheckPurpose, keyCheckValue)
44 if err != nil {
45 return err
46 }
47 return tx.Create(&Meta{Key: keyCheckMeta, Value: base64.StdEncoding.EncodeToString(sealed)}).Error
48 })
49}
50