Add all WebDavRequest classes

This commit is contained in:
Brandon Robins
2017-10-28 12:01:30 -05:00
parent ded6f77f1a
commit 8522d872fc
11 changed files with 242 additions and 0 deletions

View File

@@ -11,6 +11,16 @@ require 'calligraphy/resource'
require 'calligraphy/file_resource'
require 'calligraphy/web_dav_request'
require 'calligraphy/copy'
require 'calligraphy/delete'
require 'calligraphy/get'
require 'calligraphy/lock'
require 'calligraphy/mkcol'
require 'calligraphy/move'
require 'calligraphy/propfind'
require 'calligraphy/proppatch'
require 'calligraphy/put'
require 'calligraphy/unlock'
module Calligraphy
DAV_NS = 'DAV:'

37
lib/calligraphy/copy.rb Normal file
View File

@@ -0,0 +1,37 @@
module Calligraphy
class Copy < WebDavRequest
def request
options = copy_move_options
can_copy = @resource.can_copy? options
if can_copy[:ancestor_exist]
return :precondition_failed
else
return :conflict
end unless can_copy[:can_copy]
return :locked if can_copy[:locked]
overwritten = @resource.copy options
return overwritten ? :no_content : :created
end
private
def copy_move_options
{
depth: @headers['Depth'],
destination: remove_trailing_slash(destination_header),
overwrite: @headers['Overwrite'] || true
}
end
def destination_header
@headers['Destination'].split(@headers['Host'])[-1]
end
def remove_trailing_slash(input)
input[-1] == '/' ? input[0..-2] : input
end
end
end

17
lib/calligraphy/delete.rb Normal file
View File

@@ -0,0 +1,17 @@
module Calligraphy
class Delete < WebDavRequest
def request
return :locked if @resource.locked_to_user? @headers
if @resource.collection?
@resource.delete_collection
return :no_content
else
return :not_found unless @resource.exists?
end
return :no_content
end
end
end

12
lib/calligraphy/get.rb Normal file
View File

@@ -0,0 +1,12 @@
module Calligraphy
class Get < WebDavRequest
def request(head: false)
if @resource.readable?
return :ok if head
return :ok, @resource.read
else
return :not_found
end
end
end
end

52
lib/calligraphy/lock.rb Normal file
View File

@@ -0,0 +1,52 @@
module Calligraphy
class Lock < WebDavRequest
include Calligraphy::XML::Utils
def request
if @resource.request_body.blank? && !@resource.locked_to_user?(@headers)
lock_properties = @resource.refresh_lock
elsif (@resource.locked? && @resource.lock_is_exclusive?) ||
(@resource.locked_to_user?(@headers) && !xml_contains_shared_lock?)
return :locked
else
resource_exists_beforehand = @resource.exists?
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
end
private
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
lock_type = node.children[0].name if node.name == 'lockscope'
end
lock_type == 'shared'
end
end
end

20
lib/calligraphy/mkcol.rb Normal file
View File

@@ -0,0 +1,20 @@
module Calligraphy
class Mkcol < WebDavRequest
def request
return :method_not_allowed if @resource.exists?
return :conflict unless @resource.ancestor_exist?
return :unsupported_media_type unless @resource.request_body.blank?
@resource.create_collection
set_content_location_header
return :created
end
private
def set_content_location_header
@response.headers['Content-Location'] = @resource.full_request_path
end
end
end

31
lib/calligraphy/move.rb Normal file
View File

@@ -0,0 +1,31 @@
module Calligraphy
class Move < Copy
def request
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
if to_resource.exists?
to_resource.delete_collection
to_resource_existed = true
end
end
copy_status = super
return copy_status if [:precondition_failed, :conflict].include? copy_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
end
end
end
end

View File

@@ -0,0 +1,18 @@
module Calligraphy
class Propfind < WebDavRequest
include Calligraphy::XML::Utils
def request
xml = xml_for body: body, node: 'propfind'
return :bad_request if xml == :bad_request
properties = @resource.propfind xml
builder = xml_builder
xml_res = builder.propfind_res @resource.full_request_path, properties
set_xml_content_type
return :multi_status, xml_res
end
end
end

View File

@@ -0,0 +1,20 @@
module Calligraphy
class Proppatch < WebDavRequest
include Calligraphy::XML::Utils
def request
return :locked if @resource.locked_to_user? @headers
xml = xml_for body: body, node: 'propertyupdate'
return :bad_request if xml == :bad_request
actions = @resource.proppatch xml
builder = xml_builder
xml_res = builder.proppatch_res @resource.full_request_path, actions
set_xml_content_type
return :multi_status, xml_res
end
end
end

12
lib/calligraphy/put.rb Normal file
View File

@@ -0,0 +1,12 @@
module Calligraphy
class Put < WebDavRequest
def request
return :locked if @resource.locked_to_user? headers
return :method_not_allowed if @resource.collection?
@resource.write
return :created, @resource.contents
end
end
end

13
lib/calligraphy/unlock.rb Normal file
View File

@@ -0,0 +1,13 @@
module Calligraphy
class Unlock < WebDavRequest
def request
return :bad_request if @headers['Lock-Token'].nil?
@resource.unlock lock_token_header
end
def lock_token_header
@headers['Lock-Token'].gsub Calligraphy::LOCK_TOKEN_ANGLE_REGEX, ''
end
end
end