Instead of having one options/head method in each resource call the options/head method in the superclass.

This commit is contained in:
COLA@Redminetest 2016-11-08 22:53:41 +01:00
parent 94369569f3
commit 6bbe6fc3cc
6 changed files with 50 additions and 83 deletions

View File

@ -61,7 +61,7 @@ module RedmineDmsf
end
# Generate HTML for Get requests, or Head requests if no_body is true
def html_display(no_body = false)
def html_display
@response.body = ''
Confict unless collection?
entities = children.map{|child|
@ -80,7 +80,7 @@ module RedmineDmsf
'',
'',
] + entities if parent
@response.body << index_page % [ path.empty? ? '/' : path, path.empty? ? '/' : path, entities ] unless no_body
@response.body << index_page % [ path.empty? ? '/' : path, path.empty? ? '/' : path, entities ]
end
# Run method through proxy class - ensuring always compatible child is generated

View File

@ -29,31 +29,43 @@ module RedmineDmsf
# Return response to OPTIONS
def options
# exist? returns false if user is anonymous for ProjectResource and DmsfResource, but not for IndexResource.
unless(resource.exist? || (User.current && User.current.anonymous?))
# Return NotFound if resource does not exist and the request is not anonymous.
NotFound
if resource.exist?
# resource exists and user is not anonymous.
super
elsif resource.really_exist? &&
!request.user_agent.nil? && request.user_agent.downcase.include?('microsoft office') &&
User.current && User.current.anonymous?
# resource actually exist, but this was an anonymous request from MsOffice so respond with 405,
# hopefully the resource did actually exist but failed because of anon.
# If responding with 401 then MsOffice will fail.
# If responding with 200 then MsOffice will think that anonymous access is ok for everything.
# Responding with 405 is a workaround found in https://support.microsoft.com/en-us/kb/2019105
MethodNotAllowed
else
if !request.user_agent.nil? && request.user_agent.downcase.include?('microsoft office') && User.current && User.current.anonymous?
# Anonymous request from MsOffice, respond 405.
# If responding with 401 then MsOffice will fail.
# If responding with 200 then MsOffice will think that anonymous access is ok for everything.
# Responding with 405 is a workaround found in https://support.microsoft.com/en-us/kb/2019105
MethodNotAllowed
else
resource.options
end
# Return NotFound if resource does not exist and the request is not anonymous from MsOffice
NotFound
end
end
# Return response to HEAD
def head
# exist? returns false if user is anonymous for ProjectResource and DmsfResource, but not for IndexResource.
unless(resource.exist? || (!request.user_agent.nil? && request.user_agent.downcase.include?('microsoft office') && User.current && User.current.anonymous?))
# Return NotFound if resource does not exist and the request is not from an anonymous MsOffice product.
NotFound
if resource.exist?
# resource exists and user is not anonymous.
super
elsif resource.really_exist? &&
!request.user_agent.nil? && request.user_agent.downcase.include?('microsoft office') &&
User.current && User.current.anonymous?
# resource said it don't exist, but this was an anonymous request from MsOffice so respond anyway
# Can not call super here since it calls resource.exist? which will fail
response['Etag'] = resource.etag
response['Content-Type'] = resource.content_type
response['Last-Modified'] = resource.last_modified.httpdate
OK
else
resource.head(request, response)
end
# Return NotFound if resource does not exist and the request is not anonymous from MsOffice
NotFound
end
end
# Return response to PROPFIND

View File

@ -75,6 +75,10 @@ module RedmineDmsf
(User.current.admin? || User.current.allowed_to?(:view_dmsf_folders, project))
end
def really_exist?
return project && project.module_enabled?('dmsf') && (folder || file)
end
# Is this entity a folder?
def collection?
folder.present? # No need to check if entity exists, as false is returned if entity does not exist anyways
@ -194,23 +198,6 @@ module RedmineDmsf
OK
end
# Process incoming HEAD request
#
# MsOFfice uses anonymous HEAD requests, so always return a response.
# See https://support.microsoft.com/en-us/kb/2019105
##
def head(request, response)
raise NotFound unless project && project.module_enabled?('dmsf') && (folder || file)
if collection?
html_display(true)
response['Content-Length'] = response.body.bytesize.to_s
else
response.body = ''
end
OK
end
# Process incoming MKCOL request
#
# Create a DmsfFolder at location requested, only if parent is a folder (or root)
@ -629,13 +616,6 @@ module RedmineDmsf
end
end
def options_req
response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK'
response["Dav"] = '1, 2'
response["Ms-Author-Via"] = "DAV"
OK
end
private
# Prepare file for download using Rack functionality:
# Download (see RedmineDmsf::Webdav::Download) extends Rack::File to allow single-file

View File

@ -55,6 +55,11 @@ module RedmineDmsf
def exist?
true
end
# Index resource ALWAYS really exists
def really_exist?
true
end
def etag
sprintf('%x-%x-%x', children.count, 4096, Time.now.to_i)
@ -68,26 +73,12 @@ module RedmineDmsf
4096
end
def head(request, response)
html_display(true)
response['Content-Length'] = response.body.bytesize.to_s
OK
end
def get(request, response)
html_display
response['Content-Length'] = response.body.bytesize.to_s
OK
end
def options_req
response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK'
#response["Allow"] = 'OPTIONS,PROPFIND'
response["Dav"] = '1, 2'
response["Ms-Author-Via"] = "DAV"
OK
end
# Bugfix: Ensure that this level never indicates a parent
def parent
nil

View File

@ -44,6 +44,12 @@ module RedmineDmsf
User.current.admin? || User.current.allowed_to?(:view_dmsf_folders, project)
end
def really_exist?
return false if project.nil?
return false unless project.module_enabled?('dmsf')
true
end
def collection?
exist?
end
@ -80,30 +86,12 @@ module RedmineDmsf
4096
end
def head(request, response)
# HEAD must be allowed even for anonymous users, so just verify that the project exists and that the dmsf module is enabled.
if project.nil? || !project.module_enabled?('dmsf')
NotFound
else
html_display(true)
response['Content-Length'] = response.body.bytesize.to_s
OK
end
end
def get(request, response)
html_display
response['Content-Length'] = response.body.bytesize.to_s
OK
end
def options_req
response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK'
response["Dav"] = '1, 2'
response["Ms-Author-Via"] = "DAV"
OK
end
def folder
nil
end

View File

@ -81,6 +81,10 @@ module RedmineDmsf
@resource_c.exist?
end
def really_exist?
@resource_c.really_exist?
end
def creation_date
@resource_c.creation_date
end
@ -105,10 +109,6 @@ module RedmineDmsf
@resource_c.content_length
end
def head(request,response)
@resource_c.head(request, response)
end
def get(request, response)
@resource_c.get(request, response)
end
@ -168,10 +168,6 @@ module RedmineDmsf
def properties
@resource_c.properties
end
def options
@resource_c.options_req
end
end
end
end