summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis Reigel <mail@koffeinfrei.org>2017-09-07 15:49:29 +0200
committerAlexis Reigel <alexis.reigel.ext@siemens.com>2018-02-28 09:49:52 +0100
commit3dc0791ec212494e31f1fe66d2430240cee1ca99 (patch)
tree7d9dfb049821650d6b58e61232c33b9cb9d9230e
parent144f74d44d27097b56ecf059cefc45d19cb6745d (diff)
downloadgitlab-ce-3dc0791ec212494e31f1fe66d2430240cee1ca99.tar.gz
authorize group runners on user
-rw-r--r--app/models/group.rb2
-rw-r--r--app/models/user.rb16
-rw-r--r--spec/models/user_spec.rb64
3 files changed, 68 insertions, 14 deletions
diff --git a/app/models/group.rb b/app/models/group.rb
index 08f6bd012ed..c4e68fbadcf 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -29,6 +29,8 @@ class Group < Namespace
has_many :labels, class_name: 'GroupLabel'
has_many :variables, class_name: 'Ci::GroupVariable'
has_many :custom_attributes, class_name: 'GroupCustomAttribute'
+ has_many :runner_groups, class_name: 'Ci::RunnerGroup'
+ has_many :runners, through: :runner_groups, source: :runner, class_name: 'Ci::Runner'
has_many :uploads, as: :model, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
diff --git a/app/models/user.rb b/app/models/user.rb
index 982080763d2..1c34a229a95 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -988,10 +988,17 @@ class User < ActiveRecord::Base
def ci_authorized_runners
@ci_authorized_runners ||= begin
- runner_ids = Ci::RunnerProject
+ project_runner_ids = Ci::RunnerProject
.where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
.select(:runner_id)
- Ci::Runner.specific.where(id: runner_ids)
+
+ group_runner_ids = Ci::RunnerGroup
+ .where(group_id: owned_or_masters_groups.select(:id))
+ .select(:runner_id)
+
+ union = Gitlab::SQL::Union.new([project_runner_ids, group_runner_ids])
+
+ Ci::Runner.specific.where("ci_runners.id IN (#{union.to_sql})")
end
end
@@ -1164,6 +1171,11 @@ class User < ActiveRecord::Base
max_member_access_for_group_ids([group_id])[group_id]
end
+ def owned_or_masters_groups
+ union = Gitlab::SQL::Union.new([owned_groups, masters_groups])
+ Group.from("(#{union.to_sql}) namespaces")
+ end
+
protected
# override, from Devise::Validatable
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 3531de244bd..b2d793e9d63 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1777,14 +1777,12 @@ describe User do
describe '#ci_authorized_runners' do
let(:user) { create(:user) }
- let(:runner) { create(:ci_runner) }
+ let(:runner_1) { create(:ci_runner) }
+ let(:runner_2) { create(:ci_runner) }
- before do
- project.runners << runner
- end
-
- context 'without any projects' do
- let(:project) { create(:project) }
+ context 'without any projects nor groups' do
+ let!(:project) { create(:project, runners: [runner_1]) }
+ let!(:group) { create(:group) }
it 'does not load' do
expect(user.ci_authorized_runners).to be_empty
@@ -1793,10 +1791,38 @@ describe User do
context 'with personal projects runners' do
let(:namespace) { create(:namespace, owner: user) }
- let(:project) { create(:project, namespace: namespace) }
+ let!(:project) { create(:project, namespace: namespace, runners: [runner_1]) }
it 'loads' do
- expect(user.ci_authorized_runners).to contain_exactly(runner)
+ expect(user.ci_authorized_runners).to contain_exactly(runner_1)
+ end
+ end
+
+ context 'with personal group runner' do
+ let!(:project) { create(:project, runners: [runner_1]) }
+ let!(:group) do
+ create(:group, runners: [runner_2]).tap do |group|
+ group.add_owner(user)
+ end
+ end
+
+ it 'loads' do
+ expect(user.ci_authorized_runners).to contain_exactly(runner_2)
+ end
+ end
+
+ context 'with personal project and group runner' do
+ let(:namespace) { create(:namespace, owner: user) }
+ let!(:project) { create(:project, namespace: namespace, runners: [runner_1]) }
+
+ let!(:group) do
+ create(:group, runners: [runner_2]).tap do |group|
+ group.add_owner(user)
+ end
+ end
+
+ it 'loads' do
+ expect(user.ci_authorized_runners).to contain_exactly(runner_1, runner_2)
end
end
@@ -1807,7 +1833,7 @@ describe User do
end
it 'loads' do
- expect(user.ci_authorized_runners).to contain_exactly(runner)
+ expect(user.ci_authorized_runners).to contain_exactly(runner_1)
end
end
@@ -1824,7 +1850,21 @@ describe User do
context 'with groups projects runners' do
let(:group) { create(:group) }
- let(:project) { create(:project, group: group) }
+ let!(:project) { create(:project, group: group, runners: [runner_1]) }
+
+ def add_user(access)
+ group.add_user(user, access)
+ end
+
+ it_behaves_like :member
+ end
+
+ context 'with groups runners' do
+ let!(:group) do
+ create(:group, runners: [runner_1]).tap do |group|
+ group.add_owner(user)
+ end
+ end
def add_user(access)
group.add_user(user, access)
@@ -1834,7 +1874,7 @@ describe User do
end
context 'with other projects runners' do
- let(:project) { create(:project) }
+ let!(:project) { create(:project, runners: [runner_1]) }
def add_user(access)
project.add_role(user, access)