Webdav updated to support folder locking (shared locking not yet implemented)

This commit is contained in:
Daniel Munn 2012-06-27 07:51:46 +01:00
parent e1fdc030e6
commit f120b04b30
2 changed files with 27 additions and 16 deletions

View File

@ -7,6 +7,7 @@ Changelog for Redmine DMSF
* New: Folders are now write lockable (shared and exclusively) * New: Folders are now write lockable (shared and exclusively)
* New: Locks can now have a time-limit * New: Locks can now have a time-limit
* New: Inereted lock support (locked folders child entries are now flagged as locked) * 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* 1.4.3: *2012-06-26*
----------------- -----------------

View File

@ -384,29 +384,34 @@ module RedmineDmsf
end end
# Lock Check # 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 # At present as deletions of folders are not recursive, we do not need to extend
# this to cover every file, just queried # this to cover every file, just queried
# TODO: Allow recursive deletions and update lock code appropriately
def lock_check(lock_scope=nil) def lock_check(lock_scope=nil)
if file? if file?
raise Locked if file.locked_for_user? raise Locked if file.locked_for_user?
elsif folder?
raise Locked if folder.locked_for_user?
end end
end end
# Lock # Lock
# Locks a file entity only (DMSF Folders do not support locking)
def lock(args) 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 token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s
lock_check(args[:scope]) 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}") raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}")
else
file.lock! unless file.locked?
@response['Lock-Token'] = token
Locked
[8600, token]
end end
end end
@ -414,17 +419,22 @@ module RedmineDmsf
# Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring # Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring
# ownership of token before permitting unlock # ownership of token before permitting unlock
def unlock(token) def unlock(token)
return NoContent unless file? return NoContent unless exist?
token=token.slice(1, token.length - 2) token=token.slice(1, token.length - 2)
if (token.nil? || token.empty? || User.current.anonymous?) if (token.nil? || token.empty? || User.current.anonymous?)
BadRequest BadRequest
else else
_token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s begin
if (!file.locked? || file.locked_for_user? || token != _token) _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 Forbidden
else
file.unlock!
NoContent
end end
end end
end end