I want to know best practices for checking directory permissions
Details
Before creating a directory under a specific directory like mkdir, I would like to check the permissions and see if the directory can be created. I think the method of receiving an error in the mkdir callback is correct originally, but that method cannot be used because mkdir is executed in the processing of the external library. After reviewing the documentation, I think the correct way is to use "opendir" to receive the callback. Is that the right way?
Also, if you use the fs module "opendir", "access" for a directory that you do not have write permission for, the result will be different. I'd like to know why the results are different, do you understand?
- access (params : fs.constants.W_OK)
- No error returned
- opendir
- Error callback is returned
OS: Windows 10 Directory: Program Files
Node.js version
14.15.3
Example code
No response
Operating system
Windows 10
Scope
other
Module and version
Not applicable.
This is formally answered in the documentation: https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#fsaccesspath-mode-callback
Notice there is a subsection titled write (NOT RECOMMENDED) that makes use of the access method and a following subsection titled write (RECOMMENDED) that makes use of the open method. These code examples demonstrate how to proceed. The reason for this is stated immediately prior to the code examples:
Do not use fs.access() to check for the accessibility of a file before calling fs.open(), fs.readFile(), or fs.writeFile(). Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible.
Confirmation was delayed. thank you for answering.
The process I want to implement is to check if the directory has read / execute permissions before using rmdir to delete the directory, and if so, display a dialog without running the delete process. I want to do it. Since the deletion process itself depends on the external library, the result of the rmdir callback cannot be received as it is. In that case, even if you perform synchronization processing with statSync or accesSync and call the processing with rmdir of the external library, the race condition does not occur. Is this idea correct?
Also, if you call statSync or accesSync synchronously for open and writeFile other than rmdir, wait for the result, and execute it, I think that no conflict will occur. Is that correct?
@KazukiSugiyama107 Thanks for creating this issue. I would suggest using fs.access/fs.accessSync/fsPromises.access to check if you have write permission in your scenario. fs.opendir is not necessary because you don't need to open the dir to check if you have the write permission, fs.opendir will also not readable when its motivation is just checking permission.
I'd like to know why the results are different, do you understand?
access (params : fs.constants.W_OK) No error returned opendir Error callback is returned
I made an example code to test fs.access and fs.accessSync, it shows when we access a directory which has no write permission, an error will throw. If I understand your question correctly, then access method will have no problem checking the permission. is anything I missed?
$ cat test.mjs
import { accessSync, access, constants } from 'node:fs';
const dir = '/etc';
access(dir, constants.W_OK, (err) => {
console.log(`check ${dir} permission before rm it via fs.access, result ${err ? 'is not writeable' : 'is writeable'}`);
});
try {
accessSync(dir, constants.W_OK);
console.log(`check ${dir} permission before rm it via fs.accessSync, result is writeable`);
} catch (err) {
console.log(`check ${dir} permission before rm it via fs.accessSync, result is not writeable`);
}
$ node test.mjs
check /etc permission before rm it via fs.accessSync, result is not writeable
check /etc permission before rm it via fs.access, result is not writeable
@F3n67u thank you! What you answered was what I was looking for.
However, one question found that the results were different when using fs.accessSync on WinodwsOS and when using it on MacOS.
I think this is a file system difference, but have you ever seen such a case?
The confirmation was carried out by changing the authority for the directory. The results on Mac OS seem correct, but the results on Windows OS do not seem to be correct.
Mac OS
| Parameter | Permission | result |
|---|---|---|
| constants.R_OK | Readable | Success |
| constants.R_OK | Writable | Failure |
| constants.R_OK | Executable | Failure |
| constants.W_OK | Readable | Failure |
| constants.W_OK | Writable | Success |
| constants.W_OK | Executable | Failure |
| constants.X_OK | Readable | Failure |
| constants.X_OK | Writable | Failure |
| constants.X_OK | Executable | Success |
Windows OS
| Parameter | Permission | result |
|---|---|---|
| constants.R_OK | Read | Success |
| constants.R_OK | Write | Success |
| constants.R_OK | List folder contens | Success |
| constants.W_OK | Read | Success |
| constants.W_OK | Write | Success |
| constants.W_OK | List folder contens | Success |
| constants.X_OK | Read | Success |
| constants.X_OK | Write | Success |
| constants.X_OK | List folder contens | Success |
On Windows, access-control policies (ACLs) on a directory may limit access to a file or directory. The fs.access() function, however, does not check the ACL and therefore may report that a path is accessible even if the ACL restricts the user from reading or writing to it.
I don't test it in Windows. Seems related to this problem in Windows.https://nodejs.org/dist/latest-v18.x/docs/api/fs.html#fsaccesspath-mode-callback
I understand.
As explained below, I have confirmed that it works fine on Windows using fs.openSync.
Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile(), or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.
I'm a little skeptical, but is it correct to run fs.openSync in a directory? The results I can get are correct, but I'm wondering if there are other ways.
I don't have an answer for you. I don't know the Windows-specific side of the fs module.
@nodejs/fs Could you folks help with this question?
Can someone please answer how to use fs.openSync?
https://github.com/nodejs/help/issues/3871#issuecomment-1153947155
I would like to know if anyone has any knowledge of the following comments.
https://github.com/nodejs/help/issues/3871#issuecomment-1153947155
There has been no activity on this issue for 11 months. The help repository works best when sustained engagement moves conversation forward. The issue will be closed in 1 month. If you are still experiencing this issue on the latest supported versions of Node.js, please leave a comment.
Closing after no activity on this issue for 12 months.