cbac 0.5.4 → 0.6.0

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