forty 0.1.0 → 0.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 +4 -4
- data/lib/forty/configuration.rb +10 -0
- data/lib/forty/database.rb +0 -2
- data/lib/forty/privilege.rb +69 -0
- data/lib/forty/rake/task.rb +23 -0
- data/lib/forty/sync.rb +57 -20
- metadata +105 -5
- data/lib/forty/dbms.rb +0 -1
- data/lib/forty/redshift/privilege.rb +0 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c69cf32507f1a087a044f2571606170c3c28459
|
4
|
+
data.tar.gz: 7d13e1d39898bc33077e627463abff4040f0bb97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a77cdb8ce81e28740ece0fd5d6fc02809cb9c36d855b638224480476f07f18b63b4437882453e036d496fb31d63ddfd9c1d68d4b5beb69b7cf3bd9a5e40cc0e7
|
7
|
+
data.tar.gz: 7d5afa71ef584d53e72ae07b3a72741028fdabec327246381a8eb7d2792dd64d40a82f74c950822528d61eb73fcfd55566cdad1406836e10cda82831633a92c4
|
data/lib/forty/configuration.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
1
3
|
module Forty
|
2
4
|
class Configuration
|
3
5
|
attr_accessor :logger
|
@@ -5,6 +7,14 @@ module Forty
|
|
5
7
|
attr_accessor :schemas
|
6
8
|
attr_accessor :acl_file
|
7
9
|
attr_accessor :generate_passwords
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@logger = ::Logger.new(STDOUT)
|
13
|
+
@logger.level = ::Logger::INFO
|
14
|
+
@logger.formatter = proc do |severity, _, _, message|
|
15
|
+
"[Forty] [#{severity}] #{message}\n"
|
16
|
+
end
|
17
|
+
end
|
8
18
|
end
|
9
19
|
|
10
20
|
class Database
|
data/lib/forty/database.rb
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
module Forty
|
2
|
+
module Privilege
|
3
|
+
class Base
|
4
|
+
PRIVILEGES = self.constants.map { |const| self.const_get(const) }
|
5
|
+
|
6
|
+
def self.get_privilege_name_by_acronym(acronym)
|
7
|
+
privilege = self.constants.select do |constant|
|
8
|
+
self.const_get(constant).eql?(acronym)
|
9
|
+
end[0]
|
10
|
+
privilege.nil? ? nil : privilege.to_s.downcase
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.parse_privileges_from_string(privileges_string)
|
14
|
+
privileges = []
|
15
|
+
self.constants.each do |constant|
|
16
|
+
acronym = self.const_get(constant)
|
17
|
+
unless privileges_string.slice!(acronym).nil?
|
18
|
+
privileges << self.get_privilege_name_by_acronym(acronym)
|
19
|
+
end
|
20
|
+
break if privileges_string.empty?
|
21
|
+
end
|
22
|
+
privileges
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# https://www.postgresql.org/docs/9.6/static/sql-grant.html
|
27
|
+
# r -- SELECT ("read")
|
28
|
+
# w -- UPDATE ("write")
|
29
|
+
# a -- INSERT ("append")
|
30
|
+
# d -- DELETE
|
31
|
+
# D -- TRUNCATE
|
32
|
+
# x -- REFERENCES
|
33
|
+
# t -- TRIGGER
|
34
|
+
# X -- EXECUTE
|
35
|
+
# U -- USAGE
|
36
|
+
# C -- CREATE
|
37
|
+
# c -- CONNECT
|
38
|
+
# T -- TEMPORARY
|
39
|
+
# arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)
|
40
|
+
# * -- grant option for preceding privilege
|
41
|
+
#
|
42
|
+
# /yyyy -- role that granted this privilege
|
43
|
+
|
44
|
+
class Table < Base
|
45
|
+
ALL = 'arwdDxt'
|
46
|
+
SELECT = 'r'
|
47
|
+
UPDATE = 'W'
|
48
|
+
INSERT = 'a'
|
49
|
+
DELETE = 'd'
|
50
|
+
TRUNCATE = 'D'
|
51
|
+
REFERENCES = 'x'
|
52
|
+
TRIGGER = 't'
|
53
|
+
EXECUTE = 'X'
|
54
|
+
end
|
55
|
+
|
56
|
+
class Schema < Base
|
57
|
+
ALL = 'UC'
|
58
|
+
USAGE = 'U'
|
59
|
+
CREATE = 'C'
|
60
|
+
end
|
61
|
+
|
62
|
+
class Database < Base
|
63
|
+
ALL = 'CTc'
|
64
|
+
CREATE = 'C'
|
65
|
+
CONNECT = 'c'
|
66
|
+
TEMPORARY = 'T'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require_relative '../../forty'
|
3
|
+
|
4
|
+
module Forty
|
5
|
+
module Rake
|
6
|
+
class Task
|
7
|
+
include ::Rake::DSL if defined? ::Rake::DSL
|
8
|
+
|
9
|
+
def install_tasks
|
10
|
+
namespace :acl do
|
11
|
+
namespace :sync do
|
12
|
+
desc 'syncs entire acl config with database'
|
13
|
+
task :all, [:disable_dry_run] do
|
14
|
+
Forty.sync
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Forty::Rake::Task.new.install_tasks
|
data/lib/forty/sync.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# require_relative 'configuration'
|
2
2
|
|
3
3
|
module Forty
|
4
|
+
|
4
5
|
def self.sync
|
5
6
|
Forty::Sync.new(
|
6
7
|
Forty.configuration.logger,
|
@@ -19,6 +20,8 @@ module Forty
|
|
19
20
|
@logger = logger or raise Error, 'No logger provided'
|
20
21
|
@master_username = master_username or raise Error, 'No master username provided'
|
21
22
|
@production_schemas = production_schemas or raise Error, 'No production schemas provided'
|
23
|
+
@system_groups = ["pg_signal_backend"]
|
24
|
+
@system_users = ["postgres"]
|
22
25
|
@acl_config = acl_config or raise Error, 'No acl config provided'
|
23
26
|
@acl_config['users'] ||= {}
|
24
27
|
@acl_config['groups'] ||= {}
|
@@ -30,6 +33,7 @@ module Forty
|
|
30
33
|
end
|
31
34
|
|
32
35
|
def run
|
36
|
+
banner()
|
33
37
|
sync_users()
|
34
38
|
sync_groups()
|
35
39
|
sync_user_groups()
|
@@ -37,13 +41,39 @@ module Forty
|
|
37
41
|
sync_acl()
|
38
42
|
end
|
39
43
|
|
44
|
+
def banner
|
45
|
+
@logger.info(<<-BANNER)
|
46
|
+
Starting sync...
|
47
|
+
____ __
|
48
|
+
/ __/___ _____/ /___ __
|
49
|
+
/ /_/ __ \\/ ___/ __/ / / /
|
50
|
+
/ __/ /_/ / / / /_/ /_/ /
|
51
|
+
/_/ \\____/_/ \\__/\\__, / Database ACL Sync
|
52
|
+
/____/ v0.2.0
|
53
|
+
|
54
|
+
===============================================================================
|
55
|
+
|
56
|
+
Running in #{@dry_run ? 'DRY-MODE (not enforcing state)' : 'PRODUCTION-MODE (enforcing state)'}
|
57
|
+
|
58
|
+
Configuration:
|
59
|
+
Master user: #{@master_username}
|
60
|
+
Synced schemas: #{@production_schemas.join(', ')}
|
61
|
+
System users: #{@system_users.join(', ')}
|
62
|
+
System groups: #{@system_groups.join(', ')}
|
63
|
+
|
64
|
+
===============================================================================
|
65
|
+
BANNER
|
66
|
+
end
|
67
|
+
|
40
68
|
def sync_users
|
41
69
|
current_users = _get_current_dwh_users.keys
|
42
70
|
defined_users = @acl_config['users'].keys
|
43
71
|
|
44
|
-
undefined_users = (current_users - defined_users).uniq.compact
|
72
|
+
undefined_users = (current_users - defined_users - @system_users).uniq.compact
|
45
73
|
missing_users = (defined_users - current_users).uniq.compact
|
46
74
|
|
75
|
+
@logger.debug("Undefined users: #{undefined_users}")
|
76
|
+
@logger.debug("Missing users: #{missing_users}")
|
47
77
|
undefined_users.each { |user| _delete_user(user) }
|
48
78
|
|
49
79
|
missing_users.each do |user|
|
@@ -61,7 +91,7 @@ module Forty
|
|
61
91
|
current_groups = _get_current_dwh_groups().keys
|
62
92
|
defined_groups = @acl_config['groups'].keys
|
63
93
|
|
64
|
-
undefined_groups = (current_groups - defined_groups).uniq.compact
|
94
|
+
undefined_groups = (current_groups - defined_groups - @system_groups).uniq.compact
|
65
95
|
missing_groups = (defined_groups - current_groups).uniq.compact
|
66
96
|
|
67
97
|
undefined_groups.each { |group| _delete_group(group) }
|
@@ -108,8 +138,8 @@ module Forty
|
|
108
138
|
unless schemas_owned_by_user.empty?
|
109
139
|
tables_owned_by_user = _get_currently_owned_tables(user)
|
110
140
|
schemas_owned_by_user.each do |schema|
|
111
|
-
@executor.
|
112
|
-
tables = @executor.
|
141
|
+
@executor.execute("set search_path=#{schema}")
|
142
|
+
tables = @executor.execute("select tablename from pg_tables where schemaname='#{schema}'").map { |row| "#{schema}.#{row['tablename']}" }
|
113
143
|
nonowned_tables_by_user = tables.uniq - tables_owned_by_user
|
114
144
|
nonowned_tables_by_user.each { |table| _execute_statement("alter table #{table} owner to #{user};") }
|
115
145
|
end
|
@@ -126,7 +156,7 @@ module Forty
|
|
126
156
|
diverged = 0
|
127
157
|
|
128
158
|
users.each do |user|
|
129
|
-
next if user.eql?(@master_username)
|
159
|
+
next if user.eql?(@master_username) or @system_users.include?(user)
|
130
160
|
|
131
161
|
raise Error, "Users are not in sync #{user}" if current_user_roles[user].nil? or defined_user_roles[user].nil?
|
132
162
|
|
@@ -206,7 +236,7 @@ module Forty
|
|
206
236
|
end
|
207
237
|
|
208
238
|
def _get_current_user_roles
|
209
|
-
Hash[@executor.
|
239
|
+
Hash[@executor.execute(<<-SQL).map { |row| [row['usename'], row['user_roles'].split(',').select { |e| not e.empty? }.compact] }]
|
210
240
|
select
|
211
241
|
usename
|
212
242
|
, case when usecreatedb is true then 'createdb' else '' end
|
@@ -221,11 +251,13 @@ module Forty
|
|
221
251
|
end
|
222
252
|
|
223
253
|
def _check_group_unknown(current_groups, defined_groups)
|
224
|
-
|
254
|
+
@logger.debug("Check whether groups are in sync. Current: #{current_groups}; Defined: #{defined_groups}; System: #{@system_groups}")
|
255
|
+
raise Error, 'Groups are out of sync!' if _mismatch?(current_groups - @system_groups, defined_groups)
|
225
256
|
end
|
226
257
|
|
227
258
|
def _check_user_unknown(current_users, defined_users)
|
228
|
-
|
259
|
+
@logger.debug("Check whether users are in sync. Current: #{current_users}; Defined: #{defined_users}; System: #{@system_users}")
|
260
|
+
raise Error, 'Users are out of sync!' if _mismatch?(current_users - @system_users, defined_users)
|
229
261
|
end
|
230
262
|
|
231
263
|
def _mismatch?(current, defined)
|
@@ -243,7 +275,7 @@ module Forty
|
|
243
275
|
@logger.info("Retrying to execute statement in #{attempts*10} seconds...") if attempts > 0
|
244
276
|
sleep (attempts*10)
|
245
277
|
attempts += 1
|
246
|
-
@executor.
|
278
|
+
@executor.execute(statement)
|
247
279
|
rescue PG::UndefinedTable => e
|
248
280
|
@logger.error("#{e.class}: #{e.message}" )
|
249
281
|
retry unless attempts > 3
|
@@ -353,7 +385,7 @@ module Forty
|
|
353
385
|
;
|
354
386
|
SQL
|
355
387
|
|
356
|
-
raw_dwh_users = @executor.
|
388
|
+
raw_dwh_users = @executor.execute(query)
|
357
389
|
|
358
390
|
Hash[raw_dwh_users.map do |row|
|
359
391
|
name = row['name']
|
@@ -375,7 +407,7 @@ module Forty
|
|
375
407
|
from pg_group
|
376
408
|
;
|
377
409
|
SQL
|
378
|
-
raw_dwh_groups = @executor.
|
410
|
+
raw_dwh_groups = @executor.execute(query)
|
379
411
|
|
380
412
|
Hash[raw_dwh_groups.map do |row|
|
381
413
|
name = row['name']
|
@@ -398,7 +430,7 @@ module Forty
|
|
398
430
|
;
|
399
431
|
SQL
|
400
432
|
|
401
|
-
raw_schema_acl = @executor.
|
433
|
+
raw_schema_acl = @executor.execute(query)
|
402
434
|
_parse_current_acl('schema', raw_schema_acl)
|
403
435
|
end
|
404
436
|
|
@@ -414,7 +446,7 @@ module Forty
|
|
414
446
|
;
|
415
447
|
SQL
|
416
448
|
|
417
|
-
raw_database_acl = @executor.
|
449
|
+
raw_database_acl = @executor.execute(query)
|
418
450
|
_parse_current_acl('database', raw_database_acl)
|
419
451
|
end
|
420
452
|
|
@@ -437,7 +469,7 @@ module Forty
|
|
437
469
|
;
|
438
470
|
SQL
|
439
471
|
|
440
|
-
raw_table_acl = @executor.
|
472
|
+
raw_table_acl = @executor.execute(query)
|
441
473
|
_parse_current_acl('table', raw_table_acl)
|
442
474
|
end
|
443
475
|
|
@@ -459,7 +491,7 @@ module Forty
|
|
459
491
|
.compact
|
460
492
|
|
461
493
|
if grantees.any? { |grantee| !known_grantees.include?(grantee) }
|
462
|
-
raise Error,
|
494
|
+
raise Error, "Users or groups not in sync! Could not find #{grantees.select { |grantee| !known_grantees.include?(grantee) }.join(', ')}"
|
463
495
|
end
|
464
496
|
|
465
497
|
grantees.each do |grantee|
|
@@ -613,14 +645,14 @@ module Forty
|
|
613
645
|
|
614
646
|
if schema.eql?('*')
|
615
647
|
@production_schemas.each do |prod_schema|
|
616
|
-
tables = @executor.
|
648
|
+
tables = @executor.execute(<<-SQL).map { |row| "#{prod_schema}.#{row['tablename']}" }
|
617
649
|
select tablename from pg_tables where schemaname='#{prod_schema}'
|
618
650
|
SQL
|
619
651
|
|
620
652
|
tables_to_grant_privileges_on.concat(tables)
|
621
653
|
end
|
622
654
|
else
|
623
|
-
tables_to_grant_privileges_on = @executor.
|
655
|
+
tables_to_grant_privileges_on = @executor.execute(<<-SQL).map { |row| "#{schema}.#{row['tablename']}" }
|
624
656
|
select tablename from pg_tables where schemaname='#{schema}'
|
625
657
|
SQL
|
626
658
|
end
|
@@ -651,9 +683,14 @@ module Forty
|
|
651
683
|
parsed_acls = {}
|
652
684
|
raw_acl.each do |row|
|
653
685
|
name = row['name']
|
686
|
+
@logger.debug("Current ACL: [#{identifier_type}] '#{name}': #{row['acls']}")
|
654
687
|
parsed_acl = _parse_current_permissions(identifier_type, row['acls'])
|
655
688
|
parsed_acl.each do |grantee, privileges|
|
656
689
|
unless grantee.empty?
|
690
|
+
if _get_current_dwh_groups().keys.include?(grantee)
|
691
|
+
@logger.debug("Grantee '#{grantee}' has been identified as a group")
|
692
|
+
grantee = "group #{grantee}"
|
693
|
+
end
|
657
694
|
parsed_acls[grantee] ||= {}
|
658
695
|
parsed_acls[grantee][name] ||= []
|
659
696
|
parsed_acls[grantee][name].concat(privileges)
|
@@ -667,7 +704,7 @@ module Forty
|
|
667
704
|
# http://www.postgresql.org/docs/8.1/static/sql-grant.html
|
668
705
|
# Typical ACL string:
|
669
706
|
#
|
670
|
-
# admin=arwdRxt/admin,
|
707
|
+
# admin=arwdRxt/admin,someone=r/admin,"group selfservice=r/admin"
|
671
708
|
#
|
672
709
|
# =xxxx -- privileges granted to PUBLIC
|
673
710
|
# uname=xxxx -- privileges granted to a user
|
@@ -708,7 +745,7 @@ module Forty
|
|
708
745
|
where pg_user.usename = '#{user}'
|
709
746
|
;
|
710
747
|
SQL
|
711
|
-
@executor.
|
748
|
+
@executor.execute(query).map { |row| row['schemaname'] }
|
712
749
|
end
|
713
750
|
|
714
751
|
def _get_currently_owned_tables(user)
|
@@ -718,7 +755,7 @@ module Forty
|
|
718
755
|
where tableowner = '#{user}'
|
719
756
|
;
|
720
757
|
SQL
|
721
|
-
@executor.
|
758
|
+
@executor.execute(query).map { |row| row['tablename'] }
|
722
759
|
end
|
723
760
|
end
|
724
761
|
end
|
metadata
CHANGED
@@ -1,15 +1,115 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefanie Grunwald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2017-04-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pg
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.16'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '1.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.16'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: cucumber
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '2.0'
|
40
|
+
- - "<"
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '3.0'
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '2.0'
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '3.0'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: rake
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '10.1'
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '12.0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '10.1'
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '12.0'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rspec
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '3.1'
|
80
|
+
- - "<"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.1'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '4.0'
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: rspec-collection_matchers
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: 1.1.2
|
100
|
+
- - "<"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '2.0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.1.2
|
110
|
+
- - "<"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '2.0'
|
13
113
|
description:
|
14
114
|
email: steffi@physics.org
|
15
115
|
executables: []
|
@@ -20,8 +120,8 @@ files:
|
|
20
120
|
- lib/forty/acl.rb
|
21
121
|
- lib/forty/configuration.rb
|
22
122
|
- lib/forty/database.rb
|
23
|
-
- lib/forty/
|
24
|
-
- lib/forty/
|
123
|
+
- lib/forty/privilege.rb
|
124
|
+
- lib/forty/rake/task.rb
|
25
125
|
- lib/forty/sync.rb
|
26
126
|
homepage: https://github.com/moertel/forty
|
27
127
|
licenses:
|
data/lib/forty/dbms.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require_relative 'redshift/privilege'
|
@@ -1,49 +0,0 @@
|
|
1
|
-
module Forty
|
2
|
-
module Redshift
|
3
|
-
module Privilege
|
4
|
-
class Base
|
5
|
-
PRIVILEGES = self.constants.map { |const| self.const_get(const) }
|
6
|
-
|
7
|
-
def self.get_privilege_name_by_acronym(acronym)
|
8
|
-
privilege = self.constants.select do |constant|
|
9
|
-
self.const_get(constant).eql?(acronym)
|
10
|
-
end[0]
|
11
|
-
privilege.nil? ? nil : privilege.to_s.downcase
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.parse_privileges_from_string(privileges_string)
|
15
|
-
privileges = []
|
16
|
-
self.constants.each do |constant|
|
17
|
-
acronym = self.const_get(constant)
|
18
|
-
unless privileges_string.slice!(acronym).nil?
|
19
|
-
privileges << self.get_privilege_name_by_acronym(acronym)
|
20
|
-
end
|
21
|
-
break if privileges_string.empty?
|
22
|
-
end
|
23
|
-
privileges
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class Table < Base
|
28
|
-
ALL = 'arwdRxt'
|
29
|
-
SELECT = 'r'
|
30
|
-
UPDATE = 'w'
|
31
|
-
INSERT = 'a'
|
32
|
-
DELETE = 'd'
|
33
|
-
REFERENCES = 'x'
|
34
|
-
end
|
35
|
-
|
36
|
-
class Schema < Base
|
37
|
-
ALL = 'UC'
|
38
|
-
USAGE = 'U'
|
39
|
-
CREATE = 'C'
|
40
|
-
end
|
41
|
-
|
42
|
-
class Database < Base
|
43
|
-
ALL = 'CT'
|
44
|
-
CREATE = 'C'
|
45
|
-
TEMPORARY = 'T'
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|