cbac 0.5.4 → 0.6.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.
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