How to test file permissions using node.js? - file

How can I check to see the permissions (read/write/execute) that a running node.js process has on a given file?
I was hoping that the fs.Stats object had some information about permissions but I don't see any. Is there some built-in function that will allow me to do such checks? For example:
var filename = '/path/to/some/file';
if (fs.canRead(filename)) // OK...
if (fs.canWrite(filename)) // OK...
if (fs.canExecute(filename)) // OK...
Surely I don't have to attempt to open the file in each of those modes and handle an error as the negative affirmation, right? There's got to be a simpler way...

I am late, but, I was looking for same reasons as yours and learnt about this.
fs.access is the one you need. It is available from node v0.11.15.
function canWrite(path, callback) {
fs.access(path, fs.W_OK, function(err) {
callback(null, !err);
});
}
canWrite('/some/file/or/folder', function(err, isWritable) {
console.log(isWritable); // true or false
});

There is fs.accessSync(path[, mode]) nicely mentioned:
Synchronously tests a user's permissions for the file or directory specified by path. The mode argument is an optional integer that specifies the accessibility checks to be performed. Check File Access Constants for possible values of mode. It is possible to create a mask consisting of the bitwise OR of two or more values (e.g. fs.constants.W_OK | fs.constants.R_OK).
If any of the accessibility checks fail, an Error will be thrown. Otherwise, the method will return undefined.
Embeded example:
try {
fs.accessSync('etc/passwd', fs.constants.R_OK | fs.constants.W_OK);
console.log('can read/write');
} catch (err) {
console.error('no access!');
}

Checking readability is not so straightforward as languages like PHP make it look by abstracting it in a single library function. A file might be readable to everyone, or only to its group, or only to its owner; if it is not readble to everybody, you will need to check if you are actually a member of the group, or if you are the owner of the file. It is usually much easier and faster (not only to write the code, but also to execute the checks) to try to open the file and handle the error.

How about using a child process?
var cp = require('child_process');
cp.exec('ls -l', function(e, stdout, stderr) {
if(!e) {
console.log(stdout);
console.log(stderr);
// process the resulting string and check for permission
}
});
Not sure though if process and *child_process* share the same permissions.

Related

Having problems making a command that allows people to turn the blacklist on and off

I thought that allowing people to turn my blacklist on and off for their server would be kinda neat, but I didn't find much success so far. Also I was wondering, is it hard to make a command that allows people to add their own words to the blacklist? Here's the code:
let blacklisted = ['bad words here']
let foundInText = false;
for (var i in blacklisted) {
if (message.content.toLowerCase().includes(blacklisted[i].toLowerCase())) foundInText = true;
}
if (foundInText) {
message.delete();
}
});
You could use a variable for turning on or off the blacklist. BacklistOn = true, And use a if statement before the code you copied in here. Then make a command that changes that variable. You would need to store the variable in a JSON file if you want the setting to be saved when restarting the bot or if the bot crashes. Tutorial on reading/writing to JSON with node.js https://medium.com/#osiolabs/read-write-json-files-with-node-js-92d03cc82824

protractor: test download file without knowing filename

I followed this answer and it looks almost the thing I need.
The problem there is that he already knows the filename and I am doing e2e test for downloading a file, but the filename depends on the current time (even with milliseconds) so I don't really know the name (or it would be very difficult to get it).
I think I am missing something very simple here, but I was thinking of two ways:
Recreate filenames (with the same function that returns the name of this file) and start checking for existance of a file with that name, if it doesn't exist, then move to the next millisecond until I hit the right name.
Check the download folder for existance of "any" file, if I find one there then it should be the file I am downloading (for this case I don't know how to check an entire folder in protractor).
Hope you guys could help with these alternatives (I would like some help with point 2) or maybe give me a better one. Thanks
I ended up following #alecxe's suggestion and here is my answer:
var glob = require("glob");
browser.driver.wait(function () {
var filesArray = glob.sync(filePattern);
if (typeof filesArray !== 'undefined' && filesArray.length > 0) {
// this check is necessary because `glob.sync` can return
// an empty list, which will be considered as a valid output
// making the wait to end.
return filesArray;
}
}, timeout).then(function (filesArray) {
var filename = filesArray[0];
// now we have the filename and can do whatever we want
});
Just to add a little bit more background information to the #elRuLL's answer.
The main idea is based on 2 things:
browser.wait() fits the problem perfectly - it would execute a function continuously until it evaluates to true or a timeout is reached. And, the timeout mechanism is already built-in.
glob module provides a way to look for filenames matching a certain pattern (in the worst case, you can wait for the *.* - basically, any file to appear)

Unable to open remote file in Word Online

I am trying to open a base64 encoded file in Word Online, using the code below based on .
function displayContents(myBase64) {
Word.run(function (context) {
console.log(Office.context.requirements.isSetSupported("WordApi", "1.1"));
// Create a proxy object for the document.
var thisDocument = context.document;
// Queue a command to clear the body contents.
thisDocument.body.clear();
thisDocument.body.insertFileFromBase64(myBase64, "replace");
// Create a proxy object for the default selection.
//var mySelection = thisDocument.getSelection();
// Queue a command to insert the file into the current document.
//mySelection.insertFileFromBase64(myBase64, "replace");
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync();
})
.catch(function (error) {
console.log('Error: ' + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
}
This does not work (using body.insertFileFromBase64 or myselection.insertFileFromBase64). The code does function in the regular version of Word. I receive the following error:
Error:
"name":"OfficeExtension.Error",
"code":"GeneralException",
"message":"This browser does not support the requested API.",
"traceMessages":[],"debugInfo":{}}
LoadOfficeDoc.js:51 Debug info: {}
Office.context.requirements.isSetSupported("WordApi", "1.1") returns true.
Am I doing something wrong or is this functionality not available online?
The new Word API (e.g. anything using Word.run) is presently only supported in Word 2016 on Windows (and iPad?)
Though according to the documentation isSetSupported should be returning false.
That's correct, this is actually a bug we are working on right now.
That requirement set is not full supported on WAC hence the method must return false.

php file() triggers no Exception on valid URL

try {
$antwort = file_get_contents('http://not_existing.notnotnot', false);
if($antwort===false) echo 'ERROR';
} catch(Exception $e) {
$e->getMessage();
}
var_dump($antwort); // returns string(0) ""
I get no Exception, no false, just empty content for every URL. A valid URL returns with this snippet the right content. Why can't I get exceptions for an invalid URL?
I came to this question because a wget on the same server leads to a valid return, but with a php script I can't file() the same URL. Really weird and I have no idea how to debug it.
It won't throw an exception if the file isn't found; it will raise a warning-level error. Those are different things. From the docs:
An E_WARNING level error is generated if filename cannot be found, maxlength is less than zero, or if seeking to the specified offset in the stream fails.
You should check for a false return, as you do, and not expect to catch an exception.
Also keep in mind when fetching a URL that the remote server may return an incorrect status code (instead of the expected 404), causing your script to think the file exists when it does not. You may need to check for empty values ("") as well.
As a rule, you should avoid using file_get_contents to access files via HTTP. It's not terribly secure, and many hosts don't even allow you to use it that way. Instead, use cURL, which is specifically designed for retrieving data over the web, including via HTTP.

store all the errors occurred on eval() in PHP

Stack community.
I'm using the eval() function in PHP so my users can execute his own code in my website (Yes, i know it is a dangerous function, but that's not the point).
I want to store all the PHP errors that occur during the interpretation of the code, is there a way to fetch all of them? i want to get and register them in a table of my database.
The error_get_last gets only the last error, but i want all of them.
Help me, please. It is even possible?
General
You cannot use eval() for this, as the evaled code will run in the current context, meaning that the evaled code can overwrite all vars in your context. Beside from security considerations this could / would break functionality. Check this imaginal example:
$mode = 'execute'
// here comes a common code example, it will overwrite `$mode`
eval('
$mode = 'test';
if(....) { ...
');
// here comes your code again, will fail
switch ( $mode) {
...
}
Error Tracking
You cannot track the errors this way. One method would be to use set_error_handler() to register a custom error handler which stores the errors to db. This would work, but what if the user uses the function in it's code? Check the following examples:
set_error_handler('my_handler');
function my_handler($errno, $errstr, $errfile, $errline) {
db_save($errstr, ...);
}
eval('
$a = 1 / 0; // will trigger a warning
echo $b; // variable not defined
'
);
This would work. But problems will arise if have an evaled code like this:
eval('
restore_error_handler();
$a = 1 / 0; // will trigger a warning
echo $b; // variable not defined
'
);
Solution
A common solution to make it possible that others can execute code on your servers is:
store user code into temporary file
disable critical functions like fopen() ... in the php.ini
execute the temporary php file by php-cli and display output (and errors) to the user
if you separate stdin from stdout when calling the php-cli, you can parse the error messages and store them in a DB
According to the documentation, you just can't :
If there is a parse error in the evaluated code, eval() returns FALSE and execution of the following code continues normally. It is not possible to catch a parse error in eval() using set_error_handler().
EDIT: you can't do it with eval(), but you apparently can with php_check_syntax function. You have to write the code to a file in order to check its syntax.

Resources