Fix: Webdav sometimes called without scope or type is actually a lock extension
Fix: Controller did not properly search lock attributes because of gem bug
This commit is contained in:
parent
e3831b409f
commit
6a9fa3236f
@ -26,8 +26,21 @@ module RedmineDmsf
|
||||
existing = locks(false)
|
||||
raise DmsfLockError.new("Unable to complete lock - resource (or parent) is locked") if self.locked? && existing.empty?
|
||||
unless existing.empty?
|
||||
if existing[0].scope == :scope_exclusive
|
||||
raise DmsfLockError.new("Unable to complete lock - resource (or parent) is locked")
|
||||
if existing[0].lock_scope == :scope_exclusive
|
||||
# If it's an exclusive lock and you're re-requesting the actual desired behaviour is to not return a new lock,
|
||||
# but the same lock (extended)
|
||||
if self.folder.locked?
|
||||
raise DmsfLockError.new("Unable to complete lock - resource parent is locked")
|
||||
else
|
||||
if existing[0].user.id == User.current.id then
|
||||
l = existing[0]
|
||||
l.expires_at = expire
|
||||
l.save!
|
||||
return l
|
||||
else
|
||||
raise DmsfLockError.new("Unable to complete lock - resource is locked")
|
||||
end
|
||||
end
|
||||
else
|
||||
raise DmsfLockError.new("unable to exclusively lock a shared-locked resource") if scope == :scope_exclusive
|
||||
end
|
||||
|
||||
@ -29,6 +29,23 @@ module RedmineDmsf
|
||||
OK
|
||||
end
|
||||
|
||||
# This is just pain DIRTY
|
||||
# to fix some gem bugs we're overriding their controller
|
||||
def lock
|
||||
begin
|
||||
request.env['Timeout'] = request.env['HTTP_TIMEOUT'].split('-',2).join(',') unless request.env['HTTP_TIMEOUT'].nil?
|
||||
rescue
|
||||
#Nothing here
|
||||
end
|
||||
|
||||
request_document.remove_namespaces! if ns.empty?
|
||||
# We re-imlement the function ns - if its return is empty, there are no usable namespaces
|
||||
# so to prevent never returning data, we stip all namespaces
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
#Overload the default propfind function with this
|
||||
def propfind
|
||||
unless(resource.exist?)
|
||||
@ -63,6 +80,16 @@ module RedmineDmsf
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def ns(opt_head = '')
|
||||
_ns = opt_head
|
||||
if(request_document && request_document.root && request_document.root.namespace_definitions.size > 0)
|
||||
_ns = request_document.root.namespace_definitions.first.prefix.to_s
|
||||
_ns += ':' unless _ns.empty?
|
||||
end
|
||||
_ns.empty? ? opt_head : _ns
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -397,7 +397,7 @@ module RedmineDmsf
|
||||
|
||||
# Lock
|
||||
def lock(args)
|
||||
return Conflict unless (parent.projectless_path == "/" || parent_exists?) && !collection?
|
||||
return Conflict unless (parent.projectless_path == "/" || parent_exists?)
|
||||
token = UUIDTools::UUID.md5_create(UUIDTools::UUID_URL_NAMESPACE, projectless_path).to_s
|
||||
lock_check(args[:scope])
|
||||
entity = file? ? file : folder
|
||||
@ -405,10 +405,40 @@ module RedmineDmsf
|
||||
if (entity.locked? && entity.locked_for_user?)
|
||||
raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}")
|
||||
else
|
||||
entity.lock!
|
||||
|
||||
# If scope and type are not defined, the only thing we can
|
||||
# logically assume is that the lock is being refreshed (office loves
|
||||
# to do this for example, so we do a few checks, try to find the lock
|
||||
# and ultimately extend it, otherwise we return Conflict for any failure
|
||||
if (!args[:scope] && !args[:type]) #Perhaps a lock refresh
|
||||
http_if = request.env['HTTP_IF']
|
||||
|
||||
return Conflict if http_if.nil?
|
||||
|
||||
http_if = http_if.slice(1, http_if.length - 2)
|
||||
|
||||
return Conflict unless http_if == token
|
||||
|
||||
entity.lock(false).each {|l|
|
||||
if l.user.id == User.current.id
|
||||
l.expires_at = Time.now + 1.hour
|
||||
l.save!
|
||||
@response['Lock-Token'] = token
|
||||
return [1.hours.to_i, token]
|
||||
end
|
||||
}
|
||||
|
||||
#Unfortunately if we're here, then it's updating a lock we can't find
|
||||
|
||||
return Conflict
|
||||
end
|
||||
|
||||
scope = "scope_#{(args[:scope] || "exclusive")}".to_sym
|
||||
type = "type_#{(args[:type] || "write")}".to_sym
|
||||
|
||||
entity.lock! scope, type, Time.now + 1.hours
|
||||
@response['Lock-Token'] = token
|
||||
Locked
|
||||
[8600, token]
|
||||
[1.hours.to_i, token]
|
||||
end
|
||||
rescue DmsfLockError
|
||||
raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}")
|
||||
@ -433,7 +463,7 @@ module RedmineDmsf
|
||||
entity.unlock!
|
||||
NoContent
|
||||
end
|
||||
resue
|
||||
rescue
|
||||
Forbidden
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user