Commit f2a83cd8 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 c60c6ed3
# 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
...@@ -34,11 +36,11 @@ module AvatarsHelper ...@@ -34,11 +36,11 @@ module AvatarsHelper
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)
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
...@@ -243,6 +243,10 @@ RSpec.describe 'User page' do ...@@ -243,6 +243,10 @@ RSpec.describe 'User page' do
expect(page).to have_content("@#{user.username}") expect(page).to have_content("@#{user.username}")
end end
it 'shows default avatar' do
expect(page).to have_css('//img[data-src^="/assets/no_avatar"]')
end
it_behaves_like 'default brand title page meta description' it_behaves_like 'default brand title page meta description'
end end
...@@ -286,6 +290,10 @@ RSpec.describe 'User page' do ...@@ -286,6 +290,10 @@ RSpec.describe 'User page' do
expect(page).to have_content("This user has a private profile") expect(page).to have_content("This user has a private profile")
end end
it 'shows default avatar' do
expect(page).to have_css('//img[data-src^="/assets/no_avatar"]')
end
it_behaves_like 'default brand title page meta description' it_behaves_like 'default brand title page meta description'
end end
......
...@@ -4,6 +4,7 @@ require 'spec_helper' ...@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe AvatarsHelper do RSpec.describe AvatarsHelper do
include UploadHelpers include UploadHelpers
include Devise::Test::ControllerHelpers
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
...@@ -145,12 +146,49 @@ RSpec.describe AvatarsHelper do ...@@ -145,12 +146,49 @@ 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)) }
let(:helper_args) { [user] }
shared_examples 'blocked or unconfirmed user with avatar' do
it 'returns the default avatar' do
expect(helper.avatar_icon_for_user(user).to_s)
.to match_asset_path(described_class::DEFAULT_AVATAR_PATH)
end
context 'when the current user is an admin', :enable_admin_mode do
let(:current_user) { create(:user, :admin) }
before do
allow(helper).to receive(:current_user).and_return(current_user)
end
it 'returns the user avatar' do
expect(helper.avatar_icon_for_user(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 +209,7 @@ RSpec.describe AvatarsHelper do ...@@ -171,7 +209,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 +219,7 @@ RSpec.describe AvatarsHelper do ...@@ -181,7 +219,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