User Story # 8769 Squashed commit of the following: commitpull/1462/headfac82d68b6
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 11 15:53:21 2014 +0200 Removed cascade false call from root api commitfedff52220
Merge:7b2942c
e204fa9
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 11 14:17:27 2014 +0200 Merge commit7b2942c419
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 11 14:11:58 2014 +0200 Generated new Gemfile.lock commit7af2f77bbc
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 15:03:47 2014 +0200 Removed print call commitbb19cddee9
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 14:39:35 2014 +0200 Removed 'spec/factories/priority_factory.rb commite8bbf476f1
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 14:38:31 2014 +0200 Replaced lambda calls with '->' commit9d8a1c2423
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 19:19:40 2014 +0200 Clean up commit08f80e8c91
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 19:03:38 2014 +0200 Delete ::ConnectionManagement-call(env)> commit190c2e2d86
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 17:40:34 2014 +0200 Reset Gemfile.lock commit0a32dcaef0
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 14:43:58 2014 +0200 Small refactoring of the API specs commit963bb3e848
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 4 17:10:15 2014 +0200 Basic implementation of APIv3 work package #get commitffdb5641a7
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 4 17:08:48 2014 +0200 Basic implementation of APIv3 work package #get commit8d64840f02
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 3 16:33:02 2014 +0200 Clening up commit2caf393c94
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 3 16:30:50 2014 +0200 Work package #patch - incomplete tests commitd6b9a4f263
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:42:26 2014 +0200 Renamed #done_ratio to #percentage_done commit583ba0b525
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:30:42 2014 +0200 Cleanup commit34bfb88377
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:14:09 2014 +0200 Added basic test & improved patch work package commit377070acfe
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 15:38:58 2014 +0200 Implemented basic batch update for work packages commit9df0ffb916
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 14:41:56 2014 +0200 Set default limit and offset for GET work packages resource commitf1ac16b23f
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 14:18:00 2014 +0200 Created GET endpoint work work packages resource & N+1 query optimization commit9a7bb32f46
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 19:29:04 2014 +0200 Basic authorization for work package GET and PATCH commitda4b778d51
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 15:51:10 2014 +0200 Completed basic implementation of get, patch, head and options requests for work package resource commitc8e8ab68af
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 10:47:43 2014 +0200 Added target version attributes to the work package resource commit2ab0bea6ac
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 18:08:13 2014 +0200 Implemented work package update with some child resources commit17edd10bb5
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 16:31:18 2014 +0200 Minor refactoring of work packages api commita63f17622c
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 16:28:48 2014 +0200 Created GET work package endpoint commitabcf2e50b4
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 14:40:47 2014 +0200 Created OP API entry point commit4564bae6f5
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 13:39:57 2014 +0200 Refactor authorize method (created service object) commitcb464d9329
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 11:15:31 2014 +0200 Created basic structure for Work packages API commit00f3b7a291
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 16:29:30 2014 +0200 WorkPackage mapper changes commit622ebd04eb
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 01:30:02 2014 +0200 Added relationships to WorkPackage mapper commit80ebe54d90
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 01:14:57 2014 +0200 Created WorkPackage mapper class commit2da9225aef
Author: Marek Takac <m.takac@finn.de> Date: Mon May 12 19:21:07 2014 +0200 Mappers for Grape API commit5cd59c4ad6
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 16:54:24 2014 +0200 Created some decorators commita5cb66e5b6
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 15:31:25 2014 +0200 Added pundit for authorization commitf909e89687
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 14:49:20 2014 +0200 Created work package representer & current_user helper method for API commit5aad3c087a
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 14:24:47 2014 +0200 Created basic structure for Work packages API commitb25a348619
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 14:04:37 2014 +0200 Set up Grape API v3 commitbe76a6500e
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 13:58:38 2014 +0200 Added grape commite204fa9de8
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 15:03:47 2014 +0200 Removed print call commit39b921adc7
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 14:39:35 2014 +0200 Removed 'spec/factories/priority_factory.rb commit94c64ab855
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 10 14:38:31 2014 +0200 Replaced lambda calls with '->' commitc2101b0352
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 19:19:40 2014 +0200 Clean up commita03bc0d84c
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 19:03:38 2014 +0200 Delete ::ConnectionManagement-call(env)> commit8b2fe0b01e
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 17:40:34 2014 +0200 Reset Gemfile.lock commit5d6618eea4
Merge:f325a36
dab75c3
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 16:10:51 2014 +0200 Merge branch 'dev' into feature/api_v3_base commitf325a36d6f
Author: Marek Takac <m.takac@finn.de> Date: Fri Jun 6 14:43:58 2014 +0200 Small refactoring of the API specs commit84f78d669d
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 4 17:10:15 2014 +0200 Basic implementation of APIv3 work package #get commit82786a9717
Author: Marek Takac <m.takac@finn.de> Date: Wed Jun 4 17:08:48 2014 +0200 Basic implementation of APIv3 work package #get commitb7dd82f85f
Merge:f4ba4e8
5525bc3
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 3 17:15:48 2014 +0200 Merge commit5525bc3d52
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 3 16:33:02 2014 +0200 Clening up commit9d27e3d412
Author: Marek Takac <m.takac@finn.de> Date: Tue Jun 3 16:30:50 2014 +0200 Work package #patch - incomplete tests commit58ceeee83e
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:42:26 2014 +0200 Renamed #done_ratio to #percentage_done commit7165e32bc4
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:30:42 2014 +0200 Cleanup commit235ecdeabe
Author: Marek Takac <m.takac@finn.de> Date: Wed May 28 17:14:09 2014 +0200 Added basic test & improved patch work package commit625f273dc1
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 15:38:58 2014 +0200 Implemented basic batch update for work packages commit20239886d4
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 14:41:56 2014 +0200 Set default limit and offset for GET work packages resource commitad79163fd3
Author: Marek Takac <m.takac@finn.de> Date: Fri May 23 14:18:00 2014 +0200 Created GET endpoint work work packages resource & N+1 query optimization commitc3dcba77f0
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 19:29:04 2014 +0200 Basic authorization for work package GET and PATCH commit73d8a8551d
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 15:51:10 2014 +0200 Completed basic implementation of get, patch, head and options requests for work package resource commit479fc4b005
Author: Marek Takac <m.takac@finn.de> Date: Thu May 22 10:47:43 2014 +0200 Added target version attributes to the work package resource commita72cff36a9
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 18:08:13 2014 +0200 Implemented work package update with some child resources commit6689628a74
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 16:31:18 2014 +0200 Minor refactoring of work packages api commit97d4e9a1e6
Author: Marek Takac <m.takac@finn.de> Date: Wed May 21 16:28:48 2014 +0200 Created GET work package endpoint commit1490621af1
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 14:40:47 2014 +0200 Created OP API entry point commit1e080b7936
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 13:39:57 2014 +0200 Refactor authorize method (created service object) commit1b0b894456
Author: Marek Takac <m.takac@finn.de> Date: Tue May 20 11:15:31 2014 +0200 Created basic structure for Work packages API commit6c8f83ae54
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 16:29:30 2014 +0200 WorkPackage mapper changes commitd2a7f29201
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 01:30:02 2014 +0200 Added relationships to WorkPackage mapper commit0122cd4392
Author: Marek Takac <m.takac@finn.de> Date: Tue May 13 01:14:57 2014 +0200 Created WorkPackage mapper class commit6a40cdd6bf
Author: Marek Takac <m.takac@finn.de> Date: Mon May 12 19:21:07 2014 +0200 Mappers for Grape API commit0a4f39be58
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 16:54:24 2014 +0200 Created some decorators commit21e1c42b54
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 15:31:25 2014 +0200 Added pundit for authorization commita76f23ec51
Author: Marek Takac <m.takac@finn.de> Date: Tue Apr 29 14:49:20 2014 +0200 Created work package representer & current_user helper method for API commit4d92b35994
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 14:24:47 2014 +0200 Created basic structure for Work packages API commitd19a5d698a
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 14:04:37 2014 +0200 Set up Grape API v3 commitb270fa6164
Author: Marek Takac <m.takac@finn.de> Date: Mon Apr 28 13:58:38 2014 +0200 Added grape Signed-off-by: Alex Coles <alex@alexbcoles.com>
parent
d4770290f3
commit
ac2c89c0d7
@ -0,0 +1,48 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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. |
||||
#++ |
||||
|
||||
class AuthorizationService |
||||
def initialize(ctrl, action, project, projects, global, user = nil) |
||||
@ctrl = ctrl |
||||
@action = action |
||||
@project = project |
||||
@projects = projects |
||||
@global = global |
||||
@user = user || User.current |
||||
end |
||||
|
||||
def perform |
||||
allowed = @user.allowed_to?({:controller => @ctrl, :action => @action}, @project || @projects, :global => @global) |
||||
if allowed |
||||
true |
||||
else |
||||
false |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,11 @@ |
||||
if Rails.env.development? |
||||
ActiveSupport::Dependencies.explicitly_unloadable_constants << "API" |
||||
|
||||
api_files = Dir[Rails.root.join('app', 'api', '**', '*.rb')] |
||||
api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do |
||||
Rails.application.reload_routes! |
||||
end |
||||
ActionDispatch::Callbacks.to_prepare do |
||||
api_reloader.execute_if_updated |
||||
end |
||||
end |
@ -0,0 +1,5 @@ |
||||
class DropWorkPackagesPriorityNotNullConstraint < ActiveRecord::Migration |
||||
def change |
||||
change_column :work_packages, :priority_id, :integer, :null => true |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 Errors |
||||
class NotFound < Grape::Exceptions::Base |
||||
attr_reader :code, :title, :description, :headers |
||||
|
||||
def initialize(message, args = { }) |
||||
@message = message |
||||
@code = args[:code] || 404 |
||||
@title = args[:title] || 'not_found' |
||||
@description = args[:description] || 'Resource couldn\'t be found.' |
||||
@headers = { 'Content-Type' => 'application/hal+json' }.merge(args[:headers] || { }) |
||||
end |
||||
|
||||
def errors |
||||
[{ key: @title, messages: [@message] }] |
||||
end |
||||
|
||||
def to_json |
||||
{ title: @title, description: @description, errors: errors }.to_json |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,51 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 Errors |
||||
class Unauthenticated < Grape::Exceptions::Base |
||||
attr_reader :code, :title, :description, :headers |
||||
|
||||
def initialize(args = { }) |
||||
@code = args[:code] || 401 |
||||
@title = args[:title] || 'not_authenticated' |
||||
@description = args[:description] || 'User needs to be authenticated to access this resource.' |
||||
@headers = { 'Content-Type' => 'application/hal+json' }.merge(args[:headers] || { }) |
||||
end |
||||
|
||||
def errors |
||||
[{ key: @title, messages: ['You need to be authenticated to access this resource'] }] |
||||
end |
||||
|
||||
def to_json |
||||
{ title: @title, description: @description, errors: errors }.to_json |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 Errors |
||||
class Unauthorized < Grape::Exceptions::Base |
||||
attr_reader :code, :title, :description, :headers |
||||
|
||||
def initialize(user, args = { }) |
||||
@user = user |
||||
@code = args[:code] || 403 |
||||
@title = args[:title] || 'not_authorized' |
||||
@description = args[:description] || 'User does not have sufficent rights to access the resource.' |
||||
@headers = { 'Content-Type' => 'application/hal+json' }.merge(args[:headers] || { }) |
||||
end |
||||
|
||||
def errors |
||||
[{ key: @title, messages: ['You are not authorize to access this resource'] }] |
||||
end |
||||
|
||||
def to_json |
||||
{ title: @title, description: @description, errors: errors }.to_json |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 Errors |
||||
class UnwritableProperty < Grape::Exceptions::Base |
||||
attr_reader :code, :title, :description, :headers |
||||
|
||||
def initialize(property, args = { }) |
||||
@property = property |
||||
@code = args[:code] || 422 |
||||
@title = args[:title] || 'unwriteable_property_error' |
||||
@description = args[:description] || 'You tried to write read-only property.' |
||||
@headers = { 'Content-Type' => 'application/hal+json' }.merge(args[:headers] || { }) |
||||
end |
||||
|
||||
def errors |
||||
[{ key: @property, messages: ['is read-only'] }] |
||||
end |
||||
|
||||
def to_json |
||||
{ title: @title, description: @description, errors: errors }.to_json |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 Errors |
||||
class Validation < Grape::Exceptions::Base |
||||
attr_reader :code, :title, :description, :headers |
||||
|
||||
def initialize(obj, args = { }) |
||||
@obj = obj |
||||
@code = args[:code] || 422 |
||||
@title = args[:title] || 'validation_error' |
||||
@description = args[:description] || 'Validation failed.' |
||||
@headers = { 'Content-Type' => 'application/hal+json' }.merge(args[:headers] || { }) |
||||
end |
||||
|
||||
def errors |
||||
@obj.errors.messages.map{ |m| { key: m[0], messages: m[1] }} |
||||
end |
||||
|
||||
def to_json |
||||
{ title: @title, description: @description, errors: errors }.to_json |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,79 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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. |
||||
#++ |
||||
|
||||
# Root class of the API |
||||
# This is the place for all API wide configuration, helper methods, exceptions |
||||
# rescuing, mounting of differnet API versions etc. |
||||
|
||||
module API |
||||
class Root < Grape::API |
||||
prefix :api |
||||
content_type 'hal+json', 'application/hal+json' |
||||
format 'hal+json' |
||||
|
||||
helpers do |
||||
# Needs refactoring - Will have to find a way how to access sessions in all enviroments |
||||
def current_user |
||||
return User.current if Rails.env.test? |
||||
|
||||
if Rails.env.development? |
||||
user_id = env['action_dispatch.request.unsigned_session_cookie']['user_id'] |
||||
elsif Rails.env.production? |
||||
user_id = env['rack.session']['user_id'] |
||||
end |
||||
return nil if user_id.nil? |
||||
@current_user ||= User.find(user_id) |
||||
end |
||||
|
||||
# Split into two methods: one for authentication, one for authorization |
||||
def authorize(api, endpoint, project = nil, projects = nil, global = false) |
||||
if current_user.nil? || current_user.anonymous? |
||||
raise API::Errors::Unauthenticated.new |
||||
end |
||||
is_authorized = AuthorizationService.new(api, endpoint, project, projects, global, current_user).perform |
||||
unless is_authorized |
||||
raise API::Errors::Unauthorized.new(current_user) |
||||
end |
||||
is_authorized |
||||
end |
||||
end |
||||
|
||||
rescue_from API::Errors::Validation, API::Errors::UnwritableProperty, API::Errors::Unauthorized, |
||||
API::Errors::Unauthenticated do |e| |
||||
Rack::Response.new(e.to_json, e.code, e.headers).finish |
||||
end |
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do |e| |
||||
not_found = API::Errors::NotFound.new(e.message) |
||||
Rack::Response.new(not_found.to_json, not_found.code, not_found.headers).finish |
||||
end |
||||
|
||||
mount API::V3::Root |
||||
end |
||||
end |
@ -0,0 +1,49 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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. |
||||
#++ |
||||
|
||||
# Temporarily solution! |
||||
# Using customized version of Representable gem (git@github.com:finnlabs/representable.git) |
||||
# we can specify strategy to take place during the data serialization |
||||
|
||||
module API |
||||
module Utilities |
||||
class CamelCasingStrategy |
||||
# CamelCase properties of ROAR representer |
||||
def call(property) |
||||
to_camel_case(property) |
||||
end |
||||
|
||||
private |
||||
def to_camel_case(string) |
||||
return string if string.first == '_' |
||||
string.camelize(:lower) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,42 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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. |
||||
#++ |
||||
|
||||
# Root class of the API v3 |
||||
# This is the place for all API v3 wide configuration, helper methods, exceptions |
||||
# rescuing, mounting of differnet API versions etc. |
||||
|
||||
module API |
||||
module V3 |
||||
class Root < Grape::API |
||||
version 'v3', using: :path |
||||
|
||||
mount API::V3::WorkPackages::WorkPackagesAPI |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,106 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 'reform/form/coercion' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackageModel < Reform::Form |
||||
include Composition |
||||
include Coercion |
||||
|
||||
model :work_package |
||||
|
||||
property :subject, on: :work_package, type: String |
||||
property :description, on: :work_package, type: String |
||||
property :start_date, on: :work_package, type: Date |
||||
property :due_date, on: :work_package, type: Date |
||||
property :created_at, on: :work_package, type: DateTime |
||||
property :updated_at, on: :work_package, type: DateTime |
||||
property :author, on: :work_package, type: String |
||||
property :project_id, on: :work_package, type: Integer |
||||
property :responsible_id, on: :work_package, type: Integer |
||||
property :assigned_to_id, on: :work_package, type: Integer |
||||
property :fixed_version_id, on: :work_package, type: Integer |
||||
|
||||
def type |
||||
work_package.type.try(:name) |
||||
end |
||||
|
||||
def type=(value) |
||||
type = Type.find(:first, conditions: ['name ilike ?', value]) |
||||
work_package.type = type |
||||
end |
||||
|
||||
def status |
||||
work_package.status.try(:name) |
||||
end |
||||
|
||||
def status=(value) |
||||
status = Status.find(:first, conditions: ['name ilike ?', value]) |
||||
work_package.status = status |
||||
end |
||||
|
||||
def priority |
||||
work_package.priority.try(:name) |
||||
end |
||||
|
||||
def priority=(value) |
||||
priority = IssuePriority.find(:first, conditions: ['name ilike ?', value]) |
||||
work_package.priority = priority |
||||
end |
||||
|
||||
def estimated_time |
||||
{ units: 'hours', value: work_package.estimated_hours } |
||||
end |
||||
|
||||
def estimated_time=(value) |
||||
hours = ActiveSupport::JSON.decode(value)['value'] |
||||
work_package.estimated_hours = hours |
||||
end |
||||
|
||||
def version_id=(value) |
||||
work_package.fixed_version_id = value |
||||
end |
||||
|
||||
def percentage_done |
||||
work_package.done_ratio |
||||
end |
||||
|
||||
def percentage_done=(value) |
||||
work_package.done_ratio = value |
||||
end |
||||
|
||||
validates_presence_of :subject, :project_id, :type, :author, :status |
||||
validates_length_of :subject, maximum: 255 |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,83 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2014 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 'roar/decorator' |
||||
require 'roar/representer/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackageRepresenter < Roar::Decorator |
||||
include Roar::Representer::JSON::HAL |
||||
include Roar::Representer::Feature::Hypermedia |
||||
include Rails.application.routes.url_helpers |
||||
|
||||
self.as_strategy = API::Utilities::CamelCasingStrategy.new |
||||
|
||||
property :_type, exec_context: :decorator |
||||
|
||||
link :self do |
||||
{ href: "http://localhost:3000/api/v3/work_packages/#{represented.work_package.id}", title: "#{represented.subject}" } |
||||
end |
||||
|
||||
property :id, getter: -> (*) { work_package.id }, render_nil: true |
||||
property :subject, render_nil: true |
||||
property :type, render_nil: true |
||||
property :description, render_nil: true |
||||
property :status, render_nil: true |
||||
property :priority, render_nil: true |
||||
property :start_date, getter: -> (*) { work_package.start_date }, render_nil: true |
||||
property :due_date, getter: -> (*) { work_package.due_date }, render_nil: true |
||||
property :estimated_time, render_nil: true |
||||
property :percentage_done, render_nil: true |
||||
property :version_id, getter: -> (*) { work_package.fixed_version.try(:id) }, render_nil: true |
||||
property :version_name, getter: -> (*) { work_package.fixed_version.try(:name) }, render_nil: true |
||||
property :project_id, getter: -> (*) { work_package.project.id } |
||||
property :project_name, getter: -> (*) { work_package.project.try(:name) } |
||||
property :responsible_id, getter: -> (*) { work_package.responsible.try(:id) }, render_nil: true |
||||
property :responsible_name, getter: -> (*) { work_package.responsible.try(:name) }, render_nil: true |
||||
property :responsible_login, getter: -> (*) { work_package.responsible.try(:login) }, render_nil: true |
||||
property :responsible_mail, getter: -> (*) { work_package.responsible.try(:mail) }, render_nil: true |
||||
property :assigned_to_id, as: :assigneeId, getter: -> (*) { work_package.assigned_to.try(:id) }, render_nil: true |
||||
property :assignee_name, getter: -> (*) { work_package.assigned_to.try(:name) }, render_nil: true |
||||
property :assignee_login, getter: -> (*) { work_package.assigned_to.try(:login) }, render_nil: true |
||||
property :assignee_mail, getter: -> (*) { work_package.assigned_to.try(:mail) }, render_nil: true |
||||
property :author_name, getter: -> (*) { work_package.author.name }, render_nil: true |
||||
property :author_login, getter: -> (*) { work_package.author.login }, render_nil: true |
||||
property :author_mail, getter: -> (*) { work_package.author.mail }, render_nil: true |
||||
property :created_at, getter: -> (*) { work_package.created_at.utc.iso8601}, render_nil: true |
||||
property :updated_at, getter: -> (*) { work_package.updated_at.utc.iso8601}, render_nil: true |
||||
|
||||
def _type |
||||
"WorkPackage" |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,31 @@ |
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackagesAPI < Grape::API |
||||
|
||||
resources :work_packages do |
||||
|
||||
params do |
||||
requires :id, desc: 'Work package id' |
||||
end |
||||
namespace ':id' do |
||||
|
||||
before do |
||||
@work_package = WorkPackage.find(params[:id]) |
||||
model = WorkPackageModel.new(work_package: @work_package) |
||||
@representer = WorkPackageRepresenter.new(model) |
||||
end |
||||
|
||||
get do |
||||
authorize(:work_packages_api, :get, @work_package.project) |
||||
@representer.to_json |
||||
end |
||||
|
||||
end |
||||
|
||||
end |
||||
|
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,121 @@ |
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe 'API v3 Work package resource' do |
||||
include Rack::Test::Methods |
||||
|
||||
let(:work_package) { FactoryGirl.create(:work_package, :project_id => project.id) } |
||||
let(:project) { FactoryGirl.create(:project, :identifier => 'test_project', :is_public => false) } |
||||
let(:current_user) { FactoryGirl.create(:user) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: [:view_work_packages]) } |
||||
let(:unauthorize_user) { FactoryGirl.create(:user) } |
||||
let(:type) { FactoryGirl.create(:type) } |
||||
|
||||
describe '#get' do |
||||
let(:get_path) { "/api/v3/work_packages/#{work_package.id}" } |
||||
let(:expected_response) do |
||||
{ |
||||
"_type" => 'WorkPackage', |
||||
"_links" => { |
||||
"self" => { |
||||
"href" => "http://localhost:3000/api/v3/work_packages/#{work_package.id}", |
||||
"title" => work_package.subject |
||||
} |
||||
}, |
||||
"id" => work_package.id, |
||||
"subject" => work_package.subject, |
||||
"type" => work_package.type.name, |
||||
"description" => work_package.description, |
||||
"status" => work_package.status.name, |
||||
"priority" => work_package.priority.name, |
||||
"startDate" => work_package.start_date, |
||||
"dueDate" => work_package.due_date, |
||||
"estimatedTime" => JSON.parse({ units: 'hours', value: work_package.estimated_hours }.to_json), |
||||
"percentageDone" => work_package.done_ratio, |
||||
"versionId" => work_package.fixed_version_id, |
||||
"versionName" => work_package.fixed_version.try(:name), |
||||
"projectId" => work_package.project_id, |
||||
"projectName" => work_package.project.name, |
||||
"responsibleId" => work_package.responsible_id, |
||||
"responsibleName" => work_package.responsible.try(:name), |
||||
"responsibleLogin" => work_package.responsible.try(:login), |
||||
"responsibleMail" => work_package.responsible.try(:mail), |
||||
"assigneeId" => work_package.assigned_to_id, |
||||
"assigneeName" => work_package.assigned_to.try(:name), |
||||
"assigneeLogin" => work_package.assigned_to.try(:login), |
||||
"assigneeMail" => work_package.assigned_to.try(:mail), |
||||
"authorName" => work_package.author.name, |
||||
"authorLogin" => work_package.author.login, |
||||
"authorMail" => work_package.author.mail, |
||||
"createdAt" => work_package.created_at.utc.iso8601, |
||||
"updatedAt" => work_package.updated_at.utc.iso8601 |
||||
} |
||||
end |
||||
|
||||
context 'when acting as a user with permission to view work package' do |
||||
|
||||
before(:each) do |
||||
allow(User).to receive(:current).and_return current_user |
||||
member = FactoryGirl.build(:member, user: current_user, project: work_package.project) |
||||
member.role_ids = [role.id] |
||||
member.save! |
||||
get get_path |
||||
end |
||||
|
||||
it 'should respond with 200' do |
||||
last_response.status.should eq(200) |
||||
end |
||||
|
||||
it 'should respond with work package in HAL+JSON format' do |
||||
parsed_response = JSON.parse(last_response.body) |
||||
parsed_response.should eq(expected_response) |
||||
end |
||||
|
||||
context 'requesting nonexistent work package' do |
||||
let(:get_path) { "/api/v3/work_packages/909090" } |
||||
|
||||
it 'should respond with 404' do |
||||
last_response.status.should eq(404) |
||||
end |
||||
|
||||
it 'should respond with explanatory error message' do |
||||
parsed_errors = JSON.parse(last_response.body)['errors'] |
||||
parsed_errors.should eq([{ 'key' => 'not_found', 'messages' => ['Couldn\'t find WorkPackage with id=909090']}]) |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'when acting as an user without permission to view work package' do |
||||
before(:each) do |
||||
allow(User).to receive(:current).and_return unauthorize_user |
||||
get get_path |
||||
end |
||||
|
||||
it 'should respond with 403' do |
||||
last_response.status.should eq(403) |
||||
end |
||||
|
||||
it 'should respond with explanatory error message' do |
||||
parsed_errors = JSON.parse(last_response.body)['errors'] |
||||
parsed_errors.should eq([{ 'key' => 'not_authorized', 'messages' => ['You are not authorize to access this resource']}]) |
||||
end |
||||
end |
||||
|
||||
context 'when acting as an anonymous user' do |
||||
before(:each) do |
||||
allow(User).to receive(:current).and_return User.anonymous |
||||
get get_path |
||||
end |
||||
|
||||
it 'should respond with 401' do |
||||
last_response.status.should eq(401) |
||||
end |
||||
|
||||
it 'should respond with explanatory error message' do |
||||
parsed_errors = JSON.parse(last_response.body)['errors'] |
||||
parsed_errors.should eq([{ 'key' => 'not_authenticated', 'messages' => ['You need to be authenticated to access this resource']}]) |
||||
end |
||||
end |
||||
|
||||
end |
||||
end |
Loading…
Reference in new issue