google-cloud-storage 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aedabfdd29823eedcac9c139bd352c3361ba5d0d
4
- data.tar.gz: be5105b8c9183e3294a6bb7116f45007747c49a2
3
+ metadata.gz: ef777ddfd6e259d9f116f3a5996d058d852b7d49
4
+ data.tar.gz: 9e197669439fe3b3dc9a7bc2a6cbdb6ce9a76bc0
5
5
  SHA512:
6
- metadata.gz: 5b5160e32c88c4a8b4c20c04cd08ebd3081c94807f2489f1d45852519d12da64d596b38aa7d90a736f409a5f5193e8044b0941f0fa092733cb519cd65418f4d0
7
- data.tar.gz: ad3994f964a5f67b324cd6c475b5d59eae0ccec407a6c37018be2f3198985b9031d3faf3746f67865c9c946bd055e5043a5420af8507fb4401b3801632f59b31
6
+ metadata.gz: 44a7f28a56c19e8b9014891eca1a559e8481b25ea2a0f0ed2ea244793f883395f26ddaf1cdc9d996469ed991f478d969d11151bdd2543e09f2b51d667248c400
7
+ data.tar.gz: e8db734cf23c2a8fc846baaee9779b9212abd3f5150eeb2e9d5d4ef3094c5803e0d608624d1e228542e6bf61cb0f53cf158b68bed267c80ca4dc5b2124dc226f
@@ -435,6 +435,59 @@ module Google
435
435
  # file.acl.public!
436
436
  # ```
437
437
  #
438
+ # ## Assigning payment to the requester
439
+ #
440
+ # The requester pays feature enables the owner of a bucket to indicate that
441
+ # a client accessing the bucket or a file it contains must assume the
442
+ # transit costs related to the access. This feature is currently available
443
+ # only to whitelisted projects.
444
+ #
445
+ # Assign transit costs for bucket and file operations to requesting clients
446
+ # with the `requester_pays` flag:
447
+ #
448
+ # ```ruby
449
+ # require "google/cloud/storage"
450
+ #
451
+ # storage = Google::Cloud::Storage.new
452
+ #
453
+ # bucket = storage.bucket "my-bucket"
454
+ #
455
+ # bucket.requester_pays = true # API call
456
+ # # Clients must now provide `user_project` option when calling
457
+ # # Project#bucket to access this bucket.
458
+ # ```
459
+ #
460
+ # Once the `requester_pays` flag is enabled for a bucket, a client
461
+ # attempting to access the bucket and its files must provide the
462
+ # `user_project` option to {Project#bucket}. If the argument given is
463
+ # `true`, transit costs for operations on the requested bucket or a file it
464
+ # contains will be billed to the current project for the client. (See
465
+ # {Project#project} for the ID of the current project.)
466
+ #
467
+ # ```ruby
468
+ # require "google/cloud/storage"
469
+ #
470
+ # storage = Google::Cloud::Storage.new
471
+ #
472
+ # bucket = storage.bucket "other-project-bucket", user_project: true
473
+ #
474
+ # files = bucket.files # Billed to current project
475
+ # ```
476
+ #
477
+ # If the argument is a project ID string, and the indicated project is
478
+ # authorized for the currently authenticated service account, transit costs
479
+ # will be billed to the indicated project.
480
+ #
481
+ # ```ruby
482
+ # require "google/cloud/storage"
483
+ #
484
+ # storage = Google::Cloud::Storage.new
485
+ #
486
+ # bucket = storage.bucket "other-project-bucket",
487
+ # user_project: "my-other-project"
488
+ # files = bucket.files # Billed to "my-other-project"
489
+ # ```
490
+ #
438
491
  # ## Configuring retries and timeout
439
492
  #
440
493
  # You can configure how many times API requests may be automatically
@@ -46,11 +46,43 @@ module Google
46
46
  # @private The Google API Client object.
47
47
  attr_accessor :gapi
48
48
 
49
+ ##
50
+ # A boolean value or a project ID string for a requester pays
51
+ # bucket and its files. If this attribute is set to `true`, transit
52
+ # costs for operations on the bucket will be billed to the current
53
+ # project for this client. (See {Project#project} for the ID of the
54
+ # current project.) If this attribute is set to a project ID, and that
55
+ # project is authorized for the currently authenticated service account,
56
+ # transit costs will be billed to the that project. The default is
57
+ # `nil`.
58
+ #
59
+ # In general, this attribute should be set when first retrieving the
60
+ # bucket by providing the `user_project` option to {Project#bucket}.
61
+ #
62
+ # The requester pays feature is currently available only to whitelisted
63
+ # projects.
64
+ #
65
+ # See also {#requester_pays=} and {#requester_pays} to enable requester
66
+ # pays for a bucket.
67
+ #
68
+ # @example Setting a non-default project:
69
+ # require "google/cloud/storage"
70
+ #
71
+ # storage = Google::Cloud::Storage.new
72
+ #
73
+ # bucket = storage.bucket "other-project-bucket", user_project: true
74
+ # files = bucket.files # Billed to current project
75
+ # bucket.user_project = "my-other-project"
76
+ # files = bucket.files # Billed to "my-other-project"
77
+ #
78
+ attr_accessor :user_project
79
+
49
80
  ##
50
81
  # @private Create an empty Bucket object.
51
82
  def initialize
52
83
  @service = nil
53
84
  @gapi = Google::Apis::StorageV1::Bucket.new
85
+ @user_project = nil
54
86
  end
55
87
 
56
88
  ##
@@ -293,13 +325,60 @@ module Google
293
325
  patch_gapi! :website
294
326
  end
295
327
 
328
+ ##
329
+ # Indicates that a client accessing the bucket or a file it contains
330
+ # must assume the transit costs related to the access. The requester
331
+ # must pass the `user_project` option to {Project#bucket} to indicate
332
+ # the project to which the access costs should be billed.
333
+ #
334
+ # This feature is currently available only to whitelisted projects.
335
+ #
336
+ # @return [Boolean, nil] Returns `true` if requester pays is enabled for
337
+ # the bucket.
338
+ #
339
+ def requester_pays
340
+ @gapi.billing.requester_pays if @gapi.billing
341
+ end
342
+ alias_method :requester_pays?, :requester_pays
343
+
344
+ ##
345
+ # Enables requester pays for the bucket. If enabled, a client accessing
346
+ # the bucket or a file it contains must assume the transit costs related
347
+ # to the access. The requester must pass the `user_project` option to
348
+ # {Project#bucket} to indicate the project to which the access costs
349
+ # should be billed.
350
+ #
351
+ # This feature is currently available only to whitelisted projects.
352
+ #
353
+ # @param [Boolean] new_requester_pays When set to `true`, requester pays
354
+ # is enabled for the bucket.
355
+ #
356
+ # @example Enable requester pays for a bucket:
357
+ # require "google/cloud/storage"
358
+ #
359
+ # storage = Google::Cloud::Storage.new
360
+ #
361
+ # bucket = storage.bucket "my-bucket"
362
+ #
363
+ # bucket.requester_pays = true # API call
364
+ # # Other projects must now provide `user_project` option when calling
365
+ # # Project#bucket to access this bucket.
366
+ #
367
+ def requester_pays= new_requester_pays
368
+ @gapi.billing ||= Google::Apis::StorageV1::Bucket::Billing.new
369
+ @gapi.billing.requester_pays = new_requester_pays
370
+ patch_gapi! :billing
371
+ end
372
+
296
373
  ##
297
374
  # Updates the bucket with changes made in the given block in a single
298
375
  # PATCH request. The following attributes may be set: {#cors},
299
376
  # {#logging_bucket=}, {#logging_prefix=}, {#versioning=},
300
- # {#website_main=}, and {#website_404=}. In addition, the #cors
301
- # configuration accessible in the block is completely mutable and will
302
- # be included in the request. (See {Bucket::Cors})
377
+ # {#website_main=}, {#website_404=}, and {#requester_pays=}.
378
+ #
379
+ # In addition, the #cors configuration accessible in the block is
380
+ # completely mutable and will be included in the request. (See
381
+ # {Bucket::Cors})
303
382
  #
304
383
  # @yield [bucket] a block yielding a delegate object for updating the
305
384
  # file
@@ -360,7 +439,7 @@ module Google
360
439
  #
361
440
  def delete
362
441
  ensure_service!
363
- service.delete_bucket name
442
+ service.delete_bucket name, user_project: user_project
364
443
  true
365
444
  end
366
445
 
@@ -414,16 +493,12 @@ module Google
414
493
  def files prefix: nil, delimiter: nil, token: nil, max: nil,
415
494
  versions: nil
416
495
  ensure_service!
417
- options = {
418
- prefix: prefix,
419
- delimiter: delimiter,
420
- token: token,
421
- max: max,
422
- versions: versions
423
- }
424
- gapi = service.list_files name, options
496
+ gapi = service.list_files name, prefix: prefix, delimiter: delimiter,
497
+ token: token, max: max,
498
+ versions: versions,
499
+ user_project: user_project
425
500
  File::List.from_gapi gapi, service, name, prefix, delimiter, max,
426
- versions
501
+ versions, user_project: user_project
427
502
  end
428
503
  alias_method :find_files, :files
429
504
 
@@ -458,9 +533,10 @@ module Google
458
533
  #
459
534
  def file path, generation: nil, encryption_key: nil
460
535
  ensure_service!
461
- options = { generation: generation, key: encryption_key }
462
- gapi = service.get_file name, path, options
463
- File.from_gapi gapi, service
536
+ gapi = service.get_file name, path, generation: generation,
537
+ key: encryption_key,
538
+ user_project: user_project
539
+ File.from_gapi gapi, service, user_project: user_project
464
540
  rescue Google::Cloud::NotFoundError
465
541
  nil
466
542
  end
@@ -542,7 +618,7 @@ module Google
542
618
  # cost of storage. Values include `:multi_regional`, `:regional`,
543
619
  # `:nearline`, `:coldline`, `:standard`, and `:dra` (Durable Reduced
544
620
  # Availability), as well as the strings returned by
545
- # {Bucket#storage_class}. For more information, see [Storage
621
+ # {#storage_class}. For more information, see [Storage
546
622
  # Classes](https://cloud.google.com/storage/docs/storage-classes) and
547
623
  # [Per-Object Storage
548
624
  # Class](https://cloud.google.com/storage/docs/per-object-storage-class).
@@ -601,7 +677,8 @@ module Google
601
677
  content_disposition: content_disposition, crc32c: crc32c,
602
678
  content_encoding: content_encoding, metadata: metadata,
603
679
  content_language: content_language, key: encryption_key,
604
- storage_class: storage_class_for(storage_class) }
680
+ storage_class: storage_class_for(storage_class),
681
+ user_project: user_project }
605
682
  ensure_io_or_file_exists! file
606
683
  path ||= file.path if file.respond_to? :path
607
684
  path ||= file if file.is_a? String
@@ -811,12 +888,11 @@ module Google
811
888
  client_email: nil, signing_key: nil,
812
889
  private_key: nil
813
890
  ensure_service!
814
- options = { issuer: issuer, client_email: client_email,
815
- signing_key: signing_key, private_key: private_key,
816
- policy: policy }
817
891
 
818
892
  signer = File::Signer.from_bucket self, path
819
- signer.post_object options
893
+ signer.post_object issuer: issuer, client_email: client_email,
894
+ signing_key: signing_key, private_key: private_key,
895
+ policy: policy
820
896
  end
821
897
 
822
898
  ##
@@ -950,7 +1026,7 @@ module Google
950
1026
  def policy force: nil
951
1027
  warn "DEPRECATED: 'force' in Bucket#policy" unless force.nil?
952
1028
  ensure_service!
953
- gapi = service.get_bucket_policy name
1029
+ gapi = service.get_bucket_policy name, user_project: user_project
954
1030
  policy = Policy.from_gapi gapi
955
1031
  return policy unless block_given?
956
1032
  yield policy
@@ -991,7 +1067,8 @@ module Google
991
1067
  #
992
1068
  def policy= new_policy
993
1069
  ensure_service!
994
- gapi = service.set_bucket_policy name, new_policy.to_gapi
1070
+ gapi = service.set_bucket_policy name, new_policy.to_gapi,
1071
+ user_project: user_project
995
1072
  Policy.from_gapi gapi
996
1073
  end
997
1074
 
@@ -1024,7 +1101,8 @@ module Google
1024
1101
  def test_permissions *permissions
1025
1102
  permissions = Array(permissions).flatten
1026
1103
  ensure_service!
1027
- gapi = service.test_bucket_permissions name, permissions
1104
+ gapi = service.test_bucket_permissions name, permissions,
1105
+ user_project: user_project
1028
1106
  gapi.permissions
1029
1107
  end
1030
1108
 
@@ -1038,10 +1116,11 @@ module Google
1038
1116
 
1039
1117
  ##
1040
1118
  # @private New Bucket from a Google API Client object.
1041
- def self.from_gapi gapi, conn
1119
+ def self.from_gapi gapi, service, user_project: nil
1042
1120
  new.tap do |f|
1043
1121
  f.gapi = gapi
1044
- f.service = conn
1122
+ f.service = service
1123
+ f.user_project = user_project
1045
1124
  end
1046
1125
  end
1047
1126
 
@@ -1061,7 +1140,8 @@ module Google
1061
1140
  [attr, @gapi.send(attr)]
1062
1141
  end]
1063
1142
  patch_gapi = Google::Apis::StorageV1::Bucket.new patch_args
1064
- @gapi = service.patch_bucket name, patch_gapi
1143
+ @gapi = service.patch_bucket name, patch_gapi,
1144
+ user_project: user_project
1065
1145
  end
1066
1146
 
1067
1147
  ##
@@ -48,12 +48,35 @@ module Google
48
48
  "publicReadWrite" => "publicReadWrite",
49
49
  "public_write" => "publicReadWrite" }
50
50
 
51
+ ##
52
+ # A boolean value or a project ID string for a requester pays
53
+ # bucket and its files. If this attribute is set to `true`, transit
54
+ # costs for operations on the bucket will be billed to the current
55
+ # project for this client. (See {Project#project} for the ID of the
56
+ # current project.) If this attribute is set to a project ID, and that
57
+ # project is authorized for the currently authenticated service
58
+ # account, transit costs will be billed to the that project. The
59
+ # default is `nil`.
60
+ #
61
+ # In general, this attribute should be set when first retrieving the
62
+ # owning bucket by providing the `user_project` option to
63
+ # {Project#bucket}.
64
+ #
65
+ # The requester pays feature is currently available only to
66
+ # whitelisted projects.
67
+ #
68
+ # See also {Bucket#requester_pays=} and {Bucket#requester_pays} to
69
+ # enable requester pays for a bucket.
70
+ #
71
+ attr_accessor :user_project
72
+
51
73
  ##
52
74
  # @private Initialized a new Acl object.
53
75
  # Must provide a valid Bucket object.
54
76
  def initialize bucket
55
77
  @bucket = bucket.name
56
78
  @service = bucket.service
79
+ @user_project = bucket.user_project
57
80
  @owners = nil
58
81
  @writers = nil
59
82
  @readers = nil
@@ -72,7 +95,7 @@ module Google
72
95
  # bucket.acl.reload!
73
96
  #
74
97
  def reload!
75
- gapi = @service.list_bucket_acls @bucket
98
+ gapi = @service.list_bucket_acls @bucket, user_project: user_project
76
99
  acls = Array(gapi.items)
77
100
  @owners = entities_from_acls acls, "OWNER"
78
101
  @writers = entities_from_acls acls, "WRITER"
@@ -215,7 +238,8 @@ module Google
215
238
  # bucket.acl.add_writer "group-#{email}"
216
239
  #
217
240
  def add_writer entity
218
- gapi = @service.insert_bucket_acl @bucket, entity, "WRITER"
241
+ gapi = @service.insert_bucket_acl @bucket, entity, "WRITER",
242
+ user_project: user_project
219
243
  entity = gapi.entity
220
244
  @writers.push entity unless @writers.nil?
221
245
  entity
@@ -290,7 +314,8 @@ module Google
290
314
  # bucket.acl.delete "user-#{email}"
291
315
  #
292
316
  def delete entity
293
- @service.delete_bucket_acl @bucket, entity
317
+ @service.delete_bucket_acl @bucket, entity,
318
+ user_project: user_project
294
319
  @owners.delete entity unless @owners.nil?
295
320
  @writers.delete entity unless @writers.nil?
296
321
  @readers.delete entity unless @readers.nil?
@@ -406,7 +431,8 @@ module Google
406
431
  end
407
432
 
408
433
  def update_predefined_acl! acl_role
409
- @service.patch_bucket @bucket, predefined_acl: acl_role
434
+ @service.patch_bucket @bucket, predefined_acl: acl_role,
435
+ user_project: user_project
410
436
  clear!
411
437
  end
412
438
 
@@ -449,12 +475,35 @@ module Google
449
475
  "public" => "publicRead",
450
476
  "public_read" => "publicRead" }
451
477
 
478
+ ##
479
+ # A boolean value or a project ID string for a requester pays
480
+ # bucket and its files. If this attribute is set to `true`, transit
481
+ # costs for operations on the bucket will be billed to the current
482
+ # project for this client. (See {Project#project} for the ID of the
483
+ # current project.) If this attribute is set to a project ID, and that
484
+ # project is authorized for the currently authenticated service
485
+ # account, transit costs will be billed to the that project. The
486
+ # default is `nil`.
487
+ #
488
+ # In general, this attribute should be set when first retrieving the
489
+ # owning bucket by providing the `user_project` option to
490
+ # {Project#bucket}.
491
+ #
492
+ # The requester pays feature is currently available only to
493
+ # whitelisted projects.
494
+ #
495
+ # See also {Bucket#requester_pays=} and {Bucket#requester_pays} to
496
+ # enable requester pays for a bucket.
497
+ #
498
+ attr_accessor :user_project
499
+
452
500
  ##
453
501
  # @private Initialized a new DefaultAcl object.
454
502
  # Must provide a valid Bucket object.
455
503
  def initialize bucket
456
504
  @bucket = bucket.name
457
505
  @service = bucket.service
506
+ @user_project = bucket.user_project
458
507
  @owners = nil
459
508
  @readers = nil
460
509
  end
@@ -472,7 +521,8 @@ module Google
472
521
  # bucket.default_acl.reload!
473
522
  #
474
523
  def reload!
475
- gapi = @service.list_default_acls @bucket
524
+ gapi = @service.list_default_acls @bucket,
525
+ user_project: user_project
476
526
  acls = Array(gapi.items).map do |acl|
477
527
  next acl if acl.is_a? Google::Apis::StorageV1::ObjectAccessControl
478
528
  fail "Unknown ACL format: #{acl.class}" unless acl.is_a? Hash
@@ -557,7 +607,8 @@ module Google
557
607
  # bucket.default_acl.add_owner "group-#{email}"
558
608
  #
559
609
  def add_owner entity
560
- gapi = @service.insert_default_acl @bucket, entity, "OWNER"
610
+ gapi = @service.insert_default_acl @bucket, entity, "OWNER",
611
+ user_project: user_project
561
612
  entity = gapi.entity
562
613
  @owners.push entity unless @owners.nil?
563
614
  entity
@@ -599,7 +650,8 @@ module Google
599
650
  # bucket.default_acl.add_reader "group-#{email}"
600
651
  #
601
652
  def add_reader entity
602
- gapi = @service.insert_default_acl @bucket, entity, "READER"
653
+ gapi = @service.insert_default_acl @bucket, entity, "READER",
654
+ user_project: user_project
603
655
  entity = gapi.entity
604
656
  @readers.push entity unless @readers.nil?
605
657
  entity
@@ -632,7 +684,8 @@ module Google
632
684
  # bucket.default_acl.delete "user-#{email}"
633
685
  #
634
686
  def delete entity
635
- @service.delete_default_acl @bucket, entity
687
+ @service.delete_default_acl @bucket, entity,
688
+ user_project: user_project
636
689
  @owners.delete entity unless @owners.nil?
637
690
  @readers.delete entity unless @readers.nil?
638
691
  true
@@ -765,7 +818,8 @@ module Google
765
818
  end
766
819
 
767
820
  def update_predefined_default_acl! acl_role
768
- @service.patch_bucket @bucket, predefined_default_acl: acl_role
821
+ @service.patch_bucket @bucket, predefined_default_acl: acl_role,
822
+ user_project: user_project
769
823
  clear!
770
824
  end
771
825
 
@@ -71,8 +71,8 @@ module Google
71
71
  def next
72
72
  return nil unless next?
73
73
  ensure_service!
74
- options = { prefix: @prefix, token: @token, max: @max }
75
- gapi = @service.list_buckets options
74
+ gapi = @service.list_buckets prefix: @prefix, token: @token,
75
+ max: @max
76
76
  Bucket::List.from_gapi gapi, @service, @prefix, @max
77
77
  end
78
78
 
@@ -54,6 +54,38 @@ module Google
54
54
  # @private The Connection object.
55
55
  attr_accessor :service
56
56
 
57
+ ##
58
+ # A boolean value or a project ID string for a requester pays
59
+ # bucket and its files. If this attribute is set to `true`, transit
60
+ # costs for operations on the file will be billed to the current
61
+ # project for this client. (See {Project#project} for the ID of the
62
+ # current project.) If this attribute is set to a project ID, and that
63
+ # project is authorized for the currently authenticated service account,
64
+ # transit costs will be billed to the that project. The default is
65
+ # `nil`.
66
+ #
67
+ # In general, this attribute should be set when first retrieving the
68
+ # owning bucket by providing the `user_project` option to
69
+ # {Project#bucket}.
70
+ #
71
+ # The requester pays feature is currently available only to whitelisted
72
+ # projects.
73
+ #
74
+ # See also {Bucket#requester_pays=} and {Bucket#requester_pays} to
75
+ # enable requester pays for a bucket.
76
+ #
77
+ # @example Setting a non-default project:
78
+ # require "google/cloud/storage"
79
+ #
80
+ # storage = Google::Cloud::Storage.new
81
+ #
82
+ # bucket = storage.bucket "other-project-bucket", user_project: true
83
+ # file = bucket.file "path/to/file.ext" # Billed to current project
84
+ # file.user_project = "my-other-project"
85
+ # file.download "file.ext" # Billed to "my-other-project"
86
+ #
87
+ attr_accessor :user_project
88
+
57
89
  ##
58
90
  # @private The Google API Client object.
59
91
  attr_accessor :gapi
@@ -63,6 +95,7 @@ module Google
63
95
  def initialize
64
96
  @service = nil
65
97
  @gapi = Google::Apis::StorageV1::Object.new
98
+ @user_project = nil
66
99
  end
67
100
 
68
101
  ##
@@ -425,8 +458,7 @@ module Google
425
458
  path.set_encoding "ASCII-8BIT"
426
459
  end
427
460
  file = service.download_file \
428
- bucket, name, path,
429
- key: encryption_key
461
+ bucket, name, path, key: encryption_key, user_project: user_project
430
462
  # FIX: downloading with encryption key will return nil
431
463
  file ||= ::File.new(path)
432
464
  verify_file! file, verify
@@ -520,7 +552,8 @@ module Google
520
552
  def copy dest_bucket_or_path, dest_path = nil, acl: nil,
521
553
  generation: nil, encryption_key: nil
522
554
  ensure_service!
523
- options = { acl: acl, generation: generation, key: encryption_key }
555
+ options = { acl: acl, generation: generation, key: encryption_key,
556
+ user_project: user_project }
524
557
  dest_bucket, dest_path, options = fix_copy_args dest_bucket_or_path,
525
558
  dest_path, options
526
559
 
@@ -591,7 +624,8 @@ module Google
591
624
  def rotate encryption_key: nil, new_encryption_key: nil
592
625
  ensure_service!
593
626
  options = { source_key: encryption_key,
594
- destination_key: new_encryption_key }
627
+ destination_key: new_encryption_key,
628
+ user_project: user_project }
595
629
  gapi = service.rewrite_file bucket, name, bucket, name, nil, options
596
630
  until gapi.done
597
631
  sleep 1
@@ -618,7 +652,7 @@ module Google
618
652
  #
619
653
  def delete
620
654
  ensure_service!
621
- service.delete_file bucket, name
655
+ service.delete_file bucket, name, user_project: user_project
622
656
  true
623
657
  end
624
658
 
@@ -746,12 +780,12 @@ module Google
746
780
  content_md5: nil, headers: nil, issuer: nil,
747
781
  client_email: nil, signing_key: nil, private_key: nil
748
782
  ensure_service!
749
- options = { method: method, expires: expires, headers: headers,
750
- content_type: content_type, content_md5: content_md5,
751
- issuer: issuer, client_email: client_email,
752
- signing_key: signing_key, private_key: private_key }
753
783
  signer = File::Signer.from_file self
754
- signer.signed_url options
784
+ signer.signed_url method: method, expires: expires, headers: headers,
785
+ content_type: content_type,
786
+ content_md5: content_md5,
787
+ issuer: issuer, client_email: client_email,
788
+ signing_key: signing_key, private_key: private_key
755
789
  end
756
790
 
757
791
  ##
@@ -804,7 +838,7 @@ module Google
804
838
  # Reloads the file with current data from the Storage service.
805
839
  def reload!
806
840
  ensure_service!
807
- @gapi = service.get_file bucket, name
841
+ @gapi = service.get_file bucket, name, user_project: user_project
808
842
  end
809
843
  alias_method :refresh!, :reload!
810
844
 
@@ -817,10 +851,11 @@ module Google
817
851
 
818
852
  ##
819
853
  # @private New File from a Google API Client object.
820
- def self.from_gapi gapi, service
854
+ def self.from_gapi gapi, service, user_project: nil
821
855
  new.tap do |f|
822
856
  f.gapi = gapi
823
857
  f.service = service
858
+ f.user_project = user_project
824
859
  end
825
860
  end
826
861
 
@@ -843,7 +878,8 @@ module Google
843
878
  if attributes.include? :storage_class
844
879
  @gapi = rewrite_gapi bucket, name, update_gapi
845
880
  else
846
- @gapi = service.patch_file bucket, name, update_gapi
881
+ @gapi = service.patch_file \
882
+ bucket, name, update_gapi, user_project: user_project
847
883
  end
848
884
  end
849
885
 
@@ -857,12 +893,13 @@ module Google
857
893
  end
858
894
 
859
895
  def rewrite_gapi bucket, name, update_gapi
860
- resp = service.rewrite_file bucket, name, bucket, name, update_gapi
896
+ resp = service.rewrite_file \
897
+ bucket, name, bucket, name, update_gapi, user_project: user_project
861
898
  until resp.done
862
899
  sleep 1
863
- rewrite_options = { token: resp.rewrite_token }
864
- resp = service.rewrite_file bucket, name, bucket, name,
865
- update_gapi, rewrite_options
900
+ resp = service.rewrite_file \
901
+ bucket, name, bucket, name, update_gapi,
902
+ token: resp.rewrite_token, user_project: user_project
866
903
  end
867
904
  resp.resource
868
905
  end
@@ -50,6 +50,28 @@ module Google
50
50
  "public" => "publicRead",
51
51
  "public_read" => "publicRead" }
52
52
 
53
+ ##
54
+ # A boolean value or a project ID string for a requester pays
55
+ # bucket and its files. If this attribute is set to `true`, transit
56
+ # costs for operations on the file will be billed to the current
57
+ # project for this client. (See {Project#project} for the ID of the
58
+ # current project.) If this attribute is set to a project ID, and that
59
+ # project is authorized for the currently authenticated service
60
+ # account, transit costs will be billed to the that project. The
61
+ # default is `nil`.
62
+ #
63
+ # In general, this attribute should be set when first retrieving the
64
+ # owning bucket by providing the `user_project` option to
65
+ # {Project#bucket}.
66
+ #
67
+ # The requester pays feature is currently available only to
68
+ # whitelisted projects.
69
+ #
70
+ # See also {Bucket#requester_pays=} and {Bucket#requester_pays} to
71
+ # enable requester pays for a bucket.
72
+ #
73
+ attr_accessor :user_project
74
+
53
75
  ##
54
76
  # @private Initialized a new Acl object.
55
77
  # Must provide a valid Bucket object.
@@ -57,6 +79,7 @@ module Google
57
79
  @bucket = file.bucket
58
80
  @file = file.name
59
81
  @service = file.service
82
+ @user_project = file.user_project
60
83
  @owners = nil
61
84
  @readers = nil
62
85
  end
@@ -75,7 +98,8 @@ module Google
75
98
  # file.acl.reload!
76
99
  #
77
100
  def reload!
78
- gapi = @service.list_file_acls @bucket, @file
101
+ gapi = @service.list_file_acls @bucket, @file,
102
+ user_project: user_project
79
103
  acls = Array(gapi.items)
80
104
  @owners = entities_from_acls acls, "OWNER"
81
105
  @readers = entities_from_acls acls, "READER"
@@ -163,9 +187,9 @@ module Google
163
187
  # file.acl.add_owner "group-#{email}"
164
188
  #
165
189
  def add_owner entity, generation: nil
166
- options = { generation: generation }
167
190
  gapi = @service.insert_file_acl @bucket, @file, entity, "OWNER",
168
- options
191
+ generation: generation,
192
+ user_project: user_project
169
193
  entity = gapi.entity
170
194
  @owners.push entity unless @owners.nil?
171
195
  entity
@@ -212,9 +236,9 @@ module Google
212
236
  # file.acl.add_reader "group-#{email}"
213
237
  #
214
238
  def add_reader entity, generation: nil
215
- options = { generation: generation }
216
239
  gapi = @service.insert_file_acl @bucket, @file, entity, "READER",
217
- options
240
+ generation: generation,
241
+ user_project: user_project
218
242
  entity = gapi.entity
219
243
  @readers.push entity unless @readers.nil?
220
244
  entity
@@ -250,8 +274,9 @@ module Google
250
274
  # file.acl.delete "user-#{email}"
251
275
  #
252
276
  def delete entity, generation: nil
253
- options = { generation: generation }
254
- @service.delete_file_acl @bucket, @file, entity, options
277
+ @service.delete_file_acl \
278
+ @bucket, @file, entity,
279
+ generation: generation, user_project: user_project
255
280
  @owners.delete entity unless @owners.nil?
256
281
  @readers.delete entity unless @readers.nil?
257
282
  true
@@ -391,8 +416,9 @@ module Google
391
416
 
392
417
  def update_predefined_acl! acl_role
393
418
  patched_file = Google::Apis::StorageV1::Object.new acl: []
394
- @service.patch_file \
395
- @bucket, @file, patched_file, predefined_acl: acl_role
419
+ @service.patch_file @bucket, @file, patched_file,
420
+ predefined_acl: acl_role,
421
+ user_project: user_project
396
422
  clear!
397
423
  end
398
424
 
@@ -79,11 +79,12 @@ module Google
79
79
  ensure_service!
80
80
  options = {
81
81
  prefix: @prefix, delimiter: @delimiter, token: @token, max: @max,
82
- versions: @versions
82
+ versions: @versions, user_project: @user_project
83
83
  }
84
84
  gapi = @service.list_files @bucket, options
85
85
  File::List.from_gapi gapi, @service, @bucket, @prefix,
86
- @delimiter, @max, @versions
86
+ @delimiter, @max, @versions,
87
+ user_project: @user_project
87
88
  end
88
89
 
89
90
  ##
@@ -159,7 +160,8 @@ module Google
159
160
  # @private New File::List from a Google API Client
160
161
  # Google::Apis::StorageV1::Objects object.
161
162
  def self.from_gapi gapi_list, service, bucket = nil, prefix = nil,
162
- delimiter = nil, max = nil, versions = nil
163
+ delimiter = nil, max = nil, versions = nil,
164
+ user_project: nil
163
165
  files = new(Array(gapi_list.items).map do |gapi_object|
164
166
  File.from_gapi gapi_object, service
165
167
  end)
@@ -171,6 +173,7 @@ module Google
171
173
  files.instance_variable_set :@delimiter, delimiter
172
174
  files.instance_variable_set :@max, max
173
175
  files.instance_variable_set :@versions, versions
176
+ files.instance_variable_set :@user_project, user_project
174
177
  files
175
178
  end
176
179
 
@@ -128,8 +128,7 @@ module Google
128
128
  # end
129
129
  #
130
130
  def buckets prefix: nil, token: nil, max: nil
131
- options = { prefix: prefix, token: token, max: max }
132
- gapi = service.list_buckets options
131
+ gapi = service.list_buckets prefix: prefix, token: token, max: max
133
132
  Bucket::List.from_gapi gapi, service, prefix, max
134
133
  end
135
134
  alias_method :find_buckets, :buckets
@@ -138,6 +137,20 @@ module Google
138
137
  # Retrieves bucket by name.
139
138
  #
140
139
  # @param [String] bucket_name Name of a bucket.
140
+ # @param [Boolean, String] user_project If the `requester_pays` flag is
141
+ # enabled for the requested bucket, and if this parameter is set to
142
+ # `true`, transit costs for operations on the requested bucket or a
143
+ # file it contains will be billed to the current project for this
144
+ # client. (See {#project} for the ID of the current project.) If this
145
+ # parameter is set to a project ID other than the current project, and
146
+ # that project is authorized for the currently authenticated service
147
+ # account, transit costs will be billed to the given project. The
148
+ # default is `nil`.
149
+ #
150
+ # The requester pays feature is currently available only to
151
+ # whitelisted projects.
152
+ #
153
+ # See also {Bucket#requester_pays=} and {Bucket#requester_pays}.
141
154
  #
142
155
  # @return [Google::Cloud::Storage::Bucket, nil] Returns nil if bucket
143
156
  # does not exist
@@ -150,9 +163,26 @@ module Google
150
163
  # bucket = storage.bucket "my-bucket"
151
164
  # puts bucket.name
152
165
  #
153
- def bucket bucket_name
154
- gapi = service.get_bucket bucket_name
155
- Bucket.from_gapi gapi, service
166
+ # @example With `user_project` set to pay for a requester pays bucket:
167
+ # require "google/cloud/storage"
168
+ #
169
+ # storage = Google::Cloud::Storage.new
170
+ #
171
+ # bucket = storage.bucket "other-project-bucket", user_project: true
172
+ # files = bucket.files # Billed to current project
173
+ #
174
+ # @example With `user_project` set to a project other than the default:
175
+ # require "google/cloud/storage"
176
+ #
177
+ # storage = Google::Cloud::Storage.new
178
+ #
179
+ # bucket = storage.bucket "other-project-bucket",
180
+ # user_project: "my-other-project"
181
+ # files = bucket.files # Billed to "my-other-project"
182
+ #
183
+ def bucket bucket_name, user_project: nil
184
+ gapi = service.get_bucket bucket_name, user_project: user_project
185
+ Bucket.from_gapi gapi, service, user_project: user_project
156
186
  rescue Google::Cloud::NotFoundError
157
187
  nil
158
188
  end
@@ -270,6 +300,7 @@ module Google
270
300
  # bucket = storage.create_bucket "my-bucket" do |b|
271
301
  # b.website_main = "index.html"
272
302
  # b.website_404 = "not_found.html"
303
+ # b.requester_pays = true
273
304
  # b.cors.add_rule ["http://example.org", "https://example.org"],
274
305
  # "*",
275
306
  # headers: ["X-My-Custom-Header"],
@@ -396,12 +427,12 @@ module Google
396
427
  content_type: nil, content_md5: nil, headers: nil,
397
428
  issuer: nil, client_email: nil, signing_key: nil,
398
429
  private_key: nil
399
- options = { method: method, expires: expires, headers: headers,
400
- content_type: content_type, content_md5: content_md5,
401
- issuer: issuer, client_email: client_email,
402
- signing_key: signing_key, private_key: private_key }
403
430
  signer = File::Signer.new bucket, path, service
404
- signer.signed_url options
431
+ signer.signed_url method: method, expires: expires, headers: headers,
432
+ content_type: content_type,
433
+ content_md5: content_md5,
434
+ issuer: issuer, client_email: client_email,
435
+ signing_key: signing_key, private_key: private_key
405
436
  end
406
437
 
407
438
  protected
@@ -74,26 +74,29 @@ module Google
74
74
  ##
75
75
  # Retrieves bucket by name.
76
76
  # Returns Google::Apis::StorageV1::Bucket.
77
- def get_bucket bucket_name
78
- execute { service.get_bucket bucket_name }
77
+ def get_bucket bucket_name, user_project: nil
78
+ execute do
79
+ service.get_bucket bucket_name,
80
+ user_project: user_project(user_project)
81
+ end
79
82
  end
80
83
 
81
84
  ##
82
85
  # Creates a new bucket.
83
86
  # Returns Google::Apis::StorageV1::Bucket.
84
- def insert_bucket bucket_gapi, options = {}
87
+ def insert_bucket bucket_gapi, acl: nil, default_acl: nil
85
88
  execute do
86
89
  service.insert_bucket \
87
90
  @project, bucket_gapi,
88
- predefined_acl: options[:acl],
89
- predefined_default_object_acl: options[:default_acl]
91
+ predefined_acl: acl,
92
+ predefined_default_object_acl: default_acl
90
93
  end
91
94
  end
92
95
 
93
96
  ##
94
97
  # Updates a bucket, including its ACL metadata.
95
98
  def patch_bucket bucket_name, bucket_gapi = nil, predefined_acl: nil,
96
- predefined_default_acl: nil
99
+ predefined_default_acl: nil, user_project: nil
97
100
  bucket_gapi ||= Google::Apis::StorageV1::Bucket.new
98
101
  bucket_gapi.acl = [] if predefined_acl
99
102
  bucket_gapi.default_object_acl = [] if predefined_default_acl
@@ -102,94 +105,117 @@ module Google
102
105
  service.patch_bucket \
103
106
  bucket_name, bucket_gapi,
104
107
  predefined_acl: predefined_acl,
105
- predefined_default_object_acl: predefined_default_acl
108
+ predefined_default_object_acl: predefined_default_acl,
109
+ user_project: user_project(user_project)
106
110
  end
107
111
  end
108
112
 
109
113
  ##
110
114
  # Permanently deletes an empty bucket.
111
- def delete_bucket bucket_name
112
- execute { service.delete_bucket bucket_name }
115
+ def delete_bucket bucket_name, user_project: nil
116
+ execute do
117
+ service.delete_bucket bucket_name,
118
+ user_project: user_project(user_project)
119
+ end
113
120
  end
114
121
 
115
122
  ##
116
123
  # Retrieves a list of ACLs for the given bucket.
117
- def list_bucket_acls bucket_name
118
- execute { service.list_bucket_access_controls bucket_name }
124
+ def list_bucket_acls bucket_name, user_project: nil
125
+ execute do
126
+ service.list_bucket_access_controls \
127
+ bucket_name, user_project: user_project(user_project)
128
+ end
119
129
  end
120
130
 
121
131
  ##
122
132
  # Creates a new bucket ACL.
123
- def insert_bucket_acl bucket_name, entity, role
133
+ def insert_bucket_acl bucket_name, entity, role, user_project: nil
124
134
  new_acl = Google::Apis::StorageV1::BucketAccessControl.new({
125
135
  entity: entity, role: role }.delete_if { |_k, v| v.nil? })
126
- execute { service.insert_bucket_access_control bucket_name, new_acl }
136
+ execute do
137
+ service.insert_bucket_access_control \
138
+ bucket_name, new_acl, user_project: user_project(user_project)
139
+ end
127
140
  end
128
141
 
129
142
  ##
130
143
  # Permanently deletes a bucket ACL.
131
- def delete_bucket_acl bucket_name, entity
132
- execute { service.delete_bucket_access_control bucket_name, entity }
144
+ def delete_bucket_acl bucket_name, entity, user_project: nil
145
+ execute do
146
+ service.delete_bucket_access_control \
147
+ bucket_name, entity, user_project: user_project(user_project)
148
+ end
133
149
  end
134
150
 
135
151
  ##
136
152
  # Retrieves a list of default ACLs for the given bucket.
137
- def list_default_acls bucket_name
138
- execute { service.list_default_object_access_controls bucket_name }
153
+ def list_default_acls bucket_name, user_project: nil
154
+ execute do
155
+ service.list_default_object_access_controls \
156
+ bucket_name, user_project: user_project(user_project)
157
+ end
139
158
  end
140
159
 
141
160
  ##
142
161
  # Creates a new default ACL.
143
- def insert_default_acl bucket_name, entity, role
162
+ def insert_default_acl bucket_name, entity, role, user_project: nil
144
163
  new_acl = Google::Apis::StorageV1::ObjectAccessControl.new({
145
164
  entity: entity, role: role }.delete_if { |_k, v| v.nil? })
146
165
  execute do
147
- service.insert_default_object_access_control bucket_name, new_acl
166
+ service.insert_default_object_access_control \
167
+ bucket_name, new_acl, user_project: user_project(user_project)
148
168
  end
149
169
  end
150
170
 
151
171
  ##
152
172
  # Permanently deletes a default ACL.
153
- def delete_default_acl bucket_name, entity
173
+ def delete_default_acl bucket_name, entity, user_project: nil
154
174
  execute do
155
- service.delete_default_object_access_control bucket_name, entity
175
+ service.delete_default_object_access_control \
176
+ bucket_name, entity, user_project: user_project(user_project)
156
177
  end
157
178
  end
158
179
 
159
180
  ##
160
181
  # Returns Google::Apis::StorageV1::Policy
161
- def get_bucket_policy bucket_name
182
+ def get_bucket_policy bucket_name, user_project: nil
162
183
  # get_bucket_iam_policy(bucket, fields: nil, quota_user: nil,
163
184
  # user_ip: nil, options: nil)
164
- execute { service.get_bucket_iam_policy bucket_name }
185
+ execute do
186
+ service.get_bucket_iam_policy \
187
+ bucket_name, user_project: user_project(user_project)
188
+ end
165
189
  end
166
190
 
167
191
  ##
168
192
  # Returns Google::Apis::StorageV1::Policy
169
- def set_bucket_policy bucket_name, new_policy
193
+ def set_bucket_policy bucket_name, new_policy, user_project: nil
170
194
  execute do
171
- service.set_bucket_iam_policy bucket_name, new_policy
195
+ service.set_bucket_iam_policy \
196
+ bucket_name, new_policy, user_project: user_project(user_project)
172
197
  end
173
198
  end
174
199
 
175
200
  ##
176
201
  # Returns Google::Apis::StorageV1::TestIamPermissionsResponse
177
- def test_bucket_permissions bucket_name, permissions
202
+ def test_bucket_permissions bucket_name, permissions, user_project: nil
178
203
  execute do
179
- service.test_bucket_iam_permissions bucket_name, permissions
204
+ service.test_bucket_iam_permissions \
205
+ bucket_name, permissions, user_project: user_project(user_project)
180
206
  end
181
207
  end
182
208
 
183
209
  ##
184
210
  # Retrieves a list of files matching the criteria.
185
- def list_files bucket_name, options = {}
211
+ def list_files bucket_name, delimiter: nil, max: nil, token: nil,
212
+ prefix: nil, versions: nil, user_project: nil
186
213
  execute do
187
214
  service.list_objects \
188
- bucket_name, delimiter: options[:delimiter],
189
- max_results: options[:max],
190
- page_token: options[:token],
191
- prefix: options[:prefix],
192
- versions: options[:versions]
215
+ bucket_name, delimiter: delimiter, max_results: max,
216
+ page_token: token, prefix: prefix,
217
+ versions: versions,
218
+ user_project: user_project(user_project)
193
219
  end
194
220
  end
195
221
 
@@ -199,7 +225,7 @@ module Google
199
225
  cache_control: nil, content_disposition: nil,
200
226
  content_encoding: nil, content_language: nil,
201
227
  content_type: nil, crc32c: nil, md5: nil, metadata: nil,
202
- storage_class: nil, key: nil
228
+ storage_class: nil, key: nil, user_project: nil
203
229
  file_obj = Google::Apis::StorageV1::Object.new({
204
230
  cache_control: cache_control, content_type: content_type,
205
231
  content_disposition: content_disposition, md5_hash: md5,
@@ -213,17 +239,20 @@ module Google
213
239
  bucket_name, file_obj,
214
240
  name: path, predefined_acl: acl, upload_source: source,
215
241
  content_encoding: content_encoding, content_type: content_type,
242
+ user_project: user_project(user_project),
216
243
  options: key_options(key)
217
244
  end
218
245
  end
219
246
 
220
247
  ##
221
248
  # Retrieves an object or its metadata.
222
- def get_file bucket_name, file_path, generation: nil, key: nil
249
+ def get_file bucket_name, file_path, generation: nil, key: nil,
250
+ user_project: nil
223
251
  execute do
224
252
  service.get_object \
225
253
  bucket_name, file_path,
226
254
  generation: generation,
255
+ user_project: user_project(user_project),
227
256
  options: key_options(key)
228
257
  end
229
258
  end
@@ -232,17 +261,18 @@ module Google
232
261
  # destination bucket/object.
233
262
  def copy_file source_bucket_name, source_file_path,
234
263
  destination_bucket_name, destination_file_path,
235
- file_gapi = nil, options = {}
236
- key_options = rewrite_key_options options[:key],
237
- options[:key]
264
+ file_gapi = nil, key: nil, acl: nil, generation: nil,
265
+ token: nil, user_project: nil
266
+ key_options = rewrite_key_options key, key
238
267
  execute do
239
268
  service.rewrite_object \
240
269
  source_bucket_name, source_file_path,
241
270
  destination_bucket_name, destination_file_path,
242
271
  file_gapi,
243
- destination_predefined_acl: options[:acl],
244
- source_generation: options[:generation],
245
- rewrite_token: options[:token],
272
+ destination_predefined_acl: acl,
273
+ source_generation: generation,
274
+ rewrite_token: token,
275
+ user_project: user_project(user_project),
246
276
  options: key_options
247
277
  end
248
278
  end
@@ -251,17 +281,19 @@ module Google
251
281
  # destination bucket/object.
252
282
  def rewrite_file source_bucket_name, source_file_path,
253
283
  destination_bucket_name, destination_file_path,
254
- file_gapi = nil, options = {}
255
- key_options = rewrite_key_options options[:source_key],
256
- options[:destination_key]
284
+ file_gapi = nil, source_key: nil, destination_key: nil,
285
+ acl: nil, generation: nil, token: nil,
286
+ user_project: nil
287
+ key_options = rewrite_key_options source_key, destination_key
257
288
  execute do
258
289
  service.rewrite_object \
259
290
  source_bucket_name, source_file_path,
260
291
  destination_bucket_name, destination_file_path,
261
292
  file_gapi,
262
- destination_predefined_acl: options[:acl],
263
- source_generation: options[:generation],
264
- rewrite_token: options[:token],
293
+ destination_predefined_acl: acl,
294
+ source_generation: generation,
295
+ rewrite_token: token,
296
+ user_project: user_project(user_project),
265
297
  options: key_options
266
298
  end
267
299
  end
@@ -269,11 +301,12 @@ module Google
269
301
  ##
270
302
  # Download contents of a file.
271
303
  def download_file bucket_name, file_path, target_path, generation: nil,
272
- key: nil
304
+ key: nil, user_project: nil
273
305
  execute do
274
306
  service.get_object \
275
307
  bucket_name, file_path,
276
308
  download_dest: target_path, generation: generation,
309
+ user_project: user_project(user_project),
277
310
  options: key_options(key)
278
311
  end
279
312
  end
@@ -281,44 +314,55 @@ module Google
281
314
  ##
282
315
  # Updates a file's metadata.
283
316
  def patch_file bucket_name, file_path, file_gapi = nil,
284
- predefined_acl: nil
317
+ predefined_acl: nil, user_project: nil
285
318
  file_gapi ||= Google::Apis::StorageV1::Object.new
286
319
  execute do
287
320
  service.patch_object \
288
321
  bucket_name, file_path, file_gapi,
289
- predefined_acl: predefined_acl
322
+ predefined_acl: predefined_acl,
323
+ user_project: user_project(user_project)
290
324
  end
291
325
  end
292
326
 
293
327
  ##
294
328
  # Permanently deletes a file.
295
- def delete_file bucket_name, file_path
296
- execute { service.delete_object bucket_name, file_path }
329
+ def delete_file bucket_name, file_path, user_project: nil
330
+ execute do
331
+ service.delete_object bucket_name, file_path,
332
+ user_project: user_project(user_project)
333
+ end
297
334
  end
298
335
 
299
336
  ##
300
337
  # Retrieves a list of ACLs for the given file.
301
- def list_file_acls bucket_name, file_name
302
- execute { service.list_object_access_controls bucket_name, file_name }
338
+ def list_file_acls bucket_name, file_name, user_project: nil
339
+ execute do
340
+ service.list_object_access_controls \
341
+ bucket_name, file_name, user_project: user_project(user_project)
342
+ end
303
343
  end
304
344
 
305
345
  ##
306
346
  # Creates a new file ACL.
307
- def insert_file_acl bucket_name, file_name, entity, role, options = {}
347
+ def insert_file_acl bucket_name, file_name, entity, role,
348
+ generation: nil, user_project: nil
308
349
  new_acl = Google::Apis::StorageV1::ObjectAccessControl.new({
309
350
  entity: entity, role: role }.delete_if { |_k, v| v.nil? })
310
351
  execute do
311
352
  service.insert_object_access_control \
312
- bucket_name, file_name, new_acl, generation: options[:generation]
353
+ bucket_name, file_name, new_acl,
354
+ generation: generation, user_project: user_project(user_project)
313
355
  end
314
356
  end
315
357
 
316
358
  ##
317
359
  # Permanently deletes a file ACL.
318
- def delete_file_acl bucket_name, file_name, entity, options = {}
360
+ def delete_file_acl bucket_name, file_name, entity, generation: nil,
361
+ user_project: nil
319
362
  execute do
320
363
  service.delete_object_access_control \
321
- bucket_name, file_name, entity, generation: options[:generation]
364
+ bucket_name, file_name, entity,
365
+ generation: generation, user_project: user_project(user_project)
322
366
  end
323
367
  end
324
368
 
@@ -336,6 +380,12 @@ module Google
336
380
 
337
381
  protected
338
382
 
383
+ def user_project user_project
384
+ return nil unless user_project # nil or false get nil
385
+ return @project if user_project == true # handle the true condition
386
+ String(user_project) # convert the value to a string
387
+ end
388
+
339
389
  def key_options key
340
390
  options = {}
341
391
  encryption_key_headers options, key if key
@@ -16,7 +16,7 @@
16
16
  module Google
17
17
  module Cloud
18
18
  module Storage
19
- VERSION = "1.1.0"
19
+ VERSION = "1.2.0"
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-cloud-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Moore
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-06-01 00:00:00.000000000 Z
12
+ date: 2017-06-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: google-cloud-core
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 0.11.0
34
+ version: 0.13.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 0.11.0
41
+ version: 0.13.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: digest-crc
44
44
  requirement: !ruby/object:Gem::Requirement