From f201b61fa93c7d485123d6d7bd2584b634771380 Mon Sep 17 00:00:00 2001 From: Adrien Castex Date: Mon, 3 Jul 2017 00:35:28 +0200 Subject: [PATCH] Fixed the 'isLocked' method of the 'FileSystem' class to skip privilege checking --- lib/manager/v2/fileSystem/FileSystem.d.ts | 3 +- lib/manager/v2/fileSystem/FileSystem.js | 77 +++++++++++++--------- src/manager/v2/fileSystem/FileSystem.ts | 79 +++++++++++++++++------ 3 files changed, 108 insertions(+), 51 deletions(-) diff --git a/lib/manager/v2/fileSystem/FileSystem.d.ts b/lib/manager/v2/fileSystem/FileSystem.d.ts index 2d18bb42..3d489683 100644 --- a/lib/manager/v2/fileSystem/FileSystem.d.ts +++ b/lib/manager/v2/fileSystem/FileSystem.d.ts @@ -590,7 +590,8 @@ export declare abstract class FileSystem implements ISerializableFileSystem { * @param path Path of the resource. * @param callback Returns if the resource is locked or not (true = locked, cannot write to it ; false = not locked) or returns an error. */ - isLocked(ctx: RequestContext, path: Path | string, callback: ReturnCallback): void; + isLocked(ctx: RequestContext, path: Path | string, callback: ReturnCallback): any; + isLocked(ctx: RequestContext, path: Path | string, depth: number, callback: ReturnCallback): any; /** * Serialize the file system based on the 'this.serializer()' value. * diff --git a/lib/manager/v2/fileSystem/FileSystem.js b/lib/manager/v2/fileSystem/FileSystem.js index d0a19c1c..456b19e0 100644 --- a/lib/manager/v2/fileSystem/FileSystem.js +++ b/lib/manager/v2/fileSystem/FileSystem.js @@ -812,7 +812,11 @@ var FileSystem = (function () { var depth = _callback ? _depth : 0; var callback = _callback ? _callback : _depth; var pStartPath = new Path_1.Path(startPath); - issuePrivilegeCheck(this, ctx, startPath, 'canReadLocks', callback, function () { + this.checkPrivilege(ctx, startPath, 'canReadLocks', function (e, can) { + if (e) + return callback(e); + if (!can) + return []; _this.lockManager(ctx, pStartPath, function (e, lm) { if (e === Errors_1.Errors.ResourceNotFound) { lm = { @@ -906,37 +910,52 @@ var FileSystem = (function () { context: ctx }, callback); }; - /** - * Get if a resource is locked by another user than the one in the context argument or if the user has rights to write to the resource. - * If the user has locked the resource and there is no conflicting lock, so the resource is considered as "not locked". - * If the user didn't locked the resource and is not administrator, then the resource is considered as "locked". - * - * @param ctx Context of the operation. - * @param path Path of the resource. - * @param callback Returns if the resource is locked or not (true = locked, cannot write to it ; false = not locked) or returns an error. - */ - FileSystem.prototype.isLocked = function (ctx, path, callback) { + FileSystem.prototype.isLocked = function (ctx, path, _depth, _callback) { + var _this = this; + var callback = _callback ? _callback : _depth; + var depth = _callback ? _depth : 0; if (ctx.user && ctx.user.isAdministrator) return callback(null, false); - this.listDeepLocks(ctx, path, function (e, locks) { - if (e) - return callback(e); - if (!ctx.user) - return callback(null, Object.keys(locks).length > 0); - for (var path_1 in locks) - if (locks[path_1].some(function (l) { return ctx.user.uid !== l.userUid && l.lockKind.scope.isSame(LockScope_1.LockScope.Exclusive); })) - return callback(null, true); - var isShared = false; - for (var path_2 in locks) - for (var _i = 0, _a = locks[path_2]; _i < _a.length; _i++) { - var lock = _a[_i]; - if (lock.lockKind.scope.isSame(LockScope_1.LockScope.Shared)) { - isShared = true; - if (lock.userUid === ctx.user.uid) - return callback(null, false); + var pPath = new Path_1.Path(path); + var checkThis = function () { + _this._lockManager(pPath, { context: ctx }, function (e, lm) { + if (e === Errors_1.Errors.ResourceNotFound) + return callback(null, false); + if (e) + return callback(e); + lm.getLocks(function (e, locks) { + if (e === Errors_1.Errors.ResourceNotFound) + return callback(null, false); + if (e) + return callback(e); + locks = locks.filter(function (l) { return l.depth === -1 || l.depth >= depth; }); + if (!ctx.user) + return callback(null, locks.length > 0); + if (locks.some(function (l) { return ctx.user.uid !== l.userUid && l.lockKind.scope.isSame(LockScope_1.LockScope.Exclusive); })) + return callback(null, true); + var isShared = false; + for (var _i = 0, locks_1 = locks; _i < locks_1.length; _i++) { + var lock = locks_1[_i]; + if (lock.lockKind.scope.isSame(LockScope_1.LockScope.Shared)) { + isShared = true; + if (lock.userUid === ctx.user.uid) + return callback(null, false); + } } - } - callback(null, isShared); + callback(null, isShared); + }); + }); + }; + this.getFullPath(ctx, pPath, function (e, fullPath) { + if (fullPath.isRoot()) + return checkThis(); + ctx.server.getFileSystem(pPath.getParent(), function (fs, rootPath, subPath) { + fs.isLocked(ctx, subPath, depth + 1, function (e, locked) { + if (e || locked) + return callback(e, locked); + checkThis(); + }); + }); }); }; /** diff --git a/src/manager/v2/fileSystem/FileSystem.ts b/src/manager/v2/fileSystem/FileSystem.ts index f2685316..0446a894 100644 --- a/src/manager/v2/fileSystem/FileSystem.ts +++ b/src/manager/v2/fileSystem/FileSystem.ts @@ -1329,7 +1329,12 @@ export abstract class FileSystem implements ISerializableFileSystem const callback = _callback ? _callback : _depth as ReturnCallback<{ [path : string] : Lock[] }>; const pStartPath = new Path(startPath); - issuePrivilegeCheck(this, ctx, startPath, 'canReadLocks', callback, () => { + this.checkPrivilege(ctx, startPath, 'canReadLocks', (e, can) => { + if(e) + return callback(e); + if(!can) + return []; + this.lockManager(ctx, pStartPath, (e, lm) => { if(e === Errors.ResourceNotFound) { @@ -1505,34 +1510,66 @@ export abstract class FileSystem implements ISerializableFileSystem * @param callback Returns if the resource is locked or not (true = locked, cannot write to it ; false = not locked) or returns an error. */ isLocked(ctx : RequestContext, path : Path | string, callback : ReturnCallback) + isLocked(ctx : RequestContext, path : Path | string, depth : number, callback : ReturnCallback) + isLocked(ctx : RequestContext, path : Path | string, _depth : number | ReturnCallback, _callback ?: ReturnCallback) { + const callback = _callback ? _callback : _depth as ReturnCallback; + const depth = _callback ? _depth as number : 0; + if(ctx.user && ctx.user.isAdministrator) return callback(null, false); - this.listDeepLocks(ctx, path, (e, locks) => { - if(e) - return callback(e); - - if(!ctx.user) - return callback(null, Object.keys(locks).length > 0); + const pPath = new Path(path); + + const checkThis = () => { + this._lockManager(pPath, { context: ctx }, (e, lm) => { + if(e === Errors.ResourceNotFound) + return callback(null, false); + if(e) + return callback(e); - for(const path in locks) - if(locks[path].some((l) => ctx.user.uid !== l.userUid && l.lockKind.scope.isSame(LockScope.Exclusive))) - return callback(null, true); + lm.getLocks((e, locks) => { + if(e === Errors.ResourceNotFound) + return callback(null, false); + if(e) + return callback(e); - let isShared = false; - for(const path in locks) - for(const lock of locks[path]) - { - if(lock.lockKind.scope.isSame(LockScope.Shared)) + locks = locks.filter((l) => l.depth === -1 || l.depth >= depth); + + if(!ctx.user) + return callback(null, locks.length > 0); + + if(locks.some((l) => ctx.user.uid !== l.userUid && l.lockKind.scope.isSame(LockScope.Exclusive))) + return callback(null, true); + + let isShared = false; + for(const lock of locks) { - isShared = true; - if(lock.userUid === ctx.user.uid) - return callback(null, false); + if(lock.lockKind.scope.isSame(LockScope.Shared)) + { + isShared = true; + if(lock.userUid === ctx.user.uid) + return callback(null, false); + } } - } - - callback(null, isShared); + + callback(null, isShared); + }) + }) + } + + this.getFullPath(ctx, pPath, (e, fullPath) => { + if(fullPath.isRoot()) + return checkThis(); + + ctx.server.getFileSystem(pPath.getParent(), (fs, rootPath, subPath) => { + fs.isLocked(ctx, subPath, depth + 1, (e, locked) => { + if(e || locked) + return callback(e, locked); + + checkThis(); + }) + }) }) }