Merge branch 'issue_3508' into 'master'
Restrict public users for private instances Implements #3508 See merge request !3440
This commit is contained in:
commit
58665b64f5
|
@ -13,6 +13,7 @@ v 8.7.0 (unreleased)
|
|||
- Project switcher uses new dropdown styling
|
||||
- Load award emoji images separately unless opening the full picker. Saves several hundred KBs of data for most pages. (Connor Shea)
|
||||
- Do not include award_emojis in issue and merge_request comment_count !3610 (Lucas Charles)
|
||||
- Restrict user profiles when public visibility level is restricted.
|
||||
- All images in discussions and wikis now link to their source files !3464 (Connor Shea).
|
||||
- Return status code 303 after a branch DELETE operation to avoid project deletion (Stan Hu)
|
||||
- Add setting for customizing the list of trusted proxies !3524
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class UsersController < ApplicationController
|
||||
skip_before_action :authenticate_user!
|
||||
before_action :set_user
|
||||
before_action :user
|
||||
before_action :authorize_read_user!, only: [:show]
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
|
@ -75,22 +76,26 @@ class UsersController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def set_user
|
||||
@user = User.find_by_username!(params[:username])
|
||||
def authorize_read_user!
|
||||
render_404 unless can?(current_user, :read_user, user)
|
||||
end
|
||||
|
||||
def user
|
||||
@user ||= User.find_by_username!(params[:username])
|
||||
end
|
||||
|
||||
def contributed_projects
|
||||
ContributedProjectsFinder.new(@user).execute(current_user)
|
||||
ContributedProjectsFinder.new(user).execute(current_user)
|
||||
end
|
||||
|
||||
def contributions_calendar
|
||||
@contributions_calendar ||= Gitlab::ContributionsCalendar.
|
||||
new(contributed_projects, @user)
|
||||
new(contributed_projects, user)
|
||||
end
|
||||
|
||||
def load_events
|
||||
# Get user activity feed for projects common for both users
|
||||
@events = @user.recent_events.
|
||||
@events = user.recent_events.
|
||||
merge(projects_for_current_user).
|
||||
references(:project).
|
||||
with_associations.
|
||||
|
@ -99,16 +104,16 @@ class UsersController < ApplicationController
|
|||
|
||||
def load_projects
|
||||
@projects =
|
||||
PersonalProjectsFinder.new(@user).execute(current_user)
|
||||
PersonalProjectsFinder.new(user).execute(current_user)
|
||||
.page(params[:page])
|
||||
end
|
||||
|
||||
def load_contributed_projects
|
||||
@contributed_projects = contributed_projects.joined(@user)
|
||||
@contributed_projects = contributed_projects.joined(user)
|
||||
end
|
||||
|
||||
def load_groups
|
||||
@groups = JoinedGroupsFinder.new(@user).execute(current_user)
|
||||
@groups = JoinedGroupsFinder.new(user).execute(current_user)
|
||||
end
|
||||
|
||||
def projects_for_current_user
|
||||
|
|
|
@ -18,6 +18,7 @@ class Ability
|
|||
when Namespace then namespace_abilities(user, subject)
|
||||
when GroupMember then group_member_abilities(user, subject)
|
||||
when ProjectMember then project_member_abilities(user, subject)
|
||||
when User then user_abilities
|
||||
else []
|
||||
end.concat(global_abilities(user))
|
||||
end
|
||||
|
@ -35,6 +36,8 @@ class Ability
|
|||
anonymous_project_abilities(subject)
|
||||
when subject.is_a?(Group) || subject.respond_to?(:group)
|
||||
anonymous_group_abilities(subject)
|
||||
when subject.is_a?(User)
|
||||
anonymous_user_abilities
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
@ -81,17 +84,17 @@ class Ability
|
|||
end
|
||||
|
||||
def anonymous_group_abilities(subject)
|
||||
rules = []
|
||||
|
||||
group = if subject.is_a?(Group)
|
||||
subject
|
||||
else
|
||||
subject.group
|
||||
end
|
||||
|
||||
if group && group.public?
|
||||
[:read_group]
|
||||
else
|
||||
[]
|
||||
end
|
||||
rules << :read_group if group.public?
|
||||
|
||||
rules
|
||||
end
|
||||
|
||||
def anonymous_personal_snippet_abilities(snippet)
|
||||
|
@ -110,9 +113,14 @@ class Ability
|
|||
end
|
||||
end
|
||||
|
||||
def anonymous_user_abilities
|
||||
[:read_user] unless restricted_public_level?
|
||||
end
|
||||
|
||||
def global_abilities(user)
|
||||
rules = []
|
||||
rules << :create_group if user.can_create_group
|
||||
rules << :read_users_list
|
||||
rules
|
||||
end
|
||||
|
||||
|
@ -163,7 +171,7 @@ class Ability
|
|||
@public_project_rules ||= project_guest_rules + [
|
||||
:download_code,
|
||||
:fork_project,
|
||||
:read_commit_status,
|
||||
:read_commit_status
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -284,7 +292,6 @@ class Ability
|
|||
|
||||
def group_abilities(user, group)
|
||||
rules = []
|
||||
|
||||
rules << :read_group if can_read_group?(user, group)
|
||||
|
||||
# Only group masters and group owners can create new projects
|
||||
|
@ -456,6 +463,10 @@ class Ability
|
|||
rules
|
||||
end
|
||||
|
||||
def user_abilities
|
||||
[:read_user]
|
||||
end
|
||||
|
||||
def abilities
|
||||
@abilities ||= begin
|
||||
abilities = Six.new
|
||||
|
@ -470,6 +481,10 @@ class Ability
|
|||
|
||||
private
|
||||
|
||||
def restricted_public_level?
|
||||
current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC)
|
||||
end
|
||||
|
||||
def named_abilities(name)
|
||||
[
|
||||
:"read_#{name}",
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
.btn-group{ data: data_attrs }
|
||||
- restricted_level_checkboxes('restricted-visibility-help').each do |level|
|
||||
= level
|
||||
%span.help-block#restricted-visibility-help Selected levels cannot be used by non-admin users for projects or snippets
|
||||
%span.help-block#restricted-visibility-help
|
||||
Selected levels cannot be used by non-admin users for projects or snippets.
|
||||
If the public level is restricted, user profiles are only visible to logged in users.
|
||||
.form-group
|
||||
= f.label :import_sources, class: 'control-label col-sm-2'
|
||||
.col-sm-10
|
||||
|
|
|
@ -58,6 +58,9 @@ you are logged in or not.
|
|||
When visiting the public page of a user, you can only see the projects which
|
||||
you are privileged to.
|
||||
|
||||
If the public level is restricted, user profiles are only visible to logged in users.
|
||||
|
||||
|
||||
## Restricting the use of public or internal projects
|
||||
|
||||
In the Admin area under **Settings** (`/admin/application_settings`), you can
|
||||
|
|
|
@ -11,6 +11,10 @@ module API
|
|||
# GET /users?search=Admin
|
||||
# GET /users?username=root
|
||||
get do
|
||||
unless can?(current_user, :read_users_list, nil)
|
||||
render_api_error!("Not authorized.", 403)
|
||||
end
|
||||
|
||||
if params[:username].present?
|
||||
@users = User.where(username: params[:username])
|
||||
else
|
||||
|
@ -36,10 +40,12 @@ module API
|
|||
get ":id" do
|
||||
@user = User.find(params[:id])
|
||||
|
||||
if current_user.is_admin?
|
||||
if current_user && current_user.is_admin?
|
||||
present @user, with: Entities::UserFull
|
||||
else
|
||||
elsif can?(current_user, :read_user, @user)
|
||||
present @user, with: Entities::User
|
||||
else
|
||||
render_api_error!("User not found.", 404)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Groups::GroupMembersController do
|
||||
let(:user) { create(:user) }
|
||||
let(:group) { create(:group) }
|
||||
|
||||
context "index" do
|
||||
before do
|
||||
group.add_owner(user)
|
||||
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
|
||||
end
|
||||
|
||||
it 'renders index with group members' do
|
||||
get :index, group_id: group.path
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to render_template(:index)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,7 +33,30 @@ describe UsersController do
|
|||
it 'renders the show template' do
|
||||
get :show, username: user.username
|
||||
|
||||
expect(response).to be_success
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to render_template('show')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when public visibility level is restricted' do
|
||||
before do
|
||||
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
|
||||
end
|
||||
|
||||
context 'when logged out' do
|
||||
it 'renders 404' do
|
||||
get :show, username: user.username
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when logged in' do
|
||||
before { sign_in(user) }
|
||||
|
||||
it 'renders show' do
|
||||
get :show, username: user.username
|
||||
expect(response.status).to eq(200)
|
||||
expect(response).to render_template('show')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,6 +20,24 @@ describe API::API, api: true do
|
|||
end
|
||||
|
||||
context "when authenticated" do
|
||||
#These specs are written just in case API authentication is not required anymore
|
||||
context "when public level is restricted" do
|
||||
before do
|
||||
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
|
||||
allow_any_instance_of(API::Helpers).to receive(:authenticate!).and_return(true)
|
||||
end
|
||||
|
||||
it "renders 403" do
|
||||
get api("/users")
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "renders 404" do
|
||||
get api("/users/#{user.id}")
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
|
||||
it "should return an array of users" do
|
||||
get api("/users", user)
|
||||
expect(response.status).to eq(200)
|
||||
|
|
Loading…
Reference in New Issue