MsOffice wants response 405 on anonymous OPTIONS requests.
This commit is contained in:
parent
3812be1cea
commit
e160df298c
@ -28,16 +28,32 @@ module RedmineDmsf
|
||||
|
||||
# Return response to OPTIONS
|
||||
def options
|
||||
# Always return MethodNotAllowed(405) because how MsOffice uses anonymous OPTIONS request.
|
||||
# See https://support.microsoft.com/en-us/kb/2019105
|
||||
MethodNotAllowed
|
||||
# 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
|
||||
else
|
||||
if request.env.has_key?('HTTP_X_OFFICE_MAJOR_VERSION') && 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
|
||||
end
|
||||
end
|
||||
|
||||
# Return response to HEAD
|
||||
def head
|
||||
# Don't check resource.exist? because it returns false for anonymous requests and MsOffice's uses anonymous HEAD requests.
|
||||
# See https://support.microsoft.com/en-us/kb/2019105
|
||||
resource.head(request, response)
|
||||
# exist? returns false if user is anonymous for ProjectResource and DmsfResource, but not for IndexResource.
|
||||
unless(resource.exist? || (request.env.has_key?('HTTP_X_OFFICE_MAJOR_VERSION') && User.current && User.current.anonymous?))
|
||||
# Return NotFound if resource does not exist and the request is not from an anonymous MsOffice product.
|
||||
NotFound
|
||||
else
|
||||
resource.head(request, response)
|
||||
end
|
||||
end
|
||||
|
||||
# Return response to PROPFIND
|
||||
|
||||
@ -201,6 +201,7 @@ module RedmineDmsf
|
||||
##
|
||||
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
|
||||
@ -628,6 +629,13 @@ 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
|
||||
|
||||
@ -80,6 +80,14 @@ module RedmineDmsf
|
||||
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
|
||||
|
||||
@ -81,9 +81,14 @@ module RedmineDmsf
|
||||
end
|
||||
|
||||
def head(request, response)
|
||||
html_display(true)
|
||||
response['Content-Length'] = response.body.bytesize.to_s
|
||||
OK
|
||||
# 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)
|
||||
@ -92,6 +97,13 @@ module RedmineDmsf
|
||||
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
|
||||
|
||||
@ -52,9 +52,12 @@ module RedmineDmsf
|
||||
# seems the next best step, if the request method is OPTIONS return true, controller will simply
|
||||
# call the options method within, which accesses nothing, just returns headers about dav env.
|
||||
#return true if @request.request_method.downcase == 'options' && (path == '/' || path.empty?)
|
||||
# MsOffice does anonymous OPTIONS and HEAD requests.
|
||||
|
||||
# Allow anonymous OPTIONS requests.
|
||||
return true if @request.request_method.downcase == 'options'
|
||||
# Allow anonymous HEAD requests.
|
||||
return true if @request.request_method.downcase == 'head'
|
||||
|
||||
return false unless username && password
|
||||
User.current = User.try_to_login(username, password)
|
||||
return User.current && !User.current.anonymous?
|
||||
@ -164,6 +167,9 @@ module RedmineDmsf
|
||||
@resource_c.properties
|
||||
end
|
||||
|
||||
def options
|
||||
@resource_c.options_req
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user