New upstream version 14.9.5+ds1
This commit is contained in:
parent
514ffadb92
commit
cee083333e
25 changed files with 173 additions and 37 deletions
|
@ -280,7 +280,9 @@ coverage-frontend:
|
||||||
paths:
|
paths:
|
||||||
- coverage-frontend/
|
- coverage-frontend/
|
||||||
reports:
|
reports:
|
||||||
cobertura: coverage-frontend/cobertura-coverage.xml
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: coverage-frontend/cobertura-coverage.xml
|
||||||
|
|
||||||
.qa-frontend-node:
|
.qa-frontend-node:
|
||||||
extends:
|
extends:
|
||||||
|
|
|
@ -602,7 +602,9 @@ rspec:coverage:
|
||||||
- coverage/assets/
|
- coverage/assets/
|
||||||
- coverage/lcov/
|
- coverage/lcov/
|
||||||
reports:
|
reports:
|
||||||
cobertura: coverage/coverage.xml
|
coverage_report:
|
||||||
|
coverage_format: cobertura
|
||||||
|
path: coverage/coverage.xml
|
||||||
|
|
||||||
rspec:undercoverage:
|
rspec:undercoverage:
|
||||||
extends:
|
extends:
|
||||||
|
|
|
@ -87,12 +87,6 @@ gemnasium-dependency_scanning:
|
||||||
- apk add git-lfs
|
- apk add git-lfs
|
||||||
rules: !reference [".reports:rules:gemnasium-dependency_scanning", rules]
|
rules: !reference [".reports:rules:gemnasium-dependency_scanning", rules]
|
||||||
|
|
||||||
bundler-audit-dependency_scanning:
|
|
||||||
rules: !reference [".reports:rules:bundler-audit-dependency_scanning", rules]
|
|
||||||
|
|
||||||
retire-js-dependency_scanning:
|
|
||||||
rules: !reference [".reports:rules:retire-js-dependency_scanning", rules]
|
|
||||||
|
|
||||||
gemnasium-python-dependency_scanning:
|
gemnasium-python-dependency_scanning:
|
||||||
rules: !reference [".reports:rules:gemnasium-python-dependency_scanning", rules]
|
rules: !reference [".reports:rules:gemnasium-python-dependency_scanning", rules]
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ review-build-cng:
|
||||||
variables:
|
variables:
|
||||||
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
|
||||||
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
|
||||||
GITLAB_HELM_CHART_REF: "v5.5.0"
|
GITLAB_HELM_CHART_REF: "41d7632d9eba84f5816d808b98ccf3f5623e9fb5"
|
||||||
environment:
|
environment:
|
||||||
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
|
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
|
||||||
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}
|
||||||
|
|
|
@ -1450,18 +1450,6 @@
|
||||||
when: never
|
when: never
|
||||||
- changes: *dependency-patterns
|
- changes: *dependency-patterns
|
||||||
|
|
||||||
.reports:rules:bundler-audit-dependency_scanning:
|
|
||||||
rules:
|
|
||||||
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /bundler-audit/ || $DS_DEFAULT_ANALYZERS !~ /bundler-audit/'
|
|
||||||
when: never
|
|
||||||
- changes: *bundler-patterns
|
|
||||||
|
|
||||||
.reports:rules:retire-js-dependency_scanning:
|
|
||||||
rules:
|
|
||||||
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /retire.js/ || $DS_DEFAULT_ANALYZERS !~ /retire.js/'
|
|
||||||
when: never
|
|
||||||
- changes: *nodejs-patterns
|
|
||||||
|
|
||||||
.reports:rules:gemnasium-python-dependency_scanning:
|
.reports:rules:gemnasium-python-dependency_scanning:
|
||||||
rules:
|
rules:
|
||||||
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /gemnasium-python/ || $DS_DEFAULT_ANALYZERS !~ /gemnasium-python/'
|
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /gemnasium-python/ || $DS_DEFAULT_ANALYZERS !~ /gemnasium-python/'
|
||||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -2,6 +2,18 @@
|
||||||
documentation](doc/development/changelog.md) for instructions on adding your own
|
documentation](doc/development/changelog.md) for instructions on adding your own
|
||||||
entry.
|
entry.
|
||||||
|
|
||||||
|
## 14.9.5 (2022-06-01)
|
||||||
|
|
||||||
|
### Security (7 changes)
|
||||||
|
|
||||||
|
- [Fix IP restrictions not applying to deploy tokens](gitlab-org/security/gitlab@b429997e253110ea5eb4d20a8b90e9879be97300) ([merge request](gitlab-org/security/gitlab!2472))
|
||||||
|
- [Trigger token should respect group IP restrictions](gitlab-org/security/gitlab@326993794bba8659208cde212433a5a19fd3e5a9) ([merge request](gitlab-org/security/gitlab!2477))
|
||||||
|
- [Fix content injection in Jira issue title](gitlab-org/security/gitlab@c968f7be35d829bfefbf089794343d2d20cdd078) ([merge request](gitlab-org/security/gitlab!2465))
|
||||||
|
- [Subgroup member can list members of parent group](gitlab-org/security/gitlab@1606689819eeae574bd5d65c8c971c2d4eb19e41) ([merge request](gitlab-org/security/gitlab!2481))
|
||||||
|
- [Do not allow project member import when membership is locked](gitlab-org/security/gitlab@e8324068c61c4c58d50646d4fa8dff77c4d147ae) ([merge request](gitlab-org/security/gitlab!2448))
|
||||||
|
- [Disable changing user attributes when updating SCIM provisioned user](gitlab-org/security/gitlab@9d5aca002edb2e0ab3c7d5b6eb00ea781d3dde9f) ([merge request](gitlab-org/security/gitlab!2455))
|
||||||
|
- [Allow only job owner to run interactive terminal](gitlab-org/security/gitlab@c9fe31e3a963c421db3d9c47c65dd98a2867a699) ([merge request](gitlab-org/security/gitlab!2434))
|
||||||
|
|
||||||
## 14.9.4 (2022-04-29)
|
## 14.9.4 (2022-04-29)
|
||||||
|
|
||||||
### Security (15 changes)
|
### Security (15 changes)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
14.9.4
|
14.9.5
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
14.9.4
|
14.9.5
|
|
@ -67,6 +67,12 @@ class Groups::ApplicationController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authorize_read_group_member!
|
||||||
|
unless can?(current_user, :read_group_member, group)
|
||||||
|
render_403
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def build_canonical_path(group)
|
def build_canonical_path(group)
|
||||||
params[:group_id] = group.to_param
|
params[:group_id] = group.to_param
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
|
||||||
|
|
||||||
# Authorize
|
# Authorize
|
||||||
before_action :authorize_admin_group_member!, except: admin_not_required_endpoints
|
before_action :authorize_admin_group_member!, except: admin_not_required_endpoints
|
||||||
|
before_action :authorize_read_group_member!, only: :index
|
||||||
|
|
||||||
skip_before_action :check_two_factor_requirement, only: :leave
|
skip_before_action :check_two_factor_requirement, only: :leave
|
||||||
skip_cross_project_access_check :index, :update, :destroy, :request_access,
|
skip_cross_project_access_check :index, :update, :destroy, :request_access,
|
||||||
|
|
|
@ -84,7 +84,7 @@ module Ci
|
||||||
enable :update_commit_status
|
enable :update_commit_status
|
||||||
end
|
end
|
||||||
|
|
||||||
rule { can?(:update_build) & terminal }.enable :create_build_terminal
|
rule { can?(:update_build) & terminal & owner_of_job }.enable :create_build_terminal
|
||||||
|
|
||||||
rule { can?(:update_build) }.enable :play_job
|
rule { can?(:update_build) }.enable :play_job
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
|
||||||
condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? }
|
condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? }
|
||||||
condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? }
|
condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? }
|
||||||
condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) }
|
condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) }
|
||||||
|
condition(:can_read_group_member) { can_read_group_member? }
|
||||||
|
|
||||||
desc "User is a project bot"
|
desc "User is a project bot"
|
||||||
condition(:project_bot) { user.project_bot? && access_level >= GroupMember::GUEST }
|
condition(:project_bot) { user.project_bot? && access_level >= GroupMember::GUEST }
|
||||||
|
@ -127,6 +128,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
|
||||||
|
|
||||||
rule { ~public_group & ~has_access }.prevent :read_counts
|
rule { ~public_group & ~has_access }.prevent :read_counts
|
||||||
|
|
||||||
|
rule { ~can_read_group_member }.policy do
|
||||||
|
prevent :read_group_member
|
||||||
|
end
|
||||||
|
|
||||||
rule { ~can?(:read_group) }.policy do
|
rule { ~can?(:read_group) }.policy do
|
||||||
prevent :read_design_activity
|
prevent :read_design_activity
|
||||||
end
|
end
|
||||||
|
@ -308,6 +313,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_read_group_member?
|
||||||
|
!(@subject.private? && access_level == GroupMember::NO_ACCESS)
|
||||||
|
end
|
||||||
|
|
||||||
def resource_access_token_creation_allowed?
|
def resource_access_token_creation_allowed?
|
||||||
resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
|
resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
|
||||||
end
|
end
|
||||||
|
|
|
@ -744,6 +744,10 @@ class ProjectPolicy < BasePolicy
|
||||||
prevent :register_project_runners
|
prevent :register_project_runners
|
||||||
end
|
end
|
||||||
|
|
||||||
|
rule { can?(:admin_project_member) }.policy do
|
||||||
|
enable :import_project_members_from_another_project
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def user_is_user?
|
def user_is_user?
|
||||||
|
|
|
@ -26,6 +26,7 @@ module Ci
|
||||||
def create_pipeline_from_trigger(trigger)
|
def create_pipeline_from_trigger(trigger)
|
||||||
# this check is to not leak the presence of the project if user cannot read it
|
# this check is to not leak the presence of the project if user cannot read it
|
||||||
return unless trigger.project == project
|
return unless trigger.project == project
|
||||||
|
return unless can?(trigger.owner, :read_project, project)
|
||||||
|
|
||||||
response = Ci::CreatePipelineService
|
response = Ci::CreatePipelineService
|
||||||
.new(project, trigger.owner, ref: params[:ref], variables_attributes: variables)
|
.new(project, trigger.owner, ref: params[:ref], variables_attributes: variables)
|
||||||
|
|
|
@ -29,7 +29,7 @@ module Members
|
||||||
def import_project_team
|
def import_project_team
|
||||||
return false unless target_project.present? && source_project.present? && current_user.present?
|
return false unless target_project.present? && source_project.present? && current_user.present?
|
||||||
return false unless can?(current_user, :read_project_member, source_project)
|
return false unless can?(current_user, :read_project_member, source_project)
|
||||||
return false unless can?(current_user, :admin_project_member, target_project)
|
return false unless can?(current_user, :import_project_members_from_another_project, target_project)
|
||||||
|
|
||||||
target_project.team.import(source_project, current_user)
|
target_project.team.import(source_project, current_user)
|
||||||
end
|
end
|
||||||
|
|
|
@ -170,13 +170,13 @@ Returns a `201` status code if successful.
|
||||||
|
|
||||||
Fields that can be updated are:
|
Fields that can be updated are:
|
||||||
|
|
||||||
| SCIM/IdP field | GitLab field |
|
| SCIM/IdP field | GitLab field |
|
||||||
|:---------------------------------|:---------------------------------------|
|
|:---------------------------------|:-----------------------------------------------------------------------------|
|
||||||
| `id/externalId` | `extern_uid` |
|
| `id/externalId` | `extern_uid` |
|
||||||
| `name.formatted` | `name` |
|
| `name.formatted` | `name` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
|
||||||
| `emails\[type eq "work"\].value` | `email` |
|
| `emails\[type eq "work"\].value` | `email` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
|
||||||
| `active` | Identity removal if `active` = `false` |
|
| `active` | Identity removal if `active` = `false` |
|
||||||
| `userName` | `username` |
|
| `userName` | `username` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
|
||||||
|
|
||||||
```plaintext
|
```plaintext
|
||||||
PATCH /api/scim/v2/groups/:group_path/Users/:id
|
PATCH /api/scim/v2/groups/:group_path/Users/:id
|
||||||
|
|
|
@ -86,6 +86,9 @@ For more information, view the [permissions table](../../permissions.md#group-me
|
||||||
|
|
||||||
## Subgroup membership
|
## Subgroup membership
|
||||||
|
|
||||||
|
NOTE:
|
||||||
|
There is a bug that causes some pages in the parent group to be accessible by subgroup members. For more details, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340421).
|
||||||
|
|
||||||
When you add a member to a group, that member is also added to all subgroups. The user's permissions are inherited from
|
When you add a member to a group, that member is also added to all subgroups. The user's permissions are inherited from
|
||||||
the group's parent.
|
the group's parent.
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,10 @@ module API
|
||||||
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
|
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def authorize_read_source_member!(source_type, source)
|
||||||
|
authorize! :"read_#{source_type}_member", source
|
||||||
|
end
|
||||||
|
|
||||||
def authorize_admin_source!(source_type, source)
|
def authorize_admin_source!(source_type, source)
|
||||||
authorize! :"admin_#{source_type}", source
|
authorize! :"admin_#{source_type}", source
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,6 +29,8 @@ module API
|
||||||
get ":id/members" do
|
get ":id/members" do
|
||||||
source = find_source(source_type, params[:id])
|
source = find_source(source_type, params[:id])
|
||||||
|
|
||||||
|
authorize_read_source_member!(source_type, source)
|
||||||
|
|
||||||
members = paginate(retrieve_members(source, params: params))
|
members = paginate(retrieve_members(source, params: params))
|
||||||
|
|
||||||
present_members members
|
present_members members
|
||||||
|
@ -48,6 +50,8 @@ module API
|
||||||
get ":id/members/all" do
|
get ":id/members/all" do
|
||||||
source = find_source(source_type, params[:id])
|
source = find_source(source_type, params[:id])
|
||||||
|
|
||||||
|
authorize_read_source_member!(source_type, source)
|
||||||
|
|
||||||
members = paginate(retrieve_members(source, params: params, deep: true))
|
members = paginate(retrieve_members(source, params: params, deep: true))
|
||||||
|
|
||||||
present_members members
|
present_members members
|
||||||
|
@ -63,6 +67,8 @@ module API
|
||||||
get ":id/members/:user_id" do
|
get ":id/members/:user_id" do
|
||||||
source = find_source(source_type, params[:id])
|
source = find_source(source_type, params[:id])
|
||||||
|
|
||||||
|
authorize_read_source_member!(source_type, source)
|
||||||
|
|
||||||
members = source_members(source)
|
members = source_members(source)
|
||||||
member = members.find_by!(user_id: params[:user_id])
|
member = members.find_by!(user_id: params[:user_id])
|
||||||
|
|
||||||
|
@ -80,6 +86,8 @@ module API
|
||||||
get ":id/members/all/:user_id" do
|
get ":id/members/all/:user_id" do
|
||||||
source = find_source(source_type, params[:id])
|
source = find_source(source_type, params[:id])
|
||||||
|
|
||||||
|
authorize_read_source_member!(source_type, source)
|
||||||
|
|
||||||
members = find_all_members(source)
|
members = find_all_members(source)
|
||||||
member = members.find_by!(user_id: params[:user_id])
|
member = members.find_by!(user_id: params[:user_id])
|
||||||
|
|
||||||
|
|
|
@ -183,7 +183,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with web terminal' do
|
context 'with web terminal' do
|
||||||
let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) }
|
let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
|
||||||
|
|
||||||
it 'exposes the terminal path' do
|
it 'exposes the terminal path' do
|
||||||
expect(response).to have_gitlab_http_status(:ok)
|
expect(response).to have_gitlab_http_status(:ok)
|
||||||
|
@ -1284,7 +1284,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
|
||||||
|
|
||||||
context 'when job exists' do
|
context 'when job exists' do
|
||||||
context 'and it has a terminal' do
|
context 'and it has a terminal' do
|
||||||
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) }
|
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
|
||||||
|
|
||||||
it 'has a job' do
|
it 'has a job' do
|
||||||
get_terminal(id: job.id)
|
get_terminal(id: job.id)
|
||||||
|
@ -1295,7 +1295,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'and does not have a terminal' do
|
context 'and does not have a terminal' do
|
||||||
let!(:job) { create(:ci_build, :running, pipeline: pipeline) }
|
let!(:job) { create(:ci_build, :running, pipeline: pipeline, user: user) }
|
||||||
|
|
||||||
it 'returns not_found' do
|
it 'returns not_found' do
|
||||||
get_terminal(id: job.id)
|
get_terminal(id: job.id)
|
||||||
|
@ -1324,7 +1324,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'GET #terminal_websocket_authorize' do
|
describe 'GET #terminal_websocket_authorize' do
|
||||||
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) }
|
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
|
|
|
@ -97,7 +97,7 @@ RSpec.describe 'Private Group access' do
|
||||||
it { is_expected.to be_allowed_for(:developer).of(group) }
|
it { is_expected.to be_allowed_for(:developer).of(group) }
|
||||||
it { is_expected.to be_allowed_for(:reporter).of(group) }
|
it { is_expected.to be_allowed_for(:reporter).of(group) }
|
||||||
it { is_expected.to be_allowed_for(:guest).of(group) }
|
it { is_expected.to be_allowed_for(:guest).of(group) }
|
||||||
it { is_expected.to be_allowed_for(project_guest) }
|
it { is_expected.to be_denied_for(project_guest) }
|
||||||
it { is_expected.to be_denied_for(:user) }
|
it { is_expected.to be_denied_for(:user) }
|
||||||
it { is_expected.to be_denied_for(:external) }
|
it { is_expected.to be_denied_for(:external) }
|
||||||
it { is_expected.to be_denied_for(:visitor) }
|
it { is_expected.to be_denied_for(:visitor) }
|
||||||
|
|
|
@ -405,4 +405,52 @@ RSpec.describe Ci::BuildPolicy do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'ability :create_build_terminal' do
|
||||||
|
let(:project) { create(:project, :private) }
|
||||||
|
|
||||||
|
subject { described_class.new(user, build) }
|
||||||
|
|
||||||
|
context 'when user can update_build' do
|
||||||
|
before do
|
||||||
|
project.add_maintainer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when job has terminal' do
|
||||||
|
before do
|
||||||
|
allow(build).to receive(:has_terminal?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when current user is the job owner' do
|
||||||
|
before do
|
||||||
|
build.update!(user: user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect_allowed(:create_build_terminal) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when current user is not the job owner' do
|
||||||
|
it { expect_disallowed(:create_build_terminal) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when job does not have terminal' do
|
||||||
|
before do
|
||||||
|
allow(build).to receive(:has_terminal?).and_return(false)
|
||||||
|
build.update!(user: user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect_disallowed(:create_build_terminal) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user cannot update build' do
|
||||||
|
before do
|
||||||
|
project.add_guest(user)
|
||||||
|
allow(build).to receive(:has_terminal?).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect_disallowed(:create_build_terminal) }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -346,6 +346,36 @@ RSpec.describe ProjectPolicy do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'importing members from another project' do
|
||||||
|
%w(maintainer owner).each do |role|
|
||||||
|
context "with #{role}" do
|
||||||
|
let(:current_user) { send(role) }
|
||||||
|
|
||||||
|
it { is_expected.to be_allowed(:import_project_members_from_another_project) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
%w(guest reporter developer anonymous).each do |role|
|
||||||
|
context "with #{role}" do
|
||||||
|
let(:current_user) { send(role) }
|
||||||
|
|
||||||
|
it { is_expected.to be_disallowed(:import_project_members_from_another_project) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with an admin' do
|
||||||
|
let(:current_user) { admin }
|
||||||
|
|
||||||
|
context 'when admin mode is enabled', :enable_admin_mode do
|
||||||
|
it { expect_allowed(:import_project_members_from_another_project) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when admin mode is disabled' do
|
||||||
|
it { expect_disallowed(:import_project_members_from_another_project) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it_behaves_like 'clusterable policies' do
|
it_behaves_like 'clusterable policies' do
|
||||||
let_it_be(:clusterable) { create(:project, :repository) }
|
let_it_be(:clusterable) { create(:project, :repository) }
|
||||||
let_it_be(:cluster) do
|
let_it_be(:cluster) do
|
||||||
|
|
|
@ -180,6 +180,21 @@ RSpec.describe API::Members do
|
||||||
expect(json_response).to be_an Array
|
expect(json_response).to be_an Array
|
||||||
expect(json_response.map { |u| u['id'] }).to match_array [maintainer.id, developer.id, nested_user.id]
|
expect(json_response.map { |u| u['id'] }).to match_array [maintainer.id, developer.id, nested_user.id]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a subgroup' do
|
||||||
|
let(:group) { create(:group, :private)}
|
||||||
|
let(:subgroup) { create(:group, :private, parent: group)}
|
||||||
|
let(:project) { create(:project, group: subgroup) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
subgroup.add_developer(developer)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'subgroup member cannot get parent group members list' do
|
||||||
|
get api("/groups/#{group.id}/members/all", developer)
|
||||||
|
expect(response).to have_gitlab_http_status(:forbidden)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'GET /:source_type/:id/members/(all/):user_id' do |source_type, all|
|
shared_examples 'GET /:source_type/:id/members/(all/):user_id' do |source_type, all|
|
||||||
|
|
|
@ -56,6 +56,15 @@ RSpec.describe Ci::PipelineTriggerService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when trigger owner does not have a permission to read a project' do
|
||||||
|
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
|
||||||
|
let(:trigger) { create(:ci_trigger, project: project, owner: create(:user)) }
|
||||||
|
|
||||||
|
it 'does nothing' do
|
||||||
|
expect { result }.not_to change { Ci::Pipeline.count }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when params have an existing trigger token' do
|
context 'when params have an existing trigger token' do
|
||||||
context 'when params have an existing ref' do
|
context 'when params have an existing ref' do
|
||||||
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
|
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
|
||||||
|
|
Loading…
Reference in a new issue