Skip to content

Commit

Permalink
Check the image owner before cloning
Browse files Browse the repository at this point in the history
When an image is public and stored in Swift, but belongs to another project,
current auth scope doesn't have an access to the Swift backend.
  • Loading branch information
kayrus committed May 6, 2020
1 parent 3947f9d commit 3fedb40
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
9 changes: 9 additions & 0 deletions pkg/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,15 @@ var ImageCmd = &cobra.Command{
return fmt.Errorf("failed to wait for %q source image: %s", image, err)
}

// check whether current user scope belongs to the image owner
userProjectID, err := getAuthProjectID(srcImageClient.ProviderClient)
if err != nil {
return fmt.Errorf("failed to extract user project ID scope: %s", err)
}
if userProjectID != srcImg.Owner {
return fmt.Errorf("cannot clone an image, which belongs to another project: %s", srcImg.Owner)
}

defer measureTime()

_, err = migrateImage(srcImageClient, dstImageClient, srcObjectClient, srcImg, toName)
Expand Down
27 changes: 27 additions & 0 deletions pkg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/availabilityzones"
"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
"github.com/gophercloud/utils/client"
"github.com/gophercloud/utils/openstack/clientconfig"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -391,6 +392,32 @@ func checkAvailabilityZone(client *gophercloud.ServiceClient, srcAZ string, dstA
return nil
}

func getAuthProjectID(client *gophercloud.ProviderClient) (string, error) {
if client == nil {
return "", fmt.Errorf("provider client is nil")
}
r := client.GetAuthResult()
if r == nil {
return "", fmt.Errorf("provider client auth result is nil")
}
switch r := r.(type) {
case tokens.CreateResult:
v, err := r.ExtractProject()
if err != nil {
return "", err
}
return v.ID, nil
case tokens.GetResult:
v, err := r.ExtractProject()
if err != nil {
return "", err
}
return v.ID, nil
default:
return "", fmt.Errorf("got unexpected AuthResult type %t", r)
}
}

// isSliceContainsStr returns true if the string exists in given slice
func isSliceContainsStr(sl []string, str string) bool {
for _, s := range sl {
Expand Down

0 comments on commit 3fedb40

Please sign in to comment.