From 7520bc70b8bb6f629fe328f2e43ac3c5213869c3 Mon Sep 17 00:00:00 2001 From: Kyle Drake Date: Sat, 23 Aug 2014 10:56:01 -0500 Subject: [PATCH] implement WebDAV mount support --- Gemfile | 1 + Gemfile.lock | 9 ++++++-- app.rb | 1 - config.ru | 58 +++++++++++++++++++++++++++++++++++++++++++++++++- models/site.rb | 2 ++ 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index bff9dbc3..022c817b 100644 --- a/Gemfile +++ b/Gemfile @@ -21,6 +21,7 @@ gem 'cocaine' gem 'zipruby' gem 'always_verify_ssl_certificates' gem 'sass', require: nil +gem 'dav4rack' platform :mri do gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic diff --git a/Gemfile.lock b/Gemfile.lock index 7c754a5c..042aaf46 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -43,16 +43,20 @@ GEM cocaine (0.5.4) climate_control (>= 0.0.3, < 1.0) coderay (1.1.0) - columnize (0.3.6) + columnize (0.8.9) connection_pool (2.0.0) crack (0.4.2) safe_yaml (~> 1.0.0) + dav4rack (0.3.0) + nokogiri (>= 1.4.2) + rack (>= 1.1.0) + uuidtools (~> 2.1.1) debugger (1.6.6) columnize (>= 0.3.1) debugger-linecache (~> 1.2.0) debugger-ruby_core_source (~> 1.3.2) debugger-linecache (1.2.0) - debugger-ruby_core_source (1.3.2) + debugger-ruby_core_source (1.3.5) docile (1.1.3) erubis (2.7.0) extlib (0.9.16) @@ -211,6 +215,7 @@ DEPENDENCIES bcrypt capybara_minitest_spec cocaine + dav4rack erubis fabrication faker diff --git a/app.rb b/app.rb index 0d24f4e5..77e9151e 100644 --- a/app.rb +++ b/app.rb @@ -692,7 +692,6 @@ post '/site_files/upload' do params[:files].each do |file| results << current_site.store_file(file[:filename], file[:tempfile]) end - current_site.increment_changed_count if results.include?(true) file_upload_response diff --git a/config.ru b/config.ru index c831afe5..128f127c 100644 --- a/config.ru +++ b/config.ru @@ -1,8 +1,64 @@ +require 'rubygems' require './app.rb' require 'sidekiq/web' map('/') { run Sinatra::Application } +map '/webdav' do + + use Rack::Auth::Basic do |username, password| + Site.valid_login? username, password + end + + run lambda {|env| + site = Site[username: env['REMOTE_USER']] + + if env['REQUEST_METHOD'] == 'PUT' + path = env['PATH_INFO'] + tmpfile = Tempfile.new 'davfile', encoding: 'binary' + tmpfile.write env['rack.input'].read + tmpfile.close + + if site.file_size_too_large? tmpfile.size + return [507, {}, ['']] + end + + if Site.valid_file_type?(filename: path, tempfile: tmpfile) + site.store_file path, tmpfile + return [201, {}, ['']] + else + return [415, {}, ['']] + end + end + + if env['REQUEST_METHOD'] == 'MOVE' + tmpfile = Tempfile.new 'moved_file' + tmpfile.close + + destination = env['HTTP_DESTINATION'].match(/^.+\/webdav(.+)$/i).captures.first + + FileUtils.cp site.files_path(env['PATH_INFO']), tmpfile.path + + DB.transaction do + site.store_file destination, tmpfile + site.delete_file env['PATH_INFO'] + end + + return [201, {}, ['']] + end + + if env['REQUEST_METHOD'] == 'DELETE' + site.delete_file env['PATH_INFO'] + return [201, {}, ['']] + end + + res = DAV4Rack::Handler.new( + root: Site.select(:username).where(username: env['REMOTE_USER']).first.files_path, + root_uri_path: '/webdav' + ).call(env) + } +end + map '/sidekiq' do use Rack::Auth::Basic, "Protected Area" do |username, password| raise 'missing sidekiq auth' unless $config['sidekiq_user'] && $config['sidekiq_pass'] @@ -10,4 +66,4 @@ map '/sidekiq' do end run Sidekiq::Web -end +end \ No newline at end of file diff --git a/models/site.rb b/models/site.rb index 5c751e10..c93d258b 100644 --- a/models/site.rb +++ b/models/site.rb @@ -439,6 +439,8 @@ class Site < Sequel::Model screenshots_delete(path) if ext.match HTML_REGEX thumbnails_delete(path) if ext.match IMAGE_REGEX + path = path[1..path.length] if path[0] == '/' + SiteChangeFile.filter(site_id: self.id, filename: path).delete true