Do not leak private profile fields in JSON format

Signed-off-by: Dennis Schubert <mail@dennis-schubert.de>
This commit is contained in:
Dennis Schubert 2015-07-02 03:11:22 +02:00 committed by Jonne Haß
parent 56df5978af
commit e92c8000ba
3 changed files with 44 additions and 29 deletions

View file

@ -1,6 +1,7 @@
class PersonPresenter < BasePresenter class PersonPresenter < BasePresenter
def base_hash def base_hash
{ id: id, {
id: id,
guid: guid, guid: guid,
name: name, name: name,
diaspora_id: diaspora_handle diaspora_id: diaspora_handle
@ -8,31 +9,39 @@ class PersonPresenter < BasePresenter
end end
def full_hash def full_hash
base_hash.merge({ base_hash.merge(
relationship: relationship, relationship: relationship,
block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false, block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false,
contact: (!own_profile? && has_contact?) ? {id: current_user_person_contact.id} : false, contact: (!own_profile? && has_contact?) ? {id: current_user_person_contact.id} : false,
is_own_profile: own_profile? is_own_profile: own_profile?
}) )
end end
def full_hash_with_avatar def full_hash_with_avatar
full_hash.merge({avatar: AvatarPresenter.new(profile).base_hash}) full_hash.merge(avatar: AvatarPresenter.new(profile).base_hash)
end end
def full_hash_with_profile def full_hash_with_profile
full_hash.merge({profile: ProfilePresenter.new(profile).full_hash}) attrs = full_hash
if own_profile? || person_is_following_current_user
attrs.merge!(profile: ProfilePresenter.new(profile).private_hash)
else
attrs.merge!(profile: ProfilePresenter.new(profile).public_hash)
end end
def as_json(options={}) attrs
end
def as_json(_options={})
attrs = full_hash_with_avatar attrs = full_hash_with_avatar
if own_profile? || person_is_following_current_user if own_profile? || person_is_following_current_user
attrs.merge!({ attrs.merge!(
:location => @presentable.location, location: @presentable.location,
:birthday => @presentable.formatted_birthday, birthday: @presentable.formatted_birthday,
:bio => @presentable.bio bio: @presentable.bio
}) )
end end
attrs attrs
@ -51,7 +60,7 @@ class PersonPresenter < BasePresenter
contact = current_user_person_contact contact = current_user_person_contact
return :not_sharing unless contact return :not_sharing unless contact
[:mutual, :sharing, :receiving].find do |status| %i(mutual sharing receiving).find do |status|
contact.public_send("#{status}?") contact.public_send("#{status}?")
end || :not_sharing end || :not_sharing
end end

View file

@ -2,20 +2,26 @@ class ProfilePresenter < BasePresenter
include PeopleHelper include PeopleHelper
def base_hash def base_hash
{ id: id, {
tags: tags.pluck(:name), id: id,
bio: bio_message.plain_text_for_json,
location: location_message.plain_text_for_json,
gender: gender,
birthday: formatted_birthday,
searchable: searchable searchable: searchable
} }
end end
def full_hash def public_hash
base_hash.merge({ base_hash.merge(
avatar: AvatarPresenter.new(@presentable).base_hash, avatar: AvatarPresenter.new(@presentable).base_hash,
}) tags: tags.pluck(:name)
)
end
def private_hash
public_hash.merge(
bio: bio_message.plain_text_for_json,
birthday: formatted_birthday,
gender: gender,
location: location_message.plain_text_for_json
)
end end
def formatted_birthday def formatted_birthday

View file

@ -16,12 +16,12 @@ describe PersonPresenter do
let(:presenter){ PersonPresenter.new(person, current_user) } let(:presenter){ PersonPresenter.new(person, current_user) }
it "doesn't share private information when the users aren't connected" do it "doesn't share private information when the users aren't connected" do
expect(presenter.as_json).not_to have_key(:location) expect(presenter.full_hash_with_profile[:profile]).not_to have_key(:location)
end end
it "has private information when the person is sharing with the current user" do it "has private information when the person is sharing with the current user" do
expect(person).to receive(:shares_with).with(current_user).and_return(true) expect(person).to receive(:shares_with).with(current_user).and_return(true)
expect(presenter.as_json).to have_key(:location) expect(presenter.full_hash_with_profile[:profile]).to have_key(:location)
end end
it "returns the user's private information if a user is logged in as herself" do it "returns the user's private information if a user is logged in as herself" do