google-cloud-storage 1.24.0 → 1.25.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 +4 -4
- data/CHANGELOG.md +7 -1
- data/lib/google/cloud/storage/bucket.rb +149 -16
- data/lib/google/cloud/storage/policy.rb +275 -22
- data/lib/google/cloud/storage/policy/binding.rb +243 -0
- data/lib/google/cloud/storage/policy/bindings.rb +196 -0
- data/lib/google/cloud/storage/policy/condition.rb +136 -0
- data/lib/google/cloud/storage/service.rb +3 -3
- data/lib/google/cloud/storage/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a6c22c5d1bf15537e1a8d0b351074e67b32a9f77d70ae4febd9fac791ac1601
|
4
|
+
data.tar.gz: 3378d1c26298d5a6d985ca6b1c2f09f82e00f2303a6953b7b8ee0a077b3fa120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a3409354e221650f8893943755fd72050cd5cfa88960df584d98b9b57ad23ac5342a72857dd13528670ad93931514468e7f8b4dd29f537d4645ff3ca511adf7
|
7
|
+
data.tar.gz: 80cd7709621da535d303d2efd196ef4cddc97cd243d0a4f2400ffcd88cfc5ed113c21ca51ad9e928df1e81dd587b62859f220e90642dedfc761bc86251d1d3cd
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# Release History
|
2
2
|
|
3
|
+
### 1.25.0 / 2019-12-12
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* Add IAM Conditions support to Policy
|
8
|
+
|
3
9
|
### 1.24.0 / 2019-11-12
|
4
10
|
|
5
11
|
#### Features
|
@@ -8,7 +14,7 @@
|
|
8
14
|
|
9
15
|
#### Bug Fixes
|
10
16
|
|
11
|
-
* Update #post_object to support special variable
|
17
|
+
* Update #post_object to support special variable `${filename}`
|
12
18
|
|
13
19
|
### 1.23.0 / 2019-11-05
|
14
20
|
|
@@ -1747,6 +1747,26 @@ module Google
|
|
1747
1747
|
# @param [Boolean] force [Deprecated] Force the latest policy to be
|
1748
1748
|
# retrieved from the Storage service when `true`. Deprecated because
|
1749
1749
|
# the latest policy is now always retrieved. The default is `nil`.
|
1750
|
+
# @param [Integer] requested_policy_version The requested syntax schema
|
1751
|
+
# version of the policy. Optional. If `1`, `nil`, or not provided, a
|
1752
|
+
# {Google::Cloud::Storage::PolicyV1} object is returned, which
|
1753
|
+
# provides {Google::Cloud::Storage::PolicyV1#roles} and related
|
1754
|
+
# helpers but does not provide a `bindings` method. If `3` is
|
1755
|
+
# provided, a {Google::Cloud::Storage::PolicyV3} object is returned,
|
1756
|
+
# which provides {Google::Cloud::Storage::PolicyV3#bindings} but does
|
1757
|
+
# not provide a `roles` method or related helpers. A higher version
|
1758
|
+
# indicates that the policy contains role bindings with the newer
|
1759
|
+
# syntax schema that is unsupported by earlier versions.
|
1760
|
+
#
|
1761
|
+
# The following requested policy versions are valid:
|
1762
|
+
#
|
1763
|
+
# * 1 - The first version of Cloud IAM policy schema. Supports binding one
|
1764
|
+
# role to one or more members. Does not support conditional bindings.
|
1765
|
+
# * 3 - Introduces the condition field in the role binding, which further
|
1766
|
+
# constrains the role binding via context-based and attribute-based rules.
|
1767
|
+
# See [Understanding policies](https://cloud.google.com/iam/docs/policies)
|
1768
|
+
# and [Overview of Cloud IAM Conditions](https://cloud.google.com/iam/docs/conditions-overview)
|
1769
|
+
# for more information.
|
1750
1770
|
#
|
1751
1771
|
# @yield [policy] A block for updating the policy. The latest policy
|
1752
1772
|
# will be read from the service and passed to the block. After the
|
@@ -1756,31 +1776,98 @@ module Google
|
|
1756
1776
|
#
|
1757
1777
|
# @return [Policy] the current Cloud IAM Policy for this bucket
|
1758
1778
|
#
|
1759
|
-
# @example
|
1779
|
+
# @example Retrieving a Policy that is implicitly version 1:
|
1760
1780
|
# require "google/cloud/storage"
|
1761
1781
|
#
|
1762
1782
|
# storage = Google::Cloud::Storage.new
|
1763
|
-
#
|
1764
|
-
# bucket = storage.bucket "my-todo-app"
|
1783
|
+
# bucket = storage.bucket "my-bucket"
|
1765
1784
|
#
|
1766
1785
|
# policy = bucket.policy
|
1786
|
+
# policy.version # 1
|
1787
|
+
# puts policy.roles["roles/storage.objectViewer"]
|
1767
1788
|
#
|
1768
|
-
# @example
|
1789
|
+
# @example Retrieving a version 3 Policy using `requested_policy_version`:
|
1769
1790
|
# require "google/cloud/storage"
|
1770
1791
|
#
|
1771
1792
|
# storage = Google::Cloud::Storage.new
|
1793
|
+
# bucket = storage.bucket "my-bucket"
|
1772
1794
|
#
|
1773
|
-
#
|
1795
|
+
# policy = bucket.policy requested_policy_version: 3
|
1796
|
+
# policy.version # 3
|
1797
|
+
# puts policy.bindings.find do |b|
|
1798
|
+
# b[:role] == "roles/storage.objectViewer"
|
1799
|
+
# end
|
1800
|
+
#
|
1801
|
+
# @example Updating a Policy that is implicitly version 1:
|
1802
|
+
# require "google/cloud/storage"
|
1803
|
+
#
|
1804
|
+
# storage = Google::Cloud::Storage.new
|
1805
|
+
# bucket = storage.bucket "my-bucket"
|
1774
1806
|
#
|
1775
1807
|
# bucket.policy do |p|
|
1776
|
-
# p.
|
1808
|
+
# p.version # the value is 1
|
1809
|
+
# p.remove "roles/storage.admin", "user:owner@example.com"
|
1810
|
+
# p.add "roles/storage.admin", "user:newowner@example.com"
|
1811
|
+
# p.roles["roles/storage.objectViewer"] = ["allUsers"]
|
1812
|
+
# end
|
1813
|
+
#
|
1814
|
+
# @example Updating a Policy from version 1 to version 3 by adding a condition:
|
1815
|
+
# require "google/cloud/storage"
|
1816
|
+
#
|
1817
|
+
# storage = Google::Cloud::Storage.new
|
1818
|
+
# bucket = storage.bucket "my-bucket"
|
1819
|
+
#
|
1820
|
+
# bucket.uniform_bucket_level_access = true
|
1821
|
+
#
|
1822
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
1823
|
+
# p.version # the value is 1
|
1824
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
1825
|
+
#
|
1826
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
1827
|
+
# p.bindings.insert({
|
1828
|
+
# role: "roles/storage.admin",
|
1829
|
+
# members: ["user:owner@example.com"],
|
1830
|
+
# condition: {
|
1831
|
+
# title: "my-condition",
|
1832
|
+
# description: "description of condition",
|
1833
|
+
# expression: expr
|
1834
|
+
# }
|
1835
|
+
# })
|
1777
1836
|
# end
|
1778
1837
|
#
|
1779
|
-
|
1838
|
+
# @example Updating a version 3 Policy:
|
1839
|
+
# require "google/cloud/storage"
|
1840
|
+
#
|
1841
|
+
# storage = Google::Cloud::Storage.new
|
1842
|
+
# bucket = storage.bucket "my-bucket"
|
1843
|
+
#
|
1844
|
+
# bucket.uniform_bucket_level_access? # true
|
1845
|
+
#
|
1846
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
1847
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
1848
|
+
#
|
1849
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
1850
|
+
# p.bindings.insert({
|
1851
|
+
# role: "roles/storage.admin",
|
1852
|
+
# members: ["user:owner@example.com"],
|
1853
|
+
# condition: {
|
1854
|
+
# title: "my-condition",
|
1855
|
+
# description: "description of condition",
|
1856
|
+
# expression: expr
|
1857
|
+
# }
|
1858
|
+
# })
|
1859
|
+
# end
|
1860
|
+
#
|
1861
|
+
def policy force: nil, requested_policy_version: nil
|
1780
1862
|
warn "DEPRECATED: 'force' in Bucket#policy" unless force.nil?
|
1781
1863
|
ensure_service!
|
1782
|
-
gapi = service.get_bucket_policy name,
|
1783
|
-
|
1864
|
+
gapi = service.get_bucket_policy name, requested_policy_version: requested_policy_version,
|
1865
|
+
user_project: user_project
|
1866
|
+
policy = if requested_policy_version.nil? || requested_policy_version == 1
|
1867
|
+
PolicyV1.from_gapi gapi
|
1868
|
+
else
|
1869
|
+
PolicyV3.from_gapi gapi
|
1870
|
+
end
|
1784
1871
|
return policy unless block_given?
|
1785
1872
|
yield policy
|
1786
1873
|
update_policy policy
|
@@ -1805,24 +1892,70 @@ module Google
|
|
1805
1892
|
#
|
1806
1893
|
# @return [Policy] The policy returned by the API update operation.
|
1807
1894
|
#
|
1808
|
-
# @example
|
1895
|
+
# @example Updating a Policy that is implicitly version 1:
|
1809
1896
|
# require "google/cloud/storage"
|
1810
1897
|
#
|
1811
1898
|
# storage = Google::Cloud::Storage.new
|
1899
|
+
# bucket = storage.bucket "my-bucket"
|
1812
1900
|
#
|
1813
|
-
#
|
1901
|
+
# policy = bucket.policy
|
1902
|
+
# policy.version # 1
|
1903
|
+
# policy.remove "roles/storage.admin", "user:owner@example.com"
|
1904
|
+
# policy.add "roles/storage.admin", "user:newowner@example.com"
|
1905
|
+
# policy.roles["roles/storage.objectViewer"] = ["allUsers"]
|
1814
1906
|
#
|
1815
|
-
# policy = bucket.policy
|
1907
|
+
# policy = bucket.update_policy policy
|
1816
1908
|
#
|
1817
|
-
#
|
1909
|
+
# @example Updating a Policy from version 1 to version 3 by adding a condition:
|
1910
|
+
# require "google/cloud/storage"
|
1818
1911
|
#
|
1819
|
-
#
|
1912
|
+
# storage = Google::Cloud::Storage.new
|
1913
|
+
# bucket = storage.bucket "my-bucket"
|
1914
|
+
#
|
1915
|
+
# policy = bucket.policy requested_policy_version: 3
|
1916
|
+
# policy.version # 1
|
1917
|
+
# policy.version = 3
|
1918
|
+
#
|
1919
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
1920
|
+
# policy.bindings.insert({
|
1921
|
+
# role: "roles/storage.admin",
|
1922
|
+
# members: ["user:owner@example.com"],
|
1923
|
+
# condition: {
|
1924
|
+
# title: "my-condition",
|
1925
|
+
# description: "description of condition",
|
1926
|
+
# expression: expr
|
1927
|
+
# }
|
1928
|
+
# })
|
1929
|
+
#
|
1930
|
+
# policy = bucket.update_policy policy
|
1931
|
+
#
|
1932
|
+
# @example Updating a version 3 Policy:
|
1933
|
+
# require "google/cloud/storage"
|
1934
|
+
#
|
1935
|
+
# storage = Google::Cloud::Storage.new
|
1936
|
+
# bucket = storage.bucket "my-bucket"
|
1937
|
+
#
|
1938
|
+
# policy = bucket.policy requested_policy_version: 3
|
1939
|
+
# policy.version # 3 indicates an existing binding with a condition.
|
1940
|
+
#
|
1941
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
1942
|
+
# policy.bindings.insert({
|
1943
|
+
# role: "roles/storage.admin",
|
1944
|
+
# members: ["user:owner@example.com"],
|
1945
|
+
# condition: {
|
1946
|
+
# title: "my-condition",
|
1947
|
+
# description: "description of condition",
|
1948
|
+
# expression: expr
|
1949
|
+
# }
|
1950
|
+
# })
|
1951
|
+
#
|
1952
|
+
# policy = bucket.update_policy policy
|
1820
1953
|
#
|
1821
1954
|
def update_policy new_policy
|
1822
1955
|
ensure_service!
|
1823
1956
|
gapi = service.set_bucket_policy name, new_policy.to_gapi,
|
1824
1957
|
user_project: user_project
|
1825
|
-
|
1958
|
+
new_policy.class.from_gapi gapi
|
1826
1959
|
end
|
1827
1960
|
alias policy= update_policy
|
1828
1961
|
|
@@ -1845,7 +1978,7 @@ module Google
|
|
1845
1978
|
#
|
1846
1979
|
# storage = Google::Cloud::Storage.new
|
1847
1980
|
#
|
1848
|
-
# bucket = storage.bucket "my-
|
1981
|
+
# bucket = storage.bucket "my-bucket"
|
1849
1982
|
#
|
1850
1983
|
# permissions = bucket.test_permissions "storage.buckets.get",
|
1851
1984
|
# "storage.buckets.delete"
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
require "google/cloud/errors"
|
17
17
|
require "google/apis/storage_v1"
|
18
|
+
require "google/cloud/storage/policy/bindings"
|
18
19
|
|
19
20
|
module Google
|
20
21
|
module Cloud
|
@@ -22,7 +23,9 @@ module Google
|
|
22
23
|
##
|
23
24
|
# # Policy
|
24
25
|
#
|
25
|
-
#
|
26
|
+
# An abstract Cloud IAM Policy for the Cloud Storage service. See concrete
|
27
|
+
# subclasses {Google::Cloud::Storage::PolicyV1} and
|
28
|
+
# {Google::Cloud::Storage::PolicyV3}.
|
26
29
|
#
|
27
30
|
# A common pattern for updating a resource's metadata, such as its Policy,
|
28
31
|
# is to read the current data from the service, update the data locally,
|
@@ -49,8 +52,45 @@ module Google
|
|
49
52
|
# @attr [String] etag Used to verify whether the policy has changed since
|
50
53
|
# the last request. The policy will be written only if the `etag` values
|
51
54
|
# match.
|
52
|
-
# @attr [
|
53
|
-
#
|
55
|
+
# @attr [Integer] version The syntax schema version of the policy. Each version
|
56
|
+
# of the policy contains a specific syntax schema that can be used by bindings.
|
57
|
+
# The newer version may contain role bindings with the newer syntax schema
|
58
|
+
# that is unsupported by earlier versions. This field is not intended to
|
59
|
+
# be used for any purposes other than policy syntax schema control.
|
60
|
+
#
|
61
|
+
# The following policy versions are valid:
|
62
|
+
#
|
63
|
+
# * 1 - The first version of Cloud IAM policy schema. Supports binding one
|
64
|
+
# role to one or more members. Does not support conditional bindings.
|
65
|
+
# * 3 - Introduces the condition field in the role binding, which further
|
66
|
+
# constrains the role binding via context-based and attribute-based rules.
|
67
|
+
# See [Understanding policies](https://cloud.google.com/iam/docs/policies)
|
68
|
+
# and [Overview of Cloud IAM Conditions](https://cloud.google.com/iam/docs/conditions-overview)
|
69
|
+
# for more information.
|
70
|
+
#
|
71
|
+
class Policy
|
72
|
+
attr_reader :etag
|
73
|
+
attr_reader :version
|
74
|
+
|
75
|
+
##
|
76
|
+
# @private Creates a Policy object.
|
77
|
+
def initialize etag, version
|
78
|
+
@etag = etag
|
79
|
+
@version = version
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# A subclass of {Google::Cloud::Storage::Policy} that supports access to {#roles}
|
85
|
+
# and related helpers. Attempts to call {#bindings} and {#version=} will
|
86
|
+
# raise a runtime error. To update the Policy version and add bindings with a newer
|
87
|
+
# syntax, use {Google::Cloud::Storage::PolicyV3} instead by calling
|
88
|
+
# {Google::Cloud::Storage::Bucket#policy} with `requested_policy_version: 3`. To
|
89
|
+
# obtain instances of this class, call {Google::Cloud::Storage::Bucket#policy}
|
90
|
+
# without the `requested_policy_version` keyword argument.
|
91
|
+
#
|
92
|
+
# @attr [Hash] roles Returns the version 1 bindings (no conditions) as a hash that
|
93
|
+
# associates roles with arrays of members. See [Understanding
|
54
94
|
# Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
|
55
95
|
# listing of primitive and curated roles. See [Buckets:
|
56
96
|
# setIamPolicy](https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy)
|
@@ -60,22 +100,22 @@ module Google
|
|
60
100
|
# require "google/cloud/storage"
|
61
101
|
#
|
62
102
|
# storage = Google::Cloud::Storage.new
|
63
|
-
#
|
64
|
-
# bucket = storage.bucket "my-todo-app"
|
103
|
+
# bucket = storage.bucket "my-bucket"
|
65
104
|
#
|
66
105
|
# bucket.policy do |p|
|
106
|
+
# p.version # the value is 1
|
67
107
|
# p.remove "roles/storage.admin", "user:owner@example.com"
|
68
108
|
# p.add "roles/storage.admin", "user:newowner@example.com"
|
69
109
|
# p.roles["roles/storage.objectViewer"] = ["allUsers"]
|
70
110
|
# end
|
71
111
|
#
|
72
|
-
class Policy
|
73
|
-
attr_reader :
|
112
|
+
class PolicyV1 < Policy
|
113
|
+
attr_reader :roles
|
74
114
|
|
75
115
|
##
|
76
|
-
# @private Creates a
|
77
|
-
def initialize etag, roles
|
78
|
-
|
116
|
+
# @private Creates a PolicyV1 object.
|
117
|
+
def initialize etag, version, roles
|
118
|
+
super etag, version
|
79
119
|
@roles = roles
|
80
120
|
end
|
81
121
|
|
@@ -97,7 +137,7 @@ module Google
|
|
97
137
|
#
|
98
138
|
# storage = Google::Cloud::Storage.new
|
99
139
|
#
|
100
|
-
# bucket = storage.bucket "my-
|
140
|
+
# bucket = storage.bucket "my-bucket"
|
101
141
|
#
|
102
142
|
# bucket.policy do |p|
|
103
143
|
# p.add "roles/storage.admin", "user:newowner@example.com"
|
@@ -125,7 +165,7 @@ module Google
|
|
125
165
|
#
|
126
166
|
# storage = Google::Cloud::Storage.new
|
127
167
|
#
|
128
|
-
# bucket = storage.bucket "my-
|
168
|
+
# bucket = storage.bucket "my-bucket"
|
129
169
|
#
|
130
170
|
# bucket.policy do |p|
|
131
171
|
# p.remove "roles/storage.admin", "user:owner@example.com"
|
@@ -151,7 +191,7 @@ module Google
|
|
151
191
|
#
|
152
192
|
# storage = Google::Cloud::Storage.new
|
153
193
|
#
|
154
|
-
# bucket = storage.bucket "my-
|
194
|
+
# bucket = storage.bucket "my-bucket"
|
155
195
|
#
|
156
196
|
# bucket.policy do |p|
|
157
197
|
# p.role("roles/storage.admin") << "user:owner@example.com"
|
@@ -170,7 +210,7 @@ module Google
|
|
170
210
|
# @return [Policy]
|
171
211
|
#
|
172
212
|
def deep_dup
|
173
|
-
warn "DEPRECATED: Storage::
|
213
|
+
warn "DEPRECATED: Storage::PolicyV1#deep_dup"
|
174
214
|
dup.tap do |p|
|
175
215
|
roles_dup = p.roles.each_with_object({}) do |(k, v), memo|
|
176
216
|
memo[k] = v.dup rescue value
|
@@ -179,19 +219,32 @@ module Google
|
|
179
219
|
end
|
180
220
|
end
|
181
221
|
|
222
|
+
##
|
223
|
+
# @private Illegal operation in PolicyV1. Use {#roles} instead.
|
224
|
+
#
|
225
|
+
# @raise [RuntimeError] If called on this class.
|
226
|
+
#
|
227
|
+
def bindings
|
228
|
+
raise "Illegal operation unless using PolicyV3. Use #roles instead."
|
229
|
+
end
|
230
|
+
|
231
|
+
##
|
232
|
+
# @private Illegal operation in PolicyV1. Use {Google::Cloud::Storage::PolicyV3#version=} instead.
|
233
|
+
#
|
234
|
+
# @raise [RuntimeError] If called on this class.
|
235
|
+
#
|
236
|
+
def version=(*)
|
237
|
+
raise "Illegal operation unless using PolicyV3."
|
238
|
+
end
|
239
|
+
|
182
240
|
##
|
183
241
|
# @private Convert the Policy to a
|
184
242
|
# Google::Apis::StorageV1::Policy.
|
185
243
|
def to_gapi
|
186
244
|
Google::Apis::StorageV1::Policy.new(
|
187
245
|
etag: etag,
|
188
|
-
|
189
|
-
|
190
|
-
Google::Apis::StorageV1::Policy::Binding.new(
|
191
|
-
role: role_name,
|
192
|
-
members: roles[role_name].uniq
|
193
|
-
)
|
194
|
-
end
|
246
|
+
version: version,
|
247
|
+
bindings: roles_to_gapi
|
195
248
|
)
|
196
249
|
end
|
197
250
|
|
@@ -202,7 +255,207 @@ module Google
|
|
202
255
|
roles = Array(gapi.bindings).each_with_object({}) do |binding, memo|
|
203
256
|
memo[binding.role] = binding.members.to_a
|
204
257
|
end
|
205
|
-
new gapi.etag, roles
|
258
|
+
new gapi.etag, gapi.version, roles
|
259
|
+
end
|
260
|
+
|
261
|
+
protected
|
262
|
+
|
263
|
+
def roles_to_gapi
|
264
|
+
roles.keys.map do |role_name|
|
265
|
+
next if roles[role_name].empty?
|
266
|
+
Google::Apis::StorageV1::Policy::Binding.new(
|
267
|
+
role: role_name,
|
268
|
+
members: roles[role_name].uniq
|
269
|
+
)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
##
|
275
|
+
# A subclass of {Google::Cloud::Storage::Policy} that supports access to {#bindings}
|
276
|
+
# and {version=}. Attempts to call {#roles} and relate helpers will raise a runtime
|
277
|
+
# error. This class may be used to update the Policy version and add bindings with a newer
|
278
|
+
# syntax. To obtain instances of this class, call {Google::Cloud::Storage::Bucket#policy}
|
279
|
+
# with `requested_policy_version: 3`.
|
280
|
+
#
|
281
|
+
# @attr [Bindings] bindings Returns the Policy's bindings object that associate roles with
|
282
|
+
# an array of members. Conditions can be configured on the {Binding} object. See
|
283
|
+
# [Understanding Roles](https://cloud.google.com/iam/docs/understanding-roles) for a
|
284
|
+
# listing of primitive and curated roles. See [Buckets:
|
285
|
+
# setIamPolicy](https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy)
|
286
|
+
# for a listing of values and patterns for members.
|
287
|
+
#
|
288
|
+
# @example Updating Policy version 1 to version 3:
|
289
|
+
# require "google/cloud/storage"
|
290
|
+
#
|
291
|
+
# storage = Google::Cloud::Storage.new
|
292
|
+
# bucket = storage.bucket "my-bucket"
|
293
|
+
#
|
294
|
+
# bucket.uniform_bucket_level_access = true
|
295
|
+
#
|
296
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
297
|
+
# p.version # the value is 1
|
298
|
+
# p.version = 3
|
299
|
+
#
|
300
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
301
|
+
# p.bindings.insert({
|
302
|
+
# role: "roles/storage.admin",
|
303
|
+
# members: ["user:owner@example.com"],
|
304
|
+
# condition: {
|
305
|
+
# title: "my-condition",
|
306
|
+
# description: "description of condition",
|
307
|
+
# expression: expr
|
308
|
+
# }
|
309
|
+
# })
|
310
|
+
# end
|
311
|
+
#
|
312
|
+
# @example Using Policy version 3:
|
313
|
+
# require "google/cloud/storage"
|
314
|
+
#
|
315
|
+
# storage = Google::Cloud::Storage.new
|
316
|
+
# bucket = storage.bucket "my-bucket"
|
317
|
+
#
|
318
|
+
# bucket.uniform_bucket_level_access? # true
|
319
|
+
#
|
320
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
321
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
322
|
+
#
|
323
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
324
|
+
# p.bindings.insert({
|
325
|
+
# role: "roles/storage.admin",
|
326
|
+
# members: ["user:owner@example.com"],
|
327
|
+
# condition: {
|
328
|
+
# title: "my-condition",
|
329
|
+
# description: "description of condition",
|
330
|
+
# expression: expr
|
331
|
+
# }
|
332
|
+
# })
|
333
|
+
# end
|
334
|
+
#
|
335
|
+
class PolicyV3 < Policy
|
336
|
+
attr_reader :bindings
|
337
|
+
|
338
|
+
##
|
339
|
+
# @private Creates a PolicyV3 object.
|
340
|
+
def initialize etag, version, bindings
|
341
|
+
super etag, version
|
342
|
+
@bindings = Bindings.new
|
343
|
+
@bindings.insert(*bindings)
|
344
|
+
end
|
345
|
+
|
346
|
+
##
|
347
|
+
# Updates the syntax schema version of the policy. Each version of the
|
348
|
+
# policy contains a specific syntax schema that can be used by bindings.
|
349
|
+
# The newer version may contain role bindings with the newer syntax schema
|
350
|
+
# that is unsupported by earlier versions. This field is not intended to
|
351
|
+
# be used for any purposes other than policy syntax schema control.
|
352
|
+
#
|
353
|
+
# The following policy versions are valid:
|
354
|
+
#
|
355
|
+
# * 1 - The first version of Cloud IAM policy schema. Supports binding one
|
356
|
+
# role to one or more members. Does not support conditional bindings.
|
357
|
+
# * 3 - Introduces the condition field in the role binding, which further
|
358
|
+
# constrains the role binding via context-based and attribute-based rules.
|
359
|
+
# See [Understanding policies](https://cloud.google.com/iam/docs/policies)
|
360
|
+
# and [Overview of Cloud IAM Conditions](https://cloud.google.com/iam/docs/conditions-overview)
|
361
|
+
# for more information.
|
362
|
+
#
|
363
|
+
# @param [Integer] new_version The syntax schema version of the policy.
|
364
|
+
#
|
365
|
+
# @see https://cloud.google.com/iam/docs/policies#versions Policy versions
|
366
|
+
#
|
367
|
+
# @example Updating Policy version 1 to version 3:
|
368
|
+
# require "google/cloud/storage"
|
369
|
+
#
|
370
|
+
# storage = Google::Cloud::Storage.new
|
371
|
+
# bucket = storage.bucket "my-bucket"
|
372
|
+
#
|
373
|
+
# bucket.uniform_bucket_level_access = true
|
374
|
+
#
|
375
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
376
|
+
# p.version # the value is 1
|
377
|
+
# p.version = 3
|
378
|
+
#
|
379
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
380
|
+
# p.bindings.insert({
|
381
|
+
# role: "roles/storage.admin",
|
382
|
+
# members: ["user:owner@example.com"],
|
383
|
+
# condition: {
|
384
|
+
# title: "my-condition",
|
385
|
+
# description: "description of condition",
|
386
|
+
# expression: expr
|
387
|
+
# }
|
388
|
+
# })
|
389
|
+
# end
|
390
|
+
#
|
391
|
+
def version= new_version
|
392
|
+
if new_version < version
|
393
|
+
raise "new_version (#{new_version}) cannot be less than the current version (#{version})."
|
394
|
+
end
|
395
|
+
@version = new_version
|
396
|
+
end
|
397
|
+
|
398
|
+
##
|
399
|
+
# @private Illegal operation in PolicyV3. Use {#bindings} instead.
|
400
|
+
#
|
401
|
+
# @raise [RuntimeError] If called on this class.
|
402
|
+
#
|
403
|
+
def roles
|
404
|
+
raise "Illegal operation when using PolicyV1. Use Policy#bindings instead."
|
405
|
+
end
|
406
|
+
|
407
|
+
##
|
408
|
+
# @private Illegal operation in PolicyV3. Use {#bindings} instead.
|
409
|
+
#
|
410
|
+
# @raise [RuntimeError] If called on this class.
|
411
|
+
#
|
412
|
+
def add(*)
|
413
|
+
raise "Illegal operation when using PolicyV1. Use Policy#bindings instead."
|
414
|
+
end
|
415
|
+
|
416
|
+
##
|
417
|
+
# @private Illegal operation in PolicyV3. Use {#bindings} instead.
|
418
|
+
#
|
419
|
+
# @raise [RuntimeError] If called on this class.
|
420
|
+
#
|
421
|
+
def remove(*)
|
422
|
+
raise "Illegal operation when using PolicyV1. Use Policy#bindings instead."
|
423
|
+
end
|
424
|
+
|
425
|
+
##
|
426
|
+
# @private Illegal operation in PolicyV3. Use {#bindings} instead.
|
427
|
+
#
|
428
|
+
# @raise [RuntimeError] If called on this class.
|
429
|
+
#
|
430
|
+
def role(*)
|
431
|
+
raise "Illegal operation when using PolicyV1. Use Policy#bindings instead."
|
432
|
+
end
|
433
|
+
|
434
|
+
##
|
435
|
+
# @private Illegal operation in PolicyV3. Deprecated in PolicyV1.
|
436
|
+
#
|
437
|
+
# @raise [RuntimeError] If called on this class.
|
438
|
+
#
|
439
|
+
def deep_dup
|
440
|
+
raise "Illegal operation when using PolicyV3. Deprecated in PolicyV1."
|
441
|
+
end
|
442
|
+
|
443
|
+
##
|
444
|
+
# @private Convert the PolicyV3 to a
|
445
|
+
# Google::Apis::StorageV1::Policy.
|
446
|
+
def to_gapi
|
447
|
+
Google::Apis::StorageV1::Policy.new(
|
448
|
+
etag: etag,
|
449
|
+
version: version,
|
450
|
+
bindings: bindings.to_gapi
|
451
|
+
)
|
452
|
+
end
|
453
|
+
|
454
|
+
##
|
455
|
+
# @private New Policy from a
|
456
|
+
# Google::Apis::StorageV1::Policy object.
|
457
|
+
def self.from_gapi gapi
|
458
|
+
new gapi.etag, gapi.version, Array(gapi.bindings).map(&:to_h)
|
206
459
|
end
|
207
460
|
end
|
208
461
|
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# Copyright 2019 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
|
+
# https://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
|
+
|
16
|
+
require "google/cloud/storage/policy/condition"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Storage
|
21
|
+
class Policy
|
22
|
+
##
|
23
|
+
# # Binding
|
24
|
+
#
|
25
|
+
# Value object associating members and an optional condition with a role.
|
26
|
+
#
|
27
|
+
# @see https://cloud.google.com/iam/docs/overview Cloud IAM Overview
|
28
|
+
#
|
29
|
+
# @attr [String] role Role that is assigned to members. For example,
|
30
|
+
# `roles/viewer`, `roles/editor`, or `roles/owner`. Required.
|
31
|
+
# @attr [Array<String>] members Specifies the identities requesting
|
32
|
+
# access for a Cloud Platform resource. members can have the
|
33
|
+
# following values. Required.
|
34
|
+
#
|
35
|
+
# * `allUsers`: A special identifier that represents anyone who is on
|
36
|
+
# the internet; with or without a Google account.
|
37
|
+
# * `allAuthenticatedUsers`: A special identifier that represents
|
38
|
+
# anyone who is authenticated with a Google account or a service
|
39
|
+
# account.
|
40
|
+
# * `user:{emailid}`: An email address that represents a specific
|
41
|
+
# Google account. For example, `alice@example.com`.
|
42
|
+
# * `serviceAccount:{emailid}`: An email address that represents a
|
43
|
+
# service account. For example, `my-other-app@appspot.gserviceaccount.com`.
|
44
|
+
# * `group:{emailid}`: An email address that represents a Google group.
|
45
|
+
# For example, `admins@example.com`.
|
46
|
+
# * `domain:{domain}`: The G Suite domain (primary) that represents
|
47
|
+
# all the users of that domain. For example, `google.com` or
|
48
|
+
# `example.com`. Required.
|
49
|
+
#
|
50
|
+
# @attr [Google::Cloud::Storage::Policy::Condition, nil] condition The
|
51
|
+
# condition that is associated with this binding, or `nil` if there is
|
52
|
+
# no condition. NOTE: An unsatisfied condition will not allow user
|
53
|
+
# access via current binding. Different bindings, including their
|
54
|
+
# conditions, are examined independently.
|
55
|
+
#
|
56
|
+
# @example
|
57
|
+
# require "google/cloud/storage"
|
58
|
+
#
|
59
|
+
# storage = Google::Cloud::Storage.new
|
60
|
+
# bucket = storage.bucket "my-bucket"
|
61
|
+
#
|
62
|
+
# policy = bucket.policy requested_policy_version: 3
|
63
|
+
# policy.bindings.each do |binding|
|
64
|
+
# puts binding.role
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# @example Updating a Policy from version 1 to version 3:
|
68
|
+
# require "google/cloud/storage"
|
69
|
+
#
|
70
|
+
# storage = Google::Cloud::Storage.new
|
71
|
+
# bucket = storage.bucket "my-bucket"
|
72
|
+
#
|
73
|
+
# bucket.uniform_bucket_level_access = true
|
74
|
+
#
|
75
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
76
|
+
# p.version # the value is 1
|
77
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
78
|
+
#
|
79
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
80
|
+
# p.bindings.insert({
|
81
|
+
# role: "roles/storage.admin",
|
82
|
+
# members: ["user:owner@example.com"],
|
83
|
+
# condition: {
|
84
|
+
# title: "my-condition",
|
85
|
+
# description: "description of condition",
|
86
|
+
# expression: expr
|
87
|
+
# }
|
88
|
+
# })
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
class Binding
|
92
|
+
attr_reader :role, :members, :condition
|
93
|
+
|
94
|
+
##
|
95
|
+
# Creates a Binding object.
|
96
|
+
#
|
97
|
+
# @param [String] role Role that is assigned to members. For example,
|
98
|
+
# `roles/viewer`, `roles/editor`, or `roles/owner`. Required.
|
99
|
+
# @param [Array<String>] members Specifies the identities requesting
|
100
|
+
# access for a Cloud Platform resource. members can have the
|
101
|
+
# following values. Required.
|
102
|
+
#
|
103
|
+
# * `allUsers`: A special identifier that represents anyone who is on
|
104
|
+
# the internet; with or without a Google account.
|
105
|
+
# * `allAuthenticatedUsers`: A special identifier that represents
|
106
|
+
# anyone who is authenticated with a Google account or a service
|
107
|
+
# account.
|
108
|
+
# * `user:{emailid}`: An email address that represents a specific
|
109
|
+
# Google account. For example, `alice@example.com`.
|
110
|
+
# * `serviceAccount:{emailid}`: An email address that represents a
|
111
|
+
# service account. For example, `my-other-app@appspot.gserviceaccount.com`.
|
112
|
+
# * `group:{emailid}`: An email address that represents a Google group.
|
113
|
+
# For example, `admins@example.com`.
|
114
|
+
# * `domain:{domain}`: The G Suite domain (primary) that represents
|
115
|
+
# all the users of that domain. For example, `google.com` or
|
116
|
+
# `example.com`. Required.
|
117
|
+
#
|
118
|
+
# @param [Google::Cloud::Storage::Policy::Condition] condition The
|
119
|
+
# condition that is associated with this binding. NOTE: An unsatisfied
|
120
|
+
# condition will not allow user access via current binding. Different
|
121
|
+
# bindings, including their conditions, are examined independently.
|
122
|
+
# Optional.
|
123
|
+
#
|
124
|
+
def initialize role:, members:, condition: nil
|
125
|
+
@role = String role
|
126
|
+
|
127
|
+
@members = Array members
|
128
|
+
raise ArgumentError, "members is empty, must be provided" if @members.empty?
|
129
|
+
|
130
|
+
condition = Condition.new(**condition) if condition.is_a? Hash
|
131
|
+
if condition
|
132
|
+
raise ArgumentError, "expected Condition, not #{condition.inspect}" unless condition.is_a? Condition
|
133
|
+
end
|
134
|
+
@condition = condition
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Sets the role for the binding.
|
139
|
+
#
|
140
|
+
# @param [String] new_role Role that is assigned to members. For example,
|
141
|
+
# `roles/viewer`, `roles/editor`, or `roles/owner`. Required.
|
142
|
+
#
|
143
|
+
def role= new_role
|
144
|
+
@role = String new_role
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Sets the members for the binding.
|
149
|
+
#
|
150
|
+
# @param [Array<String>] new_members Specifies the identities requesting
|
151
|
+
# access for a Cloud Platform resource. members can have the
|
152
|
+
# following values. Required.
|
153
|
+
#
|
154
|
+
# * `allUsers`: A special identifier that represents anyone who is on
|
155
|
+
# the internet; with or without a Google account.
|
156
|
+
# * `allAuthenticatedUsers`: A special identifier that represents
|
157
|
+
# anyone who is authenticated with a Google account or a service
|
158
|
+
# account.
|
159
|
+
# * `user:{emailid}`: An email address that represents a specific
|
160
|
+
# Google account. For example, `alice@example.com`.
|
161
|
+
# * `serviceAccount:{emailid}`: An email address that represents a
|
162
|
+
# service account. For example, `my-other-app@appspot.gserviceaccount.com`.
|
163
|
+
# * `group:{emailid}`: An email address that represents a Google group.
|
164
|
+
# For example, `admins@example.com`.
|
165
|
+
# * `domain:{domain}`: The G Suite domain (primary) that represents
|
166
|
+
# all the users of that domain. For example, `google.com` or
|
167
|
+
# `example.com`. Required.
|
168
|
+
#
|
169
|
+
def members= new_members
|
170
|
+
new_members = Array new_members
|
171
|
+
raise ArgumentError, "members is empty, must be provided" if new_members.empty?
|
172
|
+
@members = new_members
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Sets the condition for the binding.
|
177
|
+
#
|
178
|
+
# @param [Google::Cloud::Storage::Policy::Condition] new_condition The
|
179
|
+
# condition that is associated with this binding. NOTE: An unsatisfied
|
180
|
+
# condition will not allow user access via current binding. Different
|
181
|
+
# bindings, including their conditions, are examined independently.
|
182
|
+
# Optional.
|
183
|
+
# @overload condition=(title:, description: nil, expression:)
|
184
|
+
# @param [String] title Used to identify the condition. Required.
|
185
|
+
# @param [String] description Used to document the condition. Optional.
|
186
|
+
# @param [String] expression Defines an attribute-based logic
|
187
|
+
# expression using a subset of the Common Expression Language (CEL).
|
188
|
+
# The condition expression can contain multiple statements, each uses
|
189
|
+
# one attributes, and statements are combined using logic operators,
|
190
|
+
# following CEL language specification. Required.
|
191
|
+
#
|
192
|
+
def condition= new_condition
|
193
|
+
new_condition = Condition.new(**new_condition) if new_condition.is_a? Hash
|
194
|
+
if new_condition && !new_condition.is_a?(Condition)
|
195
|
+
raise ArgumentError, "expected Condition, not #{new_condition.inspect}"
|
196
|
+
end
|
197
|
+
@condition = new_condition
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# @private
|
202
|
+
def <=> other
|
203
|
+
return nil unless other.is_a? Binding
|
204
|
+
|
205
|
+
ret = role <=> other.role
|
206
|
+
return ret unless ret.zero?
|
207
|
+
ret = members <=> other.members
|
208
|
+
return ret unless ret.zero?
|
209
|
+
condition&.to_gapi <=> other.condition&.to_gapi
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# @private
|
214
|
+
def eql? other
|
215
|
+
role.eql?(other.role) &&
|
216
|
+
members.eql?(other.members) &&
|
217
|
+
condition&.to_gapi.eql?(other.condition&.to_gapi)
|
218
|
+
end
|
219
|
+
|
220
|
+
##
|
221
|
+
# @private
|
222
|
+
def hash
|
223
|
+
[
|
224
|
+
@role,
|
225
|
+
@members,
|
226
|
+
@condition&.to_gapi
|
227
|
+
].hash
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# @private
|
232
|
+
def to_gapi
|
233
|
+
Google::Apis::StorageV1::Policy::Binding.new({
|
234
|
+
role: @role,
|
235
|
+
members: @members,
|
236
|
+
condition: @condition&.to_gapi
|
237
|
+
}.delete_if { |_, v| v.nil? })
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# Copyright 2019 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
|
+
# https://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
|
+
|
16
|
+
require "google/cloud/storage/policy/binding"
|
17
|
+
|
18
|
+
module Google
|
19
|
+
module Cloud
|
20
|
+
module Storage
|
21
|
+
class Policy
|
22
|
+
##
|
23
|
+
# # Bindings
|
24
|
+
#
|
25
|
+
# Enumerable object for managing Cloud IAM bindings associated with
|
26
|
+
# a bucket.
|
27
|
+
#
|
28
|
+
# @see https://cloud.google.com/iam/docs/overview Cloud IAM Overview
|
29
|
+
#
|
30
|
+
# @example Updating a Policy from version 1 to version 3:
|
31
|
+
# require "google/cloud/storage"
|
32
|
+
#
|
33
|
+
# storage = Google::Cloud::Storage.new
|
34
|
+
# bucket = storage.bucket "my-bucket"
|
35
|
+
#
|
36
|
+
# bucket.uniform_bucket_level_access = true
|
37
|
+
#
|
38
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
39
|
+
# p.version # the value is 1
|
40
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
41
|
+
#
|
42
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
43
|
+
# p.bindings.insert({
|
44
|
+
# role: "roles/storage.admin",
|
45
|
+
# members: ["user:owner@example.com"],
|
46
|
+
# condition: {
|
47
|
+
# title: "my-condition",
|
48
|
+
# description: "description of condition",
|
49
|
+
# expression: expr
|
50
|
+
# }
|
51
|
+
# })
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
class Bindings
|
55
|
+
include Enumerable
|
56
|
+
|
57
|
+
##
|
58
|
+
# @private Creates a Bindings object.
|
59
|
+
def initialize
|
60
|
+
@bindings = []
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Adds a binding or bindings to the collection. The arguments may be
|
65
|
+
# {Google::Cloud::Storage::Policy::Binding} objects or equivalent hash
|
66
|
+
# objects that will be implicitly coerced to binding objects.
|
67
|
+
#
|
68
|
+
# @param [Google::Cloud::Storage::Policy::Binding, Hash] bindings One
|
69
|
+
# or more bindings to be added to the policy owning the collection.
|
70
|
+
# The arguments may be {Google::Cloud::Storage::Policy::Binding}
|
71
|
+
# objects or equivalent hash objects that will be implicitly coerced
|
72
|
+
# to binding objects.
|
73
|
+
#
|
74
|
+
# @return [Bindings] `self` for chaining.
|
75
|
+
#
|
76
|
+
# @example Updating a Policy from version 1 to version 3:
|
77
|
+
# require "google/cloud/storage"
|
78
|
+
#
|
79
|
+
# storage = Google::Cloud::Storage.new
|
80
|
+
# bucket = storage.bucket "my-bucket"
|
81
|
+
#
|
82
|
+
# bucket.uniform_bucket_level_access = true
|
83
|
+
#
|
84
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
85
|
+
# p.version # the value is 1
|
86
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
87
|
+
#
|
88
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
89
|
+
# p.bindings.insert({
|
90
|
+
# role: "roles/storage.admin",
|
91
|
+
# members: ["user:owner@example.com"],
|
92
|
+
# condition: {
|
93
|
+
# title: "my-condition",
|
94
|
+
# description: "description of condition",
|
95
|
+
# expression: expr
|
96
|
+
# }
|
97
|
+
# })
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
def insert *bindings
|
101
|
+
bindings = coerce_bindings(*bindings)
|
102
|
+
@bindings += bindings
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Deletes the binding or bindings from the collection that are equal to
|
108
|
+
# the arguments. The specification arguments may be
|
109
|
+
# {Google::Cloud::Storage::Policy::Binding} objects or equivalent hash
|
110
|
+
# objects that will be implicitly coerced to binding objects.
|
111
|
+
#
|
112
|
+
# @param [Google::Cloud::Storage::Policy::Binding, Hash] bindings One
|
113
|
+
# or more specifications for bindings to be removed from the
|
114
|
+
# collection. The arguments may be
|
115
|
+
# {Google::Cloud::Storage::Policy::Binding} objects or equivalent
|
116
|
+
# hash objects that will be implicitly coerced to binding objects.
|
117
|
+
#
|
118
|
+
# @return [Bindings] `self` for chaining.
|
119
|
+
#
|
120
|
+
# @example
|
121
|
+
# require "google/cloud/storage"
|
122
|
+
#
|
123
|
+
# storage = Google::Cloud::Storage.new
|
124
|
+
# bucket = storage.bucket "my-bucket"
|
125
|
+
#
|
126
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
127
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
128
|
+
# p.bindings.remove({
|
129
|
+
# role: "roles/storage.admin",
|
130
|
+
# members: ["user:owner@example.com"],
|
131
|
+
# condition: {
|
132
|
+
# title: "my-condition",
|
133
|
+
# description: "description of condition",
|
134
|
+
# expression: expr
|
135
|
+
# }
|
136
|
+
# })
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
def remove *bindings
|
140
|
+
bindings = coerce_bindings(*bindings)
|
141
|
+
@bindings -= bindings
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Calls the block once for each binding in the collection, passing
|
147
|
+
# a {Google::Cloud::Storage::Policy::Binding} object as parameter. A
|
148
|
+
# {Google::Cloud::Storage::Policy::Binding} object is passed even
|
149
|
+
# when the arguments to {#insert} were hash objects.
|
150
|
+
#
|
151
|
+
# If no block is given, an enumerator is returned instead.
|
152
|
+
#
|
153
|
+
# @yield [binding] A binding in this bindings collection.
|
154
|
+
# @yieldparam [Google::Cloud::Storage::Policy::Binding] binding A
|
155
|
+
# binding object, even when the arguments to {#insert} were hash
|
156
|
+
# objects.
|
157
|
+
#
|
158
|
+
# @return [Enumerator]
|
159
|
+
#
|
160
|
+
# @example
|
161
|
+
# require "google/cloud/storage"
|
162
|
+
#
|
163
|
+
# storage = Google::Cloud::Storage.new
|
164
|
+
# bucket = storage.bucket "my-bucket"
|
165
|
+
#
|
166
|
+
# policy = bucket.policy requested_policy_version: 3
|
167
|
+
# policy.bindings.each do |binding|
|
168
|
+
# puts binding.role
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
def each
|
172
|
+
return enum_for :each unless block_given?
|
173
|
+
|
174
|
+
@bindings.each { |binding| yield binding }
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# @private
|
179
|
+
def to_gapi
|
180
|
+
@bindings.map(&:to_gapi)
|
181
|
+
end
|
182
|
+
|
183
|
+
protected
|
184
|
+
|
185
|
+
def coerce_bindings *bindings
|
186
|
+
bindings.map do |binding|
|
187
|
+
binding = Binding.new(**binding) if binding.is_a? Hash
|
188
|
+
raise ArgumentError, "expected Binding, not #{binding.inspect}" unless binding.is_a? Binding
|
189
|
+
binding
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# Copyright 2019 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
|
+
# https://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
|
+
|
16
|
+
module Google
|
17
|
+
module Cloud
|
18
|
+
module Storage
|
19
|
+
class Policy
|
20
|
+
##
|
21
|
+
# # Condition
|
22
|
+
#
|
23
|
+
# Value object accepting an attribute-based logic expression based on a
|
24
|
+
# subset of the Common Expression Language (CEL).
|
25
|
+
#
|
26
|
+
# @see https://cloud.google.com/iam/docs/conditions-overview Cloud IAM
|
27
|
+
# policies with conditions
|
28
|
+
#
|
29
|
+
# @attr [String] title Used to identify the condition. Required.
|
30
|
+
# @attr [String] description Used to document the condition. Optional.
|
31
|
+
# @attr [String] expression Defines an attribute-based logic
|
32
|
+
# expression using a subset of the Common Expression Language (CEL).
|
33
|
+
# The condition expression can contain multiple statements, each uses
|
34
|
+
# one attributes, and statements are combined using logic operators,
|
35
|
+
# following CEL language specification. Required.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# require "google/cloud/storage"
|
39
|
+
#
|
40
|
+
# storage = Google::Cloud::Storage.new
|
41
|
+
# bucket = storage.bucket "my-bucket"
|
42
|
+
#
|
43
|
+
# policy = bucket.policy requested_policy_version: 3
|
44
|
+
# policy.bindings.each do |binding|
|
45
|
+
# puts binding.condition.title if binding.condition
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @example Updating a Policy from version 1 to version 3 by adding a condition:
|
49
|
+
# require "google/cloud/storage"
|
50
|
+
#
|
51
|
+
# storage = Google::Cloud::Storage.new
|
52
|
+
# bucket = storage.bucket "my-bucket"
|
53
|
+
#
|
54
|
+
# bucket.uniform_bucket_level_access = true
|
55
|
+
#
|
56
|
+
# bucket.policy requested_policy_version: 3 do |p|
|
57
|
+
# p.version # the value is 1
|
58
|
+
# p.version = 3 # Must be explicitly set to opt-in to support for conditions.
|
59
|
+
#
|
60
|
+
# expr = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")"
|
61
|
+
# p.bindings.insert({
|
62
|
+
# role: "roles/storage.admin",
|
63
|
+
# members: ["user:owner@example.com"],
|
64
|
+
# condition: {
|
65
|
+
# title: "my-condition",
|
66
|
+
# description: "description of condition",
|
67
|
+
# expression: expr
|
68
|
+
# }
|
69
|
+
# })
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
class Condition
|
73
|
+
attr_reader :title, :description, :expression
|
74
|
+
|
75
|
+
##
|
76
|
+
# Creates a Condition object.
|
77
|
+
#
|
78
|
+
# @param [String] title Used to identify the condition. Required.
|
79
|
+
# @param [String] description Used to document the condition. Optional.
|
80
|
+
# @param [String] expression Defines an attribute-based logic
|
81
|
+
# expression using a subset of the Common Expression Language (CEL).
|
82
|
+
# The condition expression can contain multiple statements, each uses
|
83
|
+
# one attributes, and statements are combined using logic operators,
|
84
|
+
# following CEL language specification. Required.
|
85
|
+
#
|
86
|
+
def initialize title:, description: nil, expression:
|
87
|
+
@title = String title
|
88
|
+
@description = String description
|
89
|
+
@expression = String expression
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# The title used to identify the condition. Required.
|
94
|
+
#
|
95
|
+
# @param [String] new_title The new title.
|
96
|
+
#
|
97
|
+
def title= new_title
|
98
|
+
@title = String new_title
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# The description to document the condition. Optional.
|
103
|
+
#
|
104
|
+
# @param [String] new_description The new description.
|
105
|
+
#
|
106
|
+
def description= new_description
|
107
|
+
@description = String new_description
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# An attribute-based logic expression using a subset of the Common
|
112
|
+
# Expression Language (CEL). The condition expression can contain
|
113
|
+
# multiple statements, each uses one attributes, and statements are
|
114
|
+
# combined using logic operators, following CEL language
|
115
|
+
# specification. Required.
|
116
|
+
#
|
117
|
+
# @see https://cloud.google.com/iam/docs/conditions-overview CEL for conditions
|
118
|
+
#
|
119
|
+
# @param [String] new_expression The new expression.
|
120
|
+
#
|
121
|
+
def expression= new_expression
|
122
|
+
@expression = String new_expression
|
123
|
+
end
|
124
|
+
|
125
|
+
def to_gapi
|
126
|
+
{
|
127
|
+
title: @title,
|
128
|
+
description: @description,
|
129
|
+
expression: @expression
|
130
|
+
}.delete_if { |_, v| v.nil? }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -202,12 +202,12 @@ module Google
|
|
202
202
|
|
203
203
|
##
|
204
204
|
# Returns Google::Apis::StorageV1::Policy
|
205
|
-
def get_bucket_policy bucket_name, user_project: nil
|
205
|
+
def get_bucket_policy bucket_name, requested_policy_version: nil, user_project: nil
|
206
206
|
# get_bucket_iam_policy(bucket, fields: nil, quota_user: nil,
|
207
207
|
# user_ip: nil, options: nil)
|
208
208
|
execute do
|
209
|
-
service.get_bucket_iam_policy
|
210
|
-
|
209
|
+
service.get_bucket_iam_policy bucket_name, options_requested_policy_version: requested_policy_version,
|
210
|
+
user_project: user_project(user_project)
|
211
211
|
end
|
212
212
|
end
|
213
213
|
|
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.
|
4
|
+
version: 1.25.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: 2019-
|
12
|
+
date: 2019-12-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: google-cloud-core
|
@@ -272,6 +272,9 @@ files:
|
|
272
272
|
- lib/google/cloud/storage/hmac_key/list.rb
|
273
273
|
- lib/google/cloud/storage/notification.rb
|
274
274
|
- lib/google/cloud/storage/policy.rb
|
275
|
+
- lib/google/cloud/storage/policy/binding.rb
|
276
|
+
- lib/google/cloud/storage/policy/bindings.rb
|
277
|
+
- lib/google/cloud/storage/policy/condition.rb
|
275
278
|
- lib/google/cloud/storage/post_object.rb
|
276
279
|
- lib/google/cloud/storage/project.rb
|
277
280
|
- lib/google/cloud/storage/service.rb
|