Rubocop WebDavRequest classes
This commit is contained in:
@@ -1,19 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for creating a duplicate of the source resource identified
|
||||
# by the request to the destination resource identified by the URI in
|
||||
# the Destination header.
|
||||
class Copy < WebDavRequest
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
options = copy_move_options
|
||||
can_copy = @resource.can_copy? options
|
||||
|
||||
if can_copy[:ancestor_exist]
|
||||
return :precondition_failed
|
||||
else
|
||||
unless can_copy[:can_copy]
|
||||
return :precondition_failed if can_copy[:ancestor_exist]
|
||||
return :conflict
|
||||
end unless can_copy[:can_copy]
|
||||
end
|
||||
|
||||
return :locked if can_copy[:locked]
|
||||
|
||||
overwritten = @resource.copy options
|
||||
return overwritten ? :no_content : :created
|
||||
overwritten ? :no_content : :created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for deleting the resource identified by the request.
|
||||
class Delete < WebDavRequest
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :locked if @resource.locked_to_user? @headers
|
||||
|
||||
if @resource.collection?
|
||||
@@ -11,7 +15,7 @@ module Calligraphy
|
||||
return :not_found unless @resource.exists?
|
||||
end
|
||||
|
||||
return :no_content
|
||||
:no_content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for retrieving whatever information is identified by the
|
||||
# request.
|
||||
class Get < WebDavRequest
|
||||
def request(head: false)
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute(head: false)
|
||||
if @resource.readable?
|
||||
return :ok if head
|
||||
return :ok, @resource.read
|
||||
|
||||
[:ok, @resource.read]
|
||||
else
|
||||
return :not_found
|
||||
:not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,45 +1,53 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for taking out a lock of any access type and refreshing
|
||||
# existing locks.
|
||||
class Lock < WebDavRequest
|
||||
include Calligraphy::XML::Utils
|
||||
|
||||
def request
|
||||
if @resource.request_body.blank? && !@resource.locked_to_user?(@headers)
|
||||
attr_reader :resource_exists
|
||||
|
||||
def initialize(headers:, request:, response:, resource:)
|
||||
super
|
||||
|
||||
# Determine is resource already exists before lock operation.
|
||||
@resource_exists = @resource.exists?
|
||||
end
|
||||
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
if refresh_lock?
|
||||
lock_properties = @resource.refresh_lock
|
||||
elsif (@resource.locked? && @resource.lock_is_exclusive?) ||
|
||||
(@resource.locked_to_user?(@headers) && !xml_contains_shared_lock?)
|
||||
elsif resource_locked?
|
||||
return :locked
|
||||
else
|
||||
resource_exists_beforehand = @resource.exists?
|
||||
|
||||
# The `lockinfo` tag is used to specify the type of lock the client
|
||||
# wishes to have created.
|
||||
xml = xml_for body: body, node: 'lockinfo'
|
||||
return :bad_request if xml == :bad_request
|
||||
|
||||
lock_properties = @resource.lock xml, @headers['Depth']
|
||||
end
|
||||
|
||||
builder = xml_builder
|
||||
xml_res = builder.lock_res lock_properties
|
||||
|
||||
lock_token = lock_properties[-1]
|
||||
.select { |x| x.name == 'locktoken' }[0]
|
||||
.children[0]
|
||||
.text
|
||||
|
||||
response.headers['Lock-Token'] = "<#{lock_token}>"
|
||||
set_xml_content_type
|
||||
|
||||
if resource_exists_beforehand
|
||||
return :ok, xml_res
|
||||
else
|
||||
return :created, xml_res
|
||||
end
|
||||
build_response lock_properties
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def refresh_lock?
|
||||
@resource.request_body.blank? && !@resource.locked_to_user?(@headers)
|
||||
end
|
||||
|
||||
def resource_locked?
|
||||
(@resource.locked? && @resource.lock_is_exclusive?) ||
|
||||
(@resource.locked_to_user?(@headers) && !xml_contains_shared_lock?)
|
||||
end
|
||||
|
||||
def xml_contains_shared_lock?
|
||||
lock_type = nil
|
||||
xml = xml_for body: body, node: 'lockinfo'
|
||||
|
||||
xml.each do |node|
|
||||
next unless node.is_a? Nokogiri::XML::Element
|
||||
|
||||
@@ -48,5 +56,33 @@ module Calligraphy
|
||||
|
||||
lock_type == 'shared'
|
||||
end
|
||||
|
||||
def build_response(lock_properties)
|
||||
builder = xml_builder
|
||||
xml_res = builder.lock_res lock_properties
|
||||
|
||||
lock_token = extract_lock_token lock_properties
|
||||
prepare_response_headers lock_token
|
||||
|
||||
response_status xml_res
|
||||
end
|
||||
|
||||
def extract_lock_token(properties)
|
||||
properties[-1]
|
||||
.select { |x| x.name == 'locktoken' }[0]
|
||||
.children[0]
|
||||
.text
|
||||
end
|
||||
|
||||
def prepare_response_headers(lock_token)
|
||||
response.headers['Lock-Token'] = "<#{lock_token}>"
|
||||
|
||||
set_xml_content_type
|
||||
end
|
||||
|
||||
def response_status(xml_res)
|
||||
return :ok, xml_res if @resource_exists
|
||||
[:created, xml_res]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for creating a new collection resource at the location
|
||||
# specified by the request.
|
||||
class Mkcol < WebDavRequest
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :method_not_allowed if @resource.exists?
|
||||
return :conflict unless @resource.ancestor_exist?
|
||||
return :unsupported_media_type unless @resource.request_body.blank?
|
||||
@@ -8,7 +13,7 @@ module Calligraphy
|
||||
@resource.create_collection
|
||||
set_content_location_header
|
||||
|
||||
return :created
|
||||
:created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,31 +1,56 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for copying a resource then deleting the original source.
|
||||
class Move < Copy
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :locked if @resource.locked_to_user? @headers
|
||||
|
||||
options = copy_move_options
|
||||
|
||||
if @resource.is_true? options[:overwrite]
|
||||
to_path = options[:destination].tap { |s| s.slice! @resource.mount_point }
|
||||
to_resource = @resource.class.new resource: to_path, req: @request, root_dir: @resource.root_dir
|
||||
|
||||
if to_resource.exists?
|
||||
to_resource.delete_collection
|
||||
to_resource_existed = true
|
||||
end
|
||||
previous_resource_existed = overwrite_destination
|
||||
end
|
||||
|
||||
copy_status = super
|
||||
return copy_status if [:precondition_failed, :conflict].include? copy_status
|
||||
status = super
|
||||
return status if %i[precondition_failed conflict].include? status
|
||||
|
||||
@resource.delete_collection
|
||||
|
||||
if copy_status == :created && to_resource_existed
|
||||
return :no_content
|
||||
else
|
||||
response.headers['Location'] = options[:destination] if copy_status == :created
|
||||
return copy_status
|
||||
response_status status, previous_resource_existed
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def options
|
||||
copy_move_options
|
||||
end
|
||||
|
||||
def overwrite_destination
|
||||
to_path = options[:destination].tap { |s| s.slice! @resource.mount_point }
|
||||
to_resource = destination_resource to_path
|
||||
|
||||
if to_resource.exists?
|
||||
to_resource.delete_collection
|
||||
previous_resource_existed = true
|
||||
end
|
||||
|
||||
previous_resource_existed
|
||||
end
|
||||
|
||||
def destination_resource(to_path)
|
||||
@resource.class.new(
|
||||
resource: to_path,
|
||||
req: @request,
|
||||
root_dir: @resource.root_dir
|
||||
)
|
||||
end
|
||||
|
||||
def response_status(status, previous_resource)
|
||||
return :no_content if status == :created && previous_resource
|
||||
|
||||
response.headers['Location'] = options[:destination] if status == :created
|
||||
|
||||
status
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for retrieving properties defined on the resource.
|
||||
class Propfind < WebDavRequest
|
||||
include Calligraphy::XML::Utils
|
||||
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
xml = xml_for body: body, node: 'propfind'
|
||||
return :bad_request if xml == :bad_request
|
||||
|
||||
@@ -12,7 +16,8 @@ module Calligraphy
|
||||
xml_res = builder.propfind_res @resource.full_request_path, properties
|
||||
|
||||
set_xml_content_type
|
||||
return :multi_status, xml_res
|
||||
|
||||
[:multi_status, xml_res]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for processing instructions specified in the request body
|
||||
# to set and/or remove properties defined on the resource.
|
||||
class Proppatch < WebDavRequest
|
||||
include Calligraphy::XML::Utils
|
||||
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :locked if @resource.locked_to_user? @headers
|
||||
|
||||
# The `propertyupdate` tag contains the request to alter properties
|
||||
# on a resource.
|
||||
xml = xml_for body: body, node: 'propertyupdate'
|
||||
return :bad_request if xml == :bad_request
|
||||
|
||||
@@ -14,7 +21,8 @@ module Calligraphy
|
||||
xml_res = builder.proppatch_res @resource.full_request_path, actions
|
||||
|
||||
set_xml_content_type
|
||||
return :multi_status, xml_res
|
||||
|
||||
[:multi_status, xml_res]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for replacing the `Get` response entity of the resource.
|
||||
class Put < WebDavRequest
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :locked if @resource.locked_to_user? @headers
|
||||
return :method_not_allowed if @resource.collection?
|
||||
|
||||
@resource.write
|
||||
|
||||
return :created, @resource.contents
|
||||
[:created, @resource.contents]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Responsible for removing the lock identified by the lock token in the
|
||||
# request header.
|
||||
class Unlock < WebDavRequest
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
return :bad_request if @headers['Lock-Token'].nil?
|
||||
|
||||
@resource.unlock lock_token_header
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Calligraphy
|
||||
# Base class for WebDavRequests.
|
||||
#
|
||||
# `WebDavRequest` exposes the `request` method, which is used by the
|
||||
# `WebDavRequestsController` to execute the WebDAV request for a particular
|
||||
# resource. This class also provides private methods for accessing the
|
||||
# request body, setting response headers, and creating XML responses.
|
||||
class WebDavRequest
|
||||
attr_accessor :resource, :response
|
||||
attr_reader :headers, :request
|
||||
@@ -10,7 +18,8 @@ module Calligraphy
|
||||
@resource = resource
|
||||
end
|
||||
|
||||
def request
|
||||
# Executes the WebDAV request for a particular resource.
|
||||
def execute
|
||||
raise NotImplemented
|
||||
end
|
||||
|
||||
@@ -25,7 +34,9 @@ module Calligraphy
|
||||
end
|
||||
|
||||
def xml_builder
|
||||
Calligraphy::XML::Builder.new server_protocol: @request.env['SERVER_PROTOCOL']
|
||||
protocol = @request.env['SERVER_PROTOCOL']
|
||||
|
||||
Calligraphy::XML::Builder.new server_protocol: protocol
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user