google-cloud-bigquery 0.20.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.
@@ -0,0 +1,509 @@
1
+ # Copyright 2015 Google Inc. All rights reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module Google
17
+ module Cloud
18
+ module Bigquery
19
+ class Dataset
20
+ ##
21
+ # # Dataset Access Control
22
+ #
23
+ # Represents the Access rules for a {Dataset}.
24
+ #
25
+ # @see https://cloud.google.com/bigquery/access-control BigQuery Access
26
+ # Control
27
+ #
28
+ # @example
29
+ # require "google/cloud"
30
+ #
31
+ # gcloud = Google::Cloud.new
32
+ # bigquery = gcloud.bigquery
33
+ # dataset = bigquery.dataset "my_dataset"
34
+ #
35
+ # dataset.access do |access|
36
+ # access.add_owner_group "owners@example.com"
37
+ # access.add_writer_user "writer@example.com"
38
+ # access.remove_writer_user "readers@example.com"
39
+ # access.add_reader_special :all
40
+ # access.add_reader_view other_dataset_view_object
41
+ # end
42
+ #
43
+ class Access
44
+ # @private
45
+ ROLES = { "reader" => "READER",
46
+ "writer" => "WRITER",
47
+ "owner" => "OWNER" }
48
+
49
+ # @private
50
+ SCOPES = { "user" => :user_by_email,
51
+ "user_by_email" => :user_by_email,
52
+ "userByEmail" => :user_by_email,
53
+ "group" => :group_by_email,
54
+ "group_by_email" => :group_by_email,
55
+ "groupByEmail" => :group_by_email,
56
+ "domain" => :domain,
57
+ "special" => :special_group,
58
+ "special_group" => :special_group,
59
+ "specialGroup" => :special_group,
60
+ "view" => :view }
61
+
62
+ # @private
63
+ GROUPS = { "owners" => "projectOwners",
64
+ "project_owners" => "projectOwners",
65
+ "projectOwners" => "projectOwners",
66
+ "readers" => "projectReaders",
67
+ "project_readers" => "projectReaders",
68
+ "projectReaders" => "projectReaders",
69
+ "writers" => "projectWriters",
70
+ "project_writers" => "projectWriters",
71
+ "projectWriters" => "projectWriters",
72
+ "all" => "allAuthenticatedUsers",
73
+ "all_authenticated_users" => "allAuthenticatedUsers",
74
+ "allAuthenticatedUsers" => "allAuthenticatedUsers" }
75
+
76
+ ##
77
+ # @private
78
+ # Initialized a new Access object.
79
+ # Must provide a valid Google::Apis::BigqueryV2::Dataset object.
80
+ # Access will mutate the gapi object.
81
+ def initialize
82
+ @rules = [] # easiest to do this in the constructor
83
+ @original_rules_hashes = @rules.map(&:to_h)
84
+ end
85
+
86
+ # @private
87
+ def changed?
88
+ @original_rules_hashes != @rules.map(&:to_h)
89
+ end
90
+
91
+ # @private
92
+ def empty?
93
+ @rules.empty?
94
+ end
95
+
96
+ # @private
97
+ def freeze
98
+ @rules = @rules.map(&:dup).map(&:freeze)
99
+ @rules.freeze
100
+ super
101
+ end
102
+
103
+ ##
104
+ # @private View the access rules as an array of hashes.
105
+ def to_a
106
+ @rules.map(&:to_h)
107
+ end
108
+
109
+ ##
110
+ # Add reader access to a user.
111
+ def add_reader_user email
112
+ add_access_role_scope_value :reader, :user, email
113
+ end
114
+
115
+ ##
116
+ # Add reader access to a group.
117
+ def add_reader_group email
118
+ add_access_role_scope_value :reader, :group, email
119
+ end
120
+
121
+ ##
122
+ # Add reader access to a domain.
123
+ def add_reader_domain domain
124
+ add_access_role_scope_value :reader, :domain, domain
125
+ end
126
+
127
+ ##
128
+ # Add reader access to a special group.
129
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
130
+ def add_reader_special group
131
+ add_access_role_scope_value :reader, :special, group
132
+ end
133
+
134
+ ##
135
+ # Add reader access to a view.
136
+ # The view can be a Google::Cloud::Bigquery::View object,
137
+ # or a string identifier as specified by the
138
+ # [Query
139
+ # Reference](https://cloud.google.com/bigquery/query-reference#from):
140
+ # +project_name:datasetId.tableId+.
141
+ def add_reader_view view
142
+ add_access_view view
143
+ end
144
+
145
+ ##
146
+ # Add writer access to a user.
147
+ def add_writer_user email
148
+ add_access_role_scope_value :writer, :user, email
149
+ end
150
+
151
+ ##
152
+ # Add writer access to a group.
153
+ def add_writer_group email
154
+ add_access_role_scope_value :writer, :group, email
155
+ end
156
+
157
+ ##
158
+ # Add writer access to a domain.
159
+ def add_writer_domain domain
160
+ add_access_role_scope_value :writer, :domain, domain
161
+ end
162
+
163
+ ##
164
+ # Add writer access to a special group.
165
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
166
+ def add_writer_special group
167
+ add_access_role_scope_value :writer, :special, group
168
+ end
169
+
170
+ ##
171
+ # Add owner access to a user.
172
+ def add_owner_user email
173
+ add_access_role_scope_value :owner, :user, email
174
+ end
175
+
176
+ ##
177
+ # Add owner access to a group.
178
+ def add_owner_group email
179
+ add_access_role_scope_value :owner, :group, email
180
+ end
181
+
182
+ ##
183
+ # Add owner access to a domain.
184
+ def add_owner_domain domain
185
+ add_access_role_scope_value :owner, :domain, domain
186
+ end
187
+
188
+ ##
189
+ # Add owner access to a special group.
190
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
191
+ def add_owner_special group
192
+ add_access_role_scope_value :owner, :special, group
193
+ end
194
+
195
+ ##
196
+ # Remove reader access from a user.
197
+ def remove_reader_user email
198
+ remove_access_role_scope_value :reader, :user, email
199
+ end
200
+
201
+ ##
202
+ # Remove reader access from a group.
203
+ def remove_reader_group email
204
+ remove_access_role_scope_value :reader, :group, email
205
+ end
206
+
207
+ ##
208
+ # Remove reader access from a domain.
209
+ def remove_reader_domain domain
210
+ remove_access_role_scope_value :reader, :domain, domain
211
+ end
212
+
213
+ ##
214
+ # Remove reader access from a special group.
215
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
216
+ def remove_reader_special group
217
+ remove_access_role_scope_value :reader, :special, group
218
+ end
219
+
220
+ ##
221
+ # Remove reader access from a view.
222
+ # The view can be a Google::Cloud::Bigquery::View object,
223
+ # or a string identifier as specified by the
224
+ # [Query
225
+ # Reference](https://cloud.google.com/bigquery/query-reference#from):
226
+ # +project_name:datasetId.tableId+.
227
+ def remove_reader_view view
228
+ remove_access_view view
229
+ end
230
+
231
+ ##
232
+ # Remove writer access from a user.
233
+ def remove_writer_user email
234
+ remove_access_role_scope_value :writer, :user, email
235
+ end
236
+
237
+ ##
238
+ # Remove writer access from a group.
239
+ def remove_writer_group email
240
+ remove_access_role_scope_value :writer, :group, email
241
+ end
242
+
243
+ ##
244
+ # Remove writer access from a domain.
245
+ def remove_writer_domain domain
246
+ remove_access_role_scope_value :writer, :domain, domain
247
+ end
248
+
249
+ ##
250
+ # Remove writer access from a special group.
251
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
252
+ def remove_writer_special group
253
+ remove_access_role_scope_value :writer, :special, group
254
+ end
255
+
256
+ ##
257
+ # Remove owner access from a user.
258
+ def remove_owner_user email
259
+ remove_access_role_scope_value :owner, :user, email
260
+ end
261
+
262
+ ##
263
+ # Remove owner access from a group.
264
+ def remove_owner_group email
265
+ remove_access_role_scope_value :owner, :group, email
266
+ end
267
+
268
+ ##
269
+ # Remove owner access from a domain.
270
+ def remove_owner_domain domain
271
+ remove_access_role_scope_value :owner, :domain, domain
272
+ end
273
+
274
+ ##
275
+ # Remove owner access from a special group.
276
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
277
+ def remove_owner_special group
278
+ remove_access_role_scope_value :owner, :special, group
279
+ end
280
+
281
+ ##
282
+ # Checks reader access for a user.
283
+ def reader_user? email
284
+ lookup_access_role_scope_value :reader, :user, email
285
+ end
286
+
287
+ ##
288
+ # Checks reader access for a group.
289
+ def reader_group? email
290
+ lookup_access_role_scope_value :reader, :group, email
291
+ end
292
+
293
+ ##
294
+ # Checks reader access for a domain.
295
+ def reader_domain? domain
296
+ lookup_access_role_scope_value :reader, :domain, domain
297
+ end
298
+
299
+ ##
300
+ # Checks reader access for a special group.
301
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
302
+ def reader_special? group
303
+ lookup_access_role_scope_value :reader, :special, group
304
+ end
305
+
306
+ ##
307
+ # Checks reader access for a view.
308
+ # The view can be a Google::Cloud::Bigquery::View object,
309
+ # or a string identifier as specified by the
310
+ # [Query
311
+ # Reference](https://cloud.google.com/bigquery/query-reference#from):
312
+ # +project_name:datasetId.tableId+.
313
+ def reader_view? view
314
+ lookup_access_view view
315
+ end
316
+
317
+ ##
318
+ # Checks writer access for a user.
319
+ def writer_user? email
320
+ lookup_access_role_scope_value :writer, :user, email
321
+ end
322
+
323
+ ##
324
+ # Checks writer access for a group.
325
+ def writer_group? email
326
+ lookup_access_role_scope_value :writer, :group, email
327
+ end
328
+
329
+ ##
330
+ # Checks writer access for a domain.
331
+ def writer_domain? domain
332
+ lookup_access_role_scope_value :writer, :domain, domain
333
+ end
334
+
335
+ ##
336
+ # Checks writer access for a special group.
337
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
338
+ def writer_special? group
339
+ lookup_access_role_scope_value :writer, :special, group
340
+ end
341
+
342
+ ##
343
+ # Checks owner access for a user.
344
+ def owner_user? email
345
+ lookup_access_role_scope_value :owner, :user, email
346
+ end
347
+
348
+ ##
349
+ # Checks owner access for a group.
350
+ def owner_group? email
351
+ lookup_access_role_scope_value :owner, :group, email
352
+ end
353
+
354
+ ##
355
+ # Checks owner access for a domain.
356
+ def owner_domain? domain
357
+ lookup_access_role_scope_value :owner, :domain, domain
358
+ end
359
+
360
+ ##
361
+ # Checks owner access for a special group.
362
+ # Accepted values are `owners`, `writers`, `readers`, and `all`.
363
+ def owner_special? group
364
+ lookup_access_role_scope_value :owner, :special, group
365
+ end
366
+
367
+ # @private
368
+ def self.from_gapi gapi
369
+ rules = Array gapi.access
370
+ new.tap do |s|
371
+ s.instance_variable_set :@rules, rules
372
+ s.instance_variable_set :@original_rules_hashes,
373
+ rules.map(&:to_h)
374
+ s.instance_variable_set :@dataset_reference,
375
+ gapi.dataset_reference
376
+ end
377
+ end
378
+
379
+ # @private
380
+ def to_gapi
381
+ @rules
382
+ end
383
+
384
+ protected
385
+
386
+ # @private
387
+ def validate_role role
388
+ good_role = ROLES[role.to_s]
389
+ if good_role.nil?
390
+ fail ArgumentError "Unable to determine role for #{role}"
391
+ end
392
+ good_role
393
+ end
394
+
395
+ # @private
396
+ def validate_scope scope
397
+ good_scope = SCOPES[scope.to_s]
398
+ if good_scope.nil?
399
+ fail ArgumentError "Unable to determine scope for #{scope}"
400
+ end
401
+ good_scope
402
+ end
403
+
404
+ # @private
405
+ def validate_special_group value
406
+ good_value = GROUPS[value.to_s]
407
+ return good_value unless good_value.nil?
408
+ value
409
+ end
410
+
411
+ # @private
412
+ def validate_view view
413
+ if view.respond_to? :table_ref
414
+ view.table_ref
415
+ else
416
+ Service.table_ref_from_s view, @dataset_reference
417
+ end
418
+ end
419
+
420
+ # @private
421
+ def add_access_role_scope_value role, scope, value
422
+ role = validate_role(role)
423
+ scope = validate_scope scope
424
+ # If scope is special group, make sure value is in the list
425
+ value = validate_special_group(value) if scope == :special_group
426
+ # Remove any rules of this scope and value
427
+ @rules.reject!(&find_by_scope_and_value(scope, value))
428
+ # Add new rule for this role, scope, and value
429
+ opts = { role: role, scope => value }
430
+ @rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
431
+ end
432
+
433
+ # @private
434
+ def add_access_view value
435
+ # scope is view, make sure value is in the right format
436
+ value = validate_view(value)
437
+ # Remove existing view rule, if any
438
+ @rules.reject!(&find_view(value))
439
+ # Add new rule for this role, scope, and value
440
+ opts = { view: value }
441
+ @rules << Google::Apis::BigqueryV2::Dataset::Access.new(opts)
442
+ end
443
+
444
+ # @private
445
+ def remove_access_role_scope_value role, scope, value
446
+ role = validate_role(role)
447
+ scope = validate_scope scope
448
+ # If scope is special group, make sure value is in the list
449
+ value = validate_special_group(value) if scope == :special_group
450
+ # Remove any rules of this role, scope, and value
451
+ @rules.reject!(
452
+ &find_by_role_and_scope_and_value(role, scope, value))
453
+ end
454
+
455
+ # @private
456
+ def remove_access_view value
457
+ # scope is view, make sure value is in the right format
458
+ value = validate_view(value)
459
+ # Remove existing view rule, if any
460
+ @rules.reject!(&find_view(value))
461
+ end
462
+
463
+ # @private
464
+ def lookup_access_role_scope_value role, scope, value
465
+ role = validate_role(role)
466
+ scope = validate_scope scope
467
+ # If scope is special group, make sure value is in the list
468
+ value = validate_special_group(value) if scope == :special_group
469
+ # Detect any rules of this role, scope, and value
470
+ !(!@rules.detect(
471
+ &find_by_role_and_scope_and_value(role, scope, value)))
472
+ end
473
+
474
+ # @private
475
+ def lookup_access_view value
476
+ # scope is view, make sure value is in the right format
477
+ value = validate_view(value)
478
+ # Detect view rule, if any
479
+ !(!@rules.detect(&find_view(value)))
480
+ end
481
+
482
+ # @private
483
+ def find_by_role_and_scope_and_value role, scope, value
484
+ lambda do |a|
485
+ h = a.to_h
486
+ h[:role] == role && h[scope] == value
487
+ end
488
+ end
489
+
490
+ # @private
491
+ def find_by_scope_and_value scope, value
492
+ lambda do |a|
493
+ h = a.to_h
494
+ h[scope] == value
495
+ end
496
+ end
497
+
498
+ # @private
499
+ def find_view value
500
+ lambda do |a|
501
+ h = a.to_h
502
+ h[:view].to_h == value.to_h
503
+ end
504
+ end
505
+ end
506
+ end
507
+ end
508
+ end
509
+ end