]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/cloud.google.com/go/storage/acl.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / cloud.google.com / go / storage / acl.go
1 // Copyright 2014 Google LLC
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
15 package storage
16
17 import (
18 "context"
19 "net/http"
20 "reflect"
21
22 "cloud.google.com/go/internal/trace"
23 "google.golang.org/api/googleapi"
24 raw "google.golang.org/api/storage/v1"
25 )
26
27 // ACLRole is the level of access to grant.
28 type ACLRole string
29
30 const (
31 RoleOwner ACLRole = "OWNER"
32 RoleReader ACLRole = "READER"
33 RoleWriter ACLRole = "WRITER"
34 )
35
36 // ACLEntity refers to a user or group.
37 // They are sometimes referred to as grantees.
38 //
39 // It could be in the form of:
40 // "user-<userId>", "user-<email>", "group-<groupId>", "group-<email>",
41 // "domain-<domain>" and "project-team-<projectId>".
42 //
43 // Or one of the predefined constants: AllUsers, AllAuthenticatedUsers.
44 type ACLEntity string
45
46 const (
47 AllUsers ACLEntity = "allUsers"
48 AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers"
49 )
50
51 // ACLRule represents a grant for a role to an entity (user, group or team) for a
52 // Google Cloud Storage object or bucket.
53 type ACLRule struct {
54 Entity ACLEntity
55 EntityID string
56 Role ACLRole
57 Domain string
58 Email string
59 ProjectTeam *ProjectTeam
60 }
61
62 // ProjectTeam is the project team associated with the entity, if any.
63 type ProjectTeam struct {
64 ProjectNumber string
65 Team string
66 }
67
68 // ACLHandle provides operations on an access control list for a Google Cloud Storage bucket or object.
69 type ACLHandle struct {
70 c *Client
71 bucket string
72 object string
73 isDefault bool
74 userProject string // for requester-pays buckets
75 }
76
77 // Delete permanently deletes the ACL entry for the given entity.
78 func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) {
79 ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete")
80 defer func() { trace.EndSpan(ctx, err) }()
81
82 if a.object != "" {
83 return a.objectDelete(ctx, entity)
84 }
85 if a.isDefault {
86 return a.bucketDefaultDelete(ctx, entity)
87 }
88 return a.bucketDelete(ctx, entity)
89 }
90
91 // Set sets the role for the given entity.
92 func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) {
93 ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set")
94 defer func() { trace.EndSpan(ctx, err) }()
95
96 if a.object != "" {
97 return a.objectSet(ctx, entity, role, false)
98 }
99 if a.isDefault {
100 return a.objectSet(ctx, entity, role, true)
101 }
102 return a.bucketSet(ctx, entity, role)
103 }
104
105 // List retrieves ACL entries.
106 func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) {
107 ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List")
108 defer func() { trace.EndSpan(ctx, err) }()
109
110 if a.object != "" {
111 return a.objectList(ctx)
112 }
113 if a.isDefault {
114 return a.bucketDefaultList(ctx)
115 }
116 return a.bucketList(ctx)
117 }
118
119 func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) {
120 var acls *raw.ObjectAccessControls
121 var err error
122 err = runWithRetry(ctx, func() error {
123 req := a.c.raw.DefaultObjectAccessControls.List(a.bucket)
124 a.configureCall(ctx, req)
125 acls, err = req.Do()
126 return err
127 })
128 if err != nil {
129 return nil, err
130 }
131 return toObjectACLRules(acls.Items), nil
132 }
133
134 func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error {
135 return runWithRetry(ctx, func() error {
136 req := a.c.raw.DefaultObjectAccessControls.Delete(a.bucket, string(entity))
137 a.configureCall(ctx, req)
138 return req.Do()
139 })
140 }
141
142 func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
143 var acls *raw.BucketAccessControls
144 var err error
145 err = runWithRetry(ctx, func() error {
146 req := a.c.raw.BucketAccessControls.List(a.bucket)
147 a.configureCall(ctx, req)
148 acls, err = req.Do()
149 return err
150 })
151 if err != nil {
152 return nil, err
153 }
154 return toBucketACLRules(acls.Items), nil
155 }
156
157 func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error {
158 acl := &raw.BucketAccessControl{
159 Bucket: a.bucket,
160 Entity: string(entity),
161 Role: string(role),
162 }
163 err := runWithRetry(ctx, func() error {
164 req := a.c.raw.BucketAccessControls.Update(a.bucket, string(entity), acl)
165 a.configureCall(ctx, req)
166 _, err := req.Do()
167 return err
168 })
169 if err != nil {
170 return err
171 }
172 return nil
173 }
174
175 func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error {
176 return runWithRetry(ctx, func() error {
177 req := a.c.raw.BucketAccessControls.Delete(a.bucket, string(entity))
178 a.configureCall(ctx, req)
179 return req.Do()
180 })
181 }
182
183 func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
184 var acls *raw.ObjectAccessControls
185 var err error
186 err = runWithRetry(ctx, func() error {
187 req := a.c.raw.ObjectAccessControls.List(a.bucket, a.object)
188 a.configureCall(ctx, req)
189 acls, err = req.Do()
190 return err
191 })
192 if err != nil {
193 return nil, err
194 }
195 return toObjectACLRules(acls.Items), nil
196 }
197
198 func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error {
199 type setRequest interface {
200 Do(opts ...googleapi.CallOption) (*raw.ObjectAccessControl, error)
201 Header() http.Header
202 }
203
204 acl := &raw.ObjectAccessControl{
205 Bucket: a.bucket,
206 Entity: string(entity),
207 Role: string(role),
208 }
209 var req setRequest
210 if isBucketDefault {
211 req = a.c.raw.DefaultObjectAccessControls.Update(a.bucket, string(entity), acl)
212 } else {
213 req = a.c.raw.ObjectAccessControls.Update(a.bucket, a.object, string(entity), acl)
214 }
215 a.configureCall(ctx, req)
216 return runWithRetry(ctx, func() error {
217 _, err := req.Do()
218 return err
219 })
220 }
221
222 func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error {
223 return runWithRetry(ctx, func() error {
224 req := a.c.raw.ObjectAccessControls.Delete(a.bucket, a.object, string(entity))
225 a.configureCall(ctx, req)
226 return req.Do()
227 })
228 }
229
230 func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) {
231 vc := reflect.ValueOf(call)
232 vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)})
233 if a.userProject != "" {
234 vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)})
235 }
236 setClientHeader(call.Header())
237 }
238
239 func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule {
240 var rs []ACLRule
241 for _, item := range items {
242 rs = append(rs, toObjectACLRule(item))
243 }
244 return rs
245 }
246
247 func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule {
248 var rs []ACLRule
249 for _, item := range items {
250 rs = append(rs, toBucketACLRule(item))
251 }
252 return rs
253 }
254
255 func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule {
256 return ACLRule{
257 Entity: ACLEntity(a.Entity),
258 EntityID: a.EntityId,
259 Role: ACLRole(a.Role),
260 Domain: a.Domain,
261 Email: a.Email,
262 ProjectTeam: toObjectProjectTeam(a.ProjectTeam),
263 }
264 }
265
266 func toBucketACLRule(a *raw.BucketAccessControl) ACLRule {
267 return ACLRule{
268 Entity: ACLEntity(a.Entity),
269 EntityID: a.EntityId,
270 Role: ACLRole(a.Role),
271 Domain: a.Domain,
272 Email: a.Email,
273 ProjectTeam: toBucketProjectTeam(a.ProjectTeam),
274 }
275 }
276
277 func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl {
278 if len(rules) == 0 {
279 return nil
280 }
281 r := make([]*raw.ObjectAccessControl, 0, len(rules))
282 for _, rule := range rules {
283 r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary
284 }
285 return r
286 }
287
288 func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl {
289 if len(rules) == 0 {
290 return nil
291 }
292 r := make([]*raw.BucketAccessControl, 0, len(rules))
293 for _, rule := range rules {
294 r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary
295 }
296 return r
297 }
298
299 func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl {
300 return &raw.BucketAccessControl{
301 Bucket: bucket,
302 Entity: string(r.Entity),
303 Role: string(r.Role),
304 // The other fields are not settable.
305 }
306 }
307
308 func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl {
309 return &raw.ObjectAccessControl{
310 Bucket: bucket,
311 Entity: string(r.Entity),
312 Role: string(r.Role),
313 // The other fields are not settable.
314 }
315 }
316
317 func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam {
318 if p == nil {
319 return nil
320 }
321 return &ProjectTeam{
322 ProjectNumber: p.ProjectNumber,
323 Team: p.Team,
324 }
325 }
326
327 func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam {
328 if p == nil {
329 return nil
330 }
331 return &ProjectTeam{
332 ProjectNumber: p.ProjectNumber,
333 Team: p.Team,
334 }
335 }