27 个版本

使用旧的 Rust 2015

0.11.0 2020 年 10 月 8 日
0.10.0 2020 年 4 月 7 日
0.9.1 2019 年 3 月 16 日
0.8.1 2018 年 11 月 26 日
0.1.1 2014 年 12 月 12 日

Unix API 中排名 699

Download history · Rust 包仓库 43747/week @ 2024-03-14 · Rust 包仓库 46425/week @ 2024-03-21 · Rust 包仓库 62242/week @ 2024-03-28 · Rust 包仓库 45636/week @ 2024-04-04 · Rust 包仓库 44690/week @ 2024-04-11 · Rust 包仓库 40784/week @ 2024-04-18 · Rust 包仓库 39771/week @ 2024-04-25 · Rust 包仓库 37085/week @ 2024-05-02 · Rust 包仓库 34727/week @ 2024-05-09 · Rust 包仓库 42231/week @ 2024-05-16 · Rust 包仓库 39719/week @ 2024-05-23 · Rust 包仓库 36503/week @ 2024-05-30 · Rust 包仓库 37095/week @ 2024-06-06 · Rust 包仓库 33859/week @ 2024-06-13 · Rust 包仓库 35005/week @ 2024-06-20 · Rust 包仓库 32930/week @ 2024-06-27 · Rust 包仓库

每月下载量 145,054
不到 155crate中使用

MIT 许可证

81KB
1K SLoC

rust-users 最低 Rust 版本 1.31.0 构建状态

这是一个用于访问 Unix 用户和组的库。它支持获取系统用户和组,将它们存储在缓存中,并创建您自己的模拟表。

查看 Rustdoc

安装

此crate与 Cargo 一起工作。将以下内容添加到您的 Cargo.toml 依赖关系部分

[dependencies]
users = "0.11"

此crate测试的最早的 Rust 版本是 Rust v1.31.0

使用方法

在 Unix 中,每个用户都有一个唯一的 用户ID,每个进程都有一个 实际用户ID,它表示该进程正在使用哪个用户的权限。此外,用户可以是 的成员,组也有名称和ID。此功能在 libc 中公开,它是 C 标准库,但作为不安全的 Rust 接口。此包装库提供了一个安全接口,使用 UserGroup 类型以及 get_user_by_id 等函数,而不是底层指针和字符串。它还提供了基本的缓存功能。

它(目前)不提供 编辑 功能;返回的值是只读的。

用户

函数 get_current_uid 返回代表当前运行程序的用户的 uid_t 值,而 get_user_by_uid 函数扫描用户数据库并返回包含用户信息的 User。当不存在该 ID 的用户时,此函数返回 None

User 有以下访问器

  • uid: 用户的ID
  • name: 用户的名称
  • primary_group: 该用户主要组的ID

这是一个完整的示例,用于打印当前用户名。

use users::{get_user_by_uid, get_current_uid};

let user = get_user_by_uid(get_current_uid()).unwrap();
println!("Hello, {}!", user.name());

此代码假设(使用 unwrap())在程序开始运行后用户未被删除。对于任意的用户ID,这 不是 一个安全的假设:在程序运行时可能删除用户,或者用户是文件的所有者,或者该用户可能从未存在过。因此,总是要检查返回值!

还有一个名为 get_current_username 的函数,因为这是一个非常常见的操作,所以值得特殊处理。

缓存

尽管有上述警告,用户和组数据库很少改变。虽然短程序可能只需要获取一次用户信息,但长时间运行的程序可能需要多次重新查询数据库,而中等长度的程序可以通过缓存值来减少冗余的系统调用。

因此,此crate为数据库提供了一个缓存接口,该接口在保持每个结果的同时提供相同的功能,并将信息缓存起来以便重新使用。

要引入缓存,创建一个新的 UsersCache 并在它上面调用相同的方法。例如

use users::{Users, Groups, UsersCache};

let mut cache = UsersCache::new();
let uid = cache.get_current_uid();
let user = cache.get_user_by_uid(uid).unwrap();
println!("Hello again, {}!", user.name());

此缓存是 只增的:无法删除它,或删除选定的条目,因为当数据库可能已被修改时,最好是完全重新开始。所以为了实现这一点,只需开始使用一个新的 UsersCache

最后,可以通过类似的方式获取组。一个 Group 具有以下访问器

  • gid: 组的ID
  • name: 组的名称

并且,再次提供一个完整的示例

use users::{Users, Groups, UsersCache};

let mut cache = UsersCache::new();
let group = cache.get_group_by_name("admin").expect("No such group 'admin'!");
println!("The '{}' group has the ID {}", group.name(), group.gid());

日志记录

默认启用的 logging 功能使用 log crate 以 Trace 日志级别记录与操作系统的所有交互。

注意事项

你应该准备应对用户和组表可能完全损坏:不应假设ID映射到实际用户和组,并且用户名和组名也不保证映射!

可模拟的用户和组

当你测试代码时,你不想实际依赖于系统实际存在各种用户和组 - 有一个自定义的用户集会更好,这样可以保证它们存在,以便你可以针对它们进行测试。

《code>mock 模块允许你创建这些自定义用户和组定义,然后使用与主库中相同的 Users trait 访问它们,而对代码的更改很少。

创建模拟用户

模拟用户表需要预先了解当前用户的UID。除了这一点之外,你可以使用 add_useradd_group 将用户和组添加到表中

use std::sync::Arc;
use users::mock::{MockUsers, User, Group};
use users::os::unix::{UserExt, GroupExt};

let mut users = MockUsers::with_current_uid(1000);
let bobbins = User::new(1000, "Bobbins", 1000).with_home_dir("/home/bobbins");
users.add_user(bobbins);
users.add_group(Group::new(100, "funkyppl"));

导出的内容重新导出到模拟模块中,以便更简单的 use 语句。

使用模拟用户

为了设置程序以使用任一类型的 Users 表,让你的函数和结构体接受一个实现 Users trait 的泛型参数。然后,你可以传递 OS 或 Mock 类型的值。

下面是一个完整的示例

use std::sync::Arc;
use users::{Users, UsersCache, User};
use users::os::unix::UserExt;
use users::mock::MockUsers;

fn print_current_username<U: Users>(users: &mut U) {
    println!("Current user: {:?}", users.get_current_username());
}

let mut users = MockUsers::with_current_uid(1001);
users.add_user(User::new(1001, "fred", 101));
print_current_username(&mut users);

let mut actual_users = UsersCache::new();
print_current_username(&mut actual_users);

依赖关系

~64KB