lockdown 0.5.22 → 0.6.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.
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