Working as a developer sometimes requires more knowledge than just that of programming itself. It’s always a good idea to grasp some concepts from other IT fields as well.
One of these concepts is file system permissions, proper management of which is a must when it comes to working with files, e.g., using node.js
I won’t write what exactly
r/w/x mean, as it’s a very broad topic, but I’ll try to show how we can use those concepts in the node.js world.
Where may it come in handy? Definitely when we want to create new folders or files and be sure that only certain people have access to them. Let’s take a look at signatures of some
fs module functions.
fs.mkdir(path[, mode], callback);
fs.writeFile(filename, data[, options], callback);
In both cases, we’re able to set something called
mode, where for
mkdir, it’s passed as an argument, and for
writeFile, it’s one of the
options object attributes.
mode may be slightly overwhelming at first if you’ve never worked with it, but I’ll explain every part separately.
var mode = 0777 & ~process.umask();
- when you prefix a number with
0, it becomes an octal (8 based) representation, e.g.
1*(8^1) + 4*(8^0) = 12
process.umask()returns decimal representation, which is dependent on the
nodeprocess we’re running (with what permissions it has been run)
~inverts all bits in the binary representation of the number, e.g.
1110. For decimals,
-(x + 1), so
&takes only those bits that are both
1in the same positions – binary
And to make everything even more clear, let’s write one quick example using real numbers, keeping in mind that first 0 is only telling JS to treat the number as an octal representation.
Initial mode: 0777(8) = 111111111(2) // user r/w/x, group r/w/x, other r/w/x Process mask: 022(8) = 000010010(2) Reversed process mask: 0755(8) = 111101101(2) // user r/w/x, group r/x, other r/x Initial mode AND reversed mask: 0755(8) = 111101101(2) // user r/w/x, group r/x, other r/x
If AND operation return exactly the same result as the reversed process mask itself. Why don’t we just return the mask, you may ask? Because this way we can restrict default permissions. Let me show you this in the second example.
Initial mode: 0666(8) = 110110110(2) // user r/w, group r/w, other r/w Process mask: 022(8) = 000010010(2) Reversed process mask: 0755(8) = 111101101(2) // user r/w/x, group r/x, other r/x Initial mode AND reversed mask: 0644(8) = 110100100(2) // user r/w, group r, other r
Here we’ve got
0664 instead of
0755 as our mode. Why is that?
- We’ve asked for
r/wpermissions for everyone
- Process has
r/w/xfor user and
r/xfor group and other
- Process allows us to use
readpermissions that we asked for
- Process disallows us to use
writepermissions as process itself doesn’t have them
- Process has one additional permission which is
executefor everyone, but because we haven’t asked for it, it’s ignored
Now that we’ve our
mode, we can go ahead and be sure that we know what we’re doing and what permissions to our newly created files people will have.
It’s worth mentioning that
0777 & ~process.umask() for folders and
0666 & ~process.umask() for files are exactly what your system would do on its own if you would leave those parameters.