summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McGivern <sean@mcgivern.me.uk>2017-03-03 15:01:10 +0000
committerSean McGivern <sean@mcgivern.me.uk>2017-03-03 15:01:10 +0000
commitf9aae510d9d917eda1ad3970f7989fb7d4e74f2c (patch)
tree5ee7214758a2820e5f171db369b3455704e60219
parent433ec4d8da9d6c3b45660892a15e88a1719e7599 (diff)
parent6357635686fafb2fc9af5090c1edabfe25649085 (diff)
downloadgitlab-ce-f9aae510d9d917eda1ad3970f7989fb7d4e74f2c.tar.gz
Merge branch '28865-filter-by-authorized-projects-in-v4' into 'master'
Add filter param for user's authorized projects in V4 Closes #28865 See merge request !9674
-rw-r--r--changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml4
-rw-r--r--doc/api/projects.md3
-rw-r--r--doc/api/v3_to_v4.md7
-rw-r--r--lib/api/helpers.rb4
-rw-r--r--lib/api/projects.rb3
-rw-r--r--spec/requests/api/projects_spec.rb69
6 files changed, 65 insertions, 25 deletions
diff --git a/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml b/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml
new file mode 100644
index 00000000000..7c64783cbd0
--- /dev/null
+++ b/changelogs/unreleased/28865-filter-by-authorized-projects-in-v4.yml
@@ -0,0 +1,4 @@
+---
+title: Add filter param for project membership for current_user in API v4
+merge_request:
+author:
diff --git a/doc/api/projects.md b/doc/api/projects.md
index f6eabc1f663..6062c5ccd71 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -34,9 +34,10 @@ Parameters:
| `visibility` | string | no | Limit by visibility `public`, `internal`, or `private` |
| `order_by` | string | no | Return projects ordered by `id`, `name`, `path`, `created_at`, `updated_at`, or `last_activity_at` fields. Default is `created_at` |
| `sort` | string | no | Return projects sorted in `asc` or `desc` order. Default is `desc` |
-| `search` | string | no | Return list of authorized projects matching the search criteria |
+| `search` | string | no | Return list of projects matching the search criteria |
| `simple` | boolean | no | Return only the ID, URL, name, and path of each project |
| `owned` | boolean | no | Limit by projects owned by the current user |
+| `membership` | boolean | no | Limit by projects that the current user is a member of |
| `starred` | boolean | no | Limit by projects starred by the current user |
```json
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index cca58894476..42deccba0a6 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -28,7 +28,12 @@ changes are in V4:
- `/dockerfiles/:key`
- Moved `/projects/fork/:id` to `/projects/:id/fork` [!8940](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8940)
- Moved `DELETE /todos` to `POST /todos/mark_as_done` and `DELETE /todos/:todo_id` to `POST /todos/:todo_id/mark_as_done` [!9410](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9410)
-- Endpoints `/projects/owned`, `/projects/visible`, `/projects/starred` & `/projects/all` are consolidated into `/projects` using query parameters [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
+- Project filters are no longer available as `GET /projects/foo`, but as `GET /projects?foo=true` instead [!8962](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8962)
+ - `GET /projects/visible` & `GET /projects/all` are consolidated into `GET /projects` and can be used with or without authorization
+ - `GET /projects/owned` moved to `GET /projects?owned=true`
+ - `GET /projects/starred` moved to `GET /projects?starred=true`
+- `GET /projects` returns all projects visible to current user, even if the user is not a member [!9674](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9674)
+ - To get projects the user is a member of, use `/projects?membership=true`
- Return pagination headers for all endpoints that return an array [!8606](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8606)
- Added `POST /environments/:environment_id/stop` to stop an environment [!8808](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8808)
- Removed `DELETE projects/:id/deploy_keys/:key_id/disable`. Use `DELETE projects/:id/deploy_keys/:key_id` instead [!9366](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9366)
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 4600abc7dc7..9c41146f1e3 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -252,6 +252,10 @@ module API
# project helpers
def filter_projects(projects)
+ if params[:membership]
+ projects = projects.merge(current_user.authorized_projects)
+ end
+
if params[:owned]
projects = projects.merge(current_user.owned_projects)
end
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index f302496c12b..63a4cdd5954 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -46,9 +46,10 @@ module API
optional :archived, type: Boolean, default: false, desc: 'Limit by archived status'
optional :visibility, type: String, values: Gitlab::VisibilityLevel.string_values,
desc: 'Limit by visibility'
- optional :search, type: String, desc: 'Return list of authorized projects matching the search criteria'
+ optional :search, type: String, desc: 'Return list of projects matching the search criteria'
optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
optional :starred, type: Boolean, default: false, desc: 'Limit by starred status'
+ optional :membership, type: Boolean, default: false, desc: 'Limit by projects that the current user is a member of'
end
params :statistics_params do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 2e8b557e9e2..03cae074803 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -43,9 +43,10 @@ describe API::Projects, api: true do
describe 'GET /projects' do
shared_examples_for 'projects response' do
it 'returns an array of projects' do
- get api('/projects', current_user)
+ get api('/projects', current_user), filter
expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.map { |p| p['id'] }).to contain_exactly(*projects.map(&:id))
end
@@ -61,6 +62,7 @@ describe API::Projects, api: true do
context 'when unauthenticated' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { nil }
let(:projects) { [public_project] }
end
@@ -68,6 +70,7 @@ describe API::Projects, api: true do
context 'when authenticated as regular user' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { user }
let(:projects) { [public_project, project, project2, project3] }
end
@@ -133,13 +136,18 @@ describe API::Projects, api: true do
end
context 'and using search' do
- it 'returns searched project' do
- get api('/projects', user), { search: project.name }
+ it_behaves_like 'projects response' do
+ let(:filter) { { search: project.name } }
+ let(:current_user) { user }
+ let(:projects) { [project] }
+ end
+ end
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.length).to eq(1)
+ context 'and membership=true' do
+ it_behaves_like 'projects response' do
+ let(:filter) { { membership: true } }
+ let(:current_user) { user }
+ let(:projects) { [project, project2, project3] }
end
end
@@ -216,36 +224,52 @@ describe API::Projects, api: true do
end
context 'and with all query parameters' do
- # | | project5 | project6 | project7 | project8 | project9 |
- # |---------+----------+----------+----------+----------+----------|
- # | search | x | | x | x | x |
- # | starred | x | x | | x | x |
- # | public | x | x | x | | x |
- # | owned | x | x | x | x | |
- let!(:project5) { create(:empty_project, :public, path: 'gitlab5', namespace: user.namespace) }
+ let!(:project5) { create(:empty_project, :public, path: 'gitlab5', namespace: create(:namespace)) }
let!(:project6) { create(:empty_project, :public, path: 'project6', namespace: user.namespace) }
let!(:project7) { create(:empty_project, :public, path: 'gitlab7', namespace: user.namespace) }
let!(:project8) { create(:empty_project, path: 'gitlab8', namespace: user.namespace) }
let!(:project9) { create(:empty_project, :public, path: 'gitlab9') }
before do
- user.update_attributes(starred_projects: [project5, project6, project8, project9])
+ user.update_attributes(starred_projects: [project5, project7, project8, project9])
end
- it 'returns only projects that satify all query parameters' do
- get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' }
+ context 'including owned filter' do
+ it 'returns only projects that satisfy all query parameters' do
+ get api('/projects', user), { visibility: 'public', owned: true, starred: true, search: 'gitlab' }
- expect(response).to have_http_status(200)
- expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
- expect(json_response.size).to eq(1)
- expect(json_response.first['id']).to eq(project5.id)
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['id']).to eq(project7.id)
+ end
+ end
+
+ context 'including membership filter' do
+ before do
+ create(:project_member,
+ user: user,
+ project: project5,
+ access_level: ProjectMember::MASTER)
+ end
+
+ it 'returns only projects that satisfy all query parameters' do
+ get api('/projects', user), { visibility: 'public', membership: true, starred: true, search: 'gitlab' }
+
+ expect(response).to have_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |project| project['id'] }).to contain_exactly(project5.id, project7.id)
+ end
end
end
end
context 'when authenticated as a different user' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { user2 }
let(:projects) { [public_project] }
end
@@ -253,6 +277,7 @@ describe API::Projects, api: true do
context 'when authenticated as admin' do
it_behaves_like 'projects response' do
+ let(:filter) { {} }
let(:current_user) { admin }
let(:projects) { Project.all }
end