diff options
author | Quentin Dufour <quentin@deuxfleurs.fr> | 2024-06-24 10:43:11 +0200 |
---|---|---|
committer | Quentin Dufour <quentin@deuxfleurs.fr> | 2024-06-24 10:43:11 +0200 |
commit | df79d110285f1956f63206e7bc1f29e49dd6f088 (patch) | |
tree | 1bb16b3e0b61c0fbc9c959fa241852128599ce06 | |
parent | e940996f0f8cb8c6adb22c7d8780e364d65ecea2 (diff) | |
download | guichet-df79d110285f1956f63206e7bc1f29e49dd6f088.tar.gz guichet-df79d110285f1956f63206e7bc1f29e49dd6f088.zip |
implement flush for dedicated key, allow delete & key rotation
-rw-r--r-- | garage.go | 11 | ||||
-rw-r--r-- | website.go | 70 |
2 files changed, 77 insertions, 4 deletions
@@ -55,6 +55,17 @@ func grgSearchKey(name string) (*garage.KeyInfo, error) { return resp, nil } +func grgDelKey(accessKey string) error { + client, ctx := gadmin() + + _, err := client.KeyApi.DeleteKey(ctx).Id(accessKey).Execute() + if err != nil { + fmt.Printf("%+v\n", err) + return err + } + return nil +} + func grgCreateBucket(bucket string) (*garage.BucketInfo, error) { client, ctx := gadmin() @@ -134,8 +134,14 @@ func (w *WebsiteController) getDedicatedWebsiteKey(binfo *garage.BucketInfo) (*g log.Printf("Created dedicated key %s\n", dedicatedKeyName) } + // Check that the key name is *exactly* the one we requested + if *keyInfo.Name != dedicatedKeyName { + log.Printf("Expected key: %s, got %s. Invariant violated.\n", dedicatedKeyName, *keyInfo.Name) + return nil, ErrDedicatedKeyInvariant + } + // Check that the dedicated key does not contain any other bucket than this one - // and that this bucket key is found with correct permissions + // and report if this bucket key is found with correct permissions permissionsOk := false for _, buck := range keyInfo.Buckets { if *buck.Id != *binfo.Id { @@ -167,7 +173,57 @@ func (w *WebsiteController) getDedicatedWebsiteKey(binfo *garage.BucketInfo) (*g return keyInfo, nil } -//@TODO: flushDedicatedWebsiteKey() +func (w *WebsiteController) flushDedicatedWebsiteKey(binfo *garage.BucketInfo) error { + // Check bucket info is not null + if binfo == nil { + return ErrFetchBucketInfo + } + + // Check the bucket is owned by the user's root key + usersRootKeyFound := false + for _, bucketKeyInfo := range binfo.Keys { + if *bucketKeyInfo.AccessKeyId == *w.RootKey.AccessKeyId && *bucketKeyInfo.Permissions.Owner { + usersRootKeyFound = true + break + } + } + if !usersRootKeyFound { + log.Printf("%s is not an owner of bucket %s. Invariant violated.\n", w.User.Username, *binfo.Id) + return ErrDedicatedKeyInvariant + } + + // Build the string template by concatening the username and the bucket identifier + dedicatedKeyName := fmt.Sprintf("%s:web:%s", w.User.Username, *binfo.Id) + + // Fetch the dedicated key + keyInfo, err := grgSearchKey(dedicatedKeyName) + if err != nil { + return err + } + + // Check that the key name is *exactly* the one we requested + if *keyInfo.Name != dedicatedKeyName { + log.Printf("Expected key: %s, got %s. Invariant violated.\n", dedicatedKeyName, *keyInfo.Name) + return ErrDedicatedKeyInvariant + } + + // Check that the dedicated key contains no other bucket than this one + // (can also be empty, useful to heal a partially created key) + for _, buck := range keyInfo.Buckets { + if *buck.Id != *binfo.Id { + log.Printf("Key %s is used on bucket %s while it should be exclusive to %s. Invariant violated.\n", dedicatedKeyName, *buck.Id, *binfo.Id) + return ErrDedicatedKeyInvariant + } + } + + // Finally delete this key + err = grgDelKey(*keyInfo.AccessKeyId) + if err != nil { + return err + } + log.Printf("Deleted dedicated key %s", dedicatedKeyName) + return nil +} func (w *WebsiteController) Describe() (*WebsiteDescribe, error) { r := make([]*WebsiteId, 0, len(w.PrettyList)) @@ -243,7 +299,10 @@ func (w *WebsiteController) Patch(pretty string, patch *WebsitePatch) (*WebsiteV } if patch.RotateKey != nil && *patch.RotateKey { - // @TODO: rotate key by calling flush + err = w.flushDedicatedWebsiteKey(binfo) + if err != nil { + return nil, err + } } dedicatedKey, err := w.getDedicatedWebsiteKey(binfo) @@ -327,7 +386,10 @@ func (w *WebsiteController) Delete(pretty string) error { } // Delete dedicated key - // @TODO call flush + err = w.flushDedicatedWebsiteKey(binfo) + if err != nil { + return err + } // Actually delete bucket err = grgDeleteBucket(website.Internal) |