module Scrivito class WorkspacesController < WebserviceController def self.restrict_access_to(action_name, require_permission:) around_action only: action_name do |_, block| subject = params.has_key?(:id) ? current_workspace : :workspace authorize_workspace_access(require_permission, subject, &block) end end restrict_access_to :create, require_permission: :create restrict_access_to :show, require_permission: :read restrict_access_to :rename, require_permission: :write restrict_access_to :memberships, require_permission: :invite_to restrict_access_to :destroy, require_permission: :delete restrict_access_to :rebase, require_permission: :write restrict_access_to :check, require_permission: :publish restrict_access_to :publish, require_permission: :publish def index @workspaces = Workspace.all.select(&method(:can_user_read_workspace?)) render :workspaces end def show end def create create_workspace_params = workspace_params.dup unless scrivito_user.system_user? create_workspace_params.deep_merge!(memberships: {scrivito_user.id => {role: 'owner'}}) end result = task_unaware_request(:post, '/workspaces', workspace: create_workspace_params) handle_if_task(result) do @workspace_result = result end end def rename current_workspace.update(workspace_params.slice(:title)) render_empty_json end def memberships current_workspace.update(workspace_params.slice(:memberships)) render_empty_json end def destroy current_workspace.destroy render_empty_json end def rebase @task = task_unaware_request(:put, current_workspace_backend_path('/rebase'), {})['task'] render :task end def check assert_workspace_is_not_outdated @check_result = publish_checker.call(params[:from].to_i) end def publish if valid_publish_request? @task = conditional_publish['task'] render :task else raise_content_state_id_changed end rescue ScrivitoError => e raise ClientError.new(e.message, 400) end private delegate :task_unaware_request, to: CmsRestApi def current_workspace_backend_path(suffix) "/workspaces/#{current_workspace.id}#{suffix}" end def conditional_publish task_unaware_request(:put, current_workspace_backend_path('/publish'), if_content_state_id_equals: current_workspace.content_state_id) end def valid_publish_request? publish_checker.passing_certificates?(certificates_param) end def publish_checker Workspace::PublishChecker.new(current_workspace, scrivito_user) end def current_workspace @current_workspace ||= Workspace.find(params[:id]) end helper_method :current_workspace def workspace_params assert_valid_workspace_params params[:workspace] end def certificates_param assert_valid_certificates_param params[:certificates] end def handle_if_task(result) if result['task'].present? @task = result['task'] render :task else yield result end end def assert_workspace_is_not_outdated if current_workspace.outdated? raise ClientError.new( 'Workspace is outdated', 400, 'precondition_not_verifiable.workspace.publish.content_state_id' ) end end def assert_valid_certificates_param if params[:certificates].blank? raise ClientError.new("Required parameter 'certificates' is missing.", 400) end unless params[:certificates].is_a?(Array) raise ClientError.new("Parameter 'certificates' is not an array.", 400) end end def assert_valid_workspace_params raise "Required parameter 'workspace' is missing." unless params[:workspace].present? raise "Parameter 'workspace' is not a hash." unless params[:workspace].is_a?(Hash) end def raise_content_state_id_changed raise ClientError.new( 'Content state id changed', 400, 'precondition_not_met.workspace.publish.content_state_id' ) end end end