mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Provide a more robust behavior to serializers and add :force_except option
This commit is contained in:
parent
5a98e4f4e8
commit
33d7644b4f
4 changed files with 85 additions and 14 deletions
|
@ -1,5 +1,6 @@
|
|||
* bug fix
|
||||
* Improve Rails 3.1 compatibility
|
||||
* Provide a more robust behavior to serializers and add :force_except option
|
||||
|
||||
== 1.4.1
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'devise/hooks/activatable'
|
||||
require 'devise/models/serializable'
|
||||
|
||||
module Devise
|
||||
module Models
|
||||
|
@ -46,6 +47,8 @@ module Devise
|
|||
module Authenticatable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include Devise::Models::Serializable
|
||||
|
||||
included do
|
||||
class_attribute :devise_modules, :instance_writer => false
|
||||
self.devise_modules ||= []
|
||||
|
@ -76,20 +79,6 @@ module Devise
|
|||
def authenticatable_salt
|
||||
end
|
||||
|
||||
# TODO: to_xml does not call serializable_hash. Hopefully someone will fix this in AR.
|
||||
%w(to_xml serializable_hash).each do |method|
|
||||
class_eval <<-RUBY, __FILE__, __LINE__
|
||||
def #{method}(options={})
|
||||
if self.class.respond_to?(:accessible_attributes)
|
||||
options = { :only => self.class.accessible_attributes.to_a }.merge(options || {})
|
||||
super(options)
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
Devise::Models.config(self, :authentication_keys, :request_keys, :strip_whitespace_keys, :case_insensitive_keys, :http_authenticatable, :params_authenticatable)
|
||||
|
||||
|
|
43
lib/devise/models/serializable.rb
Normal file
43
lib/devise/models/serializable.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
module Devise
|
||||
module Models
|
||||
# This module redefine to_xml and serializable_hash in models for more
|
||||
# secure defaults. By default, it removes from the serializable model
|
||||
# all attributes that are *not* accessible. You can remove this default
|
||||
# by using :force_except and passing a new list of attributes you want
|
||||
# to exempt. All attributes given to :except will simply add names to
|
||||
# exempt to Devise internal list.
|
||||
module Serializable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
# TODO: to_xml does not call serializable_hash. Hopefully someone will fix this in AR.
|
||||
%w(to_xml serializable_hash).each do |method|
|
||||
class_eval <<-RUBY, __FILE__, __LINE__
|
||||
def #{method}(options=nil)
|
||||
options ||= {}
|
||||
if options.key?(:force_except)
|
||||
options[:except] = options.delete(:force_except)
|
||||
super(options)
|
||||
elsif self.class.blacklist_keys?
|
||||
except = Array(options[:except])
|
||||
super(options.merge(:except => except + self.class.blacklist_keys))
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Return true if we can retrieve blacklist keys from the record.
|
||||
def blacklist_keys?
|
||||
@has_except_keys ||= respond_to?(:accessible_attributes) && !accessible_attributes.to_a.empty?
|
||||
end
|
||||
|
||||
# Returns keys that should be removed when serializing the record.
|
||||
def blacklist_keys
|
||||
@blacklist_keys ||= to_adapter.column_names.map(&:to_s) - accessible_attributes.to_a.map(&:to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
test/models/serializable_test.rb
Normal file
38
test/models/serializable_test.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require 'test_helper'
|
||||
|
||||
class SerializableTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@user = create_user
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on XML' do
|
||||
assert_match /email/, @user.to_xml
|
||||
assert_no_match /confirmation-token/, @user.to_xml
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on XML even if a new except is provided' do
|
||||
assert_no_match /email/, @user.to_xml(:except => :email)
|
||||
assert_no_match /confirmation-token/, @user.to_xml(:except => :email)
|
||||
end
|
||||
|
||||
test 'should include unsafe keys on XML if a force_except is provided' do
|
||||
assert_no_match /email/, @user.to_xml(:force_except => :email)
|
||||
assert_match /confirmation-token/, @user.to_xml(:force_except => :email)
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on JSON' do
|
||||
assert_match /"email":/, @user.to_json
|
||||
assert_no_match /"confirmation_token":/, @user.to_json
|
||||
end
|
||||
|
||||
test 'should not include unsafe keys on JSON even if a new except is provided' do
|
||||
assert_no_match /"email":/, @user.to_json(:except => :email)
|
||||
assert_no_match /"confirmation_token":/, @user.to_json(:except => :email)
|
||||
end
|
||||
|
||||
test 'should include unsafe keys on JSON if a force_except is provided' do
|
||||
assert_no_match /"email":/, @user.to_json(:force_except => :email)
|
||||
assert_match /"confirmation_token":/, @user.to_json(:force_except => :email)
|
||||
end
|
||||
|
||||
end
|
Loading…
Add table
Reference in a new issue