Skip to content

Commit

Permalink
Merge pull request #78 from shyiko/fs_access
Browse files Browse the repository at this point in the history
Add fs.access binding.
  • Loading branch information
tschaub committed Jan 31, 2016
2 parents ff45a5c + 71edd22 commit e2df8af
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 1 deletion.
30 changes: 30 additions & 0 deletions lib/binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,36 @@ Binding.prototype.lstat = function(filepath, callback) {
});
};

/**
* Tests user permissions.
* @param {string} filepath Path.
* @param {number} mode Mode.
* @param {function(Error)} callback Callback (optional).
*/
Binding.prototype.access = function(filepath, mode, callback) {
maybeCallback(callback, this, function() {
var item = this._system.getItem(filepath);
if (!item) {
throw new FSError('ENOENT', filepath);
}
if (mode && process.getuid && process.getgid) {
var itemMode = item.getMode();
if (item.getUid() === process.getuid()) {
if ((itemMode & (mode * 64)) !== mode * 64) {
throw new FSError('EACCES', filepath);
}
} else if (item.getGid() === process.getgid()) {
if ((itemMode & (mode * 8)) !== mode * 8) {
throw new FSError('EACCES', filepath);
}
} else {
if ((itemMode & mode) !== mode) {
throw new FSError('EACCES', filepath);
}
}
}
});
};

/**
* Not yet implemented.
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ When you require `mock-fs`, Node's own `fs` module is patched to allow the bindi

### `fs` overrides

The following [`fs` functions](http://nodejs.org/api/fs.html) are overridden: `fs.ReadStream`, `fs.Stats`, `fs.WriteStream`, `fs.appendFile`, `fs.appendFileSync`, `fs.chmod`, `fs.chmodSync`, `fs.chown`, `fs.chownSync`, `fs.close`, `fs.closeSync`, `fs.createReadStream`, `fs.createWriteStream`, `fs.exists`, `fs.existsSync`, `fs.fchmod`, `fs.fchmodSync`, `fs.fchown`, `fs.fchownSync`, `fs.fdatasync`, `fs.fdatasyncSync`, `fs.fstat`, `fs.fstatSync`, `fs.fsync`, `fs.fsyncSync`, `fs.ftruncate`, `fs.ftruncateSync`, `fs.futimes`, `fs.futimesSync`, `fs.lchmod`, `fs.lchmodSync`, `fs.lchown`, `fs.lchownSync`, `fs.link`, `fs.linkSync`, `fs.lstatSync`, `fs.lstat`, `fs.mkdir`, `fs.mkdirSync`, `fs.open`, `fs.openSync`, `fs.read`, `fs.readSync`, `fs.readFile`, `fs.readFileSync`, `fs.readdir`, `fs.readdirSync`, `fs.readlink`, `fs.readlinkSync`, `fs.realpath`, `fs.realpathSync`, `fs.rename`, `fs.renameSync`, `fs.rmdir`, `fs.rmdirSync`, `fs.stat`, `fs.statSync`, `fs.symlink`, `fs.symlinkSync`, `fs.truncate`, `fs.truncateSync`, `fs.unlink`, `fs.unlinkSync`, `fs.utimes`, `fs.utimesSync`, `fs.write`, `fs.writeSync`, `fs.writeFile`, and `fs.writeFileSync`.
The following [`fs` functions](http://nodejs.org/api/fs.html) are overridden: `fs.ReadStream`, `fs.Stats`, `fs.WriteStream`, `fs.access`, `fs.accessSync`, `fs.appendFile`, `fs.appendFileSync`, `fs.chmod`, `fs.chmodSync`, `fs.chown`, `fs.chownSync`, `fs.close`, `fs.closeSync`, `fs.createReadStream`, `fs.createWriteStream`, `fs.exists`, `fs.existsSync`, `fs.fchmod`, `fs.fchmodSync`, `fs.fchown`, `fs.fchownSync`, `fs.fdatasync`, `fs.fdatasyncSync`, `fs.fstat`, `fs.fstatSync`, `fs.fsync`, `fs.fsyncSync`, `fs.ftruncate`, `fs.ftruncateSync`, `fs.futimes`, `fs.futimesSync`, `fs.lchmod`, `fs.lchmodSync`, `fs.lchown`, `fs.lchownSync`, `fs.link`, `fs.linkSync`, `fs.lstatSync`, `fs.lstat`, `fs.mkdir`, `fs.mkdirSync`, `fs.open`, `fs.openSync`, `fs.read`, `fs.readSync`, `fs.readFile`, `fs.readFileSync`, `fs.readdir`, `fs.readdirSync`, `fs.readlink`, `fs.readlinkSync`, `fs.realpath`, `fs.realpathSync`, `fs.rename`, `fs.renameSync`, `fs.rmdir`, `fs.rmdirSync`, `fs.stat`, `fs.statSync`, `fs.symlink`, `fs.symlinkSync`, `fs.truncate`, `fs.truncateSync`, `fs.unlink`, `fs.unlinkSync`, `fs.utimes`, `fs.utimesSync`, `fs.write`, `fs.writeSync`, `fs.writeFile`, and `fs.writeFileSync`.

Mock `fs.Stats` objects have the following properties: `dev`, `ino`, `nlink`, `mode`, `size`, `rdev`, `blksize`, `blocks`, `atime`, `ctime`, `mtime`, `birthtime`, `uid`, and `gid`. In addition, all of the `is*()` method are provided (e.g. `isDirectory()`, `isFile()`, et al.).

Expand Down
51 changes: 51 additions & 0 deletions test/lib/binding.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1258,4 +1258,55 @@ describe('Binding', function() {

});

describe('#access()', function() {

it('works if file exists', function() {
var binding = new Binding(system);
var pathname = path.join('mock-dir', 'one-link.txt');
binding.access(pathname);
});

if (process.getuid && process.getgid) {

it('fails in case of insufficient user permissions', function() {
var binding = new Binding(system);
var item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setMode(parseInt('0077', 8));
assert.throws(function() {
binding.access(path.join('mock-dir', 'one.txt'), 1);
}, /EACCES/);
});

it('fails in case of insufficient group permissions', function() {
var binding = new Binding(system);
var item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setUid(process.getuid() + 1);
item.setMode(parseInt('0707', 8));
assert.throws(function() {
binding.access(path.join('mock-dir', 'one.txt'), 2);
}, /EACCES/);
});

it('fails in case of insufficient permissions', function() {
var binding = new Binding(system);
var item = system.getItem(path.join('mock-dir', 'one.txt'));
item.setUid(process.getuid() + 1);
item.setGid(process.getgid() + 1);
item.setMode(parseInt('0771', 8));
assert.throws(function() {
binding.access(path.join('mock-dir', 'one.txt'), 5);
}, /EACCES/);
});

}

it('fails for bogus paths', function() {
var binding = new Binding(system);
assert.throws(function() {
binding.access(path.join('mock-dir', 'bogus'));
}, /ENOENT/);
});

});

});

0 comments on commit e2df8af

Please sign in to comment.