Commit 631562eb authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'groups_api' into 'master'

API: Add missing group parameters

See merge request gitlab-org/gitlab!17220
parents 2ea5e00f b944c0dd
# frozen_string_literal: true
# Add methods used by the groups API
module GroupAPICompatibility
extend ActiveSupport::Concern
def project_creation_level_str
::Gitlab::Access.project_creation_string_options.key(project_creation_level)
end
def project_creation_level_str=(value)
write_attribute(:project_creation_level, ::Gitlab::Access.project_creation_string_options.fetch(value))
end
def subgroup_creation_level_str
::Gitlab::Access.subgroup_creation_string_options.key(subgroup_creation_level)
end
def subgroup_creation_level_str=(value)
write_attribute(:subgroup_creation_level, ::Gitlab::Access.subgroup_creation_string_options.fetch(value))
end
end
......@@ -14,6 +14,7 @@ class Group < Namespace
include TokenAuthenticatable
include WithUploads
include Gitlab::Utils::StrongMemoize
include GroupAPICompatibility
ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT = 10
......
---
title: 'API: Add missing group parameters'
merge_request: 17220
author: Mathieu Parent
type: added
......@@ -31,6 +31,13 @@ GET /groups
"path": "foo-bar",
"description": "An interesting group",
"visibility": "public",
"share_with_group_lock": false,
"require_two_factor_authentication": false,
"two_factor_grace_period": 48,
"project_creation_level": "developer",
"auto_devops_enabled": null,
"subgroup_creation_level": "owner",
"emails_disabled": null,
"lfs_enabled": true,
"avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg",
"web_url": "http://localhost:3000/groups/foo-bar",
......@@ -57,6 +64,13 @@ GET /groups?statistics=true
"path": "foo-bar",
"description": "An interesting group",
"visibility": "public",
"share_with_group_lock": false,
"require_two_factor_authentication": false,
"two_factor_grace_period": 48,
"project_creation_level": "developer",
"auto_devops_enabled": null,
"subgroup_creation_level": "owner",
"emails_disabled": null,
"lfs_enabled": true,
"avatar_url": "http://localhost:3000/uploads/group/avatar/1/foo.jpg",
"web_url": "http://localhost:3000/groups/foo-bar",
......@@ -119,6 +133,13 @@ GET /groups/:id/subgroups
"path": "foo-bar",
"description": "An interesting group",
"visibility": "public",
"share_with_group_lock": false,
"require_two_factor_authentication": false,
"two_factor_grace_period": 48,
"project_creation_level": "developer",
"auto_devops_enabled": null,
"subgroup_creation_level": "owner",
"emails_disabled": null,
"lfs_enabled": true,
"avatar_url": "http://gitlab.example.com/uploads/group/avatar/1/foo.jpg",
"web_url": "http://gitlab.example.com/groups/foo-bar",
......@@ -434,6 +455,13 @@ Parameters:
| `path` | string | yes | The path of the group. |
| `description` | string | no | The group's description. |
| `visibility` | string | no | The group's visibility. Can be `private`, `internal`, or `public`. |
| `share_with_group_lock` | boolean | no | Prevent sharing a project with another group within this group. |
| `require_two_factor_authentication` | boolean | no | Require all users in this group to setup Two-factor authentication. |
| `two_factor_grace_period` | integer | no | Time before Two-factor authentication is enforced (in hours). |
| `project_creation_level` | string | no | Determine if developers can create projects in the group. Can be `noone` (No one), `maintainer` (Maintainers), or `developer` (Developers + Maintainers). |
| `auto_devops_enabled` | boolean | no | Default to Auto DevOps pipeline for all projects within this group. |
| `subgroup_creation_level` | integer | no | Allowed to create subgroups. Can be `owner` (Owners), or `maintainer` (Maintainers). |
| `emails_disabled` | boolean | no | Disable email notifications |
| `lfs_enabled` | boolean | no | Enable/disable Large File Storage (LFS) for the projects in this group. |
| `request_access_enabled` | boolean | no | Allow users to request member access. |
| `parent_id` | integer | no | The parent group ID for creating nested group. |
......@@ -472,6 +500,13 @@ PUT /groups/:id
| `membership_lock` | boolean | no | **(STARTER)** Prevent adding new members to project membership within this group. |
| `share_with_group_lock` | boolean | no | Prevent sharing a project with another group within this group. |
| `visibility` | string | no | The visibility level of the group. Can be `private`, `internal`, or `public`. |
| `share_with_group_lock` | boolean | no | Prevent sharing a project with another group within this group. |
| `require_two_factor_authentication` | boolean | no | Require all users in this group to setup Two-factor authentication. |
| `two_factor_grace_period` | integer | no | Time before Two-factor authentication is enforced (in hours). |
| `project_creation_level` | string | no | Determine if developers can create projects in the group. Can be `noone` (No one), `maintainer` (Maintainers), or `developer` (Developers + Maintainers). |
| `auto_devops_enabled` | boolean | no | Default to Auto DevOps pipeline for all projects within this group. |
| `subgroup_creation_level` | integer | no | Allowed to create subgroups. Can be `owner` (Owners), or `maintainer` (Maintainers). |
| `emails_disabled` | boolean | no | Disable email notifications |
| `lfs_enabled` (optional) | boolean | no | Enable/disable Large File Storage (LFS) for the projects in this group. |
| `request_access_enabled` | boolean | no | Allow users to request member access. |
| `file_template_project_id` | integer | no | **(PREMIUM)** The ID of a project to load custom file templates from. |
......
......@@ -3,6 +3,8 @@
require 'spec_helper'
describe API::Groups do
include GroupAPIHelpers
set(:group) { create(:group) }
set(:private_group) { create(:group, :private) }
set(:project) { create(:project, group: group) }
......@@ -133,14 +135,14 @@ describe API::Groups do
describe "POST /groups" do
context "when authenticated as user with group permissions" do
it "creates an ldap_group_link if ldap_cn and ldap_access are supplied" do
group_attributes = attributes_for(:group, ldap_cn: 'ldap-group', ldap_access: Gitlab::Access::DEVELOPER)
group_attributes = attributes_for_group_api ldap_cn: 'ldap-group', ldap_access: Gitlab::Access::DEVELOPER
expect { post api("/groups", admin), params: group_attributes }.to change { LdapGroupLink.count }.by(1)
end
context 'when shared_runners_minutes_limit is given' do
context 'when the current user is not an admin' do
it "does not create a group with shared_runners_minutes_limit" do
group = attributes_for(:group, { shared_runners_minutes_limit: 133 })
group = attributes_for_group_api shared_runners_minutes_limit: 133
expect do
post api("/groups", another_user), params: group
......@@ -152,7 +154,7 @@ describe API::Groups do
context 'when the current user is an admin' do
it "creates a group with shared_runners_minutes_limit" do
group = attributes_for(:group, { shared_runners_minutes_limit: 133 })
group = attributes_for_group_api shared_runners_minutes_limit: 133
expect do
post api("/groups", admin), params: group
......
......@@ -378,6 +378,13 @@ module API
class Group < BasicGroupDetails
expose :path, :description, :visibility
expose :share_with_group_lock
expose :require_two_factor_authentication
expose :two_factor_grace_period
expose :project_creation_level_str, as: :project_creation_level
expose :auto_devops_enabled
expose :subgroup_creation_level_str, as: :subgroup_creation_level
expose :emails_disabled
expose :lfs_enabled?, as: :lfs_enabled
expose :avatar_url do |group, options|
group.avatar_url(only_path: false)
......
......@@ -11,9 +11,15 @@ module API
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
desc: 'The visibility of the group'
optional :share_with_group_lock, type: Boolean, desc: 'Prevent sharing a project with another group within this group'
optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users in this group to setup Two-factor authentication'
optional :two_factor_grace_period, type: Integer, desc: 'Time before Two-factor authentication is enforced'
optional :project_creation_level, type: String, values: ::Gitlab::Access.project_creation_string_values, desc: 'Determine if developers can create projects in the group', as: :project_creation_level_str
optional :auto_devops_enabled, type: Boolean, desc: 'Default to Auto DevOps pipeline for all projects within this group'
optional :subgroup_creation_level, type: String, values: ::Gitlab::Access.subgroup_creation_string_values, desc: 'Allowed to create subgroups', as: :subgroup_creation_level_str
optional :emails_disabled, type: Boolean, desc: 'Disable email notifications'
optional :lfs_enabled, type: Boolean, desc: 'Enable/disable LFS for the projects in this group'
optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
optional :share_with_group_lock, type: Boolean, desc: 'Prevent sharing a project with another group within this group'
end
params :optional_params_ee do
......
......@@ -103,10 +103,22 @@ module Gitlab
}
end
def project_creation_string_options
{
'noone' => NO_ONE_PROJECT_ACCESS,
'maintainer' => MAINTAINER_PROJECT_ACCESS,
'developer' => DEVELOPER_MAINTAINER_PROJECT_ACCESS
}
end
def project_creation_values
project_creation_options.values
end
def project_creation_string_values
project_creation_string_options.keys
end
def project_creation_level_name(name)
project_creation_options.key(name)
end
......@@ -117,6 +129,21 @@ module Gitlab
s_('SubgroupCreationlevel|Maintainers') => MAINTAINER_SUBGROUP_ACCESS
}
end
def subgroup_creation_string_options
{
'owner' => OWNER_SUBGROUP_ACCESS,
'maintainer' => MAINTAINER_SUBGROUP_ACCESS
}
end
def subgroup_creation_values
subgroup_creation_options.values
end
def subgroup_creation_string_values
subgroup_creation_string_options.keys
end
end
def human_access
......
require 'spec_helper'
describe API::Groups do
include GroupAPIHelpers
include UploadHelpers
let(:user1) { create(:user, can_create_group: false) }
......@@ -350,6 +351,13 @@ describe API::Groups do
expect(json_response['description']).to eq(group1.description)
expect(json_response['visibility']).to eq(Gitlab::VisibilityLevel.string_level(group1.visibility_level))
expect(json_response['avatar_url']).to eq(group1.avatar_url(only_path: false))
expect(json_response['share_with_group_lock']).to eq(group1.share_with_group_lock)
expect(json_response['require_two_factor_authentication']).to eq(group1.require_two_factor_authentication)
expect(json_response['two_factor_grace_period']).to eq(group1.two_factor_grace_period)
expect(json_response['auto_devops_enabled']).to eq(group1.auto_devops_enabled)
expect(json_response['emails_disabled']).to eq(group1.emails_disabled)
expect(json_response['project_creation_level']).to eq('maintainer')
expect(json_response['subgroup_creation_level']).to eq('maintainer')
expect(json_response['web_url']).to eq(group1.web_url)
expect(json_response['request_access_enabled']).to eq(group1.request_access_enabled)
expect(json_response['full_name']).to eq(group1.full_name)
......@@ -485,11 +493,30 @@ describe API::Groups do
context 'when authenticated as the group owner' do
it 'updates the group' do
put api("/groups/#{group1.id}", user1), params: { name: new_group_name, request_access_enabled: true }
put api("/groups/#{group1.id}", user1), params: {
name: new_group_name,
request_access_enabled: true,
project_creation_level: "noone",
subgroup_creation_level: "maintainer"
}
expect(response).to have_gitlab_http_status(200)
expect(json_response['name']).to eq(new_group_name)
expect(json_response['description']).to eq('')
expect(json_response['visibility']).to eq('public')
expect(json_response['share_with_group_lock']).to eq(false)
expect(json_response['require_two_factor_authentication']).to eq(false)
expect(json_response['two_factor_grace_period']).to eq(48)
expect(json_response['auto_devops_enabled']).to eq(nil)
expect(json_response['emails_disabled']).to eq(nil)
expect(json_response['project_creation_level']).to eq("noone")
expect(json_response['subgroup_creation_level']).to eq("maintainer")
expect(json_response['request_access_enabled']).to eq(true)
expect(json_response['parent_id']).to eq(nil)
expect(json_response['projects']).to be_an Array
expect(json_response['projects'].length).to eq(2)
expect(json_response['shared_projects']).to be_an Array
expect(json_response['shared_projects'].length).to eq(0)
end
it 'returns 404 for a non existing group' do
......@@ -864,7 +891,9 @@ describe API::Groups do
describe "POST /groups" do
context "when authenticated as user without group permissions" do
it "does not create group" do
post api("/groups", user1), params: attributes_for(:group)
group = attributes_for_group_api
post api("/groups", user1), params: group
expect(response).to have_gitlab_http_status(403)
end
......@@ -896,7 +925,7 @@ describe API::Groups do
context "when authenticated as user with group permissions" do
it "creates group" do
group = attributes_for(:group, { request_access_enabled: false })
group = attributes_for_group_api request_access_enabled: false
post api("/groups", user3), params: group
......@@ -911,7 +940,7 @@ describe API::Groups do
it "creates a nested group" do
parent = create(:group)
parent.add_owner(user3)
group = attributes_for(:group, { parent_id: parent.id })
group = attributes_for_group_api parent_id: parent.id
post api("/groups", user3), params: group
......
# frozen_string_literal: true
module GroupAPIHelpers
extend self
def attributes_for_group_api(params = {})
# project_creation_level and subgroup_creation_level are Integers in the model
# but are strings in the API
attributes_for(:group, params).except(:project_creation_level, :subgroup_creation_level)
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