google-cloud-bigquery 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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