+
Skip to content

find: Implement -uid and -gid #405

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions src/find/matchers/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub struct GroupMatcher {

impl GroupMatcher {
#[cfg(unix)]
pub fn new(group: String) -> GroupMatcher {
pub fn from_group_name(group: &str) -> GroupMatcher {
// get gid from group name
let Ok(group) = Group::from_name(group.as_str()) else {
let Ok(group) = Group::from_name(group) else {
return GroupMatcher { gid: None };
};

Expand All @@ -35,8 +35,18 @@ impl GroupMatcher {
}
}

#[cfg(unix)]
pub fn from_gid(gid: u32) -> GroupMatcher {
GroupMatcher { gid: Some(gid) }
}

#[cfg(windows)]
pub fn from_group_name(_group: &str) -> GroupMatcher {
GroupMatcher { gid: None }
}

#[cfg(windows)]
pub fn new(_group: String) -> GroupMatcher {
pub fn from_gid(_gid: u32) -> GroupMatcher {
GroupMatcher { gid: None }
}

Expand Down Expand Up @@ -126,19 +136,31 @@ mod tests {
.unwrap()
.name;

let matcher = super::GroupMatcher::new(file_group.clone());
let matcher = super::GroupMatcher::from_group_name(file_group.as_str());
assert!(
matcher.matches(&file_info, &mut matcher_io),
"group should match"
);

// Testing a non-existent group name
let time_string = Local::now().format("%Y%m%d%H%M%S").to_string();
let matcher = GroupMatcher::new(time_string.clone());
let matcher = GroupMatcher::from_group_name(time_string.as_str());
assert!(
matcher.gid().is_none(),
"group name {} should not exist",
time_string
);

// Testing group id
let matcher = GroupMatcher::from_gid(file_gid);
assert!(
matcher.gid().is_some(),
"group id {} should exist",
file_gid
);
assert!(
matcher.matches(&file_info, &mut matcher_io),
"group id should match"
);
}
}
31 changes: 29 additions & 2 deletions src/find/matchers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ fn build_matcher_tree(
}

i += 1;
let matcher = UserMatcher::new(user.to_string());
let matcher = UserMatcher::from_user_name(user);
match matcher.uid() {
Some(_) => Some(matcher.into_box()),
None => {
Expand All @@ -549,6 +549,18 @@ fn build_matcher_tree(
}
}
"-nouser" => Some(NoUserMatcher {}.into_box()),
"-uid" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
// check if the argument is a number
let uid = args[i + 1].parse::<u32>();
if uid.is_err() {
return Err(From::from(format!("{} is not a number", args[i + 1])));
}
i += 1;
Some(UserMatcher::from_uid(uid.unwrap()).into_box())
}
"-group" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
Expand All @@ -563,7 +575,7 @@ fn build_matcher_tree(
}

i += 1;
let matcher = GroupMatcher::new(group.to_string());
let matcher = GroupMatcher::from_group_name(group);
match matcher.gid() {
Some(_) => Some(matcher.into_box()),
None => {
Expand All @@ -575,6 +587,21 @@ fn build_matcher_tree(
}
}
"-nogroup" => Some(NoGroupMatcher {}.into_box()),
"-gid" => {
if i >= args.len() - 1 {
return Err(From::from(format!("missing argument to {}", args[i])));
}
// check if the argument is a number
let gid = args[i + 1].parse::<u32>();
if gid.is_err() {
return Err(From::from(format!(
"find: invalid argument `{}' to `-gid'",
args[i + 1]
)));
}
i += 1;
Some(GroupMatcher::from_gid(gid.unwrap()).into_box())
}
"-executable" => Some(AccessMatcher::Executable.into_box()),
"-perm" => {
if i >= args.len() - 1 {
Expand Down
28 changes: 23 additions & 5 deletions src/find/matchers/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ pub struct UserMatcher {

impl UserMatcher {
#[cfg(unix)]
pub fn new(user: String) -> UserMatcher {
pub fn from_user_name(user: &str) -> UserMatcher {
// get uid from user name
let Ok(user) = User::from_name(user.as_str()) else {
let Ok(user) = User::from_name(user) else {
return UserMatcher { uid: None };
};

Expand All @@ -35,8 +35,18 @@ impl UserMatcher {
}
}

#[cfg(unix)]
pub fn from_uid(uid: u32) -> UserMatcher {
UserMatcher { uid: Some(uid) }
}

#[cfg(windows)]
pub fn new(_user: String) -> UserMatcher {
pub fn from_user_name(_user: &str) -> UserMatcher {
UserMatcher { uid: None }
}

#[cfg(windows)]
pub fn from_uid(_uid: u32) -> UserMatcher {
UserMatcher { uid: None }
}

Expand Down Expand Up @@ -124,19 +134,27 @@ mod tests {
.unwrap()
.name;

let matcher = UserMatcher::new(file_user.clone());
let matcher = UserMatcher::from_user_name(file_user.as_str());
assert!(
matcher.matches(&file_info, &mut matcher_io),
"user should be the same"
);

// Testing a non-existent group name
let time_string = Local::now().format("%Y%m%d%H%M%S").to_string();
let matcher = UserMatcher::new(time_string.clone());
let matcher = UserMatcher::from_user_name(time_string.as_str());
assert!(
matcher.uid().is_none(),
"user {} should not be the same",
time_string
);

// Testing user id
let matcher = UserMatcher::from_uid(file_uid);
assert!(matcher.uid().is_some(), "user id {} should exist", file_uid);
assert!(
matcher.matches(&file_info, &mut matcher_io),
"user id should match"
);
}
}
46 changes: 46 additions & 0 deletions src/find/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,29 @@ mod tests {
"./test_data/simple/subdir\n./test_data/simple/subdir/ABBBC\n"
);

// test uid
let deps = FakeDependencies::new();
let rc = find_main(
&[
"find",
"./test_data/simple/subdir",
"-uid",
&uid.to_string(),
],
&deps,
);
assert_eq!(rc, 0);

// test empty uid
let deps = FakeDependencies::new();
let rc = find_main(&["find", "./test_data/simple/subdir", "-uid", ""], &deps);
assert_eq!(rc, 1);

// test not a number
let deps = FakeDependencies::new();
let rc = find_main(&["find", "./test_data/simple/subdir", "-uid", "a"], &deps);
assert_eq!(rc, 1);

// test empty user name
["-user", "-nouser"].iter().for_each(|&arg| {
let deps = FakeDependencies::new();
Expand Down Expand Up @@ -1125,6 +1148,29 @@ mod tests {
"./test_data/simple/subdir\n./test_data/simple/subdir/ABBBC\n"
);

// test gid
let deps = FakeDependencies::new();
let rc = find_main(
&[
"find",
"./test_data/simple/subdir",
"-gid",
gid.to_string().as_str(),
],
&deps,
);
assert_eq!(rc, 0);

// test empty gid
let deps = FakeDependencies::new();
let rc = find_main(&["find", "./test_data/simple/subdir", "-gid", ""], &deps);
assert_eq!(rc, 1);

// test not a number
let deps = FakeDependencies::new();
let rc = find_main(&["find", "./test_data/simple/subdir", "-gid", "a"], &deps);
assert_eq!(rc, 1);

// test empty user name and group name
["-group", "-nogroup"].iter().for_each(|&arg| {
let deps = FakeDependencies::new();
Expand Down
36 changes: 36 additions & 0 deletions tests/find_cmd_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,24 @@ fn find_with_nouser_predicate() {
.stderr(predicate::str::is_empty());
}

#[test]
#[cfg(unix)]
#[serial(working_dir)]
fn find_with_uid_predicate() {
use std::os::unix::fs::MetadataExt;
use std::path::Path;

let path = Path::new("./test_data");
let uid = path.metadata().unwrap().uid();

Command::cargo_bin("find")
.expect("found binary")
.args(["test_data", "-uid", &uid.to_string()])
.assert()
.success()
.stderr(predicate::str::is_empty());
}

#[test]
#[serial(working_dir)]
fn find_with_group_predicate() {
Expand Down Expand Up @@ -665,6 +683,24 @@ fn find_with_nogroup_predicate() {
.stderr(predicate::str::is_empty());
}

#[test]
#[cfg(unix)]
#[serial(working_dir)]
fn find_with_gid_predicate() {
use std::os::unix::fs::MetadataExt;
use std::path::Path;

let path = Path::new("./test_data");
let gid = path.metadata().unwrap().gid();

Command::cargo_bin("find")
.expect("found binary")
.args(["test_data", "-gid", &gid.to_string()])
.assert()
.success()
.stderr(predicate::str::is_empty());
}

#[test]
#[serial(working_dir)]
fn find_newer_xy() {
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载