Skip to content

Commit fe5f592

Browse files
committed
make group member list a hashset
vec::dedup() won't work if the input is not sorted.
1 parent 6da85a6 commit fe5f592

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed

rust/userborn/src/config.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashSet;
12
use std::{fs::File, io::Read, path::Path};
23

34
use anyhow::{Context, Result};
@@ -48,7 +49,7 @@ pub struct Group {
4849
pub gid: Option<u32>,
4950
/// The members of this group
5051
#[serde(default)]
51-
pub members: Vec<String>,
52+
pub members: HashSet<String>,
5253
}
5354

5455
#[derive(Deserialize, Debug)]

rust/userborn/src/group.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::collections::HashSet;
12
use std::{
23
collections::{BTreeMap, BTreeSet},
34
fs,
@@ -13,12 +14,12 @@ pub struct Entry {
1314
name: String,
1415
password: String,
1516
gid: u32,
16-
user_list: Vec<String>,
17+
user_list: HashSet<String>,
1718
}
1819

1920
impl Entry {
2021
/// Create a new /etc/group entry.
21-
pub fn new(name: String, gid: u32, user_list: Vec<String>) -> Self {
22+
pub fn new(name: String, gid: u32, user_list: HashSet<String>) -> Self {
2223
Self {
2324
name,
2425
password: "x".into(),
@@ -28,7 +29,7 @@ impl Entry {
2829
}
2930

3031
/// Update an /etc/group entry.
31-
pub fn update(&mut self, user_list: Vec<String>) {
32+
pub fn update(&mut self, user_list: HashSet<String>) {
3233
if self.user_list != user_list {
3334
log::info!(
3435
"Updating members of group {} from {:?} to {user_list:?}...",
@@ -76,16 +77,16 @@ impl Entry {
7677
}
7778

7879
/// Split a string containing group members separated by `,` into a list.
79-
fn split_group_members(s: &str) -> Vec<String> {
80+
fn split_group_members(s: &str) -> HashSet<String> {
8081
if s.is_empty() {
81-
return Vec::new();
82+
return HashSet::new();
8283
}
8384
s.split(',').map(ToString::to_string).collect()
8485
}
8586

8687
/// Join a list of group members into a string separating each group name with a `,`.
87-
fn join_group_members(v: &[String]) -> String {
88-
v.join(",")
88+
fn join_group_members(v: &HashSet<String>) -> String {
89+
v.clone().into_iter().collect::<Vec<_>>().join(",")
8990
}
9091

9192
#[derive(Default)]

rust/userborn/src/main.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod passwd;
66
mod password;
77
mod shadow;
88

9+
use std::collections::HashSet;
910
use std::{collections::BTreeSet, io::Write, process::ExitCode};
1011

1112
use anyhow::{anyhow, Context, Result};
@@ -98,9 +99,7 @@ fn update_users_and_groups(
9899
) {
99100
for group_config in &config.groups {
100101
if let Some(existing_entry) = group_db.get_mut(&group_config.name) {
101-
let mut members = group_config.members.clone();
102-
members.dedup();
103-
existing_entry.update(members);
102+
existing_entry.update(group_config.members.clone());
104103
} else if let Err(e) = create_group(group_config, group_db) {
105104
log::error!("Failed to create group {}: {e:#}", group_config.name);
106105
};
@@ -187,7 +186,7 @@ fn create_user(
187186
is_normal: user_config.is_normal,
188187
name: user_config.name.clone(),
189188
gid,
190-
members: vec![user_config.name.clone()],
189+
members: HashSet::from([user_config.name.clone()]),
191190
};
192191

193192
create_group(&group_config, group_db)

0 commit comments

Comments
 (0)