Commit 565dc6f4 authored by Drew Blessing's avatar Drew Blessing

Hide user avatar for blocked and unconfirmed users

Avatars can sometimes be used to display spam or other undesirable
content for unconfirmed or blocked users. This change hides the
user's custom avatar in these cases until they become unblocked
or confirmed.

Changelog: changed
parent 4335649b
# frozen_string_literal: true # frozen_string_literal: true
module AvatarsHelper module AvatarsHelper
DEFAULT_AVATAR_PATH = 'no_avatar.png'
def project_icon(project, options = {}) def project_icon(project, options = {})
source_icon(project, options) source_icon(project, options)
end end
...@@ -33,12 +35,12 @@ module AvatarsHelper ...@@ -33,12 +35,12 @@ module AvatarsHelper
end end
end end
def avatar_icon_for_user(user = nil, size = nil, scale = 2, only_path: true) def avatar_icon_for_user(user = nil, size = nil, scale = 2, only_path: true, current_user: nil)
if user return gravatar_icon(nil, size, scale) unless user
user.avatar_url(size: size, only_path: only_path) || default_avatar return default_avatar if blocked_or_unconfirmed?(user) && !can_admin?(current_user)
else
gravatar_icon(nil, size, scale) user_avatar = user.avatar_url(size: size, only_path: only_path)
end user_avatar || default_avatar
end end
def gravatar_icon(user_email = '', size = nil, scale = 2) def gravatar_icon(user_email = '', size = nil, scale = 2)
...@@ -47,7 +49,7 @@ module AvatarsHelper ...@@ -47,7 +49,7 @@ module AvatarsHelper
end end
def default_avatar def default_avatar
ActionController::Base.helpers.image_path('no_avatar.png') ActionController::Base.helpers.image_path(DEFAULT_AVATAR_PATH)
end end
def author_avatar(commit_or_event, options = {}) def author_avatar(commit_or_event, options = {})
...@@ -157,4 +159,14 @@ module AvatarsHelper ...@@ -157,4 +159,14 @@ module AvatarsHelper
source.name[0, 1].upcase source.name[0, 1].upcase
end end
end end
def blocked_or_unconfirmed?(user)
user.blocked? || !user.confirmed?
end
def can_admin?(user)
return false unless user
user.can_admin_all_resources?
end
end end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= @user.name = @user.name
%ul.content-list %ul.content-list
%li %li
= image_tag avatar_icon_for_user(@user, 60), class: "avatar s60" = image_tag avatar_icon_for_user(@user, 60, current_user: current_user), class: "avatar s60"
%li %li
%span.light= _('Profile page:') %span.light= _('Profile page:')
%strong %strong
......
...@@ -50,8 +50,8 @@ ...@@ -50,8 +50,8 @@
.profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?)] } .profile-header{ class: [('with-no-profile-tabs' if profile_tabs.empty?)] }
.avatar-holder .avatar-holder
= link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do = link_to avatar_icon_for_user(@user, 400, current_user: current_user), target: '_blank', rel: 'noopener noreferrer' do
= image_tag avatar_icon_for_user(@user, 90), class: "avatar s90", alt: '', itemprop: 'image' = image_tag avatar_icon_for_user(@user, 90, current_user: current_user), class: "avatar s90", alt: '', itemprop: 'image'
- if @user.blocked? || !@user.confirmed? - if @user.blocked? || !@user.confirmed?
.user-info .user-info
......
...@@ -146,11 +146,52 @@ RSpec.describe AvatarsHelper do ...@@ -146,11 +146,52 @@ RSpec.describe AvatarsHelper do
describe '#avatar_icon_for_user' do describe '#avatar_icon_for_user' do
let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) } let(:user) { create(:user, avatar: File.open(uploaded_image_temp_path)) }
shared_examples 'blocked or unconfirmed user with avatar' do
context 'when the viewer is not an admin' do
let!(:viewing_user) { create(:user) }
it 'returns the default avatar' do
expect(helper.avatar_icon_for_user(user, current_user: viewing_user).to_s)
.to match_asset_path(described_class::DEFAULT_AVATAR_PATH)
end
end
context 'when the viewer is an admin', :enable_admin_mode do
let!(:viewing_user) { create(:user, :admin) }
it 'returns the default avatar when the user is not passed' do
expect(helper.avatar_icon_for_user(user).to_s)
.to match_asset_path(described_class::DEFAULT_AVATAR_PATH)
end
it 'returns the user avatar when the user is passed' do
expect(helper.avatar_icon_for_user(user, current_user: viewing_user).to_s)
.to eq(user.avatar.url)
end
end
end
context 'with a user object passed' do context 'with a user object passed' do
it 'returns a relative URL for the avatar' do it 'returns a relative URL for the avatar' do
expect(helper.avatar_icon_for_user(user).to_s) expect(helper.avatar_icon_for_user(user).to_s)
.to eq(user.avatar.url) .to eq(user.avatar.url)
end end
context 'when the user is blocked' do
before do
user.block!
end
it_behaves_like 'blocked or unconfirmed user with avatar'
end
context 'when the user is unconfirmed' do
before do
user.update!(confirmed_at: nil)
end
it_behaves_like 'blocked or unconfirmed user with avatar'
end
end end
context 'without a user object passed' do context 'without a user object passed' do
...@@ -171,7 +212,7 @@ RSpec.describe AvatarsHelper do ...@@ -171,7 +212,7 @@ RSpec.describe AvatarsHelper do
end end
it 'returns a generic avatar' do it 'returns a generic avatar' do
expect(helper.gravatar_icon(user_email)).to match_asset_path('no_avatar.png') expect(helper.gravatar_icon(user_email)).to match_asset_path(described_class::DEFAULT_AVATAR_PATH)
end end
end end
...@@ -181,7 +222,7 @@ RSpec.describe AvatarsHelper do ...@@ -181,7 +222,7 @@ RSpec.describe AvatarsHelper do
end end
it 'returns a generic avatar when email is blank' do it 'returns a generic avatar when email is blank' do
expect(helper.gravatar_icon('')).to match_asset_path('no_avatar.png') expect(helper.gravatar_icon('')).to match_asset_path(described_class::DEFAULT_AVATAR_PATH)
end end
it 'returns a valid Gravatar URL' do it 'returns a valid Gravatar URL' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment