lockdown 0.5.22 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest.txt CHANGED
@@ -2,7 +2,6 @@ History.txt
2
2
  License.txt
3
3
  Manifest.txt
4
4
  PostInstall.txt
5
- README
6
5
  README.txt
7
6
  Rakefile
8
7
  app_generators/lockdown/USAGE
@@ -10,17 +9,23 @@ app_generators/lockdown/lockdown_generator.rb
10
9
  app_generators/lockdown/templates/init.rb
11
10
  app_generators/lockdown/templates/session.rb
12
11
  bin/lockdown
13
- config/hoe.rb
14
- config/requirements.rb
15
12
  lib/lockdown.rb
16
13
  lib/lockdown/classy-inheritance.rb
17
14
  lib/lockdown/controller.rb
18
- lib/lockdown/controller_inspector.rb
15
+ lib/lockdown/database.rb
16
+ lib/lockdown/frameworks/merb.rb
17
+ lib/lockdown/frameworks/merb/controller.rb
18
+ lib/lockdown/frameworks/merb/view.rb
19
+ lib/lockdown/frameworks/rails.rb
20
+ lib/lockdown/frameworks/rails/controller.rb
21
+ lib/lockdown/frameworks/rails/view.rb
19
22
  lib/lockdown/helper.rb
20
- lib/lockdown/model.rb
23
+ lib/lockdown/orms/active_record.rb
24
+ lib/lockdown/orms/data_mapper.rb
25
+ lib/lockdown/rights.rb
26
+ lib/lockdown/session.rb
21
27
  lib/lockdown/system.rb
22
28
  lib/lockdown/version.rb
23
- lib/lockdown/view.rb
24
29
  rails_generators/lockdown/USAGE
25
30
  rails_generators/lockdown/lockdown_generator.rb
26
31
  rails_generators/lockdown/templates/app/controllers/permissions_controller.rb
@@ -60,9 +65,6 @@ script/destroy
60
65
  script/generate
61
66
  script/txt2html
62
67
  setup.rb
63
- tasks/deployment.rake
64
- tasks/environment.rake
65
- tasks/website.rake
66
68
  test/test_generator_helper.rb
67
69
  test/test_helper.rb
68
70
  test/test_lockdown.rb
data/Rakefile CHANGED
@@ -1,4 +1,28 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/lockdown/version'
3
3
 
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('lockdown', Lockdown::VERSION::STRING) do |p|
7
+ p.developer('Andrew Stone', 'andy@stonean.com')
8
+
9
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
10
+ p.post_install_message = 'PostInstall.txt'
11
+ p.rubyforge_name = p.name
12
+ p.extra_deps = [ ['classy-inheritance', '>=0.6.2'] ]
13
+ p.extra_dev_deps = [ ['newgem', ">= #{::Newgem::VERSION}"] ]
14
+
15
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
16
+
17
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
18
+
19
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
20
+
21
+ p.rsync_args = '-av --delete --ignore-errors'
22
+ end
23
+
24
+ require 'newgem/tasks' # load /tasks/*.rake
25
+ Dir['tasks/**/*.rake'].each { |t| load t }
26
+
27
+ # TODO - want other tests/tasks run by default? Add them to the list
28
+ # task :default => [:spec, :features]
@@ -23,9 +23,10 @@ Lockdown::System.configure do
23
23
  # Set redirect to path on successful login:
24
24
  # options[:successful_login_path] = "/"
25
25
  #
26
- # Set the system to sync the Permissions and UserGroups defined here
27
- # with the database.
28
- # options[:sync_init_rb_with_db] = true
26
+ # If deploying to a subdirectory, set that here. Defaults to nil
27
+ # options[:subdirectory] = "blog"
28
+ # *Notice: Do not add leading or trailing slashes,
29
+ # Lockdown will handle this
29
30
  #
30
31
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
32
  # Define permissions
data/bin/lockdown CHANGED
@@ -95,10 +95,8 @@ begin
95
95
  RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'lockdown', :framework => @framework)
96
96
 
97
97
  File.open(config_file, "a") do |f|
98
- require_classy = %Q(require "lockdown/classy-inheritance")
99
98
  require_lockdown = %Q(require "lockdown/init")
100
99
 
101
- f << %Q(\n#{require_classy}\n) unless configuration_file_has?(require_classy)
102
100
  f << %Q(\n#{require_lockdown}\n) unless configuration_file_has?(require_lockdown)
103
101
  end
104
102
  rescue Exception => e
@@ -1,192 +1,13 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
- =begin
5
- module ActiveRecord::Validations::ClassMethods
6
- def validates_associated(association, options = {})
7
- class_eval do
8
- validates_each(association) do |record, associate_name, value|
9
- associate = record.send(associate_name)
10
- if associate && !associate.valid?
11
- associate.errors.each do |key, value|
12
- record.errors.add(key, value)
13
- end
14
- end
15
- end
1
+ if Object.const_defined?("ActiveRecord")
2
+ unless Object.const_defined?("Stonean") && Stonean.const_defined?("ClassyInheritance")
3
+ begin
4
+ require "classy-inheritance"
5
+ rescue LoadError
6
+ puts <<-MSG
7
+ You need to install classy-inheritance to use the provided models.
8
+ With gems, use `gem install classy-inheritance'
9
+ MSG
10
+ exit
16
11
  end
17
12
  end
18
- end
19
- =end
20
-
21
- module Stonean
22
- module ClassyInheritance
23
- def self.included(base)
24
- base.extend Stonean::ClassyInheritance::ClassMethods
25
- end
26
-
27
- module ClassMethods
28
- def depends_on(model_sym, options = {})
29
- define_relationship(model_sym,options)
30
-
31
- # Optional presence of handling
32
- if options.has_key?(:validates_presence_if) && options[:validates_presence_if] != true
33
- if [Symbol, String, Proc].include?(options[:validates_presence_if].class)
34
- validates_presence_of model_sym, :if => options[:validates_presence_if]
35
- end
36
- else
37
- validates_presence_of model_sym
38
- end
39
-
40
- if options.has_key?(:validates_associated_if) && options[:validates_associated_if] != true
41
- if [Symbol, String, Proc].include?(options[:validates_assoicated_if].class)
42
- validates_associated model_sym, :if => options[:validates_associated_if]
43
- end
44
- else
45
- validates_associated model_sym
46
- end
47
-
48
- # Before save functionality to create/update the requisite object
49
- define_save_method(model_sym, options[:as])
50
-
51
- # Adds a find_with_<model_sym> class method
52
- define_find_with_method(model_sym)
53
-
54
- if options[:as]
55
- define_can_be_method_on_requisite_class(options[:class_name] || model_sym, options[:as])
56
- end
57
-
58
- options[:attrs].each{|attr| define_accessors(model_sym, attr, options)}
59
- end
60
-
61
-
62
- def can_be(model_sym, options = {})
63
- unless options[:as]
64
- raise ArgumentError, ":as attribute required when calling can_be"
65
- end
66
-
67
- klass = model_sym.to_s.classify
68
-
69
- define_method "is_a_#{model_sym}?" do
70
- eval("self.#{options[:as]}_type == '#{klass}'")
71
- end
72
-
73
- find_with_method = "find_with_#{self.name.underscore}"
74
-
75
- define_method "as_a_#{model_sym}" do
76
- eval("#{klass}.send(:#{find_with_method},self.#{options[:as]}_id)")
77
- end
78
- end
79
-
80
- private
81
-
82
- def classy_options
83
- [:as, :attrs, :prefix, :postfix, :validates_presence_if, :validates_associated_if]
84
- end
85
-
86
- def delete_classy_options(options, *keepers)
87
- options.delete_if do |key,value|
88
- classy_options.include?(key) && !keepers.include?(key)
89
- end
90
- options
91
- end
92
-
93
- def define_relationship(model_sym, options)
94
- opts = delete_classy_options(options.dup, :as)
95
- if opts[:as]
96
- as_opt = opts.delete(:as)
97
- opts = polymorphic_constraints(as_opt).merge(opts)
98
- has_one model_sym, opts
99
- else
100
- belongs_to model_sym, opts
101
- end
102
- end
103
-
104
- def define_save_method(model_sym, polymorphic_name = nil)
105
- define_method "save_requisite_#{model_sym}" do
106
- # Return unless the association exists
107
- eval("return unless self.#{model_sym}")
108
-
109
- # Set the polymorphic type and id before saving
110
- if polymorphic_name
111
- eval("self.#{model_sym}.#{polymorphic_name}_type = self.class.name")
112
- eval("self.#{model_sym}.#{polymorphic_name}_id = self.id")
113
- end
114
-
115
- if polymorphic_name
116
- # Save only if it's an update, has_one creates automatically
117
- eval <<-SAVEIT
118
- unless self.#{model_sym}.new_record?
119
- self.#{model_sym}.save
120
- end
121
- SAVEIT
122
- else
123
- eval("self.#{model_sym}.save")
124
- end
125
- end
126
-
127
- before_save "save_requisite_#{model_sym}".to_sym
128
- end
129
-
130
- def define_find_with_method(model_sym)
131
- self.class.send :define_method, "find_with_#{model_sym}" do |*args|
132
- eval <<-CODE
133
- if args[1] && args[1].is_a?(Hash)
134
- if args[1].has_key?(:include)
135
- inc_val = args[1][:include]
136
- new_val = inc_val.is_a?(Array) ? inc_val.push(:#{:model_sym}) : [inc_val, :#{model_sym}]
137
- args[1][:include] = new_val
138
- else
139
- args[1].merge!({:include => :#{model_sym}})
140
- end
141
- else
142
- args << {:include => :#{model_sym}}
143
- end
144
- find(*args)
145
- CODE
146
- end
147
- end
148
-
149
- def define_accessors(model_sym, attr, options)
150
- accessor_method_name = attr
151
-
152
- if options[:prefix]
153
- accessor_method_name = (options[:prefix] == true) ? "#{model_sym}_#{accessor_method_name}" : "#{options[:prefix]}_#{accessor_method_name}"
154
- end
155
-
156
- if options[:postfix]
157
- accessor_method_name = (options[:postfix] == true) ? "#{accessor_method_name}_#{model_sym}" : "#{accessor_method_name}_#{options[:postfix]}"
158
- end
159
-
160
- define_method accessor_method_name do
161
- eval("self.#{model_sym} ? self.#{model_sym}.#{attr} : nil")
162
- end
163
-
164
- define_method "#{accessor_method_name}=" do |val|
165
- model_defined = eval("self.#{model_sym}")
166
-
167
- unless model_defined
168
- klass = options[:class_name] || model_sym.to_s.classify
169
- eval("self.#{model_sym} = #{klass}.new")
170
- end
171
-
172
- eval("self.#{model_sym}.#{attr}= val")
173
- end
174
- end
175
-
176
- def define_can_be_method_on_requisite_class(model_sym, polymorphic_name)
177
- klass = model_sym.to_s.classify
178
- requisite_klass = eval(klass)
179
- unless requisite_klass.respond_to?(self.name.underscore.to_sym)
180
- requisite_klass.send :can_be, self.name.underscore,
181
- :as => polymorphic_name
182
- end
183
- end
184
-
185
- def polymorphic_constraints(polymorphic_name)
186
- { :foreign_key => "#{polymorphic_name}_id",
187
- :conditions => "#{polymorphic_name}_type = '#{self.name}'"}
188
- end
189
- end # ClassMethods
190
- end # ClassyInheritance module
191
- end # Stonean module
192
- ActiveRecord::Base.send :include, Stonean::ClassyInheritance
13
+ end
@@ -1,239 +1,67 @@
1
1
  module Lockdown
2
- module Controller#:nodoc:
3
- #
4
- # Core Controller locking methods
5
- #
2
+ module Controller
6
3
  module Core
7
- def self.included(base)
8
- base.send :include, Lockdown::Controller::Core::InstanceMethods
4
+ def configure_lockdown
5
+ check_session_expiry
6
+ store_location
9
7
  end
10
-
11
- module InstanceMethods
12
- def configure_lock_down
13
- check_session_expiry
14
- store_location
15
- end
16
8
 
17
- def set_current_user
18
- login_from_basic_auth? unless logged_in?
19
- if logged_in?
20
- Thread.current[:profile_id] = current_profile_id
21
- Thread.current[:client_id] = current_client_id if respond_to? :current_client_id
22
- end
9
+ def set_current_user
10
+ login_from_basic_auth? unless logged_in?
11
+ if logged_in?
12
+ Thread.current[:profile_id] = current_profile_id
13
+ Thread.current[:client_id] = current_client_id if respond_to? :current_client_id
23
14
  end
15
+ end
24
16
 
25
- def check_request_authorization
26
- unless authorized?(path_from_hash(params))
27
- raise SecurityError, "Authorization failed for params #{params.inspect}"
28
- end
17
+ def check_request_authorization
18
+ unless authorized?(path_from_hash(params))
19
+ raise SecurityError, "Authorization failed for params #{params.inspect}"
29
20
  end
21
+ end
30
22
 
31
- def redirect_back_or_default(default)
32
- session[:prevpage] ? send_to(session[:prevpage]) : send_to(default)
33
- end
34
-
35
- private
36
-
37
- def path_allowed?(url)
38
- req = Lockdown.format_controller_action(url)
39
- session[:access_rights] ||= Lockdown::System.public_access
40
- session[:access_rights].each do |ar|
41
- return true if req == ar
42
- end
43
- false
23
+ def path_allowed?(url)
24
+ session[:access_rights] ||= Lockdown::System.public_access
25
+ session[:access_rights].each do |ar|
26
+ return true if url == ar
44
27
  end
28
+ false
29
+ end
45
30
 
46
- def check_session_expiry
47
- if session[:expiry_time] && session[:expiry_time] < Time.now
48
- nil_lockdown_values
49
- timeout_method = Lockdown::System.fetch(:session_timeout_method)
50
- if timeout_method.is_a?(Symbol) && self.respond_to?(timeout_method)
51
- send(timeout_method)
52
- end
31
+ def check_session_expiry
32
+ if session[:expiry_time] && session[:expiry_time] < Time.now
33
+ nil_lockdown_values
34
+ timeout_method = Lockdown::System.fetch(:session_timeout_method)
35
+ if timeout_method.is_a?(Symbol) && self.respond_to?(timeout_method)
36
+ send(timeout_method)
53
37
  end
54
- session[:expiry_time] = Time.now + Lockdown::System.fetch(:session_timeout)
55
38
  end
39
+ session[:expiry_time] = Time.now + Lockdown::System.fetch(:session_timeout)
40
+ end
56
41
 
57
- def store_location
58
- if (request.method == :get) && (session[:thispage] != sent_from_uri)
59
- session[:prevpage] = session[:thispage] || ''
60
- session[:thispage] = sent_from_uri
61
- end
62
- end
63
-
64
- # Called from current_user. Now, attempt to login by
65
- # basic authentication information.
66
- def login_from_basic_auth?
67
- username, passwd = get_auth_data
68
- if username && passwd
69
- set_session_user User.authenticate(username, passwd)
70
- end
71
- end
72
-
73
- @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
74
- # gets BASIC auth info
75
- def get_auth_data
76
- auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
77
- auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
78
- return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
42
+ def store_location
43
+ if (request.method == :get) && (session[:thispage] != sent_from_uri)
44
+ session[:prevpage] = session[:thispage] || ''
45
+ session[:thispage] = sent_from_uri
79
46
  end
80
- end # InstanceMethods
81
- end # Core
82
-
83
- #
84
- # Merb Controller locking methods
85
- #
86
- module Merb
87
- def self.included(base)
88
- base.send :include, Lockdown::Controller::Merb::InstanceMethods
89
-
90
- base.before :set_current_user
91
- base.before :configure_lock_down
92
- base.before :check_request_authorization
93
47
  end
94
-
95
- module InstanceMethods
96
- def self.included(base)
97
- base.class_eval do
98
- alias :send_to :redirect
99
- end
100
- base.send :include, Lockdown::Controller::Core
101
- end
102
-
103
- def sent_from_uri
104
- request.uri
105
- end
106
-
107
- def authorized?(path)
108
- return true if current_user_is_admin?
109
-
110
- # See if path is known
111
- if path_allowed?(path)
112
- true
113
- else
114
- false
115
- end
116
- end
117
48
 
118
- # Can log Error => e if desired, I don't desire to now.
119
- # For now, just send home, but will probably make this configurable
120
- def access_denied(e)
121
- send_to Lockdown::Session[:access_denied_path]
122
- end
123
-
124
- def path_from_hash(hsh)
125
- return hsh if hsh.is_a?(String)
126
- hsh = hsh.to_hash if hsh.is_a?(Mash)
127
- hsh['controller'].to_s + "/" + hsh['action'].to_s
128
- end
129
-
130
- end # InstanceMethods
131
- end # Merb
132
-
133
- #
134
- # Rails Controller locking methods
135
- #
136
- module Rails
137
- def self.included(base)
138
- base.send :include, Lockdown::Controller::Rails::InstanceMethods
139
-
140
- base.before_filter do |controller|
141
- controller.set_current_user
142
- controller.configure_lock_down
143
- controller.check_request_authorization
49
+ # Called from current_user. Now, attempt to login by
50
+ # basic authentication information.
51
+ def login_from_basic_auth?
52
+ username, passwd = get_auth_data
53
+ if username && passwd
54
+ set_session_user User.authenticate(username, passwd)
144
55
  end
145
-
146
- base.send :helper_method, :authorized?
147
-
148
- base.filter_parameter_logging :password, :password_confirmation
149
-
150
- base.rescue_from SecurityError,
151
- :with => proc{|e| access_denied(e)}
152
56
  end
153
-
154
- module InstanceMethods
155
- def self.included(base)
156
- base.class_eval do
157
- alias :send_to :redirect_to
158
- end
159
- base.send :include, Lockdown::Controller::Core
160
- end
161
-
162
- def sent_from_uri
163
- request.request_uri
164
- end
165
-
166
- def authorized?(url)
167
- return false unless url
168
-
169
- return true if current_user_is_admin?
170
-
171
- url.strip!
172
-
173
- url_parts = URI::split(url)
174
-
175
- path = url_parts[5]
176
-
177
- # See if path is known
178
- return true if path_allowed?(path)
179
-
180
- # Test to see if url contains id
181
- parts = path.split("/").collect{|p| p unless p =~ /\A\d+\z/}.compact
182
- new_path = parts.join("/")
183
-
184
- return true if path_allowed?(new_path)
185
-
186
- # Test for a named routed
187
- begin
188
- hsh = ActionController::Routing::Routes.recognize_path(path)
189
- unless hsh.nil? || hsh[:id]
190
- return true if path_allowed?(path_from_hash(hsh))
191
- end
192
- rescue Exception
193
- # continue on
194
- end
195
-
196
- # Passing in different domain
197
- return true if remote_url?(url_parts[2])
198
-
199
- false
200
- end
201
-
202
- def access_denied(e)
203
- if Lockdown::System.fetch(:logout_on_access_violation)
204
- reset_session
205
- end
206
-
207
- respond_to do |accepts|
208
- accepts.html do
209
- store_location
210
- send_to Lockdown::System.fetch(:access_denied_path)
211
- end
212
- accepts.xml do
213
- headers["Status"] = "Unauthorized"
214
- headers["WWW-Authenticate"] = %(Basic realm="Web Password")
215
- render :text => e.message, :status => "401 Unauthorized"
216
- end
217
- end
218
- false
219
- end
220
-
221
- def path_from_hash(hsh)
222
- hsh[:controller].to_s + "/" + hsh[:action].to_s
223
- end
224
-
225
- def remote_url?(domain = nil)
226
- return false if domain.nil? || domain.strip.length == 0
227
- request.host.downcase != domain.downcase
228
- end
229
- end # InstanceMethods
230
- end # Rails
231
- end # Controller
232
- end # Lockdown
233
-
234
- if Lockdown.merb_app?
235
- Merb::Controller.send :include, Lockdown::Controller::Merb
236
- elsif Lockdown.rails_app?
237
- ActionController::Base.send :include, Lockdown::Controller::Rails
238
- end
239
-
57
+
58
+ @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
59
+ # gets BASIC auth info
60
+ def get_auth_data
61
+ auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
62
+ auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
63
+ return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
64
+ end
65
+ end # Core
66
+ end # Controller
67
+ end # Lockdown