os: add userInfo() method
os.userInfo() calls libuv's uv_os_get_passwd() function. It returns an object containing the current effective user's username, uid, gid, shell, and home directory. On Windows, the uid and gid are -1, and the shell is null. Refs: https://github.com/nodejs/node/issues/5582 PR-URL: https://github.com/nodejs/node/pull/6104 Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
aba035fb27
commit
d6e56fd843
@ -182,5 +182,21 @@ on OS X and `'Windows_NT'` on Windows.
|
|||||||
|
|
||||||
Returns the system uptime in seconds.
|
Returns the system uptime in seconds.
|
||||||
|
|
||||||
|
## os.userInfo([options])
|
||||||
|
|
||||||
|
* `options` {Object}
|
||||||
|
* `encoding` {String} Character encoding used to interpret resulting strings.
|
||||||
|
If `encoding` is set to `'buffer'`, the `username`, `shell`, and `homedir`
|
||||||
|
values will be `Buffer` instances. (Default: 'utf8')
|
||||||
|
|
||||||
|
Returns a subset of the password file entry for the current effective user. The
|
||||||
|
returned object includes the `username`, `uid`, `gid`, `shell`, and `homedir`.
|
||||||
|
On Windows, the `uid` and `gid` fields are `-1`, and `shell` is `null`.
|
||||||
|
|
||||||
|
The value of `homedir` returned by `userInfo()` comes directly from the
|
||||||
|
operating system. This differs from the result of `os.homedir()`, which queries
|
||||||
|
several environment variables for the home directory before falling back to the
|
||||||
|
operating system response.
|
||||||
|
|
||||||
[`process.arch`]: process.html#process_process_arch
|
[`process.arch`]: process.html#process_process_arch
|
||||||
[`process.platform`]: process.html#process_process_platform
|
[`process.platform`]: process.html#process_process_platform
|
||||||
|
@ -14,6 +14,7 @@ exports.type = binding.getOSType;
|
|||||||
exports.release = binding.getOSRelease;
|
exports.release = binding.getOSRelease;
|
||||||
exports.networkInterfaces = binding.getInterfaceAddresses;
|
exports.networkInterfaces = binding.getInterfaceAddresses;
|
||||||
exports.homedir = binding.getHomeDirectory;
|
exports.homedir = binding.getHomeDirectory;
|
||||||
|
exports.userInfo = binding.getUserInfo;
|
||||||
|
|
||||||
|
|
||||||
exports.arch = function() {
|
exports.arch = function() {
|
||||||
|
@ -94,6 +94,7 @@ namespace node {
|
|||||||
V(exchange_string, "exchange") \
|
V(exchange_string, "exchange") \
|
||||||
V(idle_string, "idle") \
|
V(idle_string, "idle") \
|
||||||
V(irq_string, "irq") \
|
V(irq_string, "irq") \
|
||||||
|
V(encoding_string, "encoding") \
|
||||||
V(enter_string, "enter") \
|
V(enter_string, "enter") \
|
||||||
V(env_pairs_string, "envPairs") \
|
V(env_pairs_string, "envPairs") \
|
||||||
V(env_string, "env") \
|
V(env_string, "env") \
|
||||||
@ -121,6 +122,7 @@ namespace node {
|
|||||||
V(handle_string, "handle") \
|
V(handle_string, "handle") \
|
||||||
V(heap_total_string, "heapTotal") \
|
V(heap_total_string, "heapTotal") \
|
||||||
V(heap_used_string, "heapUsed") \
|
V(heap_used_string, "heapUsed") \
|
||||||
|
V(homedir_string, "homedir") \
|
||||||
V(hostmaster_string, "hostmaster") \
|
V(hostmaster_string, "hostmaster") \
|
||||||
V(ignore_string, "ignore") \
|
V(ignore_string, "ignore") \
|
||||||
V(immediate_callback_string, "_immediateCallback") \
|
V(immediate_callback_string, "_immediateCallback") \
|
||||||
@ -206,6 +208,7 @@ namespace node {
|
|||||||
V(service_string, "service") \
|
V(service_string, "service") \
|
||||||
V(servername_string, "servername") \
|
V(servername_string, "servername") \
|
||||||
V(session_id_string, "sessionId") \
|
V(session_id_string, "sessionId") \
|
||||||
|
V(shell_string, "shell") \
|
||||||
V(signal_string, "signal") \
|
V(signal_string, "signal") \
|
||||||
V(size_string, "size") \
|
V(size_string, "size") \
|
||||||
V(sni_context_err_string, "Invalid SNI context") \
|
V(sni_context_err_string, "Invalid SNI context") \
|
||||||
@ -235,6 +238,7 @@ namespace node {
|
|||||||
V(uid_string, "uid") \
|
V(uid_string, "uid") \
|
||||||
V(unknown_string, "<unknown>") \
|
V(unknown_string, "<unknown>") \
|
||||||
V(user_string, "user") \
|
V(user_string, "user") \
|
||||||
|
V(username_string, "username") \
|
||||||
V(uv_string, "uv") \
|
V(uv_string, "uv") \
|
||||||
V(valid_from_string, "valid_from") \
|
V(valid_from_string, "valid_from") \
|
||||||
V(valid_to_string, "valid_to") \
|
V(valid_to_string, "valid_to") \
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "v8.h"
|
#include "v8.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "env-inl.h"
|
#include "env-inl.h"
|
||||||
|
#include "string_bytes.h"
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -32,6 +33,7 @@ using v8::Context;
|
|||||||
using v8::FunctionCallbackInfo;
|
using v8::FunctionCallbackInfo;
|
||||||
using v8::Integer;
|
using v8::Integer;
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
|
using v8::Null;
|
||||||
using v8::Number;
|
using v8::Number;
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::String;
|
using v8::String;
|
||||||
@ -290,6 +292,72 @@ static void GetHomeDirectory(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
Environment* env = Environment::GetCurrent(args);
|
||||||
|
uv_passwd_t pwd;
|
||||||
|
enum encoding encoding;
|
||||||
|
|
||||||
|
if (args[0]->IsObject()) {
|
||||||
|
Local<Object> options = args[0].As<Object>();
|
||||||
|
Local<Value> encoding_opt = options->Get(env->encoding_string());
|
||||||
|
encoding = ParseEncoding(env->isolate(), encoding_opt, UTF8);
|
||||||
|
} else {
|
||||||
|
encoding = UTF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int err = uv_os_get_passwd(&pwd);
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return env->ThrowUVException(err, "uv_os_get_passwd");
|
||||||
|
}
|
||||||
|
|
||||||
|
Local<Value> uid = Number::New(env->isolate(), pwd.uid);
|
||||||
|
Local<Value> gid = Number::New(env->isolate(), pwd.gid);
|
||||||
|
Local<Value> username = StringBytes::Encode(env->isolate(),
|
||||||
|
pwd.username,
|
||||||
|
encoding);
|
||||||
|
Local<Value> homedir = StringBytes::Encode(env->isolate(),
|
||||||
|
pwd.homedir,
|
||||||
|
encoding);
|
||||||
|
Local<Value> shell;
|
||||||
|
|
||||||
|
if (pwd.shell == NULL)
|
||||||
|
shell = Null(env->isolate());
|
||||||
|
else
|
||||||
|
shell = StringBytes::Encode(env->isolate(), pwd.shell, encoding);
|
||||||
|
|
||||||
|
uv_os_free_passwd(&pwd);
|
||||||
|
|
||||||
|
if (username.IsEmpty()) {
|
||||||
|
return env->ThrowUVException(UV_EINVAL,
|
||||||
|
"uv_os_get_passwd",
|
||||||
|
"Invalid character encoding for username");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (homedir.IsEmpty()) {
|
||||||
|
return env->ThrowUVException(UV_EINVAL,
|
||||||
|
"uv_os_get_passwd",
|
||||||
|
"Invalid character encoding for homedir");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shell.IsEmpty()) {
|
||||||
|
return env->ThrowUVException(UV_EINVAL,
|
||||||
|
"uv_os_get_passwd",
|
||||||
|
"Invalid character encoding for shell");
|
||||||
|
}
|
||||||
|
|
||||||
|
Local<Object> entry = Object::New(env->isolate());
|
||||||
|
|
||||||
|
entry->Set(env->uid_string(), uid);
|
||||||
|
entry->Set(env->gid_string(), gid);
|
||||||
|
entry->Set(env->username_string(), username);
|
||||||
|
entry->Set(env->homedir_string(), homedir);
|
||||||
|
entry->Set(env->shell_string(), shell);
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Initialize(Local<Object> target,
|
void Initialize(Local<Object> target,
|
||||||
Local<Value> unused,
|
Local<Value> unused,
|
||||||
Local<Context> context) {
|
Local<Context> context) {
|
||||||
@ -304,6 +372,7 @@ void Initialize(Local<Object> target,
|
|||||||
env->SetMethod(target, "getOSRelease", GetOSRelease);
|
env->SetMethod(target, "getOSRelease", GetOSRelease);
|
||||||
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
|
env->SetMethod(target, "getInterfaceAddresses", GetInterfaceAddresses);
|
||||||
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
|
env->SetMethod(target, "getHomeDirectory", GetHomeDirectory);
|
||||||
|
env->SetMethod(target, "getUserInfo", GetUserInfo);
|
||||||
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
|
target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "isBigEndian"),
|
||||||
Boolean::New(env->isolate(), IsBigEndian()));
|
Boolean::New(env->isolate(), IsBigEndian()));
|
||||||
}
|
}
|
||||||
|
@ -125,3 +125,27 @@ if (common.isWindows && process.env.USERPROFILE) {
|
|||||||
assert.ok(os.homedir().indexOf(path.sep) !== -1);
|
assert.ok(os.homedir().indexOf(path.sep) !== -1);
|
||||||
process.env.HOME = home;
|
process.env.HOME = home;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pwd = os.userInfo();
|
||||||
|
const pwdBuf = os.userInfo({ encoding: 'buffer' });
|
||||||
|
|
||||||
|
if (common.isWindows) {
|
||||||
|
assert.strictEqual(pwd.uid, -1);
|
||||||
|
assert.strictEqual(pwd.gid, -1);
|
||||||
|
assert.strictEqual(pwd.shell, null);
|
||||||
|
assert.strictEqual(pwdBuf.uid, -1);
|
||||||
|
assert.strictEqual(pwdBuf.gid, -1);
|
||||||
|
assert.strictEqual(pwdBuf.shell, null);
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(typeof pwd.uid, 'number');
|
||||||
|
assert.strictEqual(typeof pwd.gid, 'number');
|
||||||
|
assert.notStrictEqual(pwd.shell.indexOf(path.sep), -1);
|
||||||
|
assert.strictEqual(pwd.uid, pwdBuf.uid);
|
||||||
|
assert.strictEqual(pwd.gid, pwdBuf.gid);
|
||||||
|
assert.strictEqual(pwd.shell, pwdBuf.shell.toString('utf8'));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.strictEqual(typeof pwd.username, 'string');
|
||||||
|
assert.notStrictEqual(pwd.homedir.indexOf(path.sep), -1);
|
||||||
|
assert.strictEqual(pwd.username, pwdBuf.username.toString('utf8'));
|
||||||
|
assert.strictEqual(pwd.homedir, pwdBuf.homedir.toString('utf8'));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user