per-bucket keys #68

Merged
quentin merged 9 commits from feat-per-bucket-key into main 2024-06-24 10:15:56 +00:00
2 changed files with 77 additions and 4 deletions
Showing only changes of commit df79d11028 - Show all commits

View file

@ -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()

View file

@ -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)