Commit e1d4b86c authored by Kamil Trzcinski's avatar Kamil Trzcinski

Introduce build_read_project and perform license check

parent 4bc75dc9
......@@ -6,6 +6,7 @@ class License < ActiveRecord::Base
AUDITOR_USER_FEATURE = 'GitLab_Auditor_User'.freeze
BURNDOWN_CHARTS_FEATURE = 'GitLab_BurndownCharts'.freeze
CONTRIBUTION_ANALYTICS_FEATURE = 'GitLab_ContributionAnalytics'.freeze
CROSS_PROJECT_PIPELINES_FEATURE = 'GitLab_CrossProjectPipelines'.freeze
DB_LOAD_BALANCING_FEATURE = 'GitLab_DbLoadBalancing'.freeze
DEPLOY_BOARD_FEATURE = 'GitLab_DeployBoard'.freeze
ELASTIC_SEARCH_FEATURE = 'GitLab_ElasticSearch'.freeze
......@@ -51,6 +52,7 @@ class License < ActiveRecord::Base
audit_events: AUDIT_EVENTS_FEATURE,
burndown_charts: BURNDOWN_CHARTS_FEATURE,
contribution_analytics: CONTRIBUTION_ANALYTICS_FEATURE,
cross_project_pipelines: CROSS_PROJECT_PIPELINES_FEATURE,
deploy_board: DEPLOY_BOARD_FEATURE,
export_issues: EXPORT_ISSUES_FEATURE,
fast_forward_merge: FAST_FORWARD_MERGE_FEATURE,
......@@ -106,6 +108,7 @@ class License < ActiveRecord::Base
*EES_FEATURES,
{ ADMIN_AUDIT_LOG_FEATURE => 1 },
{ AUDITOR_USER_FEATURE => 1 },
{ CROSS_PROJECT_PIPELINES_FEATURE => 1 },
{ DB_LOAD_BALANCING_FEATURE => 1 },
{ DEPLOY_BOARD_FEATURE => 1 },
{ FILE_LOCKS_FEATURE => 1 },
......@@ -131,6 +134,7 @@ class License < ActiveRecord::Base
{ AUDITOR_USER_FEATURE => 1 },
{ BURNDOWN_CHARTS_FEATURE => 1 },
{ CONTRIBUTION_ANALYTICS_FEATURE => 1 },
{ CROSS_PROJECT_PIPELINES_FEATURE => 1 },
{ DEPLOY_BOARD_FEATURE => 1 },
{ EXPORT_ISSUES_FEATURE => 1 },
{ FAST_FORWARD_MERGE_FEATURE => 1 },
......
......@@ -101,6 +101,7 @@ class ProjectPolicy < BasePolicy
end
rule { owner | reporter }.policy do
enable :build_read_project
enable :build_download_code
enable :build_read_container_image
end
......
---
title: Allow artifacts access with CI_JOB_TOKEN
title: Allow artifacts access with job_token parameter or CI_JOB_TOKEN header
merge_request:
author:
......@@ -8,8 +8,8 @@ module API
PRIVATE_TOKEN_HEADER = "HTTP_PRIVATE_TOKEN".freeze
PRIVATE_TOKEN_PARAM = :private_token
CI_JOB_TOKEN_HEADER = "HTTP_JOB_TOKEN".freeze
CI_JOB_TOKEN_PARAM = :job_token
JOB_TOKEN_HEADER = "HTTP_JOB_TOKEN".freeze
JOB_TOKEN_PARAM = :job_token
included do |base|
# OAuth2 Resource Server Authentication
......@@ -89,13 +89,14 @@ module API
find_user_by_authentication_token(token_string) || find_user_by_personal_access_token(token_string, scopes)
end
def find_user_by_ci_token
return nil unless route_authentication_setting[:job_token_allowed]
def find_user_by_job_token
return @user_by_job_token if defined?(@user_by_job_token)
token_string = (params[CI_JOB_TOKEN_PARAM] || env[CI_JOB_TOKEN_HEADER]).to_s
return nil unless token_string.present?
Ci::Build.find_by_token(token_string)&.user
@user_by_job_token =
if route_authentication_setting[:job_token_allowed]
token_string = params[JOB_TOKEN_PARAM].presence || env[JOB_TOKEN_HEADER].presence
Ci::Build.find_by_token(token_string)&.user if token_string
end
end
def current_user
......
......@@ -58,9 +58,12 @@ module API
def find_project!(id)
project = find_project(id)
if ci_job_token && !current_user.authorized_projects.exists?(project)
not_found!('Project')
elsif can?(current_user, :read_project, project)
# CI job token authentication:
# this method grants limited privileged for admin users
# admin users can only access project if they are direct member
ability = job_token_authentication? ? :build_read_project : :read_project
if can?(current_user, ability, project)
project
else
not_found!('Project')
......@@ -84,11 +87,13 @@ module API
end
def find_group!(id)
# CI job token authentication:
# currently we do not allow any group access for CI job token
not_found!('Group') if job_token_authentication?
group = find_group(id)
if ci_job_token
not_found!('Group')
elsif can?(current_user, :read_group, group)
if can?(current_user, ability, group)
group
else
not_found!('Group')
......@@ -352,10 +357,9 @@ module API
def private_token
params[APIGuard::PRIVATE_TOKEN_PARAM] || env[APIGuard::PRIVATE_TOKEN_HEADER]
end
def ci_job_token
params[APIGuard::CI_JOB_TOKEN_PARAM] || env[APIGuard::CI_JOB_TOKEN_HEADER]
def job_token_authentication?
initial_current_user && initial_current_user == find_user_by_job_token
end
def warden
......@@ -372,12 +376,11 @@ module API
def initial_current_user
return @initial_current_user if defined?(@initial_current_user)
Gitlab::Auth::UniqueIpsLimiter.limit_user! do
@initial_current_user ||= find_user_by_private_token(scopes: scopes_registered_for_endpoint)
@initial_current_user ||= doorkeeper_guard(scopes: scopes_registered_for_endpoint)
@initial_current_user ||= find_user_from_warden
@initial_current_user ||= find_user_by_ci_token
@initial_current_user ||= find_user_by_job_token
unless @initial_current_user && Gitlab::UserAccess.new(@initial_current_user).allowed?
@initial_current_user = nil
......
......@@ -80,6 +80,7 @@ module API
route_setting :authentication, job_token_allowed: true
get ':id/jobs/:job_id/artifacts' do
authorize_read_builds!
check_cross_project_pipelines_feature!
build = get_build!(params[:job_id])
......@@ -97,6 +98,7 @@ module API
get ':id/jobs/artifacts/:ref_name/download',
requirements: { ref_name: /.+/ } do
authorize_read_builds!
check_cross_project_pipelines_feature!
builds = user_project.latest_successful_builds_for(params[:ref_name])
latest_build = builds.find_by!(name: params[:job])
......@@ -244,6 +246,10 @@ module API
def authorize_update_builds!
authorize! :update_build, user_project
end
def check_cross_project_pipelines_feature!
not_found!('Project') if job_token_authentication? && project.feature_available?(:cross_project_pipelines)
end
end
end
end
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