lockdown 0.3.15 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.4.0 2008-05-04
2
+ * Added: Automatically sync definitions in init.rb with database to remove migrations requirement
3
+ * Added: Improved notification if invalid user group or permission is referenced in init.rb
4
+ * Added: Check in user_groups controller to prevent url hack and modify/destroy user group defined in init.rb
5
+ * Modified: Renamed access_rights_for_perm to access_rights_for_permission for consistency sake. Change then method call in permissions_helper if you have this installed
6
+
1
7
  == 0.3.15 2008-05-03
2
8
  * Fixed: The controller inspection code was short-circuiting the Dependencies reload mechanism while in development mode.
3
9
 
@@ -20,6 +20,10 @@ Lockdown::System.configure do
20
20
  # Set redirect to path on successful login:
21
21
  # options[:successful_login_path] = "/"
22
22
  #
23
+ # Set the system to sync the Permissions and UserGroups defined here
24
+ # with the database.
25
+ # options[:sync_init_rb_with_db] = true
26
+ #
23
27
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
28
  # Define permissions
25
29
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -22,6 +22,16 @@ module Lockdown
22
22
  str_sym.is_a?(String) ? convert_reference_name(str_sym) : str_sym
23
23
  end
24
24
 
25
+ def lockdown_symbol(value)
26
+ if value.respond_to?(:name)
27
+ symbol_name(value.name)
28
+ elsif value.is_a?(String)
29
+ symbol_name(value)
30
+ else
31
+ value
32
+ end
33
+ end
34
+
25
35
  def camelize(str)
26
36
  str.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
27
37
  end
@@ -20,8 +20,11 @@ module Lockdown
20
20
  attr_accessor :controller_classes #:nodoc:
21
21
 
22
22
  def configure(&block)
23
- self.set_defaults
24
- self.instance_eval(&block)
23
+ set_defaults
24
+ instance_eval(&block)
25
+ if options[:use_db_models] && options[:sync_init_rb_with_db]
26
+ sync_with_db
27
+ end
25
28
  end
26
29
 
27
30
  def [](key)
@@ -41,67 +44,99 @@ module Lockdown
41
44
  @permissions.keys
42
45
  end
43
46
 
47
+ def permission_exists?(perm)
48
+ get_permissions.include?(perm)
49
+ end
50
+
44
51
  def set_user_group(name, *perms)
45
52
  @user_groups[name] ||= []
46
- perms.each{|perm| @user_groups[name].push(perm)}
53
+ perms.each do |perm|
54
+ unless permission_exists?(perm)
55
+ raise SecurityError, "For UserGroup (#{name}), permission is invalid: #{perm}"
56
+ end
57
+ @user_groups[name].push(perm)
58
+ end
47
59
  end
48
60
 
49
61
  def get_user_groups
50
62
  @user_groups.keys
51
63
  end
52
64
 
65
+ def permissions_for_user_group(ug)
66
+ sym = lockdown_symbol(ug)
67
+
68
+ if has_user_group?(sym)
69
+ @user_groups[sym].each do |perm|
70
+ unless permission_exists?(perm)
71
+ raise SecurityError, "Permission associated to User Group is invalid: #{perm}"
72
+ end
73
+ yield perm
74
+ end
75
+ elsif ug.responds_to?(:name)
76
+ # This user group was defined in the database
77
+ ug.permissions.each do |perm|
78
+ perm_sym = symbol_name(perm.name)
79
+ unless permission_exists?(perm_sym)
80
+ raise SecurityError, "Permission associated to User Group is invalid: #{perm_sym}"
81
+ end
82
+ yield perm_sym
83
+ end
84
+ else
85
+ raise SecurityError, "UserGroup is not known: #{ug.inspect}"
86
+ end
87
+ end
88
+
89
+ def access_rights_for_permission(perm)
90
+ sym = lockdown_symbol(perm)
91
+
92
+ unless permission_exists?(sym)
93
+ raise SecurityError, "Permission requested is not defined: #{sym}"
94
+ end
95
+ @permissions[sym]
96
+ end
97
+
98
+ def public_access?(perm)
99
+ @public_access.include?(perm)
100
+ end
101
+
53
102
  def set_public_access(*perms)
54
103
  perms.each{|perm| @public_access += @permissions[perm]}
55
104
  end
56
105
 
106
+ def protected_access?(perm)
107
+ @protected_access.include?(perm)
108
+ end
109
+
57
110
  def set_protected_access(*perms)
58
111
  perms.each{|perm| @protected_access += @permissions[perm]}
59
112
  end
60
113
 
114
+ def permission_assigned_automatically?(perm)
115
+ public_access?(perm) || protected_access?(perm)
116
+ end
117
+
61
118
  def standard_authorized_user_rights
62
119
  Lockdown::System.public_access + Lockdown::System.protected_access
63
120
  end
64
121
 
65
- #
66
- # Create a user group record in the database
67
- #
68
- def create_user_group(str_sym)
69
- return unless @options[:use_db_models]
70
- ug = UserGroup.create(:name => string_name(str_sym))
71
- #
72
- # No need to create permissions records for administrators
73
- #
74
- ug_sym = symbol_name(ug.name)
75
- return if ug_sym == administrator_group_symbol
76
-
77
- if self.has_user_group?(ug)
78
- @user_groups[ug_sym].collect do |perm|
79
- Permission.create(:name => string_name(perm))
80
- end
81
- end
82
- end
83
-
84
- def create_administrator_user_group
85
- return unless @options[:use_db_models]
86
- Lockdown::System.create_user_group administrator_group_symbol
87
- end
88
-
89
122
  #
90
123
  # Determine if the user group is defined in init.rb
91
124
  #
92
125
  def has_user_group?(ug)
93
- return true if symbol_name(ug.name) == administrator_group_symbol
94
- @user_groups.each do |key,value|
95
- return true if key == symbol_name(ug.name)
126
+ sym = lockdown_symbol(ug)
127
+
128
+ return true if sym == administrator_group_symbol
129
+ get_user_groups.each do |key|
130
+ return true if key == sym
96
131
  end
97
- return false
132
+ false
98
133
  end
99
134
 
100
135
  #
101
136
  # Delete a user group record from the database
102
137
  #
103
138
  def delete_user_group(str_sym)
104
- ug = UserGroup.find_by_name(string_name(str_sym))
139
+ ug = UserGroup.find(:first, :conditions => ["name = ?",string_name(str_sym)])
105
140
  ug.destroy unless ug.nil?
106
141
  end
107
142
 
@@ -113,24 +148,14 @@ module Lockdown
113
148
 
114
149
  if @options[:use_db_models]
115
150
  usr.user_groups.each do |grp|
116
- if @user_groups.has_key? symbol_name(grp.name)
117
- @user_groups[symbol_name(grp.name)].each do |perm|
118
- rights += @permissions[perm]
119
- end
120
- else
121
- grp.permissions.each do |perm|
122
- rights += @permissions[symbol_name(perm.name)]
123
- end
124
- end
151
+ permissions_for_user_group(grp) do |perm|
152
+ rights += access_rights_for_permission(perm)
153
+ end
125
154
  end
126
155
  end
127
156
  rights
128
157
  end
129
158
 
130
- def access_rights_for_perm(perm)
131
- (perms = @permissions[symbol_name(perm.name)]) == nil ? [] : perms
132
- end
133
-
134
159
  #
135
160
  # Use this for the management screen to restrict user group list to the
136
161
  # user. This will prevent a user from creating a user with more power than
@@ -168,9 +193,13 @@ module Lockdown
168
193
  end
169
194
 
170
195
  def make_user_administrator(usr)
196
+ unless Lockdown.database_table_exists?(UserGroup)
197
+ create_administrator_user_group
198
+ end
199
+
171
200
  usr.user_groups << UserGroup.find_or_create_by_name(administrator_group_string)
172
201
  end
173
-
202
+
174
203
  def administrator?(usr)
175
204
  user_has_user_group?(usr, administrator_group_symbol)
176
205
  end
@@ -196,16 +225,22 @@ module Lockdown
196
225
  @private_access = []
197
226
 
198
227
  @options = {
199
- :use_db_models => true,
200
- :session_timeout => (60 * 60),
201
- :logout_on_access_violation => false,
202
- :access_denied_path => "/",
203
- :successful_login_path => "/"
204
- }
228
+ :use_db_models => true,
229
+ :sync_init_rb_with_db => true,
230
+ :session_timeout => (60 * 60),
231
+ :logout_on_access_violation => false,
232
+ :access_denied_path => "/",
233
+ :successful_login_path => "/"
234
+ }
205
235
  end
206
236
 
207
237
  private
208
238
 
239
+ def create_administrator_user_group
240
+ return unless @options[:use_db_models]
241
+ UserGroup.create :name => administrator_group_name
242
+ end
243
+
209
244
  def user_has_user_group?(usr, sym)
210
245
  usr.user_groups.each do |ug|
211
246
  return true if convert_reference_name(ug.name) == sym
@@ -227,7 +262,7 @@ module Lockdown
227
262
  end
228
263
 
229
264
  def controller_class_name_from_file(str)
230
- str.split(".")[0].split("/").collect{|str| camelize(str) }.join("::")
265
+ str.split(".")[0].split("/").collect{|s| camelize(s) }.join("::")
231
266
  end
232
267
 
233
268
  def controller_class_name(str)
@@ -274,6 +309,64 @@ module Lockdown
274
309
  const_get(klass)
275
310
  end
276
311
  end
277
- end # class block
312
+
313
+ #
314
+ # This is very basic and could be handled better using orm specific
315
+ # functionality, but I wanted to keep it generic to avoid creating
316
+ # an interface for each the different orm implementations.
317
+ # We'll see how it works...
318
+ #
319
+ def sync_with_db
320
+ return unless database_configured?
321
+ # Create permissions not found in the database
322
+ get_permissions.each do |key|
323
+ next if permission_assigned_automatically?(key)
324
+ str = string_name(key)
325
+ p = Permission.find(:first, :conditions => ["name = ?", str])
326
+ unless p
327
+ puts ">> Lockdown: Permission not found in db: #{str}, creating."
328
+ Permission.create(:name => str)
329
+ end
330
+ end
331
+
332
+ #
333
+ # Delete the permissions not found in init.rb
334
+ #
335
+ db_perms = Permission.find(:all).dup
336
+ perm_keys = get_permissions
337
+ db_perms.each do |dbp|
338
+ unless perm_keys.include?(symbol_name(dbp.name))
339
+ puts ">> Lockdown: Permission no longer in init.rb: #{dbp.name}, deleting."
340
+ Lockdown.database_execute("delete from permissions_user_groups where permission_id = #{dbp.id}")
341
+ dbp.destroy
342
+ end
343
+ end
344
+
345
+ # Create user groups not found in the database
346
+ get_user_groups.each do |key|
347
+ str = string_name(key)
348
+ ug = UserGroup.find(:first, :conditions => ["name = ?", str])
349
+ unless ug
350
+ puts ">> Lockdown: UserGroup not in the db: #{str}, creating."
351
+ ug = UserGroup.create(:name => str)
352
+ #Inefficient, definitely, but shouldn't have any issues across orms.
353
+ permissions_for_user_group(key) do |perm|
354
+ p = Permission.find(:first, :conditions => ["name = ?", string_name(perm)])
355
+ Lockdown.database_execute <<-SQL
356
+ insert into permissions_user_groups(permission_id, user_group_id)
357
+ values(#{p.id}, #{ug.id})
358
+ SQL
359
+ end
360
+ end
361
+ end
362
+ end
363
+
364
+ def database_configured?
365
+ return unless const_defined?("Permission") && const_defined?("UserGroup")
366
+
367
+ Lockdown.database_table_exists?(Permission) &&
368
+ Lockdown.database_table_exists?(UserGroup)
369
+ end
370
+ end # class block
278
371
  end # System class
279
372
  end # Lockdown
@@ -1,8 +1,8 @@
1
1
  module Lockdown #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 3
5
- TINY = 15
4
+ MINOR = 4
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
data/lib/lockdown.rb CHANGED
@@ -47,6 +47,35 @@ module Lockdown
47
47
  end
48
48
  end
49
49
 
50
+ def database_execute(query)
51
+ if active_record_orm?
52
+ ActiveRecord::Base.connection.execute(query)
53
+ elsif datamapper_orm?
54
+ DataMapper.database.execute(query)
55
+ else
56
+ raise NotImplementedError, "ORM unknown to Lockdown! Lockdown recognizes DataMapper and ActiveRecord"
57
+ end
58
+ end
59
+
60
+ def database_query(query)
61
+ if active_record_orm?
62
+ ActiveRecord::Base.connection.execute(query)
63
+ elsif datamapper_orm?
64
+ DataMapper.database.query(query)
65
+ else
66
+ raise NotImplementedError, "ORM unknown to Lockdown! Lockdown recognizes DataMapper and ActiveRecord"
67
+ end
68
+ end
69
+
70
+ def database_table_exists?(klass)
71
+ if active_record_orm?
72
+ klass.table_exists?
73
+ elsif datamapper_orm?
74
+ DataMapper.database.table_exists?(klass)
75
+ else
76
+ raise NotImplementedError, "ORM unknown to Lockdown! Lockdown recognizes DataMapper and ActiveRecord"
77
+ end
78
+ end
50
79
  private
51
80
 
52
81
  def project_related_value(merb_val, rails_val)
@@ -88,6 +88,9 @@ class UserGroupsController < ApplicationController
88
88
 
89
89
  def find_user_group
90
90
  @user_group = UserGroup.find(params[:id])
91
+ if @action_name != "show" && Lockdown::System.has_user_group?(@user_group)
92
+ raise SecurityError,"Invalid attempt to modify user group."
93
+ end
91
94
  end
92
95
 
93
96
  def update_permissions
@@ -4,7 +4,7 @@ module PermissionsHelper
4
4
  end
5
5
 
6
6
  def permission_access_rights_value
7
- Lockdown::System.access_rights_for_perm(@permission).collect{|r| r}.join("<br/>")
7
+ Lockdown::System.access_rights_for_permission(@permission).collect{|r| r}.join("<br/>")
8
8
  end
9
9
 
10
10
  def permission_users_value
@@ -1,11 +1,5 @@
1
1
  class CreateAdminUserAndUserGroup < ActiveRecord::Migration
2
2
  def self.up
3
- #
4
- # Creating an administrators user group database record
5
- # to allow for the creation of other administrators
6
- #
7
- Lockdown::System.create_administrator_user_group
8
-
9
3
  # TODO: Change the password
10
4
  u = User.new( :password => "password",
11
5
  :password_confirmation => "password",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lockdown
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.15
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Stone
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-05-03 00:00:00 -04:00
12
+ date: 2008-05-05 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency