...

Source file src/cloud.google.com/go/storage/acl.go

Documentation: cloud.google.com/go/storage

     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  	"cloud.google.com/go/storage/internal/apiv2/storagepb"
    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  // ACLHandle on an object operates on the latest generation of that object by default.
    70  // Selecting a specific generation of an object is not currently supported by the client.
    71  type ACLHandle struct {
    72  	c           *Client
    73  	bucket      string
    74  	object      string
    75  	isDefault   bool
    76  	userProject string // for requester-pays buckets
    77  	retry       *retryConfig
    78  }
    79  
    80  // Delete permanently deletes the ACL entry for the given entity.
    81  func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) (err error) {
    82  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Delete")
    83  	defer func() { trace.EndSpan(ctx, err) }()
    84  
    85  	if a.object != "" {
    86  		return a.objectDelete(ctx, entity)
    87  	}
    88  	if a.isDefault {
    89  		return a.bucketDefaultDelete(ctx, entity)
    90  	}
    91  	return a.bucketDelete(ctx, entity)
    92  }
    93  
    94  // Set sets the role for the given entity.
    95  func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) (err error) {
    96  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.Set")
    97  	defer func() { trace.EndSpan(ctx, err) }()
    98  
    99  	if a.object != "" {
   100  		return a.objectSet(ctx, entity, role, false)
   101  	}
   102  	if a.isDefault {
   103  		return a.objectSet(ctx, entity, role, true)
   104  	}
   105  	return a.bucketSet(ctx, entity, role)
   106  }
   107  
   108  // List retrieves ACL entries.
   109  func (a *ACLHandle) List(ctx context.Context) (rules []ACLRule, err error) {
   110  	ctx = trace.StartSpan(ctx, "cloud.google.com/go/storage.ACL.List")
   111  	defer func() { trace.EndSpan(ctx, err) }()
   112  
   113  	if a.object != "" {
   114  		return a.objectList(ctx)
   115  	}
   116  	if a.isDefault {
   117  		return a.bucketDefaultList(ctx)
   118  	}
   119  	return a.bucketList(ctx)
   120  }
   121  
   122  func (a *ACLHandle) bucketDefaultList(ctx context.Context) ([]ACLRule, error) {
   123  	opts := makeStorageOpts(true, a.retry, a.userProject)
   124  	return a.c.tc.ListDefaultObjectACLs(ctx, a.bucket, opts...)
   125  }
   126  
   127  func (a *ACLHandle) bucketDefaultDelete(ctx context.Context, entity ACLEntity) error {
   128  	opts := makeStorageOpts(false, a.retry, a.userProject)
   129  	return a.c.tc.DeleteDefaultObjectACL(ctx, a.bucket, entity, opts...)
   130  }
   131  
   132  func (a *ACLHandle) bucketList(ctx context.Context) ([]ACLRule, error) {
   133  	opts := makeStorageOpts(true, a.retry, a.userProject)
   134  	return a.c.tc.ListBucketACLs(ctx, a.bucket, opts...)
   135  }
   136  
   137  func (a *ACLHandle) bucketSet(ctx context.Context, entity ACLEntity, role ACLRole) error {
   138  	opts := makeStorageOpts(false, a.retry, a.userProject)
   139  	return a.c.tc.UpdateBucketACL(ctx, a.bucket, entity, role, opts...)
   140  }
   141  
   142  func (a *ACLHandle) bucketDelete(ctx context.Context, entity ACLEntity) error {
   143  	opts := makeStorageOpts(false, a.retry, a.userProject)
   144  	return a.c.tc.DeleteBucketACL(ctx, a.bucket, entity, opts...)
   145  }
   146  
   147  func (a *ACLHandle) objectList(ctx context.Context) ([]ACLRule, error) {
   148  	opts := makeStorageOpts(true, a.retry, a.userProject)
   149  	return a.c.tc.ListObjectACLs(ctx, a.bucket, a.object, opts...)
   150  }
   151  
   152  func (a *ACLHandle) objectSet(ctx context.Context, entity ACLEntity, role ACLRole, isBucketDefault bool) error {
   153  	opts := makeStorageOpts(false, a.retry, a.userProject)
   154  	if isBucketDefault {
   155  		return a.c.tc.UpdateDefaultObjectACL(ctx, a.bucket, entity, role, opts...)
   156  	}
   157  	return a.c.tc.UpdateObjectACL(ctx, a.bucket, a.object, entity, role, opts...)
   158  }
   159  
   160  func (a *ACLHandle) objectDelete(ctx context.Context, entity ACLEntity) error {
   161  	opts := makeStorageOpts(false, a.retry, a.userProject)
   162  	return a.c.tc.DeleteObjectACL(ctx, a.bucket, a.object, entity, opts...)
   163  }
   164  
   165  func (a *ACLHandle) configureCall(ctx context.Context, call interface{ Header() http.Header }) {
   166  	vc := reflect.ValueOf(call)
   167  	vc.MethodByName("Context").Call([]reflect.Value{reflect.ValueOf(ctx)})
   168  	if a.userProject != "" {
   169  		vc.MethodByName("UserProject").Call([]reflect.Value{reflect.ValueOf(a.userProject)})
   170  	}
   171  	setClientHeader(call.Header())
   172  }
   173  
   174  func toObjectACLRules(items []*raw.ObjectAccessControl) []ACLRule {
   175  	var rs []ACLRule
   176  	for _, item := range items {
   177  		rs = append(rs, toObjectACLRule(item))
   178  	}
   179  	return rs
   180  }
   181  
   182  func toObjectACLRulesFromProto(items []*storagepb.ObjectAccessControl) []ACLRule {
   183  	var rs []ACLRule
   184  	for _, item := range items {
   185  		rs = append(rs, toObjectACLRuleFromProto(item))
   186  	}
   187  	return rs
   188  }
   189  
   190  func toBucketACLRules(items []*raw.BucketAccessControl) []ACLRule {
   191  	var rs []ACLRule
   192  	for _, item := range items {
   193  		rs = append(rs, toBucketACLRule(item))
   194  	}
   195  	return rs
   196  }
   197  
   198  func toBucketACLRulesFromProto(items []*storagepb.BucketAccessControl) []ACLRule {
   199  	var rs []ACLRule
   200  	for _, item := range items {
   201  		rs = append(rs, toBucketACLRuleFromProto(item))
   202  	}
   203  	return rs
   204  }
   205  
   206  func toObjectACLRule(a *raw.ObjectAccessControl) ACLRule {
   207  	return ACLRule{
   208  		Entity:      ACLEntity(a.Entity),
   209  		EntityID:    a.EntityId,
   210  		Role:        ACLRole(a.Role),
   211  		Domain:      a.Domain,
   212  		Email:       a.Email,
   213  		ProjectTeam: toObjectProjectTeam(a.ProjectTeam),
   214  	}
   215  }
   216  
   217  func toObjectACLRuleFromProto(a *storagepb.ObjectAccessControl) ACLRule {
   218  	return ACLRule{
   219  		Entity:      ACLEntity(a.GetEntity()),
   220  		EntityID:    a.GetEntityId(),
   221  		Role:        ACLRole(a.GetRole()),
   222  		Domain:      a.GetDomain(),
   223  		Email:       a.GetEmail(),
   224  		ProjectTeam: toProjectTeamFromProto(a.GetProjectTeam()),
   225  	}
   226  }
   227  
   228  func toBucketACLRule(a *raw.BucketAccessControl) ACLRule {
   229  	return ACLRule{
   230  		Entity:      ACLEntity(a.Entity),
   231  		EntityID:    a.EntityId,
   232  		Role:        ACLRole(a.Role),
   233  		Domain:      a.Domain,
   234  		Email:       a.Email,
   235  		ProjectTeam: toBucketProjectTeam(a.ProjectTeam),
   236  	}
   237  }
   238  
   239  func toBucketACLRuleFromProto(a *storagepb.BucketAccessControl) ACLRule {
   240  	return ACLRule{
   241  		Entity:      ACLEntity(a.GetEntity()),
   242  		EntityID:    a.GetEntityId(),
   243  		Role:        ACLRole(a.GetRole()),
   244  		Domain:      a.GetDomain(),
   245  		Email:       a.GetEmail(),
   246  		ProjectTeam: toProjectTeamFromProto(a.GetProjectTeam()),
   247  	}
   248  }
   249  
   250  func toRawObjectACL(rules []ACLRule) []*raw.ObjectAccessControl {
   251  	if len(rules) == 0 {
   252  		return nil
   253  	}
   254  	r := make([]*raw.ObjectAccessControl, 0, len(rules))
   255  	for _, rule := range rules {
   256  		r = append(r, rule.toRawObjectAccessControl("")) // bucket name unnecessary
   257  	}
   258  	return r
   259  }
   260  
   261  func toProtoObjectACL(rules []ACLRule) []*storagepb.ObjectAccessControl {
   262  	if len(rules) == 0 {
   263  		return nil
   264  	}
   265  	r := make([]*storagepb.ObjectAccessControl, 0, len(rules))
   266  	for _, rule := range rules {
   267  		r = append(r, rule.toProtoObjectAccessControl("")) // bucket name unnecessary
   268  	}
   269  	return r
   270  }
   271  
   272  func toRawBucketACL(rules []ACLRule) []*raw.BucketAccessControl {
   273  	if len(rules) == 0 {
   274  		return nil
   275  	}
   276  	r := make([]*raw.BucketAccessControl, 0, len(rules))
   277  	for _, rule := range rules {
   278  		r = append(r, rule.toRawBucketAccessControl("")) // bucket name unnecessary
   279  	}
   280  	return r
   281  }
   282  
   283  func toProtoBucketACL(rules []ACLRule) []*storagepb.BucketAccessControl {
   284  	if len(rules) == 0 {
   285  		return nil
   286  	}
   287  	r := make([]*storagepb.BucketAccessControl, 0, len(rules))
   288  	for _, rule := range rules {
   289  		r = append(r, rule.toProtoBucketAccessControl())
   290  	}
   291  	return r
   292  }
   293  
   294  func (r ACLRule) toRawBucketAccessControl(bucket string) *raw.BucketAccessControl {
   295  	return &raw.BucketAccessControl{
   296  		Bucket: bucket,
   297  		Entity: string(r.Entity),
   298  		Role:   string(r.Role),
   299  		// The other fields are not settable.
   300  	}
   301  }
   302  
   303  func (r ACLRule) toRawObjectAccessControl(bucket string) *raw.ObjectAccessControl {
   304  	return &raw.ObjectAccessControl{
   305  		Bucket: bucket,
   306  		Entity: string(r.Entity),
   307  		Role:   string(r.Role),
   308  		// The other fields are not settable.
   309  	}
   310  }
   311  
   312  func (r ACLRule) toProtoObjectAccessControl(bucket string) *storagepb.ObjectAccessControl {
   313  	return &storagepb.ObjectAccessControl{
   314  		Entity: string(r.Entity),
   315  		Role:   string(r.Role),
   316  		// The other fields are not settable.
   317  	}
   318  }
   319  
   320  func (r ACLRule) toProtoBucketAccessControl() *storagepb.BucketAccessControl {
   321  	return &storagepb.BucketAccessControl{
   322  		Entity: string(r.Entity),
   323  		Role:   string(r.Role),
   324  		// The other fields are not settable.
   325  	}
   326  }
   327  
   328  func toBucketProjectTeam(p *raw.BucketAccessControlProjectTeam) *ProjectTeam {
   329  	if p == nil {
   330  		return nil
   331  	}
   332  	return &ProjectTeam{
   333  		ProjectNumber: p.ProjectNumber,
   334  		Team:          p.Team,
   335  	}
   336  }
   337  
   338  func toProjectTeamFromProto(p *storagepb.ProjectTeam) *ProjectTeam {
   339  	if p == nil {
   340  		return nil
   341  	}
   342  	return &ProjectTeam{
   343  		ProjectNumber: p.GetProjectNumber(),
   344  		Team:          p.GetTeam(),
   345  	}
   346  }
   347  
   348  func toObjectProjectTeam(p *raw.ObjectAccessControlProjectTeam) *ProjectTeam {
   349  	if p == nil {
   350  		return nil
   351  	}
   352  	return &ProjectTeam{
   353  		ProjectNumber: p.ProjectNumber,
   354  		Team:          p.Team,
   355  	}
   356  }
   357  

View as plain text