Skip to content

Commit

Permalink
Fixed the 'isLocked' method of the 'FileSystem' class to skip privile…
Browse files Browse the repository at this point in the history
…ge checking
  • Loading branch information
AdrienCastex committed Jul 2, 2017
1 parent 25a9529 commit f201b61
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 51 deletions.
3 changes: 2 additions & 1 deletion lib/manager/v2/fileSystem/FileSystem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean>): void;
isLocked(ctx: RequestContext, path: Path | string, callback: ReturnCallback<boolean>): any;
isLocked(ctx: RequestContext, path: Path | string, depth: number, callback: ReturnCallback<boolean>): any;
/**
* Serialize the file system based on the 'this.serializer()' value.
*
Expand Down
77 changes: 48 additions & 29 deletions lib/manager/v2/fileSystem/FileSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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();
});
});
});
};
/**
Expand Down
79 changes: 58 additions & 21 deletions src/manager/v2/fileSystem/FileSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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<boolean>)
isLocked(ctx : RequestContext, path : Path | string, depth : number, callback : ReturnCallback<boolean>)
isLocked(ctx : RequestContext, path : Path | string, _depth : number | ReturnCallback<boolean>, _callback ?: ReturnCallback<boolean>)
{
const callback = _callback ? _callback : _depth as ReturnCallback<boolean>;
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();
})
})
})
}

Expand Down

0 comments on commit f201b61

Please sign in to comment.