Commit 41064baf authored by Aishwarya Subramanian's avatar Aishwarya Subramanian

API to retrieve group push rules

Adds api to list the push rules
for groups. Available to group owners
and admins.

Updated changelog text
parent dd7ca3cf
......@@ -1164,3 +1164,46 @@ DELETE /groups/:id/share/:group_id
| --------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `group_id` | integer | yes | The ID of the group to share with |
## Push Rules **(STARTER)**
### Get group push rules
Get the [push rules](../user/group/index.md#group-push-rules-starter) of a group.
```plaintext
GET /groups/:id/push_rule
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID of the group or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
```json
{
"id": 2,
"created_at": "2020-08-17T19:09:19.580Z",
"commit_message_regex": "[a-zA-Z]",
"commit_message_negative_regex": "[x+]",
"branch_name_regex": "[a-z]",
"deny_delete_tag": true,
"member_check": true,
"prevent_secrets": true,
"author_email_regex": "^[A-Za-z0-9.]+@gitlab.com$",
"file_name_regex": "(exe)$",
"max_file_size": 100
}
```
Users on GitLab [Premium, Silver, or higher](https://about.gitlab.com/pricing/) will also see
the `commit_committer_check` and `reject_unsigned_commits` parameters:
```json
{
"id": 2,
"created_at": "2020-08-17T19:09:19.580Z",
"commit_committer_check": true,
"reject_unsigned_commits": false,
...
}
```
......@@ -2124,7 +2124,7 @@ POST /projects/:id/housekeeping
### Get project push rules
Get the push rules of a project.
Get the [push rules](../push_rules/push_rules.md#enabling-push-rules) of a project.
```plaintext
GET /projects/:id/push_rule
......
---
title: API to retrieve group push rules
merge_request: 39642
author:
type: added
# frozen_string_literal: true
module API
class GroupPushRule < Grape::API::Instance
before { authenticate! }
before { authorize_admin_group }
before { check_feature_availability! }
params do
requires :id, type: String, desc: 'The ID of a group'
end
resource :groups do
helpers do
def check_feature_availability!
not_found! unless user_group.feature_available?(:push_rules)
end
end
desc 'Get group push rule' do
detail 'This feature was introduced in GitLab 13.4.'
success EE::API::Entities::GroupPushRule
end
get ":id/push_rule" do
push_rule = user_group.push_rule
not_found! unless push_rule
present push_rule, with: EE::API::Entities::GroupPushRule, user: current_user
end
end
end
end
......@@ -33,6 +33,7 @@ module EE
mount ::API::PersonalAccessTokens
mount ::API::ProjectMirror
mount ::API::ProjectPushRule
mount ::API::GroupPushRule
mount ::API::MergeTrains
mount ::API::GroupHooks
mount ::API::Scim
......
# frozen_string_literal: true
module EE
module API
module Entities
class GroupPushRule < Grape::Entity
expose :id, :created_at
expose :commit_message_regex, :commit_message_negative_regex, :branch_name_regex, :deny_delete_tag
expose :member_check, :prevent_secrets, :author_email_regex
expose :file_name_regex, :max_file_size
expose :commit_committer_check, if: lambda { |push_rule| push_rule.available?(:commit_committer_check) }
expose :reject_unsigned_commits, if: lambda { |push_rule| push_rule.available?(:reject_unsigned_commits) }
end
end
end
end
{
"type": "object",
"properties" : {
"author_email_regex": { "type": ["string", null] },
"branch_name_regex": { "type": ["string", null] },
"commit_committer_check": { "type": "boolean" },
"commit_message_negative_regex": { "type": ["string", null] },
"commit_message_regex": { "type": ["string", null] },
"created_at": { "type": "date" },
"deny_delete_tag": { "type": ["boolean", null] },
"file_name_regex": { "type": ["string", null] },
"id": { "type": "integer" },
"max_file_size": { "type": "integer" },
"member_check": { "type": "boolean" },
"prevent_secrets": { "type": "boolean" },
"reject_unsigned_commits": { "type": "boolean" }
},
"required": [
"author_email_regex",
"branch_name_regex",
"commit_message_negative_regex",
"commit_message_regex",
"created_at",
"deny_delete_tag",
"file_name_regex",
"id",
"max_file_size",
"member_check",
"prevent_secrets"
],
"additionalProperties": false
}
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe API::GroupPushRule, 'GroupPushRule', api: true do
include ApiHelpers
include AccessMatchersForRequest
let_it_be(:admin) { create(:user, :admin) }
let_it_be(:user) { create(:user) }
shared_examples 'not found when feature is unavailable' do
before do
stub_licensed_features(push_rules: false)
end
it do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
shared_examples 'allow access to api based on role' do
it { expect { subject }.to be_allowed_for(:admin) }
it { expect { subject }.to be_allowed_for(:owner).of(group) }
it { expect { subject }.to be_denied_for(:developer).of(group) }
it { expect { subject }.to be_denied_for(:reporter).of(group) }
it { expect { subject }.to be_denied_for(:guest).of(group) }
it { expect { subject }.to be_denied_for(:anonymous) }
end
describe 'GET /groups/:id/push_rule' do
let_it_be(:group) { create(:group) }
let_it_be(:attributes) do
{
author_email_regex: '^[A-Za-z0-9.]+@gitlab.com$',
commit_committer_check: true,
commit_message_negative_regex: '[x+]',
commit_message_regex: '[a-zA-Z]',
deny_delete_tag: false,
max_file_size: 100,
member_check: false,
prevent_secrets: true,
reject_unsigned_commits: true
}
end
before_all do
push_rule = create(:push_rule, **attributes)
group.update!(push_rule: push_rule)
end
context 'when unlicensed' do
subject { get api("/groups/#{group.id}/push_rule", admin) }
it_behaves_like 'not found when feature is unavailable'
end
context 'authorized user' do
subject { get api("/groups/#{group.id}/push_rule", admin) }
context 'when licensed' do
before do
stub_licensed_features(push_rules: true,
commit_committer_check: true,
reject_unsigned_commits: true)
end
it 'returns attributes as expected' do
subject
expect(json_response).to eq(
{
"author_email_regex" => attributes[:author_email_regex],
"branch_name_regex" => nil,
"commit_committer_check" => true,
"commit_message_negative_regex" => attributes[:commit_message_negative_regex],
"commit_message_regex" => attributes[:commit_message_regex],
"created_at" => group.push_rule.created_at.iso8601(3),
"deny_delete_tag" => false,
"file_name_regex" => nil,
"id" => group.push_rule.id,
"max_file_size" => 100,
"member_check" => false,
"prevent_secrets" => true,
"reject_unsigned_commits" => true
}
)
end
it 'matches response schema' do
subject
expect(response).to match_response_schema('entities/group_push_rules')
end
end
context 'when reject_unsigned_commits is unavailable' do
before do
stub_licensed_features(reject_unsigned_commits: false)
end
it do
subject
expect(json_response).not_to have_key('reject_unsigned_commits')
end
end
context 'when commit_committer_check is unavailable' do
before do
stub_licensed_features(commit_committer_check: false)
end
it do
subject
expect(json_response).not_to have_key('commit_committer_check')
end
end
end
context 'permissions' do
subject(:get_push_rules) { get api("/groups/#{group.id}/push_rule", user) }
it_behaves_like 'allow access to api based on role'
end
context 'when push rule does not exist' do
let_it_be(:no_push_rule_group) { create(:group) }
it 'returns not found' do
get api("/groups/#{no_push_rule_group.id}/push_rule", admin)
expect(response).to have_gitlab_http_status(:not_found)
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