merb-param-protection-1.1.3/0000755000175000017500000000000011757200005015224 5ustar tfheentfheenmerb-param-protection-1.1.3/spec/0000755000175000017500000000000011757200005016156 5ustar tfheentfheenmerb-param-protection-1.1.3/spec/spec.opts0000644000175000017500000000003211757200005020012 0ustar tfheentfheen--format specdoc --colour merb-param-protection-1.1.3/spec/merb_param_protection_spec.rb0000644000175000017500000001374011757200005024075 0ustar tfheentfheenrequire 'spec_helper' describe "merb-param-protection" do describe "Controller" do it "should store the accessible parameters for that controller" do dispatch_to(ParamsAccessibleController, :create).send(:accessible_params_args).should == { :address=> [:street, :zip], :post=> [:title, :body], :customer=> [:name, :phone, :email] } end it "should store the protected parameters for that controller" do dispatch_to(ParamsProtectedController, :create).send(:protected_params_args).should == { :address=> [:long, :lat], :customer=> [:activated?, :password] } end it "should remove the parameters from the request that are not accessible" do c = dispatch_to(ParamsAccessibleController, :create, :customer => {:name => "teamon", :phone => "123456789", :email => "my@mail", :activated? => "yes", :password => "secret"}, :address => {:street => "Merb Street 4", :zip => "98765", :long => "Meeeeerrrrrrbbbb sooo looong", :lat => "123"}, :post => {:title => "First port", :body => "Some long lorem ipsum stuff", :date => "today"} ) c.params[:customer][:name].should == "teamon" c.params[:customer][:phone].should == "123456789" c.params[:customer][:email].should == "my@mail" c.params[:customer].should_not have_key(:activated?) c.params[:customer].should_not have_key(:password) c.params[:address][:street].should == "Merb Street 4" c.params[:address][:zip].should == "98765" c.params[:address].should_not have_key(:long) c.params[:address].should_not have_key(:lat) c.params[:post][:title].should == "First port" c.params[:post][:body].should == "Some long lorem ipsum stuff" c.params[:post].should_not have_key(:date) end it "should remove the parameters from the request that are protected" do c = dispatch_to(ParamsProtectedController, :create, :customer => {:name => "teamon", :phone => "123456789", :email => "my@mail", :activated? => "yes", :password => "secret"}, :address => {:street => "Merb Street 4", :zip => "98765", :long => "Meeeeerrrrrrbbbb sooo looong", :lat => "123"}, :post => {:title => "First port", :body => "Some long lorem ipsum stuff", :date => "today"} ) c.params[:customer][:name].should == "teamon" c.params[:customer][:phone].should == "123456789" c.params[:customer][:email].should == "my@mail" c.params[:customer].should_not have_key(:activated?) c.params[:customer].should_not have_key(:password) c.params[:address][:street].should == "Merb Street 4" c.params[:address][:zip].should == "98765" c.params[:address].should_not have_key(:long) c.params[:address].should_not have_key(:lat) c.params[:post][:title].should == "First port" c.params[:post][:body].should == "Some long lorem ipsum stuff" c.params[:post][:date].should == "today" end end describe "param clash prevention" do it "should raise an error 'cannot make accessible'" do lambda { class TestAccessibleController < Merb::Controller params_protected :customer => [:password] params_accessible :customer => [:name, :phone, :email] def index; end end }.should raise_error(/Cannot make accessible a controller \(.*?TestAccessibleController\) that is already protected/) end it "should raise an error 'cannot protect'" do lambda { class TestProtectedController < Merb::Controller params_accessible :customer => [:name, :phone, :email] params_protected :customer => [:password] def index; end end }.should raise_error(/Cannot protect controller \(.*?TestProtectedController\) that is already accessible/) end end describe "param filtering" do it "should remove specified params" do post_body = "post[title]=hello%20there&post[body]=some%20text&post[status]=published&post[author_id]=1&commit=Submit" request = fake_request( {:request_method => 'POST'}, {:post_body => post_body}) request.remove_params_from_object(:post, [:status, :author_id]) request.params[:post][:title].should == "hello there" request.params[:post][:body].should == "some text" request.params[:post][:status].should_not == "published" request.params[:post][:author_id].should_not == 1 request.params[:commit].should == "Submit" end it "should restrict parameters" do post_body = "post[title]=hello%20there&post[body]=some%20text&post[status]=published&post[author_id]=1&commit=Submit" request = fake_request( {:request_method => 'POST'}, {:post_body => post_body}) request.restrict_params(:post, [:title, :body]) request.params[:post][:title].should == "hello there" request.params[:post][:body].should == "some text" request.params[:post][:status].should_not == "published" request.params[:post][:author_id].should_not == 1 request.params[:commit].should == "Submit" request.trashed_params.should == {"status"=>"published", "author_id"=>"1"} end end it "should not have any plugin methods accidently exposed as actions" do Merb::Controller.callable_actions.should be_empty end describe "log params filtering" do it "should filter params" do c = dispatch_to(LogParamsFiltered, :index, :password => "topsecret", :password_confirmation => "topsecret", :card_number => "1234567890", :other => "not so secret") c.params[:password].should == "topsecret" c.params[:password_confirmation].should == "topsecret" c.params[:card_number].should == "1234567890" c.params[:other].should == "not so secret" filtered = c.class._filter_params(c.params) filtered["password"].should == "[FILTERED]" filtered["password_confirmation"].should == "[FILTERED]" filtered["card_number"].should == "[FILTERED]" filtered["other"].should == "not so secret" end end end merb-param-protection-1.1.3/spec/controllers/0000755000175000017500000000000011757200005020524 5ustar tfheentfheenmerb-param-protection-1.1.3/spec/controllers/param_protection.rb0000644000175000017500000000107611757200005024423 0ustar tfheentfheenclass LogParamsFiltered < Merb::Controller log_params_filtered :password, :password_confirmation log_params_filtered :card_number # log_params_filtered :user => [:age] def index params end end class ParamsAccessibleController < Merb::Controller params_accessible :customer => [:name, :phone, :email], :address => [:street, :zip] params_accessible :post => [:title, :body] def create; end end class ParamsProtectedController < Merb::Controller params_protected :customer => [:activated?, :password], :address => [:long, :lat] def create; end end merb-param-protection-1.1.3/spec/spec_helper.rb0000644000175000017500000000112111757200005020767 0ustar tfheentfheenrequire "rubygems" # Use current merb-core sources if running from a typical dev checkout. lib = File.expand_path('../../../merb-core/lib', __FILE__) $LOAD_PATH.unshift(lib) if File.directory?(lib) require 'merb-core' # The lib under test require "merb-param-protection" # Satisfies Autotest and anyone else not using the Rake tasks require 'spec' # Additional files required for specs require "controllers/param_protection" Merb.start :environment => 'test' Spec::Runner.configure do |config| config.include Merb::Test::ControllerHelper config.include Merb::Test::RequestHelper end merb-param-protection-1.1.3/README0000644000175000017500000000236411757200005016111 0ustar tfheentfheenmerb-param-protection ================= This plugin exposes three new controller methods which allow us to simply and flexibly filter the parameters available within the controller. Setup: The request sets: params => { :post => { :title => "ello", :body => "Want it", :status => "green", :author_id => 3, :rank => 4 } } Example 1: params_accessable MyController < Application params_accessible :post => [:title, :body] end params.inspect # => { :post => { :title => "ello", :body => "Want it" } } So we see that params_accessible removes everything except what is explictly specified. Example 2: params_protected MyOtherController < Application params_protected :post => [:status, :author_id] end params.inspect # => { :post => { :title => "ello", :body => "Want it", :rank => 4 } } We also see that params_protected removes ONLY those parameters explicitly specified. Sometimes you have certain post parameters that are best left unlogged, we support that too. Your actions continue to receive the variable correctly, but the requested parameters are scrubbed at log time. MySuperDuperController < Application log_params_filtered :password end params.inspect # => { :username => 'atmos', :password => '[FILTERED]' }merb-param-protection-1.1.3/metadata.yml0000644000175000017500000000414011757200005017526 0ustar tfheentfheen--- !ruby/object:Gem::Specification name: merb-param-protection version: !ruby/object:Gem::Version hash: 21 prerelease: false segments: - 1 - 1 - 3 version: 1.1.3 platform: ruby authors: - Lance Carlson autorequire: bindir: bin cert_chain: [] date: 2010-07-11 00:00:00 +01:00 default_executable: dependencies: - !ruby/object:Gem::Dependency name: merb-core prerelease: false requirement: &id001 !ruby/object:Gem::Requirement none: false requirements: - - ~> - !ruby/object:Gem::Version hash: 21 segments: - 1 - 1 - 3 version: 1.1.3 type: :runtime version_requirements: *id001 - !ruby/object:Gem::Dependency name: rspec prerelease: false requirement: &id002 !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 13 segments: - 1 - 2 - 9 version: 1.2.9 type: :development version_requirements: *id002 description: Merb plugin that helps protecting sensible parameters email: lancecarlson@gmail.com executables: [] extensions: [] extra_rdoc_files: - README - LICENSE - TODO files: - Rakefile - lib/merb-param-protection/version.rb - lib/merb-param-protection.rb - spec/spec.opts - spec/spec_helper.rb - spec/merb_param_protection_spec.rb - spec/controllers/param_protection.rb - README - LICENSE - TODO has_rdoc: true homepage: http://merbivore.com/ licenses: [] post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ">=" - !ruby/object:Gem::Version hash: 3 segments: - 0 version: "0" requirements: [] rubyforge_project: rubygems_version: 1.3.7 signing_key: specification_version: 3 summary: Merb plugin that provides params_accessible and params_protected class methods test_files: [] merb-param-protection-1.1.3/LICENSE0000644000175000017500000000204111757200005016226 0ustar tfheentfheenCopyright (c) 2008 Lance Carlson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. merb-param-protection-1.1.3/Rakefile0000644000175000017500000000140611757200005016672 0ustar tfheentfheenrequire 'rubygems' require 'rake' # Load this library's version information require File.expand_path('../lib/merb-param-protection/version', __FILE__) require 'spec/rake/spectask' Spec::Rake::SpecTask.new(:spec) do |spec| spec.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts') spec.libs << 'lib' << 'spec' spec.spec_files = FileList['spec/**/*_spec.rb'] end Spec::Rake::SpecTask.new(:rcov) do |spec| spec.libs << 'lib' << 'spec' spec.pattern = 'spec/**/*_spec.rb' spec.rcov = true end task :default => :spec require 'rake/rdoctask' Rake::RDocTask.new do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = "test_gem #{Merb::ParamProtection::VERSION}" rdoc.rdoc_files.include('README*') rdoc.rdoc_files.include('lib/**/*.rb') end merb-param-protection-1.1.3/TODO0000644000175000017500000000011411757200005015710 0ustar tfheentfheenTODO: DRY up the code Finish spec'ing Allow specification of any parameter? merb-param-protection-1.1.3/lib/0000755000175000017500000000000011757200005015772 5ustar tfheentfheenmerb-param-protection-1.1.3/lib/merb-param-protection.rb0000644000175000017500000001467711757200005022545 0ustar tfheentfheenrequire "merb-core" module Merb module ParamsFilter module ControllerMixin def self.included(base) base.send(:extend, ClassMethods) base.send(:include, InstanceMethods) base.send(:class_inheritable_accessor, :accessible_params_args) base.send(:class_inheritable_accessor, :protected_params_args) base.send(:class_inheritable_accessor, :log_params_args) # Don't expose these as public methods - otherwise they'll become controller actions base.send(:protected, :accessible_params_args, :protected_params_args, :log_params_args) base.send(:protected, :accessible_params_args=, :protected_params_args=, :log_params_args=) base.send(:before, :initialize_params_filter) end module ClassMethods # Ensures these parameters are sent for the object # # ==== Parameters # args:: Params that will be filtered # # ==== Example # # The request sets: # params => { :post => { :title => "ello", :body => "Want it", :status => "green", :author_id => 3, :rank => 4 } } # # MyController < Application # params_accessible :post => [:title, :body] # end # # params.inspect # => { :post => { :title => "ello", :body => "Want it" } } # # So we see that params_accessible removes everything except what is explictly specified. # # :api: public def params_accessible(args = {}) assign_filtered_params(:accessible_params_args, args) end # Protects parameters of an object # # ==== Parameters # args:: Params that will be filtered # # ==== Example # # The request sets: # params => { :post => { :title => "ello", :body => "Want it", :status => "green", :author_id => 3, :rank => 4 } } # # MyController < Application # params_protected :post => [:status, :author_id] # end # # params.inspect # => { :post => { :title => "ello", :body => "Want it", :rank => 4 } } # # So we see that params_protected removes ONLY those parameters explicitly specified. # # :api: public def params_protected(args = {}) assign_filtered_params(:protected_params_args, args) end # Filters parameters out from the default log string # # Params will still be passed to the controller properly, they will # show up as [FILTERED] in the merb logs. # # ==== Parameters # args:: Params that will be filtered # # ==== Example # log_params_filtered :password, 'token' # # :api: public def log_params_filtered(*args) self.log_params_args ||= [] self.log_params_args += args.collect { |arg| arg.to_s } end private def assign_filtered_params(method, args) validate_filtered_params(method, args) # If the method is nil, set to initial hash, otherwise merge self.send(method).nil? ? self.send(method.to_s + '=', args) : self.send(method).merge!(args) end def validate_filtered_params(method, args) # Reversing methods params_methods = [:accessible_params_args, :protected_params_args] params_methods.delete(method) params_method = params_methods.first # Make sure the opposite method is not nil unless self.send(params_method).nil? # Loop through arg's keys args.keys.each do |key| # If the key exists on the opposite method, raise exception if self.send(params_method).include?(key) case method when :accessible_params_args then raise "Cannot make accessible a controller (#{self}) that is already protected" when :protected_params_args then raise "Cannot protect controller (#{self}) that is already accessible" end end end end end end module InstanceMethods def initialize_params_filter if accessible_params_args.is_a?(Hash) accessible_params_args.keys.each do |obj| self.request.restrict_params(obj, accessible_params_args[obj]) end end if protected_params_args.is_a?(Hash) protected_params_args.keys.each do |obj| self.request.remove_params_from_object(obj, protected_params_args[obj]) end end end end end module RequestMixin attr_accessor :trashed_params # Removes specified parameters of an object # # ==== Parameters # obj:: Params key # attrs:: Attributes to restrict # # ==== Example # remove_params_from_object(:post, [:status, :author_id]) # # :api: plugin def remove_params_from_object(obj, attrs = []) unless params[obj].nil? filtered = params attrs.each {|a| filtered[obj].delete(a)} @params = filtered end end # Restricts parameters of an object # # ==== Parameters # obj:: Params key # attrs:: Attributes to restrict # # ==== Example # restrict_params(:post, [:title, :body]) # # :api: plugin def restrict_params(obj, attrs = []) # Make sure the params for the object exists unless params[obj].nil? attrs = attrs.collect {|a| a.to_s} trashed_params_keys = params[obj].keys - attrs # Store a hash of the key/value pairs we are going # to remove in case we need them later. Lighthouse Bug # 105 @trashed_params = {} trashed_params_keys.each do |key| @trashed_params.merge!({key => params[obj][key]}) end remove_params_from_object(obj, trashed_params_keys) end end end end end Merb::Controller.send(:include, Merb::ParamsFilter::ControllerMixin) Merb::Request.send(:include, Merb::ParamsFilter::RequestMixin) class Merb::Controller # Filters parameters so they are not showed in logs def self._filter_params(params) return params if self.log_params_args.nil? result = { } params.each do |k,v| result[k] = (self.log_params_args.include?(k.to_s) ? '[FILTERED]' : v) end result end end merb-param-protection-1.1.3/lib/merb-param-protection/0000755000175000017500000000000011757200005022201 5ustar tfheentfheenmerb-param-protection-1.1.3/lib/merb-param-protection/version.rb0000644000175000017500000000011411757200005024207 0ustar tfheentfheenmodule Merb module ParamProtection VERSION = '1.1.3'.freeze end end