cbac 0.6.1 → 0.6.2

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 (75) hide show
  1. data/Manifest +70 -74
  2. data/README.rdoc +51 -51
  3. data/Rakefile +39 -39
  4. data/cbac.gemspec +30 -31
  5. data/config/cbac/context_roles.rb +21 -21
  6. data/config/cbac/privileges.rb +50 -50
  7. data/context_roles.rb +21 -21
  8. data/init.rb +3 -3
  9. data/lib/cbac.rb +132 -132
  10. data/lib/cbac/cbac_pristine/pristine.rb +138 -135
  11. data/lib/cbac/cbac_pristine/pristine_file.rb +173 -170
  12. data/lib/cbac/cbac_pristine/pristine_permission.rb +205 -194
  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 -117
  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 -37
  25. data/lib/generators/cbac/USAGE +33 -33
  26. data/lib/generators/cbac/cbac_generator.rb +75 -75
  27. data/lib/generators/cbac/copy_files/config/cbac.pristine +2 -2
  28. data/lib/generators/cbac/copy_files/config/context_roles.rb +17 -17
  29. data/lib/generators/cbac/copy_files/config/privileges.rb +25 -25
  30. data/lib/generators/cbac/copy_files/controllers/generic_roles_controller.rb +30 -30
  31. data/lib/generators/cbac/copy_files/controllers/memberships_controller.rb +22 -22
  32. data/lib/generators/cbac/copy_files/controllers/permissions_controller.rb +61 -61
  33. data/lib/generators/cbac/copy_files/controllers/upgrade_controller.rb +23 -23
  34. data/lib/generators/cbac/copy_files/fixtures/cbac_generic_roles.yml +9 -9
  35. data/lib/generators/cbac/copy_files/fixtures/cbac_memberships.yml +8 -8
  36. data/lib/generators/cbac/copy_files/fixtures/cbac_permissions.yml +8 -8
  37. data/lib/generators/cbac/copy_files/initializers/cbac_config.rb +4 -4
  38. data/lib/generators/cbac/copy_files/migrate/create_cbac_from_scratch.rb +59 -59
  39. data/lib/generators/cbac/copy_files/migrate/create_cbac_upgrade_path.rb +40 -31
  40. data/lib/generators/cbac/copy_files/stylesheets/cbac.css +65 -65
  41. data/lib/generators/cbac/copy_files/tasks/cbac.rake +345 -345
  42. data/lib/generators/cbac/copy_files/views/generic_roles/index.html.erb +58 -58
  43. data/lib/generators/cbac/copy_files/views/layouts/cbac.html.erb +18 -18
  44. data/lib/generators/cbac/copy_files/views/memberships/_update.html.erb +11 -11
  45. data/lib/generators/cbac/copy_files/views/memberships/index.html.erb +23 -23
  46. data/lib/generators/cbac/copy_files/views/permissions/_update_context_role.html.erb +11 -11
  47. data/lib/generators/cbac/copy_files/views/permissions/_update_generic_role.html.erb +11 -11
  48. data/lib/generators/cbac/copy_files/views/permissions/index.html.erb +39 -39
  49. data/lib/generators/cbac/copy_files/views/upgrade/index.html.erb +31 -31
  50. data/migrations/20110211105533_add_pristine_files_to_cbac_upgrade_path.rb +16 -0
  51. data/privileges.rb +50 -50
  52. data/spec/cbac_pristine_file_spec.rb +329 -329
  53. data/spec/cbac_pristine_permission_spec.rb +358 -358
  54. data/spec/cbac_pristine_role_spec.rb +85 -85
  55. data/spec/rcov.opts +1 -1
  56. data/spec/spec.opts +4 -4
  57. data/spec/spec_helper.rb +11 -11
  58. data/tasks/cbac.rake +345 -345
  59. data/test/fixtures/cbac_generic_roles.yml +9 -9
  60. data/test/fixtures/cbac_memberships.yml +8 -8
  61. data/test/fixtures/cbac_permissions.yml +14 -14
  62. data/test/fixtures/cbac_privilege_set.yml +18 -18
  63. data/test/test_cbac_actions.rb +71 -71
  64. data/test/test_cbac_authorize_context_roles.rb +39 -39
  65. data/test/test_cbac_authorize_generic_roles.rb +36 -36
  66. data/test/test_cbac_context_role.rb +50 -50
  67. data/test/test_cbac_privilege.rb +151 -151
  68. data/test/test_cbac_privilege_set.rb +50 -50
  69. data/test/test_helper.rb +28 -28
  70. metadata +14 -15
  71. data/nbproject/private/private.properties +0 -3
  72. data/nbproject/private/private.xml +0 -4
  73. data/nbproject/private/rake-d.txt +0 -0
  74. data/nbproject/project.properties +0 -9
  75. data/nbproject/project.xml +0 -16
@@ -1,31 +1,40 @@
1
- class CreateCbacUpgradePath < ActiveRecord::Migration
2
- def self.up
3
-
4
- create_table :cbac_staged_permissions do |t|
5
- t.integer :pristine_role_id
6
- t.string :privilege_set_name
7
- t.integer :line_number
8
- t.string :comment
9
- t.text :operation, :limit => 2
10
- t.timestamps
11
- end
12
-
13
- create_table :cbac_staged_roles do |t|
14
- t.string :role_type
15
- t.string :name
16
- t.integer :role_id
17
- t.timestamps
18
- end
19
-
20
- create_table :cbac_known_permissions do |t|
21
- t.integer :permission_number, :null => :no
22
- t.integer :permission_type, :default => 0
23
- end
24
- end
25
-
26
- def self.down
27
- drop_table :cbac_staged_permissions
28
- drop_table :cbac_staged_roles
29
- drop_table :cbac_known_permissions
30
- end
31
- end
1
+ class CreateCbacUpgradePath < ActiveRecord::Migration
2
+ def self.up
3
+
4
+ create_table :cbac_pristine_files do |t|
5
+ t.string :type
6
+ t.string :file_name
7
+ t.timestamps
8
+ end
9
+
10
+ create_table :cbac_staged_permissions do |t|
11
+ t.integer :pristine_role_id
12
+ t.integer :pristine_file_id
13
+ t.string :privilege_set_name
14
+ t.integer :line_number
15
+ t.string :comment
16
+ t.text :operation, :limit => 2
17
+ t.timestamps
18
+ end
19
+
20
+ create_table :cbac_staged_roles do |t|
21
+ t.string :role_type
22
+ t.string :name
23
+ t.integer :role_id
24
+ t.timestamps
25
+ end
26
+
27
+ create_table :cbac_known_permissions do |t|
28
+ t.integer :permission_number, :null => :no
29
+ t.integer :permission_type, :default => 0
30
+ end
31
+
32
+ end
33
+
34
+ def self.down
35
+ drop_table :cbac_pristine_files
36
+ drop_table :cbac_staged_permissions
37
+ drop_table :cbac_staged_roles
38
+ drop_table :cbac_known_permissions
39
+ end
40
+ end
@@ -1,65 +1,65 @@
1
- /****
2
- * General
3
- */
4
-
5
- div.cbac h1 {
6
-
7
- }
8
-
9
- div.cbac table {
10
- padding: 0px;
11
- margin: 0px;
12
- border-collapse: collapse;
13
- }
14
-
15
- div.cbac div.linebreak {
16
- height: 20px;
17
- }
18
-
19
- /****
20
- * Table
21
- */
22
-
23
- div.cbac th {
24
- background-color: #ABEB71;
25
- }
26
-
27
- div.cbac td, div.cbac th {
28
- border: 1px solid black;
29
- }
30
-
31
- div.cbac td.small, div.cbac th.small {
32
- width: 50px;
33
- }
34
-
35
- div.cbac td.medium, div.cbac th.medium {
36
- width: 150px;
37
- }
38
-
39
- div.cbac td.large, div.cbac th.large {
40
- width: 600px;
41
- }
42
-
43
- div.cbac td.checked {
44
- text-align: center;
45
- }
46
-
47
- div.cbac td.submit {
48
- text-align: right;
49
- }
50
-
51
- /****
52
- * Controls
53
- */
54
-
55
- div.cbac input[type="text"] {
56
- margin: 2px;
57
- }
58
-
59
- div.cbac td.medium input[type="text"] {
60
- width: 138px;
61
- }
62
-
63
- div.cbac td.large input[type="text"] {
64
- width: 588px;
65
- }
1
+ /****
2
+ * General
3
+ */
4
+
5
+ div.cbac h1 {
6
+
7
+ }
8
+
9
+ div.cbac table {
10
+ padding: 0px;
11
+ margin: 0px;
12
+ border-collapse: collapse;
13
+ }
14
+
15
+ div.cbac div.linebreak {
16
+ height: 20px;
17
+ }
18
+
19
+ /****
20
+ * Table
21
+ */
22
+
23
+ div.cbac th {
24
+ background-color: #ABEB71;
25
+ }
26
+
27
+ div.cbac td, div.cbac th {
28
+ border: 1px solid black;
29
+ }
30
+
31
+ div.cbac td.small, div.cbac th.small {
32
+ width: 50px;
33
+ }
34
+
35
+ div.cbac td.medium, div.cbac th.medium {
36
+ width: 150px;
37
+ }
38
+
39
+ div.cbac td.large, div.cbac th.large {
40
+ width: 600px;
41
+ }
42
+
43
+ div.cbac td.checked {
44
+ text-align: center;
45
+ }
46
+
47
+ div.cbac td.submit {
48
+ text-align: right;
49
+ }
50
+
51
+ /****
52
+ * Controls
53
+ */
54
+
55
+ div.cbac input[type="text"] {
56
+ margin: 2px;
57
+ }
58
+
59
+ div.cbac td.medium input[type="text"] {
60
+ width: 138px;
61
+ }
62
+
63
+ div.cbac td.large input[type="text"] {
64
+ width: 588px;
65
+ }
@@ -1,345 +1,345 @@
1
- #TODO: zip (or something) the directory resulting from a snapshot and delete it
2
- #TODO: unzip (or something) the provided snapshot and load from it, then delete temp dir
3
- #TODO: add staging area to extracted snapshot, inserted snapshot, clearing code, etc.
4
-
5
- #TODO: add comments to pristine lines, in a Comment() style
6
-
7
- # WARNING: Non-changes are not saved as known_permissions when using pristine or such. THIS IS NOT A BUG! Think of the following scenario:
8
- # 1) Developers grant permission X
9
- # 2) User deploys. Permission X is granted in the database.
10
- # 3) User revokes permission X
11
- # 4) Developers revoke permission X
12
- # 5) User upgrades. No change in permission X detected, (since devteam and user agree) so the user is not prompted to accept the change.
13
- # 6) User grants permission X again
14
- # 7) User upgrades again. At this point, we want the user to be warned that the devteam thinks granting this permission is not a good idea.
15
- # This is only possible if the non-change in #5 is not registered as KnownChange
16
-
17
- # Get a privilege set that fulfills the provided conditions
18
- def get_privilege_set(conditions)
19
- Cbac::PrivilegeSetRecord.first(:conditions => conditions)
20
- end
21
-
22
- # Get a Hash containing all entries from the provided table
23
- def select_all(table)
24
- ActiveRecord::Base.connection.select_all("SELECT * FROM %s;" % table)
25
- end
26
-
27
- # Generate a usable filename for dumping records of the specified type
28
- def get_filename(type)
29
- "#{ENV['SNAPSHOT_NAME']}/cbac_#{type}.yml"
30
- end
31
-
32
- def load_objects_from_yaml(type)
33
- filename = get_filename(type)
34
-
35
- Yaml.load_file(filename)
36
- end
37
-
38
- # Dump the specified permissions to a YAML file
39
- def dump_permissions_to_yaml_file(permissions)
40
- permissions.each do |cp|
41
- privilege_set_name = get_privilege_set(:id => cp['privilege_set_id']).name
42
- cp['privilege_set_id'] = "<%= Cbac::PrivilegeSetRecord.find(:first, :conditions => {:name => '#{privilege_set_name}'}).id %>"
43
- end
44
- dump_objects_to_yaml_file(permissions, "permissions")
45
- end
46
-
47
- # Dump a set of objects to a YAML file. Filename is determined by type-string
48
- def dump_objects_to_yaml_file(objects, type)
49
- filename = get_filename(type)
50
-
51
- puts "Writing #{type} to disk"
52
-
53
- File.open(filename, "w") do |output_file|
54
- index = "0000"
55
- output_file.write objects.inject({}) { |hash, record|
56
- hash["#{type.singularize}_#{index.succ!}"] = record
57
- hash
58
- }.to_yaml
59
- end
60
- end
61
-
62
- def get_cbac_pristine_adapter
63
- adapter_class = Class.new
64
- adapter_class.send :include, Cbac::CbacPristine
65
- adapter_class.new
66
- end
67
-
68
- namespace :cbac do
69
- desc 'Initialize CBAC tables with bootstrap data. Allows ADMINUSER to log in and visit CBAC administration pages. Also, if a Privilege Set called "login" exists, this privilege is granted to "everyone"'
70
- task :bootstrap => :environment do
71
- adapter = get_cbac_pristine_adapter
72
- if adapter.database_contains_cbac_data?
73
- if ENV['FORCE'] == "true"
74
- puts "FORCE specified: emptying CBAC tables"
75
- adapter.clear_cbac_tables
76
- else
77
- puts "CBAC bootstrap failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
78
- exit
79
- end
80
- end
81
-
82
- adminuser = ENV['ADMINUSER'] || 1
83
- login_privilege_set = get_privilege_set(:name => "login")
84
- everybody_context_role = ContextRole.roles[:everybody]
85
- if !login_privilege_set.nil? and !everybody_context_role.nil?
86
- puts "Login privilege exists. Allowing context role 'everybody' to use login privilege"
87
- login_permission = Cbac::Permission.new(:context_role => 'everybody', :privilege_set_id => login_privilege_set.id)
88
- throw "Failed to save Login Permission" unless login_permission.save
89
- end
90
-
91
- puts "Creating Generic Role: administrators"
92
- admin_role = Cbac::GenericRole.new(:name => "administrator", :remarks => "System administrators - may edit CBAC permissions")
93
- throw "Failed to save new Generic Role" unless admin_role.save
94
-
95
- puts "Creating Administrator Membership for user #{adminuser}"
96
- membership = Cbac::Membership.new(:user_id => adminuser, :generic_role_id => admin_role.id)
97
- throw "Failed to save new Administrator Membership" unless membership.save
98
-
99
- begin
100
- admin_privilege_set_id = get_privilege_set({:name => 'cbac_administration'}).id
101
- rescue
102
- throw "No PrivilegeSet cbac_administration defined. Aborting."
103
- end
104
- cbac_admin_permission = Cbac::Permission.new(:generic_role_id => admin_role.id, :privilege_set_id => admin_privilege_set_id)
105
- throw "Failed to save Cbac_Administration Permission" unless cbac_admin_permission.save
106
-
107
- puts <<EOF
108
- **********************************************************
109
- * Succesfully bootstrapped CBAC. The specified user (# #{adminuser} ) *
110
- * may now visit the cbac administration pages, which are *
111
- * located at the URL /cbac/permissions/index by default *
112
- **********************************************************
113
- EOF
114
- end
115
-
116
- desc 'Extract a snapshot of the current authorization settings, which can later be restored using the restore_snapshot task. Parameter SNAPSHOT_NAME determines where the snapshot is stored'
117
- task :extract_snapshot => :environment do
118
- if ENV['SNAPSHOT_NAME'].nil?
119
- puts "Missing argument SNAPSHOT_NAME. Substituting timestamp for SNAPSHOT_NAME"
120
- require 'date'
121
- ENV['SNAPSHOT_NAME'] = DateTime.now.strftime("%Y%m%d%H%M%S")
122
- end
123
-
124
- if File::exists?(ENV['SNAPSHOT_NAME']) # Directory already exists!
125
- if ENV['FORCE'] == "true"
126
- puts "FORCE specified - overwriting older snapshot with same name."
127
- else
128
- puts "A snapshot with the given name (#{ENV['SNAPSHOT_NAME']}) already exists, and overwriting is dangerous. Specify FORCE=true to override this check"
129
- exit
130
- end
131
- else # Directory does not exist yet
132
- FileUtils.mkdir(ENV['SNAPSHOT_NAME'])
133
- end
134
-
135
- puts "Extracting CBAC permissions to #{ENV['SNAPSHOT_NAME']}"
136
-
137
- # Don't need privilege sets since they are loaded from a config file.
138
- staged_changes = select_all "cbac_staged_permissions"
139
- dump_objects_to_yaml_file(staged_changes, "staged_permissions")
140
-
141
- staged_roles = select_all "cbac_staged_roles"
142
- dump_objects_to_yaml_file(staged_roles, "staged_roles")
143
-
144
- permissions = select_all "cbac_permissions"
145
- dump_permissions_to_yaml_file(permissions)
146
-
147
- generic_roles = select_all "cbac_generic_roles"
148
- dump_objects_to_yaml_file(generic_roles, "generic_roles")
149
-
150
- memberships = select_all "cbac_memberships"
151
- dump_objects_to_yaml_file(memberships, "memberships")
152
-
153
- known_permissions = select_all "cbac_known_permissions"
154
- dump_objects_to_yaml_file(known_permissions, "known_permissions")
155
- end
156
-
157
- desc 'Restore a snapshot of authorization settings that was extracted earlier. Specify a snapshot using SNAPSHOT_NAME'
158
- task :restore_snapshot => :environment do
159
- adapter = get_cbac_pristine_adapter
160
- if ENV['SNAPSHOT_NAME'].nil?
161
- puts "Missing required parameter SNAPSHOT_NAME. Exiting."
162
- exit
163
- elsif adapter.database_contains_cbac_data?
164
- if ENV['FORCE'] == "true"
165
- puts "FORCE specified: emptying CBAC tables"
166
- adapter.clear_cbac_tables
167
- else
168
- puts "Reloading snapshot failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
169
- exit
170
- end
171
- end
172
-
173
- puts "Restoring snapshot #{ENV['SNAPSHOT_NAME']}"
174
-
175
- ENV['FIXTURES_PATH'] = ENV['SNAPSHOT_NAME']
176
-
177
- # Don't need privilege sets since they are loaded from a config file.
178
- ENV['FIXTURES'] = "cbac_generic_roles,cbac_memberships,cbac_known_permissions,cbac_permissions,cbac_staged_permissions, cbac_staged_roles"
179
-
180
- Rake::Task["db:fixtures:load"].invoke
181
- puts "Successfully restored snapshot."
182
- #TODO: check if rake task was successful. else
183
- # puts "Restoring snapshot failed."
184
- #end
185
- end
186
-
187
- desc 'Restore permissions to factory settings by loading the pristine file into the database'
188
- task :pristine => :environment do
189
- adapter = get_cbac_pristine_adapter
190
- if adapter.database_contains_cbac_data?
191
- if ENV['FORCE'] == "true"
192
- puts "FORCE specified: emptying CBAC tables"
193
- else
194
- puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
195
- exit
196
- end
197
- end
198
-
199
- if ENV['SKIP_SNAPSHOT'] == 'true'
200
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
201
- else
202
- puts "\nDumping a snapshot of the database"
203
- Rake::Task["cbac:extract_snapshot"].invoke
204
- end
205
- filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
206
- puts "Parsing pristine file #{filename}"
207
- pristine_file = adapter.create_pristine_file(filename)
208
- adapter.set_pristine_state([pristine_file], true)
209
- puts "Applied #{pristine_file.permissions.length.to_s} permissions."
210
- puts "Task cbac:pristine finished."
211
- end
212
-
213
- desc 'Restore generic permissions to factory settings'
214
- task :pristine_generic => :environment do
215
- adapter = get_cbac_pristine_adapter
216
- if adapter.database_contains_cbac_data?
217
- if ENV['FORCE'] == "true"
218
- puts "FORCE specified. Dropping all generic permissions and replacing them with generic pristine"
219
- adapter.delete_generic_known_permissions
220
- adapter.delete_generic_permissions
221
- else
222
- puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
223
- exit
224
- end
225
- end
226
-
227
- if ENV['SKIP_SNAPSHOT'] == 'true'
228
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
229
- else
230
- puts "\nDumping a snapshot of the database"
231
- Rake::Task["cbac:extract_snapshot"].invoke
232
- end
233
-
234
- filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
235
- puts "Parsing pristine file #{filename}"
236
- pristine_file = adapter.create_generic_pristine_file(filename)
237
- adapter.set_pristine_state([pristine_file], false)
238
- puts "Applied #{pristine_file.permissions.length.to_s} permissions."
239
- puts "Task cbac:pristine_generic finished."
240
- end
241
-
242
- desc 'Restore all permissions to factory state. Uses the pristine file and the generic pristine file'
243
- task :pristine_all => :environment do
244
- adapter = get_cbac_pristine_adapter
245
- if adapter.database_contains_cbac_data?
246
- if ENV['FORCE'] == "true"
247
- puts "FORCE specified: emptying CBAC tables"
248
- else
249
- puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
250
- exit
251
- end
252
- end
253
-
254
- if ENV['SKIP_SNAPSHOT'] == 'true'
255
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
256
- else
257
- puts "\nDumping a snapshot of the database"
258
- Rake::Task["cbac:extract_snapshot"].invoke
259
- end
260
- filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
261
- generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
262
- puts "Parsing pristine file #{filename} and generic pristine file #{generic_filename}"
263
- pristine_file = adapter.create_pristine_file(filename)
264
- generic_pristine_file = adapter.create_generic_pristine_file(generic_filename)
265
- adapter.set_pristine_state([pristine_file, generic_pristine_file], true)
266
- puts "Applied #{pristine_file.permissions.length.to_s} permissions and #{generic_pristine_file.permissions.length.to_s} generic permissions."
267
- puts "Task cbac:pristine_all finished."
268
- end
269
-
270
- desc 'Upgrade permissions by adding them to the staging area. Does not upgrade generic permissions'
271
- task :upgrade_pristine => :environment do
272
- adapter = get_cbac_pristine_adapter
273
- if ENV['SKIP_SNAPSHOT'] == 'true'
274
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
275
- else
276
- puts "\nDumping a snapshot of the database"
277
- Rake::Task["cbac:extract_snapshot"].invoke
278
- end
279
-
280
- ENV['CHANGE_TYPE'] = 'context'
281
- filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
282
- puts "Parsing pristine file #{filename}"
283
-
284
- pristine_file = adapter.create_pristine_file(filename)
285
- adapter.delete_non_generic_staged_permissions
286
- puts "Deleted all staged context and administrator permissions"
287
-
288
- adapter.stage_permissions([pristine_file])
289
- puts "Staged #{adapter.number_of_non_generic_staged_permissions.to_s} permissions."
290
- puts "Task cbac:upgrade_pristine finished."
291
- end
292
-
293
-
294
- desc 'Upgrade generic permissions by adding them to the staging area. Does not upgrade context or admin permissions.'
295
- task :upgrade_pristine_generic => :environment do
296
- adapter = get_cbac_pristine_adapter
297
- if ENV['SKIP_SNAPSHOT'] == 'true'
298
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
299
- else
300
- puts "\nDumping a snapshot of the database"
301
- Rake::Task["cbac:extract_snapshot"].invoke
302
- end
303
-
304
- ENV['CHANGE_TYPE'] = 'context'
305
- generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
306
-
307
- puts "Parsing pristine file #{generic_filename}"
308
- generic_pristine_file = adapter.create_generic_pristine_file(generic_filename)
309
-
310
- adapter.delete_non_generic_staged_permissions
311
- puts "Deleted all staged generic permissions"
312
-
313
- adapter.stage_permissions([generic_pristine_file])
314
- puts "Staged #{adapter.number_of_generic_staged_permissions.to_s} generic permissions."
315
- puts "Task cbac:upgrade_pristine finished."
316
- end
317
-
318
- desc 'Upgrade all permissions by adding them to the staging area.'
319
- task :upgrade_all => :environment do
320
- adapter = get_cbac_pristine_adapter
321
- if ENV['SKIP_SNAPSHOT'] == 'true'
322
- puts "\nSKIP_SNAPSHOT provided - not dumping database."
323
- else
324
- puts "\nDumping a snapshot of the database"
325
- Rake::Task["cbac:extract_snapshot"].invoke
326
- end
327
-
328
- ENV['CHANGE_TYPE'] = 'context'
329
- filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
330
- generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
331
- puts "Parsing pristine file #{filename} and generic pristine file #{generic_filename}"
332
-
333
- pristine_file = adapter.create_pristine_file(filename)
334
- generic_pristine_file = adapter.create_generic_pristine_file(generic_filename)
335
-
336
- adapter.delete_generic_staged_permissions
337
- adapter.delete_non_generic_staged_permissions
338
- puts "Deleted all current staged permissions"
339
-
340
-
341
- adapter.stage_permissions([pristine_file, generic_pristine_file])
342
- puts "Staged #{adapter.number_of_non_generic_staged_permissions.to_s} permissions and #{adapter.number_of_generic_staged_permissions.to_s} generic permissions."
343
- puts "Task cbac:upgrade_all finished."
344
- end
345
- end
1
+ #TODO: zip (or something) the directory resulting from a snapshot and delete it
2
+ #TODO: unzip (or something) the provided snapshot and load from it, then delete temp dir
3
+ #TODO: add staging area to extracted snapshot, inserted snapshot, clearing code, etc.
4
+
5
+ #TODO: add comments to pristine lines, in a Comment() style
6
+
7
+ # WARNING: Non-changes are not saved as known_permissions when using pristine or such. THIS IS NOT A BUG! Think of the following scenario:
8
+ # 1) Developers grant permission X
9
+ # 2) User deploys. Permission X is granted in the database.
10
+ # 3) User revokes permission X
11
+ # 4) Developers revoke permission X
12
+ # 5) User upgrades. No change in permission X detected, (since devteam and user agree) so the user is not prompted to accept the change.
13
+ # 6) User grants permission X again
14
+ # 7) User upgrades again. At this point, we want the user to be warned that the devteam thinks granting this permission is not a good idea.
15
+ # This is only possible if the non-change in #5 is not registered as KnownChange
16
+
17
+ # Get a privilege set that fulfills the provided conditions
18
+ def get_privilege_set(conditions)
19
+ Cbac::PrivilegeSetRecord.first(:conditions => conditions)
20
+ end
21
+
22
+ # Get a Hash containing all entries from the provided table
23
+ def select_all(table)
24
+ ActiveRecord::Base.connection.select_all("SELECT * FROM %s;" % table)
25
+ end
26
+
27
+ # Generate a usable filename for dumping records of the specified type
28
+ def get_filename(type)
29
+ "#{ENV['SNAPSHOT_NAME']}/cbac_#{type}.yml"
30
+ end
31
+
32
+ def load_objects_from_yaml(type)
33
+ filename = get_filename(type)
34
+
35
+ Yaml.load_file(filename)
36
+ end
37
+
38
+ # Dump the specified permissions to a YAML file
39
+ def dump_permissions_to_yaml_file(permissions)
40
+ permissions.each do |cp|
41
+ privilege_set_name = get_privilege_set(:id => cp['privilege_set_id']).name
42
+ cp['privilege_set_id'] = "<%= Cbac::PrivilegeSetRecord.find(:first, :conditions => {:name => '#{privilege_set_name}'}).id %>"
43
+ end
44
+ dump_objects_to_yaml_file(permissions, "permissions")
45
+ end
46
+
47
+ # Dump a set of objects to a YAML file. Filename is determined by type-string
48
+ def dump_objects_to_yaml_file(objects, type)
49
+ filename = get_filename(type)
50
+
51
+ puts "Writing #{type} to disk"
52
+
53
+ File.open(filename, "w") do |output_file|
54
+ index = "0000"
55
+ output_file.write objects.inject({}) { |hash, record|
56
+ hash["#{type.singularize}_#{index.succ!}"] = record
57
+ hash
58
+ }.to_yaml
59
+ end
60
+ end
61
+
62
+ def get_cbac_pristine_adapter
63
+ adapter_class = Class.new
64
+ adapter_class.send :include, Cbac::CbacPristine
65
+ adapter_class.new
66
+ end
67
+
68
+ namespace :cbac do
69
+ desc 'Initialize CBAC tables with bootstrap data. Allows ADMINUSER to log in and visit CBAC administration pages. Also, if a Privilege Set called "login" exists, this privilege is granted to "everyone"'
70
+ task :bootstrap => :environment do
71
+ adapter = get_cbac_pristine_adapter
72
+ if adapter.database_contains_cbac_data?
73
+ if ENV['FORCE'] == "true"
74
+ puts "FORCE specified: emptying CBAC tables"
75
+ adapter.clear_cbac_tables
76
+ else
77
+ puts "CBAC bootstrap failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
78
+ exit
79
+ end
80
+ end
81
+
82
+ adminuser = ENV['ADMINUSER'] || 1
83
+ login_privilege_set = get_privilege_set(:name => "login")
84
+ everybody_context_role = ContextRole.roles[:everybody]
85
+ if !login_privilege_set.nil? and !everybody_context_role.nil?
86
+ puts "Login privilege exists. Allowing context role 'everybody' to use login privilege"
87
+ login_permission = Cbac::Permission.new(:context_role => 'everybody', :privilege_set_id => login_privilege_set.id)
88
+ throw "Failed to save Login Permission" unless login_permission.save
89
+ end
90
+
91
+ puts "Creating Generic Role: administrators"
92
+ admin_role = Cbac::GenericRole.new(:name => "administrator", :remarks => "System administrators - may edit CBAC permissions")
93
+ throw "Failed to save new Generic Role" unless admin_role.save
94
+
95
+ puts "Creating Administrator Membership for user #{adminuser}"
96
+ membership = Cbac::Membership.new(:user_id => adminuser, :generic_role_id => admin_role.id)
97
+ throw "Failed to save new Administrator Membership" unless membership.save
98
+
99
+ begin
100
+ admin_privilege_set_id = get_privilege_set({:name => 'cbac_administration'}).id
101
+ rescue
102
+ throw "No PrivilegeSet cbac_administration defined. Aborting."
103
+ end
104
+ cbac_admin_permission = Cbac::Permission.new(:generic_role_id => admin_role.id, :privilege_set_id => admin_privilege_set_id)
105
+ throw "Failed to save Cbac_Administration Permission" unless cbac_admin_permission.save
106
+
107
+ puts <<EOF
108
+ **********************************************************
109
+ * Succesfully bootstrapped CBAC. The specified user (# #{adminuser} ) *
110
+ * may now visit the cbac administration pages, which are *
111
+ * located at the URL /cbac/permissions/index by default *
112
+ **********************************************************
113
+ EOF
114
+ end
115
+
116
+ desc 'Extract a snapshot of the current authorization settings, which can later be restored using the restore_snapshot task. Parameter SNAPSHOT_NAME determines where the snapshot is stored'
117
+ task :extract_snapshot => :environment do
118
+ if ENV['SNAPSHOT_NAME'].nil?
119
+ puts "Missing argument SNAPSHOT_NAME. Substituting timestamp for SNAPSHOT_NAME"
120
+ require 'date'
121
+ ENV['SNAPSHOT_NAME'] = DateTime.now.strftime("%Y%m%d%H%M%S")
122
+ end
123
+
124
+ if File::exists?(ENV['SNAPSHOT_NAME']) # Directory already exists!
125
+ if ENV['FORCE'] == "true"
126
+ puts "FORCE specified - overwriting older snapshot with same name."
127
+ else
128
+ puts "A snapshot with the given name (#{ENV['SNAPSHOT_NAME']}) already exists, and overwriting is dangerous. Specify FORCE=true to override this check"
129
+ exit
130
+ end
131
+ else # Directory does not exist yet
132
+ FileUtils.mkdir(ENV['SNAPSHOT_NAME'])
133
+ end
134
+
135
+ puts "Extracting CBAC permissions to #{ENV['SNAPSHOT_NAME']}"
136
+
137
+ # Don't need privilege sets since they are loaded from a config file.
138
+ staged_changes = select_all "cbac_staged_permissions"
139
+ dump_objects_to_yaml_file(staged_changes, "staged_permissions")
140
+
141
+ staged_roles = select_all "cbac_staged_roles"
142
+ dump_objects_to_yaml_file(staged_roles, "staged_roles")
143
+
144
+ permissions = select_all "cbac_permissions"
145
+ dump_permissions_to_yaml_file(permissions)
146
+
147
+ generic_roles = select_all "cbac_generic_roles"
148
+ dump_objects_to_yaml_file(generic_roles, "generic_roles")
149
+
150
+ memberships = select_all "cbac_memberships"
151
+ dump_objects_to_yaml_file(memberships, "memberships")
152
+
153
+ known_permissions = select_all "cbac_known_permissions"
154
+ dump_objects_to_yaml_file(known_permissions, "known_permissions")
155
+ end
156
+
157
+ desc 'Restore a snapshot of authorization settings that was extracted earlier. Specify a snapshot using SNAPSHOT_NAME'
158
+ task :restore_snapshot => :environment do
159
+ adapter = get_cbac_pristine_adapter
160
+ if ENV['SNAPSHOT_NAME'].nil?
161
+ puts "Missing required parameter SNAPSHOT_NAME. Exiting."
162
+ exit
163
+ elsif adapter.database_contains_cbac_data?
164
+ if ENV['FORCE'] == "true"
165
+ puts "FORCE specified: emptying CBAC tables"
166
+ adapter.clear_cbac_tables
167
+ else
168
+ puts "Reloading snapshot failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
169
+ exit
170
+ end
171
+ end
172
+
173
+ puts "Restoring snapshot #{ENV['SNAPSHOT_NAME']}"
174
+
175
+ ENV['FIXTURES_PATH'] = ENV['SNAPSHOT_NAME']
176
+
177
+ # Don't need privilege sets since they are loaded from a config file.
178
+ ENV['FIXTURES'] = "cbac_generic_roles,cbac_memberships,cbac_known_permissions,cbac_permissions,cbac_staged_permissions, cbac_staged_roles"
179
+
180
+ Rake::Task["db:fixtures:load"].invoke
181
+ puts "Successfully restored snapshot."
182
+ #TODO: check if rake task was successful. else
183
+ # puts "Restoring snapshot failed."
184
+ #end
185
+ end
186
+
187
+ desc 'Restore permissions to factory settings by loading the pristine file into the database'
188
+ task :pristine => :environment do
189
+ adapter = get_cbac_pristine_adapter
190
+ if adapter.database_contains_cbac_data?
191
+ if ENV['FORCE'] == "true"
192
+ puts "FORCE specified: emptying CBAC tables"
193
+ else
194
+ puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
195
+ exit
196
+ end
197
+ end
198
+
199
+ if ENV['SKIP_SNAPSHOT'] == 'true'
200
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
201
+ else
202
+ puts "\nDumping a snapshot of the database"
203
+ Rake::Task["cbac:extract_snapshot"].invoke
204
+ end
205
+ filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
206
+ puts "Parsing pristine file #{filename}"
207
+ pristine_file = adapter.find_or_create_pristine_file(filename)
208
+ adapter.set_pristine_state([pristine_file], true)
209
+ puts "Applied #{pristine_file.permissions.length.to_s} permissions."
210
+ puts "Task cbac:pristine finished."
211
+ end
212
+
213
+ desc 'Restore generic permissions to factory settings'
214
+ task :pristine_generic => :environment do
215
+ adapter = get_cbac_pristine_adapter
216
+ if adapter.database_contains_cbac_data?
217
+ if ENV['FORCE'] == "true"
218
+ puts "FORCE specified. Dropping all generic permissions and replacing them with generic pristine"
219
+ adapter.delete_generic_known_permissions
220
+ adapter.delete_generic_permissions
221
+ else
222
+ puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
223
+ exit
224
+ end
225
+ end
226
+
227
+ if ENV['SKIP_SNAPSHOT'] == 'true'
228
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
229
+ else
230
+ puts "\nDumping a snapshot of the database"
231
+ Rake::Task["cbac:extract_snapshot"].invoke
232
+ end
233
+
234
+ filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
235
+ puts "Parsing pristine file #{filename}"
236
+ pristine_file = adapter.find_or_create_generic_pristine_file(filename)
237
+ adapter.set_pristine_state([pristine_file], false)
238
+ puts "Applied #{pristine_file.permissions.length.to_s} permissions."
239
+ puts "Task cbac:pristine_generic finished."
240
+ end
241
+
242
+ desc 'Restore all permissions to factory state. Uses the pristine file and the generic pristine file'
243
+ task :pristine_all => :environment do
244
+ adapter = get_cbac_pristine_adapter
245
+ if adapter.database_contains_cbac_data?
246
+ if ENV['FORCE'] == "true"
247
+ puts "FORCE specified: emptying CBAC tables"
248
+ else
249
+ puts "CBAC pristine failed: CBAC tables are nonempty. Specify FORCE=true to override this check and empty the tables"
250
+ exit
251
+ end
252
+ end
253
+
254
+ if ENV['SKIP_SNAPSHOT'] == 'true'
255
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
256
+ else
257
+ puts "\nDumping a snapshot of the database"
258
+ Rake::Task["cbac:extract_snapshot"].invoke
259
+ end
260
+ filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
261
+ generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
262
+ puts "Parsing pristine file #{filename} and generic pristine file #{generic_filename}"
263
+ pristine_file = adapter.find_or_create_pristine_file(filename)
264
+ generic_pristine_file = adapter.find_or_create_generic_pristine_file(generic_filename)
265
+ adapter.set_pristine_state([pristine_file, generic_pristine_file], true)
266
+ puts "Applied #{pristine_file.permissions.length.to_s} permissions and #{generic_pristine_file.permissions.length.to_s} generic permissions."
267
+ puts "Task cbac:pristine_all finished."
268
+ end
269
+
270
+ desc 'Upgrade permissions by adding them to the staging area. Does not upgrade generic permissions'
271
+ task :upgrade_pristine => :environment do
272
+ adapter = get_cbac_pristine_adapter
273
+ if ENV['SKIP_SNAPSHOT'] == 'true'
274
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
275
+ else
276
+ puts "\nDumping a snapshot of the database"
277
+ Rake::Task["cbac:extract_snapshot"].invoke
278
+ end
279
+
280
+ ENV['CHANGE_TYPE'] = 'context'
281
+ filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
282
+ puts "Parsing pristine file #{filename}"
283
+
284
+ pristine_file = adapter.find_or_create_pristine_file(filename)
285
+ adapter.delete_non_generic_staged_permissions
286
+ puts "Deleted all staged context and administrator permissions"
287
+
288
+ adapter.stage_permissions([pristine_file])
289
+ puts "Staged #{adapter.number_of_non_generic_staged_permissions.to_s} permissions."
290
+ puts "Task cbac:upgrade_pristine finished."
291
+ end
292
+
293
+
294
+ desc 'Upgrade generic permissions by adding them to the staging area. Does not upgrade context or admin permissions.'
295
+ task :upgrade_pristine_generic => :environment do
296
+ adapter = get_cbac_pristine_adapter
297
+ if ENV['SKIP_SNAPSHOT'] == 'true'
298
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
299
+ else
300
+ puts "\nDumping a snapshot of the database"
301
+ Rake::Task["cbac:extract_snapshot"].invoke
302
+ end
303
+
304
+ ENV['CHANGE_TYPE'] = 'context'
305
+ generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
306
+
307
+ puts "Parsing pristine file #{generic_filename}"
308
+ generic_pristine_file = adapter.find_or_create_generic_pristine_file(generic_filename)
309
+
310
+ adapter.delete_non_generic_staged_permissions
311
+ puts "Deleted all staged generic permissions"
312
+
313
+ adapter.stage_permissions([generic_pristine_file])
314
+ puts "Staged #{adapter.number_of_generic_staged_permissions.to_s} generic permissions."
315
+ puts "Task cbac:upgrade_pristine finished."
316
+ end
317
+
318
+ desc 'Upgrade all permissions by adding them to the staging area.'
319
+ task :upgrade_all => :environment do
320
+ adapter = get_cbac_pristine_adapter
321
+ if ENV['SKIP_SNAPSHOT'] == 'true'
322
+ puts "\nSKIP_SNAPSHOT provided - not dumping database."
323
+ else
324
+ puts "\nDumping a snapshot of the database"
325
+ Rake::Task["cbac:extract_snapshot"].invoke
326
+ end
327
+
328
+ ENV['CHANGE_TYPE'] = 'context'
329
+ filename = ENV['PRISTINE_FILE'] || "config/cbac/cbac.pristine"
330
+ generic_filename = ENV['GENERIC_PRISTINE_FILE'] || "config/cbac/cbac_generic.pristine"
331
+ puts "Parsing pristine file #{filename} and generic pristine file #{generic_filename}"
332
+
333
+ pristine_file = adapter.find_or_create_pristine_file(filename)
334
+ generic_pristine_file = adapter.find_or_create_generic_pristine_file(generic_filename)
335
+
336
+ adapter.delete_generic_staged_permissions
337
+ adapter.delete_non_generic_staged_permissions
338
+ puts "Deleted all current staged permissions"
339
+
340
+
341
+ adapter.stage_permissions([pristine_file, generic_pristine_file])
342
+ puts "Staged #{adapter.number_of_non_generic_staged_permissions.to_s} permissions and #{adapter.number_of_generic_staged_permissions.to_s} generic permissions."
343
+ puts "Task cbac:upgrade_all finished."
344
+ end
345
+ end