forked from heartcombo/devise
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide a more robust behavior to serializers and add :force_except o…
…ption
- Loading branch information
Showing
4 changed files
with
85 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |