diff --git a/doc/apiv3/endpoints/queries.apib b/doc/apiv3/endpoints/queries.apib index edba8e1092..8dec84b0dc 100644 --- a/doc/apiv3/endpoints/queries.apib +++ b/doc/apiv3/endpoints/queries.apib @@ -183,7 +183,7 @@ } } ], - "isPublic": "false", + "isPublic": false, "columnNames": [ "type", "status", @@ -198,7 +198,7 @@ ] ], "groupBy": null, - "displaySums": "false", + "displaySums": false, "isStarred": true } @@ -294,7 +294,7 @@ } } ], - "isPublic": "false", + "isPublic": false, "columnNames": [ "type", "status", @@ -309,8 +309,8 @@ ] ], "groupBy": null, - "displaySums": "false", - "isStarred": "false" + "displaySums": false, + "isStarred": false } ## Unstar query [PATCH] @@ -365,3 +365,185 @@ "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound", "message": "The specified query does not exist." } + +##Global Queries [/api/v3/queries] + ++ Model + + Body + + { + "_links": + { + "self": + { + "href": "/api/v3/queries" + } + }, + "total": 1, + "count": 1, + "_type": "Collection", + "_embedded": + { + "elements": [ + { + "_type": "Query", + "_links": { + "self": { + "href": "/api/v3/queries/2", + "title": "My work packages" + }, + "project": { + "href": null + }, + "user": { + "href": "/api/v3/users/1", + "title": "John Sheppard" + } + }, + "id": 2, + "name": "My work packages", + "filters": [], + "isPublic": false, + "columnNames": [ + "type", + "status", + "subject" + ], + "sortCriteria": [ + [ + "parent", + "desc" + ] + ], + "groupBy": null, + "displaySums": false, + "isStarred": true + } + ] + } + } + +## List global queries [GET] + ++ Parameters + + id (required, integer, `1`) ... Query id + ++ Response 200 (application/hal+json) + + [Global Queries][] + ++ Response 403 (application/hal+json) + + Returned if the client does not have sufficient permissions to see queries. + + **Required permission:** view work packages in any project or globally + + + Body + + { + "_type": "Error", + "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission", + "message": "You are not allowed to see the queries." + } + +## Queries by project [/api/v3/projects/{id}/queries] + ++ Model + + Body + + { + "_links": + { + "self": + { + "href": "/api/v3/projects/1/queries" + } + }, + "total": 1, + "count": 1, + "_type": "Collection", + "_embedded": + { + "elements": [ + { + "_type": "Query", + "_links": { + "self": { + "href": "/api/v3/queries/2", + "title": "My work packages" + }, + "project": { + "href": "/api/v3/projects/1" + }, + "user": { + "href": "/api/v3/users/1", + "title": "John Sheppard" + } + }, + "id": 2, + "name": "My work packages", + "filters": [], + "isPublic": false, + "columnNames": [ + "type", + "status", + "subject" + ], + "sortCriteria": [ + [ + "parent", + "desc" + ] + ], + "groupBy": null, + "displaySums": false, + "isStarred": true + } + ] + } + } + +## List project queries [GET] + ++ Parameters + + id (required, integer, `1`) ... Query id + ++ Response 200 (application/hal+json) + + [Queries by project][] + ++ Response 403 (application/hal+json) + + Returned if the client does not have sufficient permissions to see queries. + + **Required permission:** view work packages (on given project) + + *Note that you will only receive this error, if you are at least allowed to see the corresponding project.* + + + Body + + { + "_type": "Error", + "errorIdentifier": "urn:openproject-org:api:v3:errors:MissingPermission", + "message": "You are not allowed to see the queries of this project." + } + ++ Response 404 (application/hal+json) + + Returned if the project does not exist or the client does not have sufficient permissions + to see it. + + **Required permission:** view work packages (on given project) + + *Note: A client without sufficient permissions shall not be able to test for the existence of a project. + That's why a 404 is returned here, even if a 403 might be more appropriate.* + + + Body + + { + "_type": "Error", + "errorIdentifier": "urn:openproject-org:api:v3:errors:NotFound", + "message": "The specified project does not exist." + } + + diff --git a/lib/api/v3/projects/projects_api.rb b/lib/api/v3/projects/projects_api.rb index 9320698d53..ca1dc1e39b 100644 --- a/lib/api/v3/projects/projects_api.rb +++ b/lib/api/v3/projects/projects_api.rb @@ -56,6 +56,7 @@ module API mount API::V3::Categories::CategoriesByProjectAPI mount API::V3::Versions::VersionsByProjectAPI mount API::V3::Types::TypesByProjectAPI + mount API::V3::Queries::QueriesByProjectAPI end end end diff --git a/lib/api/v3/queries/queries_api.rb b/lib/api/v3/queries/queries_api.rb index 805932c3ff..b4ec53aab6 100644 --- a/lib/api/v3/queries/queries_api.rb +++ b/lib/api/v3/queries/queries_api.rb @@ -34,6 +34,16 @@ module API module Queries class QueriesAPI < ::API::OpenProjectAPI resources :queries do + get do + authorize(:view_work_packages, global: true) + + queries = Query.visible(to: current_user).global + self_link = api_v3_paths.queries + ::API::V3::Queries::QueryCollectionRepresenter.new(queries, + self_link, + current_user: current_user) + end + params do requires :id, desc: 'Query id' end diff --git a/lib/api/v3/queries/queries_by_project_api.rb b/lib/api/v3/queries/queries_by_project_api.rb new file mode 100644 index 0000000000..7aaf1bfbee --- /dev/null +++ b/lib/api/v3/queries/queries_by_project_api.rb @@ -0,0 +1,47 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See doc/COPYRIGHT.rdoc for more details. +#++ + +module API + module V3 + module Queries + class QueriesByProjectAPI < ::API::OpenProjectAPI + resources :queries do + get do + authorize(:view_work_packages, context: @project) + + queries = Query.visible(to: current_user).where(project: @project) + self_link = api_v3_paths.project_queries(@project.id) + ::API::V3::Queries::QueryCollectionRepresenter.new(queries, + self_link, + current_user: current_user) + end + end + end + end + end +end diff --git a/lib/api/v3/queries/query_collection_representer.rb b/lib/api/v3/queries/query_collection_representer.rb new file mode 100644 index 0000000000..c60cf0f0b0 --- /dev/null +++ b/lib/api/v3/queries/query_collection_representer.rb @@ -0,0 +1,38 @@ +#-- encoding: UTF-8 +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See doc/COPYRIGHT.rdoc for more details. +#++ + +module API + module V3 + module Queries + class QueryCollectionRepresenter < ::API::Decorators::UnpaginatedCollection + element_decorator ::API::V3::Queries::QueryRepresenter + end + end + end +end diff --git a/lib/api/v3/utilities/path_helper.rb b/lib/api/v3/utilities/path_helper.rb index 3f04765d61..5029fb0b8f 100644 --- a/lib/api/v3/utilities/path_helper.rb +++ b/lib/api/v3/utilities/path_helper.rb @@ -127,8 +127,16 @@ module API "#{projects}/#{id}" end + def self.project_queries(id) + "#{project(id)}/queries" + end + + def self.queries + "#{root}/queries" + end + def self.query(id) - "#{root}/queries/#{id}" + "#{queries}/#{id}" end def self.query_star(id) diff --git a/spec/lib/api/v3/utilities/path_helper_spec.rb b/spec/lib/api/v3/utilities/path_helper_spec.rb index d2fa02a82d..7a378d099c 100644 --- a/spec/lib/api/v3/utilities/path_helper_spec.rb +++ b/spec/lib/api/v3/utilities/path_helper_spec.rb @@ -216,6 +216,18 @@ describe ::API::V3::Utilities::PathHelper do it_behaves_like 'api v3 path', '/projects/1' end + + describe '#project_queries' do + subject { helper.project_queries 1 } + + it_behaves_like 'api v3 path', '/projects/1/queries' + end + end + + describe '#queries' do + subject { helper.queries } + + it_behaves_like 'api v3 path', '/queries' end describe '#query' do diff --git a/spec/requests/api/v3/queries/queries_by_project_resource_spec.rb b/spec/requests/api/v3/queries/queries_by_project_resource_spec.rb new file mode 100644 index 0000000000..a004b127b9 --- /dev/null +++ b/spec/requests/api/v3/queries/queries_by_project_resource_spec.rb @@ -0,0 +1,68 @@ +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2013 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See doc/COPYRIGHT.rdoc for more details. +#++ + +require 'spec_helper' +require 'rack/test' + +describe 'API v3 Queries by project resource', type: :request do + include Rack::Test::Methods + include API::V3::Utilities::PathHelper + + let(:project) { FactoryGirl.create(:project, is_public: false) } + let(:current_user) { + FactoryGirl.create(:user, member_in_project: project, member_through_role: role) + } + let(:role) { FactoryGirl.create(:role, permissions: permissions) } + let(:permissions) { [:view_work_packages] } + + before do + allow(User).to receive(:current).and_return(current_user) + end + + describe '#get' do + before do + get api_v3_paths.project_queries(project.id) + end + + it 'succeeds' do + expect(last_response.status).to eql 200 + end + + context 'user not allowed to see work packages' do + let(:permissions) { [] } + + it_behaves_like 'unauthorized access' + end + + context 'user not allowed to see project' do + let(:current_user) { FactoryGirl.create(:user) } + + it_behaves_like 'not found' + end + end +end diff --git a/spec/requests/api/v3/query_resource_spec.rb b/spec/requests/api/v3/queries/query_resource_spec.rb similarity index 92% rename from spec/requests/api/v3/query_resource_spec.rb rename to spec/requests/api/v3/queries/query_resource_spec.rb index e71401d8b9..db461cf05a 100644 --- a/spec/requests/api/v3/query_resource_spec.rb +++ b/spec/requests/api/v3/queries/query_resource_spec.rb @@ -46,9 +46,9 @@ describe 'API v3 Query resource', type: :request do allow(User).to receive(:current).and_return current_user end - describe '#get' do + describe '#get queries/' do before do - get api_v3_paths.query(query.id) + get api_v3_paths.queries end it 'should succeed' do @@ -56,13 +56,33 @@ describe 'API v3 Query resource', type: :request do end context 'user not allowed to see queries' do - let(:permissions) { [] } + include_context 'with non-member permissions from non_member_permissions' + let(:current_user) { FactoryGirl.create(:user) } + let(:non_member_permissions) { [:view_work_packages] } + + it 'should succeed' do + expect(last_response.status).to eq(200) + end + + context 'that is not allowed to see queries anywhere' do + let(:non_member_permissions) { [] } - it_behaves_like 'not found' + it_behaves_like 'unauthorized access' + end + end + end + + describe '#get queries/:id' do + before do + get api_v3_paths.query(query.id) + end + + it 'should succeed' do + expect(last_response.status).to eq(200) end end - describe '#delete' do + describe '#delete queries/:id' do let(:path) { api_v3_paths.query query.id } let(:permissions) { [:view_work_packages, :manage_public_queries] }