fingerd: add raw user response variant
This commit is contained in:
@@ -214,7 +214,13 @@ fn parse_bsd_finger_time(time: &str) -> anyhow::Result<DateTime<Utc>> {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FingerResponseUserEntry {
|
||||
pub enum FingerResponseUserEntry {
|
||||
Structured(Box<FingerResponseStructuredUserEntry>),
|
||||
Raw(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct FingerResponseStructuredUserEntry {
|
||||
/// The unix username of this user, as noted in passwd
|
||||
pub username: String,
|
||||
|
||||
@@ -258,7 +264,7 @@ pub struct FingerResponseUserEntry {
|
||||
pub plan: Option<String>,
|
||||
}
|
||||
|
||||
impl FingerResponseUserEntry {
|
||||
impl FingerResponseStructuredUserEntry {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
username: String,
|
||||
@@ -736,9 +742,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "alice".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(user_entry.username, "alice");
|
||||
assert_eq!(user_entry.full_name, "Alice Wonderland");
|
||||
assert_eq!(user_entry.home_dir, PathBuf::from("/home/alice"));
|
||||
@@ -762,9 +770,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "alice".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(user_entry.office, Some("123 Main St".to_string()));
|
||||
assert_eq!(user_entry.office_phone, Some("012-345-6789".to_string()));
|
||||
@@ -786,9 +796,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "alice".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"alice".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(user_entry.office, Some("123 Main St".to_string()));
|
||||
assert_eq!(user_entry.office_phone, Some("012-345-6789".to_string()));
|
||||
@@ -807,9 +819,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "bob".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"bob".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(user_entry.never_logged_in);
|
||||
assert!(user_entry.sessions.is_empty());
|
||||
@@ -827,9 +841,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "bob".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"bob".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(user_entry.mail_status, Some(MailStatus::NoMail));
|
||||
}
|
||||
|
||||
@@ -846,9 +862,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "bob".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"bob".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
user_entry.mail_status,
|
||||
Some(MailStatus::NewMailReceived {
|
||||
@@ -870,9 +888,11 @@ mod tests {
|
||||
.trim();
|
||||
|
||||
let response = RawFingerResponse::from(response_content.to_string());
|
||||
let user_entry =
|
||||
FingerResponseUserEntry::try_from_raw_finger_response(&response, "bob".to_string())
|
||||
.unwrap();
|
||||
let user_entry = FingerResponseStructuredUserEntry::try_from_raw_finger_response(
|
||||
&response,
|
||||
"bob".to_string(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
user_entry.mail_status,
|
||||
Some(MailStatus::MailLastRead(
|
||||
|
||||
@@ -11,7 +11,7 @@ use users::all_users;
|
||||
use uucore::utmpx::{Utmpx, UtmpxRecord};
|
||||
|
||||
use crate::{
|
||||
proto::finger_protocol::{FingerResponseUserEntry, FingerResponseUserSession},
|
||||
proto::finger_protocol::{FingerResponseStructuredUserEntry, FingerResponseUserSession},
|
||||
server::fingerd::{FingerRequestInfo, local_email},
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ pub fn search_for_user(
|
||||
search_string: &str,
|
||||
match_fullnames: bool,
|
||||
_request_info: &FingerRequestInfo,
|
||||
) -> Vec<anyhow::Result<FingerResponseUserEntry>> {
|
||||
) -> Vec<anyhow::Result<FingerResponseStructuredUserEntry>> {
|
||||
(unsafe { all_users() })
|
||||
.filter_map(|user| {
|
||||
let user = match nix::unistd::User::from_uid(user.uid().into()) {
|
||||
@@ -69,7 +69,7 @@ pub fn search_for_user(
|
||||
/// Retrieve information about all users currently logged in, based on utmpx records.
|
||||
pub fn finger_utmp_users(
|
||||
_request_info: &FingerRequestInfo,
|
||||
) -> Vec<anyhow::Result<FingerResponseUserEntry>> {
|
||||
) -> Vec<anyhow::Result<FingerResponseStructuredUserEntry>> {
|
||||
Utmpx::iter_all_records()
|
||||
.filter(|entry| entry.is_user_process())
|
||||
.into_group_map_by(|entry| entry.user())
|
||||
@@ -113,7 +113,7 @@ fn read_file_content_if_exists(path: &Path) -> anyhow::Result<Option<String>> {
|
||||
fn get_local_user(
|
||||
username: &str,
|
||||
utmp_records: Option<Vec<UtmpxRecord>>,
|
||||
) -> anyhow::Result<Option<FingerResponseUserEntry>> {
|
||||
) -> anyhow::Result<Option<FingerResponseStructuredUserEntry>> {
|
||||
tracing::trace!(
|
||||
"Retrieving local user information for username: {}",
|
||||
username
|
||||
@@ -211,7 +211,7 @@ fn get_local_user(
|
||||
let plan_path = user_entry.dir.join(".plan");
|
||||
let plan = read_file_content_if_exists(&plan_path)?;
|
||||
|
||||
Ok(Some(FingerResponseUserEntry::new(
|
||||
Ok(Some(FingerResponseStructuredUserEntry::new(
|
||||
username,
|
||||
full_name,
|
||||
home_dir,
|
||||
|
||||
@@ -204,6 +204,8 @@ impl VarlinkRoowhoo2ClientServer {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(Box::new)
|
||||
.map(FingerResponseUserEntry::Structured)
|
||||
.collect(),
|
||||
None => finger_utmp_users(&request_info)
|
||||
.into_iter()
|
||||
@@ -214,6 +216,8 @@ impl VarlinkRoowhoo2ClientServer {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(Box::new)
|
||||
.map(FingerResponseUserEntry::Structured)
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user