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,85 +1,85 @@
1
- require 'spec'
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
3
- require 'cbac/cbac_pristine/pristine_role'
4
-
5
- include Cbac::CbacPristine
6
-
7
- describe "CbacPristineRole" do
8
-
9
- describe "convert pristine role to a yml fixture" do
10
- it "should return an empty string if the pristine role is of type :context" do
11
- pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:context], :name => "name is irrelevant")
12
-
13
- pristine_role.to_yml_fixture.should be_empty
14
- end
15
-
16
- it "should raise an error if the role name is not specified" do
17
- pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "")
18
-
19
- proc{
20
- pristine_role.to_yml_fixture
21
- }.should raise_error(ArgumentError)
22
- end
23
-
24
-
25
- it "should return a yml string starting with cbac_generic_role_ " do
26
- pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
27
-
28
- pristine_role.to_yml_fixture.should match(/\Acbac_generic_role_/)
29
- end
30
-
31
- it "should return a yml string containing the id of the pristine role" do
32
- role_id = 100
33
- pristine_role = PristineRole.new(:role_id => role_id, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
34
-
35
- pristine_role.to_yml_fixture.should match(/id: #{role_id}/)
36
- end
37
-
38
- it "should return a yml string containing the name of the pristine role" do
39
- name = "Administrator"
40
- pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => name)
41
- pristine_role.to_yml_fixture.should match(/name: #{name}/)
42
- end
43
-
44
- it "should return a yml string containing created_at and updated_at" do
45
- pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
46
-
47
- pristine_role.to_yml_fixture.should match(/created_at:.+updated_at:/m)
48
- end
49
- end
50
-
51
- describe "admin role" do
52
- it "should return a role with the admin role_type" do
53
- admin_role = PristineRole.admin_role
54
-
55
- admin_role.role_type.should == PristineRole.ROLE_TYPES[:admin]
56
- end
57
-
58
- it "should return a new admin role if the role does not exist in the database" do
59
- admin_role = PristineRole.admin_role
60
-
61
- admin_role.id.should be_nil
62
- end
63
-
64
- it "should return an existing admin role if possible" do
65
- existing_admin_role = PristineRole.create(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "administrator")
66
-
67
- admin_role = PristineRole.admin_role
68
-
69
- admin_role.should == existing_admin_role
70
- end
71
-
72
- it "should not return an existing admin role if database should not be used" do
73
- existing_admin_role = PristineRole.create(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "administrator")
74
-
75
- admin_role = PristineRole.admin_role(false)
76
-
77
- admin_role.should_not == existing_admin_role
78
- admin_role.id.should be_nil
79
- end
80
- end
81
-
82
-
83
-
84
- end
85
-
1
+ require 'spec'
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
3
+ require 'cbac/cbac_pristine/pristine_role'
4
+
5
+ include Cbac::CbacPristine
6
+
7
+ describe "CbacPristineRole" do
8
+
9
+ describe "convert pristine role to a yml fixture" do
10
+ it "should return an empty string if the pristine role is of type :context" do
11
+ pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:context], :name => "name is irrelevant")
12
+
13
+ pristine_role.to_yml_fixture.should be_empty
14
+ end
15
+
16
+ it "should raise an error if the role name is not specified" do
17
+ pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "")
18
+
19
+ proc{
20
+ pristine_role.to_yml_fixture
21
+ }.should raise_error(ArgumentError)
22
+ end
23
+
24
+
25
+ it "should return a yml string starting with cbac_generic_role_ " do
26
+ pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
27
+
28
+ pristine_role.to_yml_fixture.should match(/\Acbac_generic_role_/)
29
+ end
30
+
31
+ it "should return a yml string containing the id of the pristine role" do
32
+ role_id = 100
33
+ pristine_role = PristineRole.new(:role_id => role_id, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
34
+
35
+ pristine_role.to_yml_fixture.should match(/id: #{role_id}/)
36
+ end
37
+
38
+ it "should return a yml string containing the name of the pristine role" do
39
+ name = "Administrator"
40
+ pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => name)
41
+ pristine_role.to_yml_fixture.should match(/name: #{name}/)
42
+ end
43
+
44
+ it "should return a yml string containing created_at and updated_at" do
45
+ pristine_role = PristineRole.new(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:generic], :name => "name is irrelevant")
46
+
47
+ pristine_role.to_yml_fixture.should match(/created_at:.+updated_at:/m)
48
+ end
49
+ end
50
+
51
+ describe "admin role" do
52
+ it "should return a role with the admin role_type" do
53
+ admin_role = PristineRole.admin_role
54
+
55
+ admin_role.role_type.should == PristineRole.ROLE_TYPES[:admin]
56
+ end
57
+
58
+ it "should return a new admin role if the role does not exist in the database" do
59
+ admin_role = PristineRole.admin_role
60
+
61
+ admin_role.id.should be_nil
62
+ end
63
+
64
+ it "should return an existing admin role if possible" do
65
+ existing_admin_role = PristineRole.create(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "administrator")
66
+
67
+ admin_role = PristineRole.admin_role
68
+
69
+ admin_role.should == existing_admin_role
70
+ end
71
+
72
+ it "should not return an existing admin role if database should not be used" do
73
+ existing_admin_role = PristineRole.create(:role_id => 0, :role_type => PristineRole.ROLE_TYPES[:admin], :name => "administrator")
74
+
75
+ admin_role = PristineRole.admin_role(false)
76
+
77
+ admin_role.should_not == existing_admin_role
78
+ admin_role.id.should be_nil
79
+ end
80
+ end
81
+
82
+
83
+
84
+ end
85
+
@@ -1,2 +1,2 @@
1
- --exclude "spec/*,gems/*"
1
+ --exclude "spec/*,gems/*"
2
2
  --rails
@@ -1,4 +1,4 @@
1
- --colour
2
- --format progress
3
- --loadby mtime
4
- --reverse
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -1,12 +1,12 @@
1
- ENV["RAILS_ENV"] ||= 'test'
2
-
3
- require 'spec/autorun'
4
- require 'spec/rails'
5
-
6
- Spec::Runner.configure do |config|
7
- # If you're not using ActiveRecord you should remove these
8
- # lines, delete config/database.yml and disable :active_record
9
- # in your config/boot.rb
10
- config.use_transactional_fixtures = true
11
- config.use_instantiated_fixtures = false
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ require 'spec/autorun'
4
+ require 'spec/rails'
5
+
6
+ Spec::Runner.configure do |config|
7
+ # If you're not using ActiveRecord you should remove these
8
+ # lines, delete config/database.yml and disable :active_record
9
+ # in your config/boot.rb
10
+ config.use_transactional_fixtures = true
11
+ config.use_instantiated_fixtures = false
12
12
  end
@@ -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