Commit 0d72e121 authored by Rémy Coutable's avatar Rémy Coutable Committed by Ruben Davila

Merge branch 'issue_20978' into 'master'

Allow to set request_access_enabled for groups and projects using API

Closes #20978

See merge request !6359
parent 6fad5c49
......@@ -5,6 +5,7 @@ v 8.12.0 (unreleased)
- Only check :can_resolve permission if the note is resolvable
- Bump fog-aws to v0.11.0 to support ap-south-1 region
- Add ability to fork to a specific namespace using API. (ritave)
- Allow to set request_access_enabled for groups and projects
- Cleanup misalignments in Issue list view !6206
- Only create a protected branch upon a push to a new branch if a rule for that branch doesn't exist
- Prune events older than 12 months. (ritave)
......
......@@ -84,7 +84,8 @@ Parameters:
"forks_count": 0,
"open_issues_count": 3,
"public_builds": true,
"shared_with_groups": []
"shared_with_groups": [],
"request_access_enabled": false
}
]
```
......@@ -118,6 +119,7 @@ Example response:
"visibility_level": 20,
"avatar_url": null,
"web_url": "https://gitlab.example.com/groups/twitter",
"request_access_enabled": false,
"projects": [
{
"id": 7,
......@@ -163,7 +165,8 @@ Example response:
"forks_count": 0,
"open_issues_count": 3,
"public_builds": true,
"shared_with_groups": []
"shared_with_groups": [],
"request_access_enabled": false
},
{
"id": 6,
......@@ -209,7 +212,8 @@ Example response:
"forks_count": 0,
"open_issues_count": 8,
"public_builds": true,
"shared_with_groups": []
"shared_with_groups": [],
"request_access_enabled": false
}
],
"shared_projects": [
......@@ -289,6 +293,7 @@ Parameters:
- `description` (optional) - The group's description
- `visibility_level` (optional) - The group's visibility. 0 for private, 10 for internal, 20 for public.
- `lfs_enabled` (optional) - Enable/disable Large File Storage (LFS) for the projects in this group
- `request_access_enabled` (optional) - Allow users to request member access.
## Transfer project to group
......@@ -319,6 +324,7 @@ PUT /groups/:id
| `description` | string | no | The description of the group |
| `visibility_level` | integer | no | The visibility level of the group. 0 for private, 10 for internal, 20 for public. |
| `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. |
```bash
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/groups/5?name=Experimental"
......@@ -336,6 +342,7 @@ Example response:
"visibility_level": 10,
"avatar_url": null,
"web_url": "http://gitlab.example.com/groups/h5bp",
"request_access_enabled": false,
"projects": [
{
"id": 9,
......@@ -380,7 +387,8 @@ Example response:
"forks_count": 0,
"open_issues_count": 3,
"public_builds": true,
"shared_with_groups": []
"shared_with_groups": [],
"request_access_enabled": false
}
]
}
......
......@@ -85,7 +85,8 @@ Parameters:
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
},
{
"id": 6,
......@@ -146,7 +147,8 @@ Parameters:
"runners_token": "b8547b1dc37721d05889db52fa2f02",
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
]
```
......@@ -283,7 +285,8 @@ Parameters:
"group_access_level": 10
}
],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
```
......@@ -453,6 +456,7 @@ Parameters:
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
- `lfs_enabled` (optional)
- `request_access_enabled` (optional) - Allow users to request member access.
### Create project for user
......@@ -480,6 +484,7 @@ Parameters:
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
- `lfs_enabled` (optional)
- `request_access_enabled` (optional) - Allow users to request member access.
### Edit project
......@@ -508,6 +513,7 @@ Parameters:
- `public_builds` (optional)
- `only_allow_merge_if_build_succeeds` (optional)
- `lfs_enabled` (optional)
- `request_access_enabled` (optional) - Allow users to request member access.
On success, method returns 200 with the updated project. If parameters are
invalid, 400 is returned.
......@@ -588,7 +594,8 @@ Example response:
"star_count": 1,
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
```
......@@ -655,7 +662,8 @@ Example response:
"star_count": 0,
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
```
......@@ -742,7 +750,8 @@ Example response:
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
```
......@@ -829,7 +838,8 @@ Example response:
"runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b",
"public_builds": true,
"shared_with_groups": [],
"only_allow_merge_if_build_succeeds": false
"only_allow_merge_if_build_succeeds": false,
"request_access_enabled": false
}
```
......
......@@ -100,6 +100,7 @@ module API
SharedGroup.represent(project.project_group_links.all, options)
end
expose :only_allow_merge_if_build_succeeds
expose :request_access_enabled
end
class Member < UserBasic
......@@ -125,6 +126,7 @@ module API
expose :lfs_enabled?, as: :lfs_enabled
expose :avatar_url
expose :web_url
expose :request_access_enabled
end
class GroupDetail < Group
......
......@@ -23,18 +23,19 @@ module API
# Create group. Available only for users who can create groups.
#
# Parameters:
# name (required) - The name of the group
# path (required) - The path of the group
# description (optional) - The description of the group
# visibility_level (optional) - The visibility level of the group
# lfs_enabled (optional) - Enable/disable LFS for the projects in this group
# name (required) - The name of the group
# path (required) - The path of the group
# description (optional) - The description of the group
# visibility_level (optional) - The visibility level of the group
# lfs_enabled (optional) - Enable/disable LFS for the projects in this group
# request_access_enabled (optional) - Allow users to request member access
# Example Request:
# POST /groups
post do
authorize! :create_group
required_attributes! [:name, :path]
attrs = attributes_for_keys [:name, :path, :description, :visibility_level, :lfs_enabled]
attrs = attributes_for_keys [:name, :path, :description, :visibility_level, :lfs_enabled, :request_access_enabled]
@group = Group.new(attrs)
if @group.save
......@@ -48,18 +49,19 @@ module API
# Update group. Available only for users who can administrate groups.
#
# Parameters:
# id (required) - The ID of a group
# path (optional) - The path of the group
# description (optional) - The description of the group
# visibility_level (optional) - The visibility level of the group
# lfs_enabled (optional) - Enable/disable LFS for the projects in this group
# id (required) - The ID of a group
# path (optional) - The path of the group
# description (optional) - The description of the group
# visibility_level (optional) - The visibility level of the group
# lfs_enabled (optional) - Enable/disable LFS for the projects in this group
# request_access_enabled (optional) - Allow users to request member access
# Example Request:
# PUT /groups/:id
put ':id' do
group = find_group(params[:id])
authorize! :admin_group, group
attrs = attributes_for_keys [:name, :path, :description, :visibility_level, :lfs_enabled]
attrs = attributes_for_keys [:name, :path, :description, :visibility_level, :lfs_enabled, :request_access_enabled]
if ::Groups::UpdateService.new(group, current_user, attrs).execute
present group, with: Entities::GroupDetail
......
......@@ -91,8 +91,8 @@ module API
# Create new project
#
# Parameters:
# name (required) - name for new project
# description (optional) - short project description
# name (required) - name for new project
# description (optional) - short project description
# issues_enabled (optional)
# merge_requests_enabled (optional)
# builds_enabled (optional)
......@@ -100,33 +100,35 @@ module API
# snippets_enabled (optional)
# container_registry_enabled (optional)
# shared_runners_enabled (optional)
# namespace_id (optional) - defaults to user namespace
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - 0 by default
# namespace_id (optional) - defaults to user namespace
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional) - 0 by default
# import_url (optional)
# public_builds (optional)
# lfs_enabled (optional)
# request_access_enabled (optional) - Allow users to request member access
# Example Request
# POST /projects
post do
required_attributes! [:name]
attrs = attributes_for_keys [:name,
:path,
attrs = attributes_for_keys [:builds_enabled,
:container_registry_enabled,
:description,
:import_url,
:issues_enabled,
:lfs_enabled,
:merge_requests_enabled,
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
:container_registry_enabled,
:shared_runners_enabled,
:name,
:namespace_id,
:only_allow_merge_if_build_succeeds,
:path,
:public,
:visibility_level,
:import_url,
:public_builds,
:only_allow_merge_if_build_succeeds,
:lfs_enabled]
:request_access_enabled,
:shared_runners_enabled,
:snippets_enabled,
:visibility_level,
:wiki_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(current_user, attrs).execute
if @project.saved?
......@@ -143,10 +145,10 @@ module API
# Create new project for a specified user. Only available to admin users.
#
# Parameters:
# user_id (required) - The ID of a user
# name (required) - name for new project
# description (optional) - short project description
# default_branch (optional) - 'master' by default
# user_id (required) - The ID of a user
# name (required) - name for new project
# description (optional) - short project description
# default_branch (optional) - 'master' by default
# issues_enabled (optional)
# merge_requests_enabled (optional)
# builds_enabled (optional)
......@@ -154,31 +156,33 @@ module API
# snippets_enabled (optional)
# container_registry_enabled (optional)
# shared_runners_enabled (optional)
# public (optional) - if true same as setting visibility_level = 20
# public (optional) - if true same as setting visibility_level = 20
# visibility_level (optional)
# import_url (optional)
# public_builds (optional)
# lfs_enabled (optional)
# request_access_enabled (optional) - Allow users to request member access
# Example Request
# POST /projects/user/:user_id
post "user/:user_id" do
authenticated_as_admin!
user = User.find(params[:user_id])
attrs = attributes_for_keys [:name,
:description,
attrs = attributes_for_keys [:builds_enabled,
:default_branch,
:description,
:import_url,
:issues_enabled,
:lfs_enabled,
:merge_requests_enabled,
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
:shared_runners_enabled,
:name,
:only_allow_merge_if_build_succeeds,
:public,
:visibility_level,
:import_url,
:public_builds,
:only_allow_merge_if_build_succeeds,
:lfs_enabled]
:request_access_enabled,
:shared_runners_enabled,
:snippets_enabled,
:visibility_level,
:wiki_enabled]
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(user, attrs).execute
if @project.saved?
......@@ -242,22 +246,23 @@ module API
# Example Request
# PUT /projects/:id
put ':id' do
attrs = attributes_for_keys [:name,
:path,
:description,
attrs = attributes_for_keys [:builds_enabled,
:container_registry_enabled,
:default_branch,
:description,
:issues_enabled,
:lfs_enabled,
:merge_requests_enabled,
:builds_enabled,
:wiki_enabled,
:snippets_enabled,
:container_registry_enabled,
:shared_runners_enabled,
:name,
:only_allow_merge_if_build_succeeds,
:path,
:public,
:visibility_level,
:public_builds,
:only_allow_merge_if_build_succeeds,
:lfs_enabled]
:request_access_enabled,
:shared_runners_enabled,
:snippets_enabled,
:visibility_level,
:wiki_enabled]
attrs = map_public_to_visibility_level(attrs)
authorize_admin_project
authorize! :rename_project, user_project if attrs[:name].present?
......
......@@ -120,10 +120,11 @@ describe API::API, api: true do
context 'when authenticated as the group owner' do
it 'updates the group' do
put api("/groups/#{group1.id}", user1), name: new_group_name
put api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true
expect(response).to have_http_status(200)
expect(json_response['name']).to eq(new_group_name)
expect(json_response['request_access_enabled']).to eq(true)
end
it 'returns 404 for a non existing group' do
......@@ -238,8 +239,14 @@ describe API::API, api: true do
context "when authenticated as user with group permissions" do
it "creates group" do
post api("/groups", user3), attributes_for(:group)
group = attributes_for(:group, { request_access_enabled: false })
post api("/groups", user3), group
expect(response).to have_http_status(201)
expect(json_response["name"]).to eq(group[:name])
expect(json_response["path"]).to eq(group[:path])
expect(json_response["request_access_enabled"]).to eq(group[:request_access_enabled])
end
it "does not create group, duplicate" do
......
......@@ -225,7 +225,8 @@ describe API::API, api: true do
issues_enabled: false,
merge_requests_enabled: false,
wiki_enabled: false,
only_allow_merge_if_build_succeeds: false
only_allow_merge_if_build_succeeds: false,
request_access_enabled: true
})
post api('/projects', user), project
......@@ -352,7 +353,8 @@ describe API::API, api: true do
description: FFaker::Lorem.sentence,
issues_enabled: false,
merge_requests_enabled: false,
wiki_enabled: false
wiki_enabled: false,
request_access_enabled: true
})
post api("/projects/user/#{user.id}", admin), project
......@@ -887,6 +889,15 @@ describe API::API, api: true do
expect(json_response['message']['name']).to eq(['has already been taken'])
end
it 'updates request_access_enabled' do
project_param = { request_access_enabled: false }
put api("/projects/#{project.id}", user), project_param
expect(response).to have_http_status(200)
expect(json_response['request_access_enabled']).to eq(false)
end
it 'updates path & name to existing path & name in different namespace' do
project_param = { path: project4.path, name: project4.name }
put api("/projects/#{project3.id}", user), project_param
......@@ -948,7 +959,8 @@ describe API::API, api: true do
wiki_enabled: true,
snippets_enabled: true,
merge_requests_enabled: true,
description: 'new description' }
description: 'new description',
request_access_enabled: true }
put api("/projects/#{project.id}", user3), project_param
expect(response).to have_http_status(403)
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