Commit 9ce103af authored by Fabio Pitino's avatar Fabio Pitino
Browse files

Cancel all running CI jobs when user is blocked

This prevents a MITM attack where attacker could
still access Git repository if any jobs were
running long enough.
parent 39381519
......@@ -265,6 +265,16 @@ def inactive_message
BLOCKED_MESSAGE
end
end
# rubocop: disable CodeReuse/ServiceClass
# Ideally we should not call a service object here but user.block
# is also bcalled by Users::MigrateToGhostUserService which references
# this state transition object in order to do a rollback.
# For this reason the tradeoff is to disable this cop.
after_transition any => :blocked do |user|
Ci::CancelUserPipelinesService.new.execute(user)
end
# rubocop: enable CodeReuse/ServiceClass
end
# Scopes
......
# frozen_string_literal: true
module Ci
class CancelUserPipelinesService
# rubocop: disable CodeReuse/ActiveRecord
# This is a bug with CodeReuse/ActiveRecord cop
# https://gitlab.com/gitlab-org/gitlab/issues/32332
def execute(user)
user.pipelines.cancelable.find_each(&:cancel_running)
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
---
title: Cancel all running CI jobs triggered by the user who is just blocked
merge_request:
author:
type: security
......@@ -1067,11 +1067,27 @@
describe 'blocking user' do
let(:user) { create(:user, name: 'John Smith') }
it "blocks user" do
it 'blocks user' do
user.block
expect(user.blocked?).to be_truthy
end
context 'when user has running CI pipelines' do
let(:service) { double }
before do
pipeline = create(:ci_pipeline, :running, user: user)
create(:ci_build, :running, pipeline: pipeline)
end
it 'cancels all running pipelines and related jobs' do
expect(Ci::CancelUserPipelinesService).to receive(:new).and_return(service)
expect(service).to receive(:execute).with(user)
user.block
end
end
end
describe '.filter_items' do
......
# frozen_string_literal: true
require 'spec_helper'
describe Ci::CancelUserPipelinesService do
describe '#execute' do
let(:user) { create(:user) }
subject { described_class.new.execute(user) }
context 'when user has running CI pipelines' do
let(:pipeline) { create(:ci_pipeline, :running, user: user) }
let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
it 'cancels all running pipelines and related jobs' do
subject
expect(pipeline.reload).to be_canceled
expect(build.reload).to be_canceled
end
end
end
end
Supports Markdown
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