lockdown 1.6.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. data/.gitignore +1 -0
  2. data/README.txt +8 -5
  3. data/Rakefile +43 -26
  4. data/lib/lockdown/access.rb +108 -0
  5. data/lib/lockdown/configuration.rb +201 -0
  6. data/lib/lockdown/database.rb +31 -36
  7. data/lib/lockdown/delivery.rb +26 -0
  8. data/lib/lockdown/errors.rb +3 -7
  9. data/lib/lockdown/frameworks/rails/controller.rb +21 -59
  10. data/lib/lockdown/frameworks/rails/view.rb +1 -1
  11. data/lib/lockdown/frameworks/rails.rb +7 -43
  12. data/lib/lockdown/helper.rb +14 -85
  13. data/lib/lockdown/orms/active_record.rb +7 -9
  14. data/lib/lockdown/permission.rb +37 -203
  15. data/lib/lockdown/resource.rb +54 -0
  16. data/lib/lockdown/session.rb +16 -25
  17. data/lib/lockdown/user_group.rb +16 -0
  18. data/lib/lockdown.rb +15 -60
  19. data/lockdown.gemspec +29 -69
  20. data/test/helper.rb +9 -0
  21. data/test/lockdown/test_access.rb +80 -0
  22. data/test/lockdown/test_configuration.rb +194 -0
  23. data/test/lockdown/test_delivery.rb +163 -0
  24. data/test/lockdown/test_helper.rb +33 -0
  25. data/test/lockdown/test_permission.rb +73 -0
  26. data/test/lockdown/test_resource.rb +47 -0
  27. data/test/lockdown/test_session.rb +31 -0
  28. data/test/lockdown/test_user_group.rb +17 -0
  29. data/test/test_lockdown.rb +11 -0
  30. metadata +41 -78
  31. data/lib/lockdown/context.rb +0 -41
  32. data/lib/lockdown/references.rb +0 -19
  33. data/lib/lockdown/rspec_helper.rb +0 -118
  34. data/lib/lockdown/rules.rb +0 -372
  35. data/lib/lockdown/system.rb +0 -58
  36. data/rails_generators/lockdown/lockdown_generator.rb +0 -274
  37. data/rails_generators/lockdown/templates/app/controllers/permissions_controller.rb +0 -22
  38. data/rails_generators/lockdown/templates/app/controllers/sessions_controller.rb +0 -39
  39. data/rails_generators/lockdown/templates/app/controllers/user_groups_controller.rb +0 -122
  40. data/rails_generators/lockdown/templates/app/controllers/users_controller.rb +0 -117
  41. data/rails_generators/lockdown/templates/app/helpers/permissions_helper.rb +0 -2
  42. data/rails_generators/lockdown/templates/app/helpers/user_groups_helper.rb +0 -2
  43. data/rails_generators/lockdown/templates/app/helpers/users_helper.rb +0 -2
  44. data/rails_generators/lockdown/templates/app/models/permission.rb +0 -13
  45. data/rails_generators/lockdown/templates/app/models/profile.rb +0 -10
  46. data/rails_generators/lockdown/templates/app/models/user.rb +0 -95
  47. data/rails_generators/lockdown/templates/app/models/user_group.rb +0 -15
  48. data/rails_generators/lockdown/templates/app/views/permissions/index.html.erb +0 -16
  49. data/rails_generators/lockdown/templates/app/views/permissions/show.html.erb +0 -26
  50. data/rails_generators/lockdown/templates/app/views/sessions/new.html.erb +0 -12
  51. data/rails_generators/lockdown/templates/app/views/user_groups/edit.html.erb +0 -33
  52. data/rails_generators/lockdown/templates/app/views/user_groups/index.html.erb +0 -20
  53. data/rails_generators/lockdown/templates/app/views/user_groups/new.html.erb +0 -31
  54. data/rails_generators/lockdown/templates/app/views/user_groups/show.html.erb +0 -29
  55. data/rails_generators/lockdown/templates/app/views/users/edit.html.erb +0 -51
  56. data/rails_generators/lockdown/templates/app/views/users/index.html.erb +0 -22
  57. data/rails_generators/lockdown/templates/app/views/users/new.html.erb +0 -50
  58. data/rails_generators/lockdown/templates/app/views/users/show.html.erb +0 -33
  59. data/rails_generators/lockdown/templates/config/initializers/lockit.rb +0 -1
  60. data/rails_generators/lockdown/templates/db/migrate/create_admin_user.rb +0 -17
  61. data/rails_generators/lockdown/templates/db/migrate/create_permissions.rb +0 -19
  62. data/rails_generators/lockdown/templates/db/migrate/create_profiles.rb +0 -26
  63. data/rails_generators/lockdown/templates/db/migrate/create_user_groups.rb +0 -19
  64. data/rails_generators/lockdown/templates/db/migrate/create_users.rb +0 -17
  65. data/rails_generators/lockdown/templates/lib/lockdown/README +0 -42
  66. data/rails_generators/lockdown/templates/lib/lockdown/init.rb +0 -131
  67. data/spec/lockdown/context_spec.rb +0 -191
  68. data/spec/lockdown/database_spec.rb +0 -162
  69. data/spec/lockdown/frameworks/rails/controller_spec.rb +0 -215
  70. data/spec/lockdown/frameworks/rails/view_spec.rb +0 -96
  71. data/spec/lockdown/frameworks/rails_spec.rb +0 -163
  72. data/spec/lockdown/permission_spec.rb +0 -156
  73. data/spec/lockdown/rspec_helper_spec.rb +0 -40
  74. data/spec/lockdown/rules_spec.rb +0 -245
  75. data/spec/lockdown/session_spec.rb +0 -112
  76. data/spec/lockdown/system_spec.rb +0 -51
  77. data/spec/lockdown_spec.rb +0 -19
  78. data/spec/rcov.opts +0 -5
  79. data/spec/spec.opts +0 -3
  80. data/spec/spec_helper.rb +0 -8
@@ -1,118 +0,0 @@
1
- module Lockdown
2
- module RspecHelper
3
- def self.included(mod)
4
- Lockdown.maybe_parse_init
5
- end
6
-
7
- def login_admin
8
- login_user(:admin)
9
- end
10
-
11
- def login_with_groups(*user_group_symbols)
12
- access_rights = Lockdown::System.standard_authorized_user_rights
13
- user_group_symbols.each do |ugs|
14
- access_rights << Lockdown::System.access_rights_for_user_group(ugs)
15
- end
16
- login_user
17
- controller.session[:access_rights] = access_rights.flatten
18
- end
19
-
20
- alias login_with_group login_with_groups
21
-
22
- def login_with_permissions(*permissions_symbols)
23
- access_rights = Lockdown::System.standard_authorized_user_rights
24
- permissions_symbols.each do |ps|
25
- access_rights << Lockdown::System.access_rights_for_permission(ps)
26
- end
27
- login_user
28
- controller.session[:access_rights] = access_rights.flatten.uniq
29
- end
30
-
31
- alias login_with_permission login_with_permissions
32
-
33
- def login_standard
34
- login_user
35
- end
36
-
37
- def public_user
38
- setup_public_user
39
- end
40
-
41
-
42
- private
43
-
44
- def login_user(user_type = :standard)
45
- initialize_user(user_type)
46
-
47
- create_user_session
48
-
49
- controller.stub!(:current_user).and_return(@current_user)
50
- end
51
-
52
- def setup_public_user
53
- controller.session[:access_rights] = Lockdown::System.public_access
54
- end
55
-
56
- def all_actions(hash = {})
57
- methods = controller.send :action_methods
58
-
59
- if excepts = hash.delete(:except)
60
- excepts = Array.new(excepts)
61
- methods.reject!{|m| excepts.include?(m.to_sym)}
62
- end
63
-
64
- Lockdown::System.paths_for(controller.controller_name,methods.to_a).sort
65
- end
66
-
67
- def only_actions(*actions)
68
- Lockdown::System.paths_for(controller.controller_name,actions).sort
69
- end
70
-
71
- def allowed_actions
72
- if rights = controller.session[:access_rights]
73
- if rights == :all
74
- all_actions
75
- else
76
- name = controller.controller_name
77
- rights.collect{|r| r if r =~ /^#{name}\// || r == name}.compact.sort
78
- end
79
- else
80
- []
81
- end
82
- end
83
-
84
- def initialize_user(user_type)
85
- @current_user = mock_user
86
-
87
- if user_type == :admin
88
- set_user_group(Lockdown.administrator_group_symbol)
89
- end
90
- end
91
-
92
- # You may want to override this method
93
- def mock_user
94
- mock_model User,
95
- :user_groups => [],
96
- :first_name => 'John',
97
- :last_name => 'Smith',
98
- :password => "mysecret",
99
- :password_confirmation => "mysecret"
100
- end
101
-
102
- def create_user_session
103
- controller.send :add_lockdown_session_values, @current_user
104
- end
105
-
106
- # Lockdown.convert_reference_name converts :users to "Users"
107
- def set_user_group(sym)
108
- user_group = mock_user_group
109
- user_group.stub!(:name).and_return( Lockdown.convert_reference_name(sym) )
110
- @current_user.stub!(Lockdown.user_groups_hbtm_reference).and_return([user_group])
111
- end
112
-
113
- # You may want to override this method
114
- def mock_user_group
115
- mock_model(UserGroup)
116
- end
117
- end
118
- end
@@ -1,372 +0,0 @@
1
- module Lockdown
2
- module Rules
3
- attr_accessor :options
4
- attr_accessor :permissions
5
- attr_accessor :user_groups
6
-
7
- attr_reader :protected_access
8
- attr_reader :public_access
9
-
10
- attr_reader :permission_objects
11
-
12
- def set_defaults
13
- @permissions = {}
14
- @user_groups = {}
15
- @options = {}
16
-
17
- @permission_objects = {}
18
-
19
- @public_access = []
20
- @protected_access = []
21
-
22
- @options = {
23
- :session_timeout => (60 * 60),
24
- :who_did_it => :current_user_id,
25
- :default_who_did_it => 1,
26
- :logout_on_access_violation => false,
27
- :access_denied_path => "/",
28
- :successful_login_path => "/",
29
- :subdirectory => nil,
30
- :skip_db_sync_in => ["test"],
31
- :link_separator => ' | ',
32
- :user_group_model => "UserGroup",
33
- :user_model => "User"
34
- }
35
- end
36
-
37
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38
- # =Rule defining methods. e.g. Methods used in lib/lockdown/init.rb
39
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40
-
41
- # Creates new permission object
42
- # Refer to the Permission object for the full functionality
43
- def set_permission(name)
44
- @permission_objects[name] = Lockdown::Permission.new(name)
45
- end
46
-
47
- # Defines public access by the permission symbols
48
- #
49
- # ==== Example
50
- # set_public_access(:permission_one, :permission_two)
51
- #
52
- def set_public_access(*perms)
53
- perms.each do |perm_symbol|
54
- perm = find_permission_object(perm_symbol)
55
- if perm
56
- perm.set_as_public_access
57
- else
58
- msg = "Permission not found: #{perm_symbol}"
59
- raise Lockdown::InvalidRuleAssignment, msg
60
- end
61
- end
62
- end
63
-
64
- # Defines protected access by the permission symbols
65
- #
66
- # ==== Example
67
- # set_public_access(:permission_one, :permission_two)
68
- #
69
- def set_protected_access(*perms)
70
- perms.each do |perm_symbol|
71
- perm = find_permission_object(perm_symbol)
72
- if perm
73
- perm.set_as_protected_access
74
- else
75
- msg = "Permission not found: #{perm_symbol}"
76
- raise Lockdown::InvalidRuleAssignment, msg
77
- end
78
- end
79
- end
80
-
81
- # Define a user groups by name and permission symbol(s)
82
- #
83
- # ==== Example
84
- # set_user_group(:managment_group, :permission_one, :permission_two)
85
- #
86
- def set_user_group(name, *perms)
87
- user_groups[name] ||= []
88
- perms.each do |perm|
89
- if permission_assigned_automatically?(perm)
90
- raise Lockdown::InvalidPermissionAssignment, "Permission is assigned automatically. Please remove it from #{name} user group"
91
- end
92
- user_groups[name].push(perm)
93
- end
94
- end
95
-
96
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97
- # =Convenience methods for permissions and user groups
98
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
99
-
100
- # Returns array of permission names as symbols
101
- def get_permissions
102
- permissions.keys
103
- end
104
-
105
- # Is the permission defined?
106
- def permission_exists?(permission_symbol)
107
- get_permissions.include?(permission_symbol)
108
- end
109
-
110
- alias_method :has_permission?, :permission_exists?
111
-
112
- # returns true if the permission is public
113
- def public_access?(perm_symbol)
114
- obj = find_permission_object(perm_symbol)
115
- obj.nil? ? false : obj.public_access?
116
- end
117
-
118
- # returns true if the permission is public
119
- def protected_access?(perm_symbol)
120
- obj = find_permission_object(perm_symbol)
121
- obj.nil? ? false : obj.protected_access?
122
- end
123
-
124
- # These permissions are assigned by the system
125
- def permission_assigned_automatically?(permmision_symbol)
126
- public_access?(permmision_symbol) || protected_access?(permmision_symbol)
127
- end
128
-
129
- # Returns array of user group names as symbols
130
- def get_user_groups
131
- user_groups.keys
132
- end
133
-
134
- # Is the user group defined?
135
- # The :administrators user group always exists
136
- def user_group_exists?(user_group_symbol)
137
- return true if user_group_symbol == Lockdown.administrator_group_symbol
138
- get_user_groups.include?(user_group_symbol)
139
- end
140
-
141
- alias_method :has_user_group?, :user_group_exists?
142
-
143
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
144
- # =Convenience methods for permissions and user groups
145
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146
-
147
- # Pass in a user object to be associated to the administrator user group
148
- # The group will be created if it doesn't exist
149
- def make_user_administrator(usr)
150
- user_groups = usr.send(Lockdown.user_groups_hbtm_reference)
151
- user_groups << Lockdown.user_group_class.
152
- find_or_create_by_name(Lockdown.administrator_group_string)
153
- end
154
-
155
-
156
- # Returns array of controller/action values all logged in users can access.
157
- def standard_authorized_user_rights
158
- public_access + protected_access
159
- end
160
-
161
- # Return array of controller/action values user can access.
162
- def access_rights_for_user(usr)
163
- return unless usr
164
- return :all if administrator?(usr)
165
-
166
- rights = standard_authorized_user_rights
167
-
168
- user_groups = usr.send(Lockdown.user_groups_hbtm_reference)
169
- user_groups.each do |grp|
170
- permissions_for_user_group(grp).each do |perm|
171
- rights += access_rights_for_permission(perm)
172
- end
173
- end
174
- rights
175
- end
176
-
177
- # Return array of controller/action for a user group
178
- def access_rights_for_user_group(user_group_sym)
179
- res = []
180
- permissions_for_user_group(user_group_sym).each do |perm|
181
- res << access_rights_for_permission(perm)
182
- end
183
- res.flatten
184
- end
185
-
186
- # Return array of controller/action for a permission
187
- def access_rights_for_permission(perm)
188
- sym = Lockdown.get_symbol(perm)
189
-
190
- permissions[sym]
191
- rescue
192
- raise SecurityError, "Permission requested is not defined: #{sym}"
193
- end
194
-
195
-
196
- # Test user for administrator rights
197
- def administrator?(usr)
198
- user_has_user_group?(usr, Lockdown.administrator_group_symbol)
199
- end
200
-
201
- # Pass in user object and symbol for name of user group
202
- def user_has_user_group?(usr, sym)
203
- user_groups = usr.send(Lockdown.user_groups_hbtm_reference)
204
- user_groups.any? do |ug|
205
- Lockdown.convert_reference_name(ug.name) == sym
206
- end
207
- end
208
-
209
- # Use this for the management screen to restrict user group list to the
210
- # user. This will prevent a user from creating a user with more power than
211
- # him/her self.
212
- def user_groups_assignable_for_user(usr)
213
- return [] if usr.nil?
214
- ug_table = Lockdown.user_groups_hbtm_reference.to_s
215
- if administrator?(usr)
216
- Lockdown.user_group_class.find_by_sql <<-SQL
217
- select #{ug_table}.* from #{ug_table} order by #{ug_table}.name
218
- SQL
219
- else
220
- usr_table = Lockdown.users_hbtm_reference.to_s
221
- if usr_table < ug_table
222
- join_table = "#{usr_table}_#{ug_table}"
223
- else
224
- join_table = "#{ug_table}_#{usr_table}"
225
- end
226
- Lockdown.user_group_class.find_by_sql <<-SQL
227
- select #{ug_table}.* from #{ug_table}, #{join_table}
228
- where #{ug_table}.id = #{join_table}.#{Lockdown.user_group_id_reference}
229
- and #{join_table}.#{Lockdown.user_id_reference} = #{usr.id}
230
- order by #{ug_table}.name
231
- SQL
232
- end
233
- end
234
-
235
- # Similar to user_groups_assignable_for_user, this method should be
236
- # used to restrict users from creating a user group with more power than
237
- # they have been allowed.
238
- def permissions_assignable_for_user(usr)
239
- return [] if usr.nil?
240
- if administrator?(usr)
241
- get_permissions.collect do |k|
242
- ::Permission.find_by_name(Lockdown.get_string(k))
243
- end.compact
244
- else
245
- user_groups_assignable_for_user(usr).collect do |g|
246
- g.permissions
247
- end.flatten.compact
248
- end
249
- end
250
-
251
- # Returns and array of permission symbols for the user group
252
- def permissions_for_user_group(ug)
253
- sym = Lockdown.get_symbol(ug)
254
- perm_array = []
255
-
256
- if has_user_group?(sym)
257
- permissions = user_groups[sym] || []
258
- else
259
- if ug.respond_to?(:permissions)
260
- permissions = ug.permissions
261
- else
262
- raise GroupUndefinedError, "#{ug} not found in init.rb and does not respond to #permissions"
263
- end
264
- end
265
-
266
-
267
- permissions.each do |perm|
268
- perm_sym = Lockdown.get_symbol(perm)
269
-
270
- unless permission_exists?(perm_sym)
271
- msg = "Permission associated to User Group is invalid: #{perm}"
272
- raise SecurityError, msg
273
- end
274
-
275
- perm_array << perm_sym
276
- end
277
-
278
- perm_array
279
- end
280
-
281
- def process_rules
282
- parse_permissions
283
- validate_user_groups
284
- end
285
-
286
- private
287
-
288
- def find_permission_object(perm_symbol)
289
- obj = permission_objects.find{|name, pobj| pobj.name == perm_symbol}
290
- obj[1] if obj
291
- end
292
-
293
- def validate_user_groups
294
- user_groups.each do |user_group, perms|
295
- perms.each do |perm|
296
- unless permission_exists?(perm)
297
- msg ="User Group: #{user_group}, permission not found: #{perm}"
298
- raise Lockdown::InvalidRuleAssignment, msg
299
- end
300
- end
301
- end
302
- end
303
-
304
- def parse_permissions
305
- permission_objects.each do |name, perm|
306
- @permissions[perm.name] ||= []
307
- set_controller_access(perm)
308
- end
309
-
310
- set_model_access
311
- end
312
-
313
- def set_controller_access(perm)
314
- perm.controllers.each do |name, controller|
315
- controller.set_access_methods
316
-
317
- @permissions[perm.name] |= controller.access_methods
318
-
319
- if perm.public_access?
320
- @public_access |= controller.access_methods
321
- elsif perm.protected_access?
322
- @protected_access |= controller.access_methods
323
- end
324
- end
325
- end
326
-
327
- def set_model_access
328
- method_definition = "\tdef check_model_authorization\n\t#This method will check for access to model resources\n"
329
-
330
- permission_objects.each do |name, perm|
331
- next if perm.models.empty?
332
-
333
- #Set filter for each controller
334
- perm.controllers.each do |controller_name, controller|
335
- #Set filter for each model on controller
336
- perm.models.each do |model_name, model|
337
- method_definition << define_restrict_model_access(controller, model)
338
- end
339
- end
340
- end
341
-
342
- method_definition << "\n\tend"
343
-
344
- Lockdown.add_controller_method method_definition
345
- end
346
-
347
- def define_restrict_model_access(controller, model)
348
- controller_class = Lockdown.fetch_controller_class(controller.name)
349
-
350
- methods = controller.
351
- access_methods.
352
- collect do |am|
353
- am[am.index('/') + 1..-1].to_sym if am.index('/')
354
- end.compact.inspect
355
-
356
- return <<-RUBY
357
- if controller_name == "#{controller.name}"
358
- if #{methods}.include?(action_name.to_sym)
359
- unless instance_variable_defined?(:@#{model.name})
360
- @#{model.name} = #{model.class_name}.find(params[#{model.param.inspect}])
361
- end
362
- # Need to make sure we find the model first before checking admin status.
363
- return true if current_user_is_admin?
364
- unless @#{model.name}.#{model.model_method}.#{model.association}(#{model.controller_method})
365
- raise SecurityError, "Access to #\{action_name\} denied to #{model.name}.id #\{@#{model.name}.id\}"
366
- end
367
- end
368
- end
369
- RUBY
370
- end
371
- end
372
- end
@@ -1,58 +0,0 @@
1
- module Lockdown
2
- class System
3
- extend Lockdown::Rules
4
-
5
- def self.configure(&block)
6
- set_defaults
7
-
8
- # Lockdown::Rules defines the methods that are used inside block
9
- instance_eval(&block)
10
-
11
- # Lockdown::Rules defines process_rules
12
- process_rules
13
-
14
- Lockdown::Database.sync_with_db unless skip_sync?
15
-
16
- @initialized = true if Lockdown.caching?
17
- end
18
-
19
- def self.initialized?
20
- @initialized
21
- end
22
-
23
- def self.fetch(key)
24
- (@options||={})[key]
25
- end
26
-
27
- def self.call(object, system_option)
28
- method = fetch(system_option)
29
- if method.is_a?(Symbol) && object.respond_to?(method)
30
- object.send(method)
31
- end
32
- end
33
-
34
- protected
35
-
36
- def self.paths_for(str_sym, *methods)
37
- str_sym = str_sym.to_s if str_sym.is_a?(Symbol)
38
- if methods.empty?
39
- klass = Lockdown.fetch_controller_class(str_sym)
40
- methods = available_actions(klass)
41
- end
42
- path_str = str_sym.gsub("__","\/")
43
-
44
- subdir = Lockdown::System.fetch(:subdirectory)
45
- path_str = "#{subdir}/#{path_str}" if subdir
46
-
47
- controller_actions = methods.flatten.collect{|m| m.to_s}
48
-
49
- paths = controller_actions.collect{|meth| "#{path_str}/#{meth.to_s}" }
50
-
51
- if controller_actions.include?("index")
52
- paths += [path_str]
53
- end
54
-
55
- paths
56
- end
57
- end # System class
58
- end # Lockdown