diff --git a/lib/api/v3/projects/available_work_packages_api.rb b/lib/api/v3/projects/available_work_packages_api.rb index 9cd00f24c1..1e357b44f1 100644 --- a/lib/api/v3/projects/available_work_packages_api.rb +++ b/lib/api/v3/projects/available_work_packages_api.rb @@ -42,13 +42,13 @@ module API helpers ::API::V3::WorkPackages::WorkPackagesSharedHelpers post do - @work_package = WorkPackage.new(project: @project, - author: current_user, - created_at: Time.now) - @work_package.type = Type.where(is_default: true).first - @work_package.save(validate: false) + hash = { + project: @project, + author: current_user, + type: Type.where(is_default: true).first + } + @work_package = @project.add_work_package(hash) write_work_package_attributes - @work_package.lock_version = 1 send_notifications = !(params.has_key?(:notify) && params[:notify] == 'false') update_service = UpdateWorkPackageService.new(current_user, @@ -57,7 +57,7 @@ module API send_notifications, WorkPackageObserver) - if write_request_valid? && update_service.save + if write_request_valid?(WorkPackages::CreateContract) && update_service.save @work_package.reload WorkPackages::WorkPackageRepresenter.create(@work_package, diff --git a/lib/api/v3/work_packages/work_package_contract.rb b/lib/api/v3/work_packages/base_contract.rb similarity index 86% rename from lib/api/v3/work_packages/work_package_contract.rb rename to lib/api/v3/work_packages/base_contract.rb index 2b4f2a052f..a892dcf773 100644 --- a/lib/api/v3/work_packages/work_package_contract.rb +++ b/lib/api/v3/work_packages/base_contract.rb @@ -30,7 +30,7 @@ module API module V3 module WorkPackages - class WorkPackageContract < ::API::Contracts::ModelContract + class BaseContract < ::API::Contracts::ModelContract attribute :subject attribute :description attribute :start_date, :due_date @@ -39,10 +39,7 @@ module API attribute :priority_id attribute :category_id attribute :fixed_version_id - - attribute :lock_version do - errors.add :error_conflict, '' if model.lock_version.nil? || model.lock_version_changed? - end + attribute :lock_version attribute :parent_id do if model.changed.include? 'parent_id' @@ -100,7 +97,6 @@ module API @can = WorkPackagePolicy.new(user) end - validate :user_allowed_to_access validate :user_allowed_to_edit extend Reform::Form::ActiveModel::ModelValidations @@ -108,15 +104,6 @@ module API private - # TODO: when someone every fixes the way errors are added in the contract: - # find a solution to ensure that THIS validation supersedes others (i.e. show 404 if - # there is no access allowed) - def user_allowed_to_access - unless ::WorkPackage.visible(@user).exists?(model) - errors.add :error_not_found, I18n.t('api_v3.errors.code_404') - end - end - def user_allowed_to_edit errors.add :error_unauthorized, '' unless @can.allowed?(model, :edit) end diff --git a/lib/api/v3/work_packages/create_contract.rb b/lib/api/v3/work_packages/create_contract.rb new file mode 100644 index 0000000000..f742e83541 --- /dev/null +++ b/lib/api/v3/work_packages/create_contract.rb @@ -0,0 +1,42 @@ +#-- 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 WorkPackages + class CreateContract < BaseContract + # These attributes need to be set during creation and cannot be modified via representer. + # Hence making them writable here is unproblematic. + attribute :project_id + attribute :author_id + end + end + end +end + diff --git a/lib/api/v3/work_packages/form/form_api.rb b/lib/api/v3/work_packages/form/form_api.rb index 4cd145cb0e..7d24a0ccc1 100644 --- a/lib/api/v3/work_packages/form/form_api.rb +++ b/lib/api/v3/work_packages/form/form_api.rb @@ -35,7 +35,7 @@ module API class FormAPI < ::API::OpenProjectAPI post '/form' do write_work_package_attributes(reset_lock_version: true) - write_request_valid? + write_request_valid?(UpdateContract) #TODO choose contract according to context error = ::API::Errors::ErrorBase.create(@work_package.errors) diff --git a/lib/api/v3/work_packages/update_contract.rb b/lib/api/v3/work_packages/update_contract.rb new file mode 100644 index 0000000000..0b495af004 --- /dev/null +++ b/lib/api/v3/work_packages/update_contract.rb @@ -0,0 +1,54 @@ +#-- 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 WorkPackages + class UpdateContract < BaseContract + attribute :lock_version do + errors.add :error_conflict, '' if model.lock_version.nil? || model.lock_version_changed? + end + + validate :user_allowed_to_access + + private + + # TODO: when someone every fixes the way errors are added in the contract: + # find a solution to ensure that THIS validation supersedes others (i.e. show 404 if + # there is no access allowed) + def user_allowed_to_access + unless ::WorkPackage.visible(@user).exists?(model) || true + errors.add :error_not_found, I18n.t('api_v3.errors.code_404') + end + end + end + end + end +end + diff --git a/lib/api/v3/work_packages/work_packages_api.rb b/lib/api/v3/work_packages/work_packages_api.rb index cd0baa5585..cc5516c361 100644 --- a/lib/api/v3/work_packages/work_packages_api.rb +++ b/lib/api/v3/work_packages/work_packages_api.rb @@ -69,7 +69,7 @@ module API nil, send_notifications) - if write_request_valid? && update_service.save + if write_request_valid?(UpdateContract) && update_service.save @work_package.reload work_package_representer diff --git a/lib/api/v3/work_packages/work_packages_shared_helpers.rb b/lib/api/v3/work_packages/work_packages_shared_helpers.rb index 750d49ebf6..8f0edb60d8 100644 --- a/lib/api/v3/work_packages/work_packages_shared_helpers.rb +++ b/lib/api/v3/work_packages/work_packages_shared_helpers.rb @@ -26,7 +26,7 @@ # See doc/COPYRIGHT.rdoc for more details. #++ -require 'api/v3/work_packages/work_package_contract' +require 'api/v3/work_packages/base_contract' require 'api/v3/work_packages/form/work_package_payload_representer' module API @@ -61,8 +61,8 @@ module API end end - def write_request_valid? - contract = WorkPackageContract.new(@work_package, current_user) + def write_request_valid?(contract_class) + contract = contract_class.new(@work_package, current_user) contract_valid = contract.validate represented_valid = @work_package.valid? diff --git a/spec/lib/api/v3/work_packages/work_package_contract_spec.rb b/spec/lib/api/v3/work_packages/work_package_contract_spec.rb index 57fe255092..944d76f838 100644 --- a/spec/lib/api/v3/work_packages/work_package_contract_spec.rb +++ b/spec/lib/api/v3/work_packages/work_package_contract_spec.rb @@ -28,7 +28,7 @@ require 'spec_helper' -describe ::API::V3::WorkPackages::WorkPackageContract do +describe ::API::V3::WorkPackages::BaseContract do let(:work_package) do FactoryGirl.create(:work_package, done_ratio: 50,