diff --git a/config/routes.rb b/config/routes.rb index a43cd4c9..3d27b11b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -92,5 +92,6 @@ RedmineApp::Application.routes.draw do # :root => Rails.root.to_s, :root_uri_path => "/dmsf/webdav", :resource_class => RedmineDmsf::Webdav::ResourceProxy, + :controller_class => RedmineDmsf::Webdav::Controller ), :at => "/dmsf/webdav" end diff --git a/init.rb b/init.rb index 6c2f57ca..d9b385e8 100644 --- a/init.rb +++ b/init.rb @@ -17,19 +17,29 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require 'redmine' -#require 'dispatcher' - -#Dispatcher.to_prepare :redmine_dmsf do +require 'redmine_dmsf' + +# +# This may need to be configurable +# +Rails.configuration.middleware.insert_before(ActionDispatch::ParamsParser, + RedmineDmsf::NoParse, :urls => ['/dmsf/webdav']) + + + Rails.configuration.to_prepare do - unless ProjectsHelper.included_modules.include?(ProjectTabsExtended) - ProjectsHelper.send(:include, ProjectTabsExtended) - end + unless ProjectsHelper.included_modules.include?(ProjectTabsExtended) + ProjectsHelper.send(:include, ProjectTabsExtended) + end - unless CustomFieldsHelper.included_modules.include?(CustomFieldsHelper) - CustomFieldsHelper.send(:include, RedmineDmsf::Patches::CustomFieldsHelper) - end + unless CustomFieldsHelper.included_modules.include?(CustomFieldsHelper) + CustomFieldsHelper.send(:include, RedmineDmsf::Patches::CustomFieldsHelper) + end + + Project.send(:include, RedmineDmsf::Patches::ProjectPatch) + + #ActiveSupport::XmlMini.backend = 'Nokogiri' - Project.send(:include, RedmineDmsf::Patches::ProjectPatch) end Redmine::Plugin.register :redmine_dmsf do diff --git a/lib/redmine_dmsf.rb b/lib/redmine_dmsf.rb index 99a6fcb5..7e3e9c12 100644 --- a/lib/redmine_dmsf.rb +++ b/lib/redmine_dmsf.rb @@ -2,6 +2,7 @@ require 'redmine_dmsf/patches/custom_fields_helper' require 'redmine_dmsf/patches/acts_as_customizable' require 'redmine_dmsf/patches/project_patch' require 'redmine_dmsf/webdav' +require 'redmine_dmsf/no_parse' module RedmineDmsf end diff --git a/lib/redmine_dmsf/no_parse.rb b/lib/redmine_dmsf/no_parse.rb new file mode 100644 index 00000000..3dc99238 --- /dev/null +++ b/lib/redmine_dmsf/no_parse.rb @@ -0,0 +1,25 @@ +module RedmineDmsf + class NoParse + def initialize(app, options={}) + @app = app + @urls = options[:urls] + end + + def call(env) + if env['REQUEST_METHOD'] == "PUT" && env.has_key?('CONTENT_TYPE') then + if (@urls.dup.delete_if {|x| !env['PATH_INFO'].starts_with? x}.length > 0) then + logger "RedmineDmsf::NoParse prevented mime parsing for PUT #{env['PATH_INFO']}" + env['CONTENT_TYPE'] = 'text/plain' + end + end + @app.call(env) + end + + private + + def logger(env) + env['action_dispatch.logger'] || Logger.new($stdout) + end + + end +end diff --git a/lib/redmine_dmsf/webdav.rb b/lib/redmine_dmsf/webdav.rb index 05984b5b..93e8f55a 100644 --- a/lib/redmine_dmsf/webdav.rb +++ b/lib/redmine_dmsf/webdav.rb @@ -1,7 +1,7 @@ +# Load up classes that make up our webdav solution ontop +# of DAV4Rack require 'redmine_dmsf/webdav/resource_proxy' - require 'redmine_dmsf/webdav/base_resource' - require 'redmine_dmsf/webdav/index_resource' require 'redmine_dmsf/webdav/project_resource' require 'redmine_dmsf/webdav/dmsf_resource' diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index d1077ea6..7484b088 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -51,6 +51,7 @@ module RedmineDmsf def parent p = @__proxy.parent + return nil if p.nil? return p.resource.nil? ? p : p.resource end diff --git a/lib/redmine_dmsf/webdav/controller.rb b/lib/redmine_dmsf/webdav/controller.rb new file mode 100644 index 00000000..01c18e5a --- /dev/null +++ b/lib/redmine_dmsf/webdav/controller.rb @@ -0,0 +1,49 @@ +module RedmineDmsf + module Webdav + class Controller < DAV4Rack::Controller + + #Overload default options + def options + response["Allow"] = 'OPTIONS,HEAD,GET,PUT,POST,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK' + response["Dav"] = "1,2,3" + response["Ms-Author-Via"] = "DAV" + OK + end + + #Overload the default propfind function with this + def propfind + unless(resource.exist?) + NotFound + else + unless(request_document.xpath("//#{ns}propfind/#{ns}allprop").empty?) + names = resource.property_names + else + names = ( + ns.empty? ? request_document.remove_namespaces! : request_document + ).xpath( + "//#{ns}propfind/#{ns}prop" + ).children.find_all{ |item| + item.element? && item.name.start_with?(ns) + }.map{ |item| + item.name.sub("#{ns}::", '') + } + names = resource.property_names if names.empty? + end + multistatus do |xml| + find_resources.each do |resource| + xml.response do + unless(resource.propstat_relative_path) + xml.href "#{scheme}://#{host}:#{port}#{url_format(resource)}" + else + xml.href url_format(resource) + end + propstats(xml, get_properties(resource, names)) + end + end + end + end + end + + end + end +end diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index c84855fb..9857d6df 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -167,7 +167,6 @@ module RedmineDmsf # # Create a DmsfFolder at location requested, only if parent is a folder (or root) def make_collection - debugger if (request.body.read.to_s == '') return MethodNotAllowed if exist? #If we already exist, why waste the time trying to save? parent_folder = nil diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index 28c7730f..f30a6a16 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -9,6 +9,7 @@ module RedmineDmsf def children #caching for repeat usage return @children unless @children.nil? + return [] if project.nil? || project.id.nil? @children = [] DmsfFolder.project_root_folders(project).map do |p| @children.push child(p.title, p) @@ -65,6 +66,13 @@ module RedmineDmsf OK end + def folder + nil + end + def file + nil + end + end end end diff --git a/lib/redmine_dmsf/webdav/resource_proxy.rb b/lib/redmine_dmsf/webdav/resource_proxy.rb index dcba5ec7..1dbbf884 100644 --- a/lib/redmine_dmsf/webdav/resource_proxy.rb +++ b/lib/redmine_dmsf/webdav/resource_proxy.rb @@ -30,7 +30,7 @@ module RedmineDmsf # going to fork it to ensure compliance, checking the request method in the authentication # 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 false if (@request.request_method.downcase == "options") + return true if ( @request.request_method.downcase == "options" && ( path == "/" || path.empty? ) ) User.current = User.try_to_login(username, password) || nil return !User.current.anonymous? unless User.current.nil? false