1// Copyright 2017 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package storage 16 17import ( 18 "cloud.google.com/go/iam" 19 "golang.org/x/net/context" 20 raw "google.golang.org/api/storage/v1" 21 iampb "google.golang.org/genproto/googleapis/iam/v1" 22) 23 24// IAM provides access to IAM access control for the bucket. 25func (b *BucketHandle) IAM() *iam.Handle { 26 return iam.InternalNewHandleClient(&iamClient{raw: b.c.raw}, b.name) 27} 28 29// iamClient implements the iam.client interface. 30type iamClient struct { 31 raw *raw.Service 32} 33 34func (c *iamClient) Get(ctx context.Context, resource string) (*iampb.Policy, error) { 35 req := c.raw.Buckets.GetIamPolicy(resource) 36 setClientHeader(req.Header()) 37 var rp *raw.Policy 38 var err error 39 err = runWithRetry(ctx, func() error { 40 rp, err = req.Context(ctx).Do() 41 return err 42 }) 43 if err != nil { 44 return nil, err 45 } 46 return iamFromStoragePolicy(rp), nil 47} 48 49func (c *iamClient) Set(ctx context.Context, resource string, p *iampb.Policy) error { 50 rp := iamToStoragePolicy(p) 51 req := c.raw.Buckets.SetIamPolicy(resource, rp) 52 setClientHeader(req.Header()) 53 return runWithRetry(ctx, func() error { 54 _, err := req.Context(ctx).Do() 55 return err 56 }) 57} 58 59func (c *iamClient) Test(ctx context.Context, resource string, perms []string) ([]string, error) { 60 req := c.raw.Buckets.TestIamPermissions(resource, perms) 61 setClientHeader(req.Header()) 62 var res *raw.TestIamPermissionsResponse 63 var err error 64 err = runWithRetry(ctx, func() error { 65 res, err = req.Context(ctx).Do() 66 return err 67 }) 68 if err != nil { 69 return nil, err 70 } 71 return res.Permissions, nil 72} 73 74func iamToStoragePolicy(ip *iampb.Policy) *raw.Policy { 75 return &raw.Policy{ 76 Bindings: iamToStorageBindings(ip.Bindings), 77 Etag: string(ip.Etag), 78 } 79} 80 81func iamToStorageBindings(ibs []*iampb.Binding) []*raw.PolicyBindings { 82 var rbs []*raw.PolicyBindings 83 for _, ib := range ibs { 84 rbs = append(rbs, &raw.PolicyBindings{ 85 Role: ib.Role, 86 Members: ib.Members, 87 }) 88 } 89 return rbs 90} 91 92func iamFromStoragePolicy(rp *raw.Policy) *iampb.Policy { 93 return &iampb.Policy{ 94 Bindings: iamFromStorageBindings(rp.Bindings), 95 Etag: []byte(rp.Etag), 96 } 97} 98 99func iamFromStorageBindings(rbs []*raw.PolicyBindings) []*iampb.Binding { 100 var ibs []*iampb.Binding 101 for _, rb := range rbs { 102 ibs = append(ibs, &iampb.Binding{ 103 Role: rb.Role, 104 Members: rb.Members, 105 }) 106 } 107 return ibs 108} 109