Skip to content
Snippets Groups Projects
Unverified Commit ad8eea38 authored by Yorick Peterse's avatar Yorick Peterse
Browse files

Merge dev.gitlab.org@master into GitLab.com@master

parents 228d752f b0f939a7
No related branches found
No related tags found
No related merge requests found
Showing
with 170 additions and 29 deletions
---
title: "Don't leak private members in project member autocomplete suggestions"
type: security
---
title: Return 404 on LFS request if project doesn't exist
merge_request:
author:
type: security
---
title: Mask sentry auth token in Error Tracking dashboard
author:
type: security
---
title: Fixes a Open Redirect issue in `InternalRedirect`.
merge_request:
author:
type: security
---
title: Sanitize search text to prevent XSS
merge_request:
author:
type: security
---
title: Sanitize all wiki markup formats with GitLab sanitization pipelines
merge_request:
author:
type: security
Loading
Loading
@@ -44,6 +44,10 @@ Admins are able to share projects with any group in the system.
 
In the example above, the maximum access level of 'Developer' for members from 'Engineering' means that users with higher access levels in 'Engineering' ('Maintainer' or 'Owner') will only have 'Developer' access to 'Project Acme'.
 
## Sharing public project with private group
When sharing a public project with a private group, owners and maintainers of the project will see the name of the group in the `members` page. Owners will also have the possibility to see members of the private group they don't have access to when mentioning them in the issue or merge request.
## Share project with group lock
 
It is possible to prevent projects in a group from [sharing
Loading
Loading
# frozen_string_literal: true
# Recursive queries, with relatively low effort, can quickly spiral out of control exponentially
# and may not be picked up by depth and complexity alone.
module Gitlab
module Graphql
module QueryAnalyzers
class RecursionAnalyzer
IGNORED_FIELDS = %w(node edges ofType).freeze
RECURSION_THRESHOLD = 2
def initial_value(query)
{
recurring_fields: {}
}
end
def call(memo, visit_type, irep_node)
return memo if skip_node?(irep_node)
node_name = irep_node.ast_node.name
times_encountered = memo[node_name] || 0
if visit_type == :enter
times_encountered += 1
memo[:recurring_fields][node_name] = times_encountered if recursion_too_deep?(node_name, times_encountered)
else
times_encountered -= 1
end
memo[node_name] = times_encountered
memo
end
def final_value(memo)
recurring_fields = memo[:recurring_fields]
recurring_fields = recurring_fields.select { |k, v| recursion_too_deep?(k, v) }
if recurring_fields.any?
GraphQL::AnalysisError.new("Recursive query - too many of fields '#{recurring_fields}' detected in single branch of the query")
end
end
private
def recursion_too_deep?(node_name, times_encountered)
return if IGNORED_FIELDS.include?(node_name)
times_encountered > recursion_threshold
end
def skip_node?(irep_node)
ast_node = irep_node.ast_node
!ast_node.is_a?(GraphQL::Language::Nodes::Field) || ast_node.selections.empty?
end
def recursion_threshold
RECURSION_THRESHOLD
end
end
end
end
end
Loading
Loading
@@ -10,7 +10,7 @@ module Gitlab
def self.render(file_name, input, context)
html = GitHub::Markup.render(file_name, input)
.force_encoding(input.encoding)
context[:pipeline] = :markup
context[:pipeline] ||= :markup
 
html = Banzai.render(html, context)
 
Loading
Loading
Loading
Loading
@@ -163,7 +163,7 @@ module Gitlab
return Milestone.none if project_ids.nil?
 
authorized_project_ids_relation =
Project.where(id: project_ids).ids_with_milestone_available_for(current_user)
Project.where(id: project_ids).ids_with_issuables_available_for(current_user)
 
milestones.where(project_id: authorized_project_ids_relation)
end
Loading
Loading
Loading
Loading
@@ -186,7 +186,7 @@ describe ApplicationController do
expect(response).to have_gitlab_http_status(404)
end
 
it 'redirects to login page via authenticate_user! if not authenticated' do
it 'redirects to login page if not authenticated' do
get :index
 
expect(response).to redirect_to new_user_session_path
Loading
Loading
Loading
Loading
@@ -19,7 +19,8 @@ describe InternalRedirect do
[
'Hello world',
'//example.com/hello/world',
'https://example.com/hello/world'
'https://example.com/hello/world',
"not-starting-with-a-slash\n/starting/with/slash"
]
end
 
Loading
Loading
Loading
Loading
@@ -16,13 +16,17 @@ describe LfsRequest do
end
 
def project
@project ||= Project.find(params[:id])
@project ||= Project.find_by(id: params[:id])
end
 
def download_request?
true
end
 
def upload_request?
false
end
def ci?
false
end
Loading
Loading
@@ -49,4 +53,41 @@ describe LfsRequest do
expect(assigns(:storage_project)).to eq(project)
end
end
context 'user is authenticated without access to lfs' do
before do
allow(controller).to receive(:authenticate_user)
allow(controller).to receive(:authentication_result) do
Gitlab::Auth::Result.new
end
end
context 'with access to the project' do
it 'returns 403' do
get :show, params: { id: project.id }
expect(response.status).to eq(403)
end
end
context 'without access to the project' do
context 'project does not exist' do
it 'returns 404' do
get :show, params: { id: 'does not exist' }
expect(response.status).to eq(404)
end
end
context 'project is private' do
let(:project) { create(:project, :private) }
it 'returns 404' do
get :show, params: { id: project.id }
expect(response.status).to eq(404)
end
end
end
end
end
Loading
Loading
@@ -8,6 +8,10 @@ describe Projects::AutocompleteSourcesController do
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user) }
 
def members_by_username(username)
json_response.find { |member| member['username'] == username }
end
describe 'GET members' do
before do
group.add_owner(user)
Loading
Loading
@@ -17,22 +21,21 @@ describe Projects::AutocompleteSourcesController do
it 'returns an array of member object' do
get :members, format: :json, params: { namespace_id: group.path, project_id: project.path, type: issue.class.name, type_id: issue.id }
 
all = json_response.find {|member| member["username"] == 'all'}
the_group = json_response.find {|member| member["username"] == group.full_path}
the_user = json_response.find {|member| member["username"] == user.username}
expect(all.symbolize_keys).to include(username: 'all',
name: 'All Project and Group Members',
count: 1)
expect(the_group.symbolize_keys).to include(type: group.class.name,
name: group.full_name,
avatar_url: group.avatar_url,
count: 1)
expect(the_user.symbolize_keys).to include(type: user.class.name,
name: user.name,
avatar_url: user.avatar_url)
expect(members_by_username('all').symbolize_keys).to include(
username: 'all',
name: 'All Project and Group Members',
count: 1)
expect(members_by_username(group.full_path).symbolize_keys).to include(
type: group.class.name,
name: group.full_name,
avatar_url: group.avatar_url,
count: 1)
expect(members_by_username(user.username).symbolize_keys).to include(
type: user.class.name,
name: user.name,
avatar_url: user.avatar_url)
end
end
 
Loading
Loading
Loading
Loading
@@ -142,7 +142,7 @@ describe Projects::CommitsController do
 
context 'token authentication' do
context 'public project' do
it_behaves_like 'authenticates sessionless user', :show, :atom, public: true do
it_behaves_like 'authenticates sessionless user', :show, :atom, { public: true, ignore_incrementing: true } do
before do
public_project = create(:project, :repository, :public)
 
Loading
Loading
@@ -152,7 +152,7 @@ describe Projects::CommitsController do
end
 
context 'private project' do
it_behaves_like 'authenticates sessionless user', :show, :atom, public: false do
it_behaves_like 'authenticates sessionless user', :show, :atom, { public: false, ignore_incrementing: true } do
before do
private_project = create(:project, :repository, :private)
private_project.add_maintainer(user)
Loading
Loading
Loading
Loading
@@ -146,7 +146,7 @@ describe Projects::ErrorTrackingController do
it 'redirects to sign-in page' do
post :list_projects, params: list_projects_params
 
expect(response).to have_gitlab_http_status(:unauthorized)
expect(response).to have_gitlab_http_status(:redirect)
end
end
 
Loading
Loading
Loading
Loading
@@ -1441,7 +1441,7 @@ describe Projects::IssuesController do
context 'private project with token authentication' do
let(:private_project) { create(:project, :private) }
 
it_behaves_like 'authenticates sessionless user', :index, :atom do
it_behaves_like 'authenticates sessionless user', :index, :atom, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
 
Loading
Loading
@@ -1449,7 +1449,7 @@ describe Projects::IssuesController do
end
end
 
it_behaves_like 'authenticates sessionless user', :calendar, :ics do
it_behaves_like 'authenticates sessionless user', :calendar, :ics, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
 
Loading
Loading
Loading
Loading
@@ -41,7 +41,7 @@ describe Projects::TagsController do
context 'private project with token authentication' do
let(:private_project) { create(:project, :repository, :private) }
 
it_behaves_like 'authenticates sessionless user', :index, :atom do
it_behaves_like 'authenticates sessionless user', :index, :atom, ignore_incrementing: true do
before do
default_params.merge!(project_id: private_project, namespace_id: private_project.namespace)
 
Loading
Loading
Loading
Loading
@@ -1149,7 +1149,7 @@ describe ProjectsController do
context 'private project with token authentication' do
let(:private_project) { create(:project, :private) }
 
it_behaves_like 'authenticates sessionless user', :show, :atom do
it_behaves_like 'authenticates sessionless user', :show, :atom, ignore_incrementing: true do
before do
default_params.merge!(id: private_project, namespace_id: private_project.namespace)
 
Loading
Loading
Loading
Loading
@@ -819,7 +819,10 @@ describe 'Pipelines', :js do
context 'when project is private' do
let(:project) { create(:project, :private, :repository) }
 
it { expect(page).to have_content 'You need to sign in' }
it 'redirects the user to sign_in and displays the flash alert' do
expect(page).to have_content 'You need to sign in'
expect(page.current_path).to eq("/users/sign_in")
end
end
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment