cbac 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Manifest +71 -71
  2. data/README.rdoc +51 -51
  3. data/Rakefile +39 -39
  4. data/cbac.gemspec +30 -30
  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 -138
  11. data/lib/cbac/cbac_pristine/pristine_file.rb +179 -179
  12. data/lib/cbac/cbac_pristine/pristine_permission.rb +205 -205
  13. data/lib/cbac/cbac_pristine/pristine_role.rb +43 -43
  14. data/lib/cbac/config.rb +9 -9
  15. data/lib/cbac/context_role.rb +27 -27
  16. data/lib/cbac/generic_role.rb +7 -7
  17. data/lib/cbac/known_permission.rb +15 -15
  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 -40
  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 -16
  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/db/test.sqlite3 +0 -0
  60. data/test/fixtures/cbac_generic_roles.yml +9 -9
  61. data/test/fixtures/cbac_memberships.yml +8 -8
  62. data/test/fixtures/cbac_permissions.yml +14 -14
  63. data/test/fixtures/cbac_privilege_set.yml +18 -18
  64. data/test/test_cbac_actions.rb +71 -71
  65. data/test/test_cbac_authorize_context_roles.rb +39 -39
  66. data/test/test_cbac_authorize_generic_roles.rb +36 -36
  67. data/test/test_cbac_context_role.rb +50 -50
  68. data/test/test_cbac_privilege.rb +151 -151
  69. data/test/test_cbac_privilege_set.rb +50 -50
  70. data/test/test_helper.rb +28 -28
  71. metadata +11 -13
@@ -1,40 +1,40 @@
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
+ 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.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
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