cbac 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest +71 -71
- data/README.rdoc +51 -51
- data/Rakefile +39 -39
- data/cbac.gemspec +30 -30
- data/config/cbac/context_roles.rb +21 -21
- data/config/cbac/privileges.rb +50 -50
- data/context_roles.rb +21 -21
- data/init.rb +3 -3
- data/lib/cbac.rb +132 -132
- data/lib/cbac/cbac_pristine/pristine.rb +138 -138
- data/lib/cbac/cbac_pristine/pristine_file.rb +179 -179
- data/lib/cbac/cbac_pristine/pristine_permission.rb +205 -205
- data/lib/cbac/cbac_pristine/pristine_role.rb +43 -43
- data/lib/cbac/config.rb +9 -9
- data/lib/cbac/context_role.rb +27 -27
- data/lib/cbac/generic_role.rb +7 -7
- data/lib/cbac/known_permission.rb +15 -15
- data/lib/cbac/membership.rb +3 -3
- data/lib/cbac/permission.rb +5 -5
- data/lib/cbac/privilege.rb +117 -117
- data/lib/cbac/privilege_new_api.rb +56 -56
- data/lib/cbac/privilege_set.rb +29 -29
- data/lib/cbac/privilege_set_record.rb +6 -6
- data/lib/cbac/setup.rb +37 -37
- data/lib/generators/cbac/USAGE +33 -33
- data/lib/generators/cbac/cbac_generator.rb +75 -75
- data/lib/generators/cbac/copy_files/config/cbac.pristine +2 -2
- data/lib/generators/cbac/copy_files/config/context_roles.rb +17 -17
- data/lib/generators/cbac/copy_files/config/privileges.rb +25 -25
- data/lib/generators/cbac/copy_files/controllers/generic_roles_controller.rb +30 -30
- data/lib/generators/cbac/copy_files/controllers/memberships_controller.rb +22 -22
- data/lib/generators/cbac/copy_files/controllers/permissions_controller.rb +61 -61
- data/lib/generators/cbac/copy_files/controllers/upgrade_controller.rb +23 -23
- data/lib/generators/cbac/copy_files/fixtures/cbac_generic_roles.yml +9 -9
- data/lib/generators/cbac/copy_files/fixtures/cbac_memberships.yml +8 -8
- data/lib/generators/cbac/copy_files/fixtures/cbac_permissions.yml +8 -8
- data/lib/generators/cbac/copy_files/initializers/cbac_config.rb +4 -4
- data/lib/generators/cbac/copy_files/migrate/create_cbac_from_scratch.rb +59 -59
- data/lib/generators/cbac/copy_files/migrate/create_cbac_upgrade_path.rb +40 -40
- data/lib/generators/cbac/copy_files/stylesheets/cbac.css +65 -65
- data/lib/generators/cbac/copy_files/tasks/cbac.rake +345 -345
- data/lib/generators/cbac/copy_files/views/generic_roles/index.html.erb +58 -58
- data/lib/generators/cbac/copy_files/views/layouts/cbac.html.erb +18 -18
- data/lib/generators/cbac/copy_files/views/memberships/_update.html.erb +11 -11
- data/lib/generators/cbac/copy_files/views/memberships/index.html.erb +23 -23
- data/lib/generators/cbac/copy_files/views/permissions/_update_context_role.html.erb +11 -11
- data/lib/generators/cbac/copy_files/views/permissions/_update_generic_role.html.erb +11 -11
- data/lib/generators/cbac/copy_files/views/permissions/index.html.erb +39 -39
- data/lib/generators/cbac/copy_files/views/upgrade/index.html.erb +31 -31
- data/migrations/20110211105533_add_pristine_files_to_cbac_upgrade_path.rb +16 -16
- data/privileges.rb +50 -50
- data/spec/cbac_pristine_file_spec.rb +329 -329
- data/spec/cbac_pristine_permission_spec.rb +358 -358
- data/spec/cbac_pristine_role_spec.rb +85 -85
- data/spec/rcov.opts +1 -1
- data/spec/spec.opts +4 -4
- data/spec/spec_helper.rb +11 -11
- data/tasks/cbac.rake +345 -345
- data/test/db/test.sqlite3 +0 -0
- data/test/fixtures/cbac_generic_roles.yml +9 -9
- data/test/fixtures/cbac_memberships.yml +8 -8
- data/test/fixtures/cbac_permissions.yml +14 -14
- data/test/fixtures/cbac_privilege_set.yml +18 -18
- data/test/test_cbac_actions.rb +71 -71
- data/test/test_cbac_authorize_context_roles.rb +39 -39
- data/test/test_cbac_authorize_generic_roles.rb +36 -36
- data/test/test_cbac_context_role.rb +50 -50
- data/test/test_cbac_privilege.rb +151 -151
- data/test/test_cbac_privilege_set.rb +50 -50
- data/test/test_helper.rb +28 -28
- metadata +11 -13
@@ -1,179 +1,179 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_role'))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
-
|
4
|
-
module Cbac
|
5
|
-
module CbacPristine
|
6
|
-
class AbstractPristineFile < ActiveRecord::Base
|
7
|
-
set_table_name "cbac_pristine_files"
|
8
|
-
attr_accessor :permissions, :generic_roles
|
9
|
-
attr_readonly :file_name
|
10
|
-
|
11
|
-
def initialize(*args)
|
12
|
-
super(*args)
|
13
|
-
@generic_roles = []
|
14
|
-
@context_roles = []
|
15
|
-
@permissions = []
|
16
|
-
end
|
17
|
-
|
18
|
-
def parse(use_db = true)
|
19
|
-
@generic_roles = []
|
20
|
-
@context_roles = []
|
21
|
-
@permissions = []
|
22
|
-
|
23
|
-
f = File.open(file_name, "r")
|
24
|
-
last_row_number = -1
|
25
|
-
f.each_with_index do |l, line_number|
|
26
|
-
pristine_permission = PristinePermission.new
|
27
|
-
pristine_permission.pristine_file = self
|
28
|
-
permission_line = l.chomp
|
29
|
-
# if this is not a line we can convert into a permission, go to next line (or fail.....)
|
30
|
-
next unless is_pristine_permission_line?(permission_line, line_number)
|
31
|
-
|
32
|
-
# check if the row numbers are constructed properly.
|
33
|
-
# this is needed for migration purposes, each permission should have an unique and persistent row number
|
34
|
-
header_match = permission_line.match(/^(\d+):([\+-x]|=>):\s*/)
|
35
|
-
pristine_permission.line_number = header_match.captures[0].to_i
|
36
|
-
if pristine_permission.line_number != last_row_number.succ
|
37
|
-
raise SyntaxError, "Error: row numbers in pristine file do not increase monotonously"
|
38
|
-
else
|
39
|
-
last_row_number = pristine_permission.line_number
|
40
|
-
end
|
41
|
-
pristine_permission.operation = header_match.captures[1]
|
42
|
-
# parse the role and privilege set name
|
43
|
-
pristine_permission.privilege_set_name = parse_privilege_set_name(permission_line, line_number)
|
44
|
-
pristine_permission.pristine_role = parse_role(permission_line, line_number, use_db)
|
45
|
-
# it's pristine, so changes should be treated as such
|
46
|
-
# if a permission was created and later revoked, we should remove the pristine line which was created before
|
47
|
-
case pristine_permission.operation
|
48
|
-
when '+'
|
49
|
-
@permissions.push(pristine_permission)
|
50
|
-
when '-'
|
51
|
-
permission_to_delete = nil
|
52
|
-
#check if this is actually a permission that can be revoked.
|
53
|
-
@permissions.each do |known_permission|
|
54
|
-
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name
|
55
|
-
permission_to_delete = known_permission
|
56
|
-
break
|
57
|
-
end
|
58
|
-
end
|
59
|
-
if permission_to_delete.nil?
|
60
|
-
raise SyntaxError, "Error: trying to remove a privilege set with \"#{permission_line}\" on line #{(line_number + 1).to_s}, but this privilege set wasn't created!"
|
61
|
-
else
|
62
|
-
@permissions.push(pristine_permission)
|
63
|
-
end
|
64
|
-
when 'x', '=>'
|
65
|
-
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
def is_pristine_permission_line?(line, line_number)
|
71
|
-
if line.match(/^\s*(\d+)\s*:\s*([\+-x]|=>)\s*:(\s*[A-Za-z]+\(\s*[A-Za-z_]*\s*\))+\s*\Z/) #looks like pristine line.....
|
72
|
-
return true
|
73
|
-
end
|
74
|
-
if line.match(/^\s*(#.*|\s*)$/) # line is whitespace or comment line
|
75
|
-
return false
|
76
|
-
end
|
77
|
-
raise SyntaxError, "Error: garbage found in input file on line #{(line_number + 1).to_s}" #line is rubbish
|
78
|
-
end
|
79
|
-
|
80
|
-
def parse_privilege_set_name(line, line_number)
|
81
|
-
if match_data= line.match(/^.*PrivilegeSet\(\s*([A-Za-z0-9_]+)\s*\)\s*/)
|
82
|
-
return match_data.captures[0]
|
83
|
-
end
|
84
|
-
raise SyntaxError, "Error: PrivilegeSet expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
85
|
-
end
|
86
|
-
|
87
|
-
def parse_role(line, line_number, use_db = true)
|
88
|
-
raise NotImplementedError("Error: the AbstractPristineFile cannot parse roles, use a PristineFile or GenericPristineFile instead")
|
89
|
-
end
|
90
|
-
|
91
|
-
def permission_set
|
92
|
-
permission_set = Array.new(@permissions)
|
93
|
-
@permissions.each do |pristine_permission|
|
94
|
-
case pristine_permission.operation
|
95
|
-
when '+'
|
96
|
-
permission_set.push(pristine_permission)
|
97
|
-
when '-'
|
98
|
-
permission_to_delete = nil
|
99
|
-
#check if this is actually a permission that can be revoked.
|
100
|
-
permission_set.each do |known_permission|
|
101
|
-
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name and known_permission.operation == '+'
|
102
|
-
permission_to_delete = known_permission
|
103
|
-
break
|
104
|
-
end
|
105
|
-
end
|
106
|
-
if permission_to_delete.nil?
|
107
|
-
raise ArgumentError, "Error: trying to remove permission #{pristine_permission.privilege_set_name}\" for #{pristine_permission.pristine_role.name}, but this permission wasn't created!"
|
108
|
-
else
|
109
|
-
permission_set.delete(permission_to_delete)
|
110
|
-
permission_set.delete(pristine_permission)
|
111
|
-
end
|
112
|
-
when 'x', '=>'
|
113
|
-
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
114
|
-
end
|
115
|
-
end
|
116
|
-
permission_set
|
117
|
-
end
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
class PristineFile < Cbac::CbacPristine::AbstractPristineFile
|
123
|
-
def parse_role(line, line_number, use_db = true)
|
124
|
-
if line.match(/^.*Admin\(\)/)
|
125
|
-
return @admin_role unless @admin_role.nil?
|
126
|
-
|
127
|
-
@admin_role = PristineRole.admin_role(use_db)
|
128
|
-
@generic_roles.push(@admin_role)
|
129
|
-
return @admin_role
|
130
|
-
end
|
131
|
-
if context_role_name = line.match(/^.*ContextRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
132
|
-
# NOTE: the 0 for an ID is very important! In CBAC a context role permission MUST have 0 as generic_role_id
|
133
|
-
# if not, the context role is not found by CBAC and thus will not work
|
134
|
-
|
135
|
-
# this may be a context role that's already in the database
|
136
|
-
context_role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]}) : nil
|
137
|
-
|
138
|
-
# this may still be a context role we've seen before...
|
139
|
-
context_role = @context_roles.select do |cr| cr.role_type == PristineRole.ROLE_TYPES[:context] and cr.name == context_role_name.captures[0] end.first if context_role.nil?
|
140
|
-
|
141
|
-
if context_role.nil?
|
142
|
-
# this is a never-before-seen context role
|
143
|
-
context_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]) if context_role.nil?
|
144
|
-
context_role.save if use_db
|
145
|
-
@context_roles.push context_role
|
146
|
-
end
|
147
|
-
return context_role
|
148
|
-
end
|
149
|
-
raise SyntaxError, "Error: ContextRole or Admin expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
150
|
-
end
|
151
|
-
|
152
|
-
|
153
|
-
end
|
154
|
-
|
155
|
-
class GenericPristineFile < Cbac::CbacPristine::AbstractPristineFile
|
156
|
-
def parse_role(line, line_number, use_db = true)
|
157
|
-
# generic pristine files differ, because they create generic roles when needed
|
158
|
-
# but those generic roles should be re-used if one with that name already exists
|
159
|
-
if generic_role= line.match(/^.*GenericRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
160
|
-
@generic_roles.each do |generic_cbac_role|
|
161
|
-
if generic_cbac_role.name == generic_role.captures[0]
|
162
|
-
return generic_cbac_role
|
163
|
-
end
|
164
|
-
end
|
165
|
-
role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0]}) : nil
|
166
|
-
|
167
|
-
if role.nil?
|
168
|
-
role = PristineRole.new(:role_id => @generic_roles.length + 2, :role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0])
|
169
|
-
role.save if use_db
|
170
|
-
end
|
171
|
-
|
172
|
-
@generic_roles.push(role)
|
173
|
-
return role
|
174
|
-
end
|
175
|
-
raise SyntaxError, "Error: GenericRole expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
176
|
-
end
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_role'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
+
|
4
|
+
module Cbac
|
5
|
+
module CbacPristine
|
6
|
+
class AbstractPristineFile < ActiveRecord::Base
|
7
|
+
set_table_name "cbac_pristine_files"
|
8
|
+
attr_accessor :permissions, :generic_roles
|
9
|
+
attr_readonly :file_name
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super(*args)
|
13
|
+
@generic_roles = []
|
14
|
+
@context_roles = []
|
15
|
+
@permissions = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def parse(use_db = true)
|
19
|
+
@generic_roles = []
|
20
|
+
@context_roles = []
|
21
|
+
@permissions = []
|
22
|
+
|
23
|
+
f = File.open(file_name, "r")
|
24
|
+
last_row_number = -1
|
25
|
+
f.each_with_index do |l, line_number|
|
26
|
+
pristine_permission = PristinePermission.new
|
27
|
+
pristine_permission.pristine_file = self
|
28
|
+
permission_line = l.chomp
|
29
|
+
# if this is not a line we can convert into a permission, go to next line (or fail.....)
|
30
|
+
next unless is_pristine_permission_line?(permission_line, line_number)
|
31
|
+
|
32
|
+
# check if the row numbers are constructed properly.
|
33
|
+
# this is needed for migration purposes, each permission should have an unique and persistent row number
|
34
|
+
header_match = permission_line.match(/^(\d+):([\+-x]|=>):\s*/)
|
35
|
+
pristine_permission.line_number = header_match.captures[0].to_i
|
36
|
+
if pristine_permission.line_number != last_row_number.succ
|
37
|
+
raise SyntaxError, "Error: row numbers in pristine file do not increase monotonously"
|
38
|
+
else
|
39
|
+
last_row_number = pristine_permission.line_number
|
40
|
+
end
|
41
|
+
pristine_permission.operation = header_match.captures[1]
|
42
|
+
# parse the role and privilege set name
|
43
|
+
pristine_permission.privilege_set_name = parse_privilege_set_name(permission_line, line_number)
|
44
|
+
pristine_permission.pristine_role = parse_role(permission_line, line_number, use_db)
|
45
|
+
# it's pristine, so changes should be treated as such
|
46
|
+
# if a permission was created and later revoked, we should remove the pristine line which was created before
|
47
|
+
case pristine_permission.operation
|
48
|
+
when '+'
|
49
|
+
@permissions.push(pristine_permission)
|
50
|
+
when '-'
|
51
|
+
permission_to_delete = nil
|
52
|
+
#check if this is actually a permission that can be revoked.
|
53
|
+
@permissions.each do |known_permission|
|
54
|
+
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name
|
55
|
+
permission_to_delete = known_permission
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
if permission_to_delete.nil?
|
60
|
+
raise SyntaxError, "Error: trying to remove a privilege set with \"#{permission_line}\" on line #{(line_number + 1).to_s}, but this privilege set wasn't created!"
|
61
|
+
else
|
62
|
+
@permissions.push(pristine_permission)
|
63
|
+
end
|
64
|
+
when 'x', '=>'
|
65
|
+
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_pristine_permission_line?(line, line_number)
|
71
|
+
if line.match(/^\s*(\d+)\s*:\s*([\+-x]|=>)\s*:(\s*[A-Za-z]+\(\s*[A-Za-z_]*\s*\))+\s*\Z/) #looks like pristine line.....
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
if line.match(/^\s*(#.*|\s*)$/) # line is whitespace or comment line
|
75
|
+
return false
|
76
|
+
end
|
77
|
+
raise SyntaxError, "Error: garbage found in input file on line #{(line_number + 1).to_s}" #line is rubbish
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_privilege_set_name(line, line_number)
|
81
|
+
if match_data= line.match(/^.*PrivilegeSet\(\s*([A-Za-z0-9_]+)\s*\)\s*/)
|
82
|
+
return match_data.captures[0]
|
83
|
+
end
|
84
|
+
raise SyntaxError, "Error: PrivilegeSet expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def parse_role(line, line_number, use_db = true)
|
88
|
+
raise NotImplementedError("Error: the AbstractPristineFile cannot parse roles, use a PristineFile or GenericPristineFile instead")
|
89
|
+
end
|
90
|
+
|
91
|
+
def permission_set
|
92
|
+
permission_set = Array.new(@permissions)
|
93
|
+
@permissions.each do |pristine_permission|
|
94
|
+
case pristine_permission.operation
|
95
|
+
when '+'
|
96
|
+
permission_set.push(pristine_permission)
|
97
|
+
when '-'
|
98
|
+
permission_to_delete = nil
|
99
|
+
#check if this is actually a permission that can be revoked.
|
100
|
+
permission_set.each do |known_permission|
|
101
|
+
if known_permission.privilege_set_name == pristine_permission.privilege_set_name and known_permission.pristine_role.name == pristine_permission.pristine_role.name and known_permission.operation == '+'
|
102
|
+
permission_to_delete = known_permission
|
103
|
+
break
|
104
|
+
end
|
105
|
+
end
|
106
|
+
if permission_to_delete.nil?
|
107
|
+
raise ArgumentError, "Error: trying to remove permission #{pristine_permission.privilege_set_name}\" for #{pristine_permission.pristine_role.name}, but this permission wasn't created!"
|
108
|
+
else
|
109
|
+
permission_set.delete(permission_to_delete)
|
110
|
+
permission_set.delete(pristine_permission)
|
111
|
+
end
|
112
|
+
when 'x', '=>'
|
113
|
+
raise NotImplementedError, "Using an x or => in a pristine file is not implemented yet"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
permission_set
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
class PristineFile < Cbac::CbacPristine::AbstractPristineFile
|
123
|
+
def parse_role(line, line_number, use_db = true)
|
124
|
+
if line.match(/^.*Admin\(\)/)
|
125
|
+
return @admin_role unless @admin_role.nil?
|
126
|
+
|
127
|
+
@admin_role = PristineRole.admin_role(use_db)
|
128
|
+
@generic_roles.push(@admin_role)
|
129
|
+
return @admin_role
|
130
|
+
end
|
131
|
+
if context_role_name = line.match(/^.*ContextRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
132
|
+
# NOTE: the 0 for an ID is very important! In CBAC a context role permission MUST have 0 as generic_role_id
|
133
|
+
# if not, the context role is not found by CBAC and thus will not work
|
134
|
+
|
135
|
+
# this may be a context role that's already in the database
|
136
|
+
context_role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]}) : nil
|
137
|
+
|
138
|
+
# this may still be a context role we've seen before...
|
139
|
+
context_role = @context_roles.select do |cr| cr.role_type == PristineRole.ROLE_TYPES[:context] and cr.name == context_role_name.captures[0] end.first if context_role.nil?
|
140
|
+
|
141
|
+
if context_role.nil?
|
142
|
+
# this is a never-before-seen context role
|
143
|
+
context_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:context], :name => context_role_name.captures[0]) if context_role.nil?
|
144
|
+
context_role.save if use_db
|
145
|
+
@context_roles.push context_role
|
146
|
+
end
|
147
|
+
return context_role
|
148
|
+
end
|
149
|
+
raise SyntaxError, "Error: ContextRole or Admin expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
class GenericPristineFile < Cbac::CbacPristine::AbstractPristineFile
|
156
|
+
def parse_role(line, line_number, use_db = true)
|
157
|
+
# generic pristine files differ, because they create generic roles when needed
|
158
|
+
# but those generic roles should be re-used if one with that name already exists
|
159
|
+
if generic_role= line.match(/^.*GenericRole\(\s*([A-Za-z0-9_]+)\s*\)/)
|
160
|
+
@generic_roles.each do |generic_cbac_role|
|
161
|
+
if generic_cbac_role.name == generic_role.captures[0]
|
162
|
+
return generic_cbac_role
|
163
|
+
end
|
164
|
+
end
|
165
|
+
role = use_db ? PristineRole.first(:conditions => {:role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0]}) : nil
|
166
|
+
|
167
|
+
if role.nil?
|
168
|
+
role = PristineRole.new(:role_id => @generic_roles.length + 2, :role_type => PristineRole.ROLE_TYPES[:generic], :name => generic_role.captures[0])
|
169
|
+
role.save if use_db
|
170
|
+
end
|
171
|
+
|
172
|
+
@generic_roles.push(role)
|
173
|
+
return role
|
174
|
+
end
|
175
|
+
raise SyntaxError, "Error: GenericRole expected, but found: \"#{line}\" on line #{(line_number + 1).to_s}"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -1,205 +1,205 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_role'))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
-
require 'active_record'
|
4
|
-
|
5
|
-
module Cbac
|
6
|
-
module CbacPristine
|
7
|
-
class PristinePermission < ActiveRecord::Base
|
8
|
-
set_table_name 'cbac_staged_permissions'
|
9
|
-
|
10
|
-
belongs_to :pristine_role, :class_name => "Cbac::CbacPristine::PristineRole"
|
11
|
-
belongs_to :pristine_file, :class_name => "Cbac::CbacPristine::AbstractPristineFile"
|
12
|
-
|
13
|
-
def privilege_set
|
14
|
-
Cbac::PrivilegeSetRecord.first(:conditions => {:name => privilege_set_name})
|
15
|
-
end
|
16
|
-
|
17
|
-
def operation_string
|
18
|
-
case operation
|
19
|
-
when '+'
|
20
|
-
return "add"
|
21
|
-
when '-'
|
22
|
-
return "revoke"
|
23
|
-
else
|
24
|
-
return "unknown"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
#convert this pristine line to a yml statement which can be used to create a yml fixtures file
|
29
|
-
#executing this statement will result in one cbac_permission in the DB
|
30
|
-
def to_yml_fixture(fixture_id = nil)
|
31
|
-
raise ArgumentError, "Error: cannot convert line #{line_number.to_s} to yml because the role is not specified" if pristine_role.nil?
|
32
|
-
raise ArgumentError, "Error: cannot convert line #{line_number.to_s} to yml because the privilege_set_name is not specified" if privilege_set_name.blank?
|
33
|
-
|
34
|
-
fixture_id = line_number if fixture_id.nil?
|
35
|
-
|
36
|
-
yml = "cbac_permission_00" << fixture_id.to_s << ":\n"
|
37
|
-
yml << " id: " << fixture_id.to_s << "\n"
|
38
|
-
yml << " context_role: "
|
39
|
-
yml << pristine_role.name if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
40
|
-
yml << "\n"
|
41
|
-
yml << " generic_role_id: " << pristine_role.role_id.to_s << "\n"
|
42
|
-
yml << " privilege_set_id: <%= Cbac::PrivilegeSetRecord.find(:first, :conditions => {:name => '" << privilege_set_name << "'}).id %>\n"
|
43
|
-
yml << " created_at: " << Time.now.strftime("%Y-%m-%d %H:%M:%S") << "\n"
|
44
|
-
yml << " updated_at: " << Time.now.strftime("%Y-%m-%d %H:%M:%S") << "\n"
|
45
|
-
yml << "\n"
|
46
|
-
end
|
47
|
-
|
48
|
-
# checks if the current cbac permissions contains a permission which is exactly like this one
|
49
|
-
def cbac_permission_exists?
|
50
|
-
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
51
|
-
Cbac::Permission.count(:joins => [:privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :context_role => pristine_role.name}) > 0
|
52
|
-
else
|
53
|
-
Cbac::Permission.count(:joins => [:generic_role, :privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :cbac_generic_roles => {:name => pristine_role.name}}) > 0
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
# checks if a pristine permission with the same properties(except line_number) exists in the database
|
58
|
-
def exists?
|
59
|
-
Cbac::CbacPristine::PristinePermission.count(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => operation}) > 0
|
60
|
-
end
|
61
|
-
|
62
|
-
# checks if a pristine permission with the exact same properties(except line_number), but the reverse operation exists in the database
|
63
|
-
def reverse_exists?
|
64
|
-
Cbac::CbacPristine::PristinePermission.count(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => reverse_operation}) > 0
|
65
|
-
end
|
66
|
-
|
67
|
-
# delete the pristine permission with the reverse operation of this one
|
68
|
-
def delete_reverse_permission
|
69
|
-
reverse_permission = Cbac::CbacPristine::PristinePermission.first(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => reverse_operation})
|
70
|
-
reverse_permission.delete
|
71
|
-
end
|
72
|
-
|
73
|
-
# get the reverse operation of this one
|
74
|
-
def reverse_operation
|
75
|
-
case operation
|
76
|
-
when '+'
|
77
|
-
return '-'
|
78
|
-
when '-'
|
79
|
-
return '+'
|
80
|
-
when 'x', '=>'
|
81
|
-
raise NotImplementedError, "Error: using an x or => in a pristine file is not implemented yet"
|
82
|
-
else
|
83
|
-
raise ArgumentError, "Error: invalid operation #{operation} is used in the pristine file"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# checks if the known_permissions table has an entry for this permission
|
88
|
-
def known_permission_exists?
|
89
|
-
Cbac::KnownPermission.count(:conditions => {:permission_type => pristine_role.known_permission_type, :permission_number => line_number}) > 0
|
90
|
-
end
|
91
|
-
|
92
|
-
# accept this permission and apply to the current cbac permission set
|
93
|
-
def accept
|
94
|
-
case operation
|
95
|
-
when '+'
|
96
|
-
handle_grant_permission
|
97
|
-
when '-'
|
98
|
-
handle_revoke_permission
|
99
|
-
when 'x', '=>'
|
100
|
-
raise NotImplementedError, "Error: using an x or => in a pristine file is not implemented yet"
|
101
|
-
else
|
102
|
-
raise ArgumentError, "Error: invalid operation #{operation} is used in the pristine file"
|
103
|
-
end
|
104
|
-
PristinePermission.delete(id) unless id.nil?
|
105
|
-
end
|
106
|
-
|
107
|
-
# reject this permission, but register it as a known permission. The user actually rejected this himself.
|
108
|
-
def reject
|
109
|
-
register_change
|
110
|
-
PristinePermission.delete(id) unless id.nil?
|
111
|
-
end
|
112
|
-
|
113
|
-
# add this permission to the cbac permission set, unless it already exists
|
114
|
-
def handle_grant_permission
|
115
|
-
return if cbac_permission_exists?
|
116
|
-
|
117
|
-
permission = Cbac::Permission.new
|
118
|
-
permission.privilege_set = privilege_set
|
119
|
-
|
120
|
-
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
121
|
-
permission.context_role = pristine_role.name
|
122
|
-
else
|
123
|
-
generic_role = Cbac::GenericRole.first(:conditions => {:name => pristine_role.name})
|
124
|
-
permission.generic_role = generic_role.nil? ? Cbac::GenericRole.create(:name => pristine_role.name, :remarks => "Autogenerated by Cbac loading / upgrade system") : generic_role
|
125
|
-
end
|
126
|
-
|
127
|
-
register_change if permission.save
|
128
|
-
permission
|
129
|
-
end
|
130
|
-
|
131
|
-
# revoke this permission from the current permission set, raises an error if it doesn't exist yet
|
132
|
-
def handle_revoke_permission
|
133
|
-
raise ArgumentError, "Error: trying to revoke permission #{privilege_set_name} for #{pristine_role.name}, but this permission does not exist" unless cbac_permission_exists?
|
134
|
-
|
135
|
-
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
136
|
-
permission = Cbac::Permission.first(:joins => [:privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :context_role => pristine_role.name})
|
137
|
-
else
|
138
|
-
permission = Cbac::Permission.first(:joins => [:generic_role, :privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :cbac_generic_roles => {:name => pristine_role.name}})
|
139
|
-
end
|
140
|
-
|
141
|
-
register_change if permission.destroy
|
142
|
-
end
|
143
|
-
|
144
|
-
# register this permission as a known permission
|
145
|
-
def register_change
|
146
|
-
pristine_file.parse(true) unless pristine_file.permissions.present?
|
147
|
-
line_numbers = [line_number]
|
148
|
-
|
149
|
-
pristine_file.permissions.each do |permission|
|
150
|
-
line_numbers.push(permission.line_number) if permission.privilege_set_name == self.privilege_set_name && permission.pristine_role_id
|
151
|
-
end
|
152
|
-
|
153
|
-
line_numbers.each do |number|
|
154
|
-
Cbac::KnownPermission.create(:permission_number => number, :permission_type => pristine_role.known_permission_type) if Cbac::KnownPermission.count(:conditions => {:permission_number => number, :permission_type => pristine_role.known_permission_type}) == 0
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
# add this permission to the staging area
|
160
|
-
def stage
|
161
|
-
raise ArgumentError, "Error: this staged permission already exists. Record with line number #{line_number} is a duplicate permission." if exists?
|
162
|
-
return if known_permission_exists?
|
163
|
-
|
164
|
-
if operation == '-'
|
165
|
-
# if the reverse permission is also staged, remove it and do not add this one
|
166
|
-
if reverse_exists?
|
167
|
-
delete_reverse_permission
|
168
|
-
return
|
169
|
-
end
|
170
|
-
# if this is an attempt to revoke a permission, it should exist as a real cbac permission!
|
171
|
-
save if cbac_permission_exists?
|
172
|
-
elsif operation == '+'
|
173
|
-
# if this is an attempt to add a permission, it MUST not exist yet
|
174
|
-
save unless cbac_permission_exists?
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
# clear the staging area of all generic pristine permissions
|
181
|
-
def self.delete_generic_permissions
|
182
|
-
generic_staged_permissions = all(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type = ?", PristineRole.ROLE_TYPES[:generic]])
|
183
|
-
generic_staged_permissions.each do |permission|
|
184
|
-
delete(permission.id)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
# clear the staging area of all non generic permissions
|
189
|
-
def self.delete_non_generic_permissions
|
190
|
-
staged_permissions = all(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type != ?", PristineRole.ROLE_TYPES[:generic]])
|
191
|
-
staged_permissions.each do |permission|
|
192
|
-
delete(permission.id)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
def self.count_generic_permissions
|
197
|
-
count(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type = ?", PristineRole.ROLE_TYPES[:generic]])
|
198
|
-
end
|
199
|
-
|
200
|
-
def self.count_non_generic_permissions
|
201
|
-
count(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type != ?", PristineRole.ROLE_TYPES[:generic]])
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
end
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_role'))
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'pristine_permission'))
|
3
|
+
require 'active_record'
|
4
|
+
|
5
|
+
module Cbac
|
6
|
+
module CbacPristine
|
7
|
+
class PristinePermission < ActiveRecord::Base
|
8
|
+
set_table_name 'cbac_staged_permissions'
|
9
|
+
|
10
|
+
belongs_to :pristine_role, :class_name => "Cbac::CbacPristine::PristineRole"
|
11
|
+
belongs_to :pristine_file, :class_name => "Cbac::CbacPristine::AbstractPristineFile"
|
12
|
+
|
13
|
+
def privilege_set
|
14
|
+
Cbac::PrivilegeSetRecord.first(:conditions => {:name => privilege_set_name})
|
15
|
+
end
|
16
|
+
|
17
|
+
def operation_string
|
18
|
+
case operation
|
19
|
+
when '+'
|
20
|
+
return "add"
|
21
|
+
when '-'
|
22
|
+
return "revoke"
|
23
|
+
else
|
24
|
+
return "unknown"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#convert this pristine line to a yml statement which can be used to create a yml fixtures file
|
29
|
+
#executing this statement will result in one cbac_permission in the DB
|
30
|
+
def to_yml_fixture(fixture_id = nil)
|
31
|
+
raise ArgumentError, "Error: cannot convert line #{line_number.to_s} to yml because the role is not specified" if pristine_role.nil?
|
32
|
+
raise ArgumentError, "Error: cannot convert line #{line_number.to_s} to yml because the privilege_set_name is not specified" if privilege_set_name.blank?
|
33
|
+
|
34
|
+
fixture_id = line_number if fixture_id.nil?
|
35
|
+
|
36
|
+
yml = "cbac_permission_00" << fixture_id.to_s << ":\n"
|
37
|
+
yml << " id: " << fixture_id.to_s << "\n"
|
38
|
+
yml << " context_role: "
|
39
|
+
yml << pristine_role.name if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
40
|
+
yml << "\n"
|
41
|
+
yml << " generic_role_id: " << pristine_role.role_id.to_s << "\n"
|
42
|
+
yml << " privilege_set_id: <%= Cbac::PrivilegeSetRecord.find(:first, :conditions => {:name => '" << privilege_set_name << "'}).id %>\n"
|
43
|
+
yml << " created_at: " << Time.now.strftime("%Y-%m-%d %H:%M:%S") << "\n"
|
44
|
+
yml << " updated_at: " << Time.now.strftime("%Y-%m-%d %H:%M:%S") << "\n"
|
45
|
+
yml << "\n"
|
46
|
+
end
|
47
|
+
|
48
|
+
# checks if the current cbac permissions contains a permission which is exactly like this one
|
49
|
+
def cbac_permission_exists?
|
50
|
+
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
51
|
+
Cbac::Permission.count(:joins => [:privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :context_role => pristine_role.name}) > 0
|
52
|
+
else
|
53
|
+
Cbac::Permission.count(:joins => [:generic_role, :privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :cbac_generic_roles => {:name => pristine_role.name}}) > 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# checks if a pristine permission with the same properties(except line_number) exists in the database
|
58
|
+
def exists?
|
59
|
+
Cbac::CbacPristine::PristinePermission.count(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => operation}) > 0
|
60
|
+
end
|
61
|
+
|
62
|
+
# checks if a pristine permission with the exact same properties(except line_number), but the reverse operation exists in the database
|
63
|
+
def reverse_exists?
|
64
|
+
Cbac::CbacPristine::PristinePermission.count(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => reverse_operation}) > 0
|
65
|
+
end
|
66
|
+
|
67
|
+
# delete the pristine permission with the reverse operation of this one
|
68
|
+
def delete_reverse_permission
|
69
|
+
reverse_permission = Cbac::CbacPristine::PristinePermission.first(:conditions => {:privilege_set_name => privilege_set_name, :pristine_role_id => pristine_role_id, :operation => reverse_operation})
|
70
|
+
reverse_permission.delete
|
71
|
+
end
|
72
|
+
|
73
|
+
# get the reverse operation of this one
|
74
|
+
def reverse_operation
|
75
|
+
case operation
|
76
|
+
when '+'
|
77
|
+
return '-'
|
78
|
+
when '-'
|
79
|
+
return '+'
|
80
|
+
when 'x', '=>'
|
81
|
+
raise NotImplementedError, "Error: using an x or => in a pristine file is not implemented yet"
|
82
|
+
else
|
83
|
+
raise ArgumentError, "Error: invalid operation #{operation} is used in the pristine file"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# checks if the known_permissions table has an entry for this permission
|
88
|
+
def known_permission_exists?
|
89
|
+
Cbac::KnownPermission.count(:conditions => {:permission_type => pristine_role.known_permission_type, :permission_number => line_number}) > 0
|
90
|
+
end
|
91
|
+
|
92
|
+
# accept this permission and apply to the current cbac permission set
|
93
|
+
def accept
|
94
|
+
case operation
|
95
|
+
when '+'
|
96
|
+
handle_grant_permission
|
97
|
+
when '-'
|
98
|
+
handle_revoke_permission
|
99
|
+
when 'x', '=>'
|
100
|
+
raise NotImplementedError, "Error: using an x or => in a pristine file is not implemented yet"
|
101
|
+
else
|
102
|
+
raise ArgumentError, "Error: invalid operation #{operation} is used in the pristine file"
|
103
|
+
end
|
104
|
+
PristinePermission.delete(id) unless id.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
# reject this permission, but register it as a known permission. The user actually rejected this himself.
|
108
|
+
def reject
|
109
|
+
register_change
|
110
|
+
PristinePermission.delete(id) unless id.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
# add this permission to the cbac permission set, unless it already exists
|
114
|
+
def handle_grant_permission
|
115
|
+
return if cbac_permission_exists?
|
116
|
+
|
117
|
+
permission = Cbac::Permission.new
|
118
|
+
permission.privilege_set = privilege_set
|
119
|
+
|
120
|
+
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
121
|
+
permission.context_role = pristine_role.name
|
122
|
+
else
|
123
|
+
generic_role = Cbac::GenericRole.first(:conditions => {:name => pristine_role.name})
|
124
|
+
permission.generic_role = generic_role.nil? ? Cbac::GenericRole.create(:name => pristine_role.name, :remarks => "Autogenerated by Cbac loading / upgrade system") : generic_role
|
125
|
+
end
|
126
|
+
|
127
|
+
register_change if permission.save
|
128
|
+
permission
|
129
|
+
end
|
130
|
+
|
131
|
+
# revoke this permission from the current permission set, raises an error if it doesn't exist yet
|
132
|
+
def handle_revoke_permission
|
133
|
+
raise ArgumentError, "Error: trying to revoke permission #{privilege_set_name} for #{pristine_role.name}, but this permission does not exist" unless cbac_permission_exists?
|
134
|
+
|
135
|
+
if pristine_role.role_type == PristineRole.ROLE_TYPES[:context]
|
136
|
+
permission = Cbac::Permission.first(:joins => [:privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :context_role => pristine_role.name})
|
137
|
+
else
|
138
|
+
permission = Cbac::Permission.first(:joins => [:generic_role, :privilege_set], :conditions => {:cbac_privilege_set => {:name => privilege_set_name}, :cbac_generic_roles => {:name => pristine_role.name}})
|
139
|
+
end
|
140
|
+
|
141
|
+
register_change if permission.destroy
|
142
|
+
end
|
143
|
+
|
144
|
+
# register this permission as a known permission
|
145
|
+
def register_change
|
146
|
+
pristine_file.parse(true) unless pristine_file.permissions.present?
|
147
|
+
line_numbers = [line_number]
|
148
|
+
|
149
|
+
pristine_file.permissions.each do |permission|
|
150
|
+
line_numbers.push(permission.line_number) if permission.privilege_set_name == self.privilege_set_name && permission.pristine_role_id == self.pristine_role_id && permission.line_number < self.line_number
|
151
|
+
end
|
152
|
+
|
153
|
+
line_numbers.each do |number|
|
154
|
+
Cbac::KnownPermission.create(:permission_number => number, :permission_type => pristine_role.known_permission_type) if Cbac::KnownPermission.count(:conditions => {:permission_number => number, :permission_type => pristine_role.known_permission_type}) == 0
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
# add this permission to the staging area
|
160
|
+
def stage
|
161
|
+
raise ArgumentError, "Error: this staged permission already exists. Record with line number #{line_number} is a duplicate permission." if exists?
|
162
|
+
return if known_permission_exists?
|
163
|
+
|
164
|
+
if operation == '-'
|
165
|
+
# if the reverse permission is also staged, remove it and do not add this one
|
166
|
+
if reverse_exists?
|
167
|
+
delete_reverse_permission
|
168
|
+
return
|
169
|
+
end
|
170
|
+
# if this is an attempt to revoke a permission, it should exist as a real cbac permission!
|
171
|
+
save if cbac_permission_exists?
|
172
|
+
elsif operation == '+'
|
173
|
+
# if this is an attempt to add a permission, it MUST not exist yet
|
174
|
+
save unless cbac_permission_exists?
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
# clear the staging area of all generic pristine permissions
|
181
|
+
def self.delete_generic_permissions
|
182
|
+
generic_staged_permissions = all(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type = ?", PristineRole.ROLE_TYPES[:generic]])
|
183
|
+
generic_staged_permissions.each do |permission|
|
184
|
+
delete(permission.id)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# clear the staging area of all non generic permissions
|
189
|
+
def self.delete_non_generic_permissions
|
190
|
+
staged_permissions = all(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type != ?", PristineRole.ROLE_TYPES[:generic]])
|
191
|
+
staged_permissions.each do |permission|
|
192
|
+
delete(permission.id)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def self.count_generic_permissions
|
197
|
+
count(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type = ?", PristineRole.ROLE_TYPES[:generic]])
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.count_non_generic_permissions
|
201
|
+
count(:joins => :pristine_role, :conditions => ["cbac_staged_roles.role_type != ?", PristineRole.ROLE_TYPES[:generic]])
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|