From f120b04b30cd23454886dbc83c921f4434fdcd91 Mon Sep 17 00:00:00 2001 From: Daniel Munn Date: Wed, 27 Jun 2012 07:51:46 +0100 Subject: [PATCH] Webdav updated to support folder locking (shared locking not yet implemented) --- CHANGELOG.md | 1 + lib/redmine_dmsf/webdav/dmsf_resource.rb | 42 +++++++++++++++--------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc4335df..dd61c9c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Changelog for Redmine DMSF * New: Folders are now write lockable (shared and exclusively) * New: Locks can now have a time-limit * New: Inereted lock support (locked folders child entries are now flagged as locked) +* Fix: Some testcases erroniously passed when files are locked, when they should be unlocked 1.4.3: *2012-06-26* ----------------- diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index 23dc9a9f..6e1d58e7 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -384,29 +384,34 @@ module RedmineDmsf end # Lock Check - # Check for the existance of locks of files (Folders unsupported) + # Check for the existance of locks # At present as deletions of folders are not recursive, we do not need to extend # this to cover every file, just queried - # TODO: Allow recursive deletions and update lock code appropriately def lock_check(lock_scope=nil) if file? raise Locked if file.locked_for_user? + elsif folder? + raise Locked if folder.locked_for_user? end end # Lock - # Locks a file entity only (DMSF Folders do not support locking) def lock(args) - return Conflict unless (parent.projectless_path == "/" || parent_exists?) && !collection? && file? + return Conflict unless (parent.projectless_path == "/" || parent_exists?) && !collection? token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s lock_check(args[:scope]) - if (file.locked? && file.locked_for_user?) + entity = file? ? file : folder + begin + if (entity.locked? && entity.locked_for_user?) + raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}") + else + entity.lock! + @response['Lock-Token'] = token + Locked + [8600, token] + end + rescue DmsfLockError raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}") - else - file.lock! unless file.locked? - @response['Lock-Token'] = token - Locked - [8600, token] end end @@ -414,17 +419,22 @@ module RedmineDmsf # Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring # ownership of token before permitting unlock def unlock(token) - return NoContent unless file? + return NoContent unless exist? token=token.slice(1, token.length - 2) if (token.nil? || token.empty? || User.current.anonymous?) BadRequest else - _token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s - if (!file.locked? || file.locked_for_user? || token != _token) + begin + _token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s + entity = file? ? file : folder + if (!entity.locked? || entity.locked_for_user? || token != _token) + Forbidden + else + entity.unlock! + NoContent + end + resue Forbidden - else - file.unlock! - NoContent end end end