Commit 20093f9d authored by Agustin Henze's avatar Agustin Henze Committed by Kamil Trzciński

Add new permission model `read-pipeline-variable`

Used to get the variables via the API endpoint
`/projects/:id/pipelines/:pipeline_id/variables`
Signed-off-by: default avatarAgustin Henze <tin@redhat.com>
parent 67c33084
......@@ -750,6 +750,10 @@ module Ci
self.sha == sha || self.source_sha == sha
end
def triggered_by?(current_user)
user == current_user
end
private
def ci_yaml_from_repo
......
......@@ -14,6 +14,10 @@ module Ci
@subject.external?
end
condition(:triggerer_of_pipeline) do
@subject.triggered_by?(@user)
end
# Disallow users without permissions from accessing internal pipelines
rule { ~can?(:read_build) & ~external_pipeline }.policy do
prevent :read_pipeline
......@@ -29,6 +33,14 @@ module Ci
enable :destroy_pipeline
end
rule { can?(:admin_pipeline) }.policy do
enable :read_pipeline_variable
end
rule { can?(:update_pipeline) & triggerer_of_pipeline }.policy do
enable :read_pipeline_variable
end
def ref_protected?(user, project, tag, ref)
access = ::Gitlab::UserAccess.new(user, project: project)
......
---
title: Expose pipeline variables via API
merge_request: 26501
author: Agustin Henze <tin@redhat.com>
type: added
......@@ -93,6 +93,36 @@ Example of response
}
```
### Get variables of a pipeline
```
GET /projects/:id/pipelines/:pipeline_id/variables
```
| Attribute | Type | Required | Description |
|------------|---------|----------|---------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `pipeline_id` | integer | yes | The ID of a pipeline |
```
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/pipelines/46/variables"
```
Example of response
```json
[
{
"key": "RUN_NIGHTLY_BUILD",
"value": "true"
},
{
"key": "foo",
"value": "bar"
}
]
```
## Create a new pipeline
> [Introduced][ce-7209] in GitLab 8.14
......
......@@ -81,6 +81,19 @@ module API
present pipeline, with: Entities::Pipeline
end
desc 'Gets the variables for a given pipeline' do
detail 'This feature was introduced in GitLab 11.11'
success Entities::Variable
end
params do
requires :pipeline_id, type: Integer, desc: 'The pipeline ID'
end
get ':id/pipelines/:pipeline_id/variables' do
authorize! :read_pipeline_variable, pipeline
present pipeline.variables, with: Entities::Variable
end
desc 'Deletes a pipeline' do
detail 'This feature was introduced in GitLab 11.6'
http_codes [[204, 'Pipeline was deleted'], [403, 'Forbidden']]
......
......@@ -100,5 +100,51 @@ describe Ci::PipelinePolicy, :models do
end
end
end
describe 'read_pipeline_variable' do
let(:project) { create(:project, :public) }
context 'when user has owner access' do
let(:user) { project.owner }
it 'is enabled' do
expect(policy).to be_allowed :read_pipeline_variable
end
end
context 'when user is developer and the creator of the pipeline' do
let(:pipeline) { create(:ci_empty_pipeline, project: project, user: user) }
before do
project.add_developer(user)
create(:protected_branch, :developers_can_merge,
name: pipeline.ref, project: project)
end
it 'is enabled' do
expect(policy).to be_allowed :read_pipeline_variable
end
end
context 'when user is developer and it is not the creator of the pipeline' do
let(:pipeline) { create(:ci_empty_pipeline, project: project, user: project.owner) }
before do
project.add_developer(user)
create(:protected_branch, :developers_can_merge,
name: pipeline.ref, project: project)
end
it 'is disabled' do
expect(policy).to be_disallowed :read_pipeline_variable
end
end
context 'when user is not owner nor developer' do
it 'is disabled' do
expect(policy).not_to be_allowed :read_pipeline_variable
end
end
end
end
end
......@@ -445,6 +445,72 @@ describe API::Pipelines do
end
end
describe 'GET /projects/:id/pipelines/:pipeline_id/variables' do
subject { get api("/projects/#{project.id}/pipelines/#{pipeline.id}/variables", api_user) }
let(:api_user) { user }
context 'user is a mantainer' do
it 'returns pipeline variables empty' do
subject
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_empty
end
context 'with variables' do
let!(:variable) { create(:ci_pipeline_variable, pipeline: pipeline, key: 'foo', value: 'bar') }
it 'returns pipeline variables' do
subject
expect(response).to have_gitlab_http_status(200)
expect(json_response).to contain_exactly({ "key" => "foo", "value" => "bar" })
end
end
end
context 'user is a developer' do
let(:pipeline_owner_user) { create(:user) }
let(:pipeline) { create(:ci_empty_pipeline, project: project, user: pipeline_owner_user) }
before do
project.add_developer(api_user)
end
context 'pipeline created by the developer user' do
let(:api_user) { pipeline_owner_user }
let!(:variable) { create(:ci_pipeline_variable, pipeline: pipeline, key: 'foo', value: 'bar') }
it 'returns pipeline variables' do
subject
expect(response).to have_gitlab_http_status(200)
expect(json_response).to contain_exactly({ "key" => "foo", "value" => "bar" })
end
end
context 'pipeline created is not created by the developer user' do
let(:api_user) { create(:user) }
it 'should not return pipeline variables' do
subject
expect(response).to have_gitlab_http_status(403)
end
end
end
context 'user is not a project member' do
it 'should not return pipeline variables' do
get api("/projects/#{project.id}/pipelines/#{pipeline.id}/variables", non_member)
expect(response).to have_gitlab_http_status(404)
expect(json_response['message']).to eq '404 Project Not Found'
end
end
end
describe 'DELETE /projects/:id/pipelines/:pipeline_id' do
context 'authorized user' do
let(:owner) { project.owner }
......
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