Format Rust sources at 100 columns

This commit is contained in:
Samuel Onoja committed 2026-10-22 01:28:03 +01:00
1 parent 4661f595f8
commit 610478f8c7
336 files changed
+23497 -7892

No files matched your search

+52 -16
View File
@@ -94,10 +94,21 @@ struct Agent {
impl Agent {
async fn vendor(&self, action_id: &str) -> (String, String) {
let lookup = async {
let authority = zbus::Proxy::new(&self.connection, AUTHORITY, AUTHORITY_PATH, AUTHORITY_INTERFACE).await?;
let authority = zbus::Proxy::new(
&self.connection,
AUTHORITY,
AUTHORITY_PATH,
AUTHORITY_INTERFACE,
)
.await?;
let locale = std::env::var("LANG").unwrap_or_default();
let actions: Vec<ActionDescription> = authority.call("EnumerateActions", &(locale,)).await?;
Ok::<_, zbus::Error>(actions.into_iter().find(|action| action.action_id == action_id))
let actions: Vec<ActionDescription> =
authority.call("EnumerateActions", &(locale,)).await?;
Ok::<_, zbus::Error>(
actions
.into_iter()
.find(|action| action.action_id == action_id),
)
};
// Missing metadata must never prevent authentication or cancellation.
match tokio::time::timeout(std::time::Duration::from_secs(2), lookup).await {
@@ -119,8 +130,9 @@ impl Agent {
identities: Vec<Identity>,
) -> zbus::fdo::Result<()> {
let allowed = available_identities(&identities);
let uid = choose_identity(&allowed)
.ok_or_else(|| zbus::fdo::Error::Failed("No supported authentication identity".into()))?;
let uid = choose_identity(&allowed).ok_or_else(|| {
zbus::fdo::Error::Failed("No supported authentication identity".into())
})?;
let cancelled = Arc::new(AtomicBool::new(false));
{
@@ -176,7 +188,11 @@ fn available_identities(identities: &[Identity]) -> Vec<u32> {
for uid in identities
.iter()
.filter(|(kind, _)| kind == "unix-user")
.filter_map(|(_, details)| details.get("uid").and_then(|uid| u32::try_from(uid.clone()).ok()))
.filter_map(|(_, details)| {
details
.get("uid")
.and_then(|uid| u32::try_from(uid.clone()).ok())
})
.filter(|uid| *uid <= i32::MAX as u32)
{
if !available.contains(&uid) {
@@ -212,7 +228,10 @@ fn process_subject() -> Result<(String, HashMap<String, Value<'static>>), String
.map_err(|error| error.to_string())?;
let mut details = HashMap::new();
details.insert("pid".to_owned(), Value::from(std::process::id()));
details.insert("uid".to_owned(), Value::from(unsafe { libc::geteuid() } as i32));
details.insert(
"uid".to_owned(),
Value::from(unsafe { libc::geteuid() } as i32),
);
details.insert("start-time".to_owned(), Value::from(started));
Ok(("unix-process".into(), details))
}
@@ -233,7 +252,10 @@ async fn session_subject(
"org.freedesktop.login1.Manager",
)
.await?;
let path: zbus::zvariant::OwnedObjectPath = match manager.call("GetSessionByPID", &(std::process::id(),)).await {
let path: zbus::zvariant::OwnedObjectPath = match manager
.call("GetSessionByPID", &(std::process::id(),))
.await
{
Ok(path) => path,
Err(error) => {
// A launcher in the user manager can be outside the session cgroup
@@ -273,11 +295,15 @@ async fn run_agent() -> Result<(), Box<dyn std::error::Error>> {
)
.await?;
let subject = session_subject(&connection).await?;
let authority = zbus::Proxy::new(&connection, AUTHORITY, AUTHORITY_PATH, AUTHORITY_INTERFACE).await?;
let authority =
zbus::Proxy::new(&connection, AUTHORITY, AUTHORITY_PATH, AUTHORITY_INTERFACE).await?;
let locale = std::env::var("LANG").unwrap_or_default();
authority
.call::<_, _, ()>("RegisterAuthenticationAgent", &(subject, locale, AGENT_PATH))
.call::<_, _, ()>(
"RegisterAuthenticationAgent",
&(subject, locale, AGENT_PATH),
)
.await?;
std::future::pending::<()>().await;
@@ -343,9 +369,10 @@ mod tests {
#[test]
fn prompt_protocol_keeps_selection_response_and_echo_fields() {
let selection: PromptEvent =
serde_json::from_str(r#"{"type":"select_identity","generation":{"selection":2,"attempt":0},"uid":1001}"#)
.unwrap();
let selection: PromptEvent = serde_json::from_str(
r#"{"type":"select_identity","generation":{"selection":2,"attempt":0},"uid":1001}"#,
)
.unwrap();
assert!(matches!(
selection,
PromptEvent::SelectIdentity {
@@ -498,9 +525,15 @@ mod tests {
agent.vendor("test.action").await,
("Test vendor".into(), "https://example.test/vendor".into())
);
assert_eq!(agent.vendor("missing.action").await, (String::new(), String::new()));
assert_eq!(
agent.vendor("missing.action").await,
(String::new(), String::new())
);
server.close().await.unwrap();
assert_eq!(agent.vendor("test.action").await, (String::new(), String::new()));
assert_eq!(
agent.vendor("test.action").await,
(String::new(), String::new())
);
}
#[test]
@@ -516,7 +549,10 @@ mod tests {
let (kind, details) = process_subject().unwrap();
assert_eq!(kind, "unix-process");
assert_eq!(details["pid"], Value::from(std::process::id()));
assert_eq!(details["uid"], Value::from(unsafe { libc::geteuid() } as i32));
assert_eq!(
details["uid"],
Value::from(unsafe { libc::geteuid() } as i32)
);
assert!(u64::try_from(details["start-time"].clone()).unwrap() > 0);
}
+100 -34
View File
@@ -114,13 +114,18 @@ fn content_height(description: &str, status: Option<&str>) -> f32 {
.lines()
.map(|line| line.chars().count().div_ceil(48).max(1))
.sum();
let status_height = status.map_or(0, |message| 14 + 18 * message.chars().count().div_ceil(48).clamp(1, 3));
let status_height = status.map_or(0, |message| {
14 + 18 * message.chars().count().div_ceil(48).clamp(1, 3)
});
(214 + 18 * lines.saturating_sub(1) + status_height).min(360) as f32
}
fn dialog_height(request: &AuthenticationRequest, status: Option<&str>, expanded: bool) -> f32 {
let extra = if request.identities.len() > 1 { 54. } else { 0. }
+ if has_details(request) { 40. } else { 0. }
let extra = if request.identities.len() > 1 {
54.
} else {
0.
} + if has_details(request) { 40. } else { 0. }
+ if expanded { 96. } else { 0. };
(content_height(&request.message, status) + extra).min(360.)
}
@@ -141,7 +146,10 @@ fn action_icon(name: &str) -> Option<widget::icon::Handle> {
.map(widget::icon::from_path)
}
fn read_events(lines: impl Iterator<Item = std::io::Result<String>>, queue: &Mutex<VecDeque<PromptEvent>>) {
fn read_events(
lines: impl Iterator<Item = std::io::Result<String>>,
queue: &Mutex<VecDeque<PromptEvent>>,
) {
for line in lines {
let Ok(line) = line else { break };
if let Ok(event) = serde_json::from_str(&line) {
@@ -242,7 +250,11 @@ impl Prompt {
impl cosmic::Application for Prompt {
type Executor = cosmic::executor::Default;
type Flags = (Arc<Mutex<VecDeque<PromptEvent>>>, AuthenticationRequest, Appearance);
type Flags = (
Arc<Mutex<VecDeque<PromptEvent>>>,
AuthenticationRequest,
Appearance,
);
type Message = Message;
const APP_ID: &'static str = "dev.ferese.Authentication";
@@ -255,11 +267,15 @@ impl cosmic::Application for Prompt {
}
fn style(&self) -> Option<cosmic::iced::theme::Style> {
Some(self.appearance.palette().application_style(if self.material.is_some() {
cosmic::iced::Color::TRANSPARENT
} else {
self.appearance.surface
}))
Some(
self.appearance
.palette()
.application_style(if self.material.is_some() {
cosmic::iced::Color::TRANSPARENT
} else {
self.appearance.surface
}),
)
}
fn init(mut core: Core, (incoming, request, appearance): Self::Flags) -> (Self, Task<Message>) {
@@ -303,7 +319,8 @@ impl cosmic::Application for Prompt {
fn subscription(&self) -> Subscription<Message> {
Subscription::batch([
ferese_theme_client::service::subscription().map(|snapshot| Message::ThemeChanged(Box::new(snapshot))),
ferese_theme_client::service::subscription()
.map(|snapshot| Message::ThemeChanged(Box::new(snapshot))),
cosmic::iced::time::every(Duration::from_millis(30)).map(|_| Message::Tick),
cosmic::iced::event::listen_with(|event, _, id| match event {
cosmic::iced::Event::Window(cosmic::iced::window::Event::Opened { .. }) => {
@@ -321,8 +338,11 @@ impl cosmic::Application for Prompt {
return cosmic::command::set_theme(self.appearance.theme());
}
Message::WindowOpened(id) => {
return cosmic::iced::window::run(id, ferese_theme_client::material::ModalMaterial::attach)
.map(|result| cosmic::Action::App(Message::MaterialAttached(result)));
return cosmic::iced::window::run(
id,
ferese_theme_client::material::ModalMaterial::attach,
)
.map(|result| cosmic::Action::App(Message::MaterialAttached(result)));
}
Message::MaterialAttached(result) => {
self.material = result.ok();
@@ -336,7 +356,8 @@ impl cosmic::Application for Prompt {
if uid == self.request.selected_uid
&& generation.selection == self.request.generation.selection
&& (generation.attempt > self.request.generation.attempt
|| (generation == self.request.generation && self.awaiting_ack)) =>
|| (generation == self.request.generation
&& self.awaiting_ack)) =>
{
self.request.generation = generation;
self.reset_authentication(uid);
@@ -422,12 +443,18 @@ impl cosmic::Application for Prompt {
fn view(&self) -> Element<'_, Message> {
let palette = &self.appearance;
let material_opacity = if palette.high_contrast { 1.0 } else { palette.surface.a };
let material_opacity = if palette.high_contrast {
1.0
} else {
palette.surface.a
};
let mut input = widget::text_input(&self.question, self.answer.as_str())
.id(widget::Id::new("auth-response"))
.font(palette.font)
.padding([7, 12])
.style(ferese_theme::controls::authentication_input(palette.palette()));
.style(ferese_theme::controls::authentication_input(
palette.palette(),
));
if !self.echo {
input = input.password();
}
@@ -438,7 +465,9 @@ impl cosmic::Application for Prompt {
});
}
let action = button::custom(ferese_theme::text("Authenticate", palette.font).size(13))
.class(ferese_theme::controls::authentication_button(palette.palette()))
.class(ferese_theme::controls::authentication_button(
palette.palette(),
))
.height(Length::Fixed(36.))
.padding([8, 16])
.on_press_maybe((!self.waiting && !self.answer.is_empty()).then_some(Message::Submit));
@@ -461,7 +490,10 @@ impl cosmic::Application for Prompt {
.height(40)
.center_x(40)
.center_y(40)
.class(ferese_theme::controls::surface(palette.accent.scale_alpha(0.13), 12.,)),
.class(ferese_theme::controls::surface(
palette.accent.scale_alpha(0.13),
12.,
)),
column![
ferese_theme::text("Authentication required", palette.font).size(18),
ferese_theme::text(format!("Confirm as {user}"), palette.font)
@@ -472,9 +504,10 @@ impl cosmic::Application for Prompt {
]
.spacing(12)
.align_y(Alignment::Center);
let mut information = column![ferese_theme::text(&self.request.message, palette.font).size(13)]
.spacing(10)
.width(Length::Fill);
let mut information =
column![ferese_theme::text(&self.request.message, palette.font).size(13)]
.spacing(10)
.width(Length::Fill);
if has_details(&self.request) {
information = information.push(
button::custom(
@@ -522,15 +555,26 @@ impl cosmic::Application for Prompt {
ferese_theme::text("Account", palette.font)
.size(12)
.class(theme::Text::Color(palette.muted)),
widget::dropdown(&self.identity_names[..], selected, Message::SelectIdentity)
.width(Length::Fill),
ferese_theme::icons::tinted(ferese_theme::icons::CHEVRON_DOWN, 16, palette.muted),
widget::dropdown(
&self.identity_names[..],
selected,
Message::SelectIdentity
)
.width(Length::Fill),
ferese_theme::icons::tinted(
ferese_theme::icons::CHEVRON_DOWN,
16,
palette.muted
),
]
.spacing(10)
.align_y(Alignment::Center),
)
.padding([4, 10])
.class(ferese_theme::controls::surface(palette.accent.scale_alpha(0.08), 8.)),
.class(ferese_theme::controls::surface(
palette.accent.scale_alpha(0.08),
8.,
)),
);
}
body = body.push(input);
@@ -582,7 +626,9 @@ fn detail_row<'a>(key: &'a str, value: &'a str, palette: &Appearance) -> Element
.size(12)
.class(theme::Text::Color(palette.muted))
.width(Length::Fixed(106.)),
ferese_theme::text(value, palette.font).size(12).width(Length::Fill),
ferese_theme::text(value, palette.font)
.size(12)
.width(Length::Fill),
]
.spacing(8)
.into()
@@ -595,7 +641,9 @@ mod tests {
use cosmic::app::Core;
use super::{Appearance, Message, Prompt, action_icon, content_height, dialog_height, has_details};
use super::{
Appearance, Message, Prompt, action_icon, content_height, dialog_height, has_details,
};
use crate::tests::request_fixture;
#[test]
@@ -610,7 +658,8 @@ mod tests {
let (reader, mut writer) = UnixStream::pair().unwrap();
let incoming = Arc::new(Mutex::new(VecDeque::new()));
let queue = incoming.clone();
let reader_thread = std::thread::spawn(move || super::read_events(BufReader::new(reader).lines(), &queue));
let reader_thread =
std::thread::spawn(move || super::read_events(BufReader::new(reader).lines(), &queue));
writeln!(
writer,
"{{\"type\":\"request\",\"generation\":{{\"selection\":0,\"attempt\":0}},\"prompt\":\"Password:\",\"echo\":false}}"
@@ -618,9 +667,13 @@ mod tests {
.unwrap();
drop(writer);
reader_thread.join().unwrap();
assert!(matches!(incoming.lock().unwrap().back(), Some(PromptEvent::Cancel)));
assert!(matches!(
incoming.lock().unwrap().back(),
Some(PromptEvent::Cancel)
));
let appearance = Appearance::from_resolved(&ferese_config::theme::default_theme());
let (mut prompt, _) = Prompt::init(Core::default(), (incoming, request_fixture(), appearance));
let (mut prompt, _) =
Prompt::init(Core::default(), (incoming, request_fixture(), appearance));
*prompt.answer = "test-password".into();
prompt.waiting = false;
let _ = prompt.update(Message::Tick);
@@ -636,7 +689,10 @@ mod tests {
let incoming = Arc::new(Mutex::new(VecDeque::new()));
let appearance = Appearance::from_resolved(&ferese_config::theme::default_theme());
let (mut prompt, _) = Prompt::init(Core::default(), (incoming.clone(), request_fixture(), appearance));
let (mut prompt, _) = Prompt::init(
Core::default(),
(incoming.clone(), request_fixture(), appearance),
);
assert_eq!(prompt.select_identity(1), Some(1001));
let older = prompt.request.generation;
assert_eq!(prompt.select_identity(0), Some(1000));
@@ -700,7 +756,10 @@ mod tests {
assert_eq!(prompt.question, "Current password");
// A fresh retry gets its own generation, even for the same account.
let retry = Generation { attempt: 1, ..current };
let retry = Generation {
attempt: 1,
..current
};
incoming.lock().unwrap().extend([
PromptEvent::IdentityChanged {
generation: retry,
@@ -732,7 +791,11 @@ mod tests {
let appearance = Appearance::from_resolved(&ferese_config::theme::default_theme());
let (mut prompt, _) = <Prompt as cosmic::Application>::init(
Core::default(),
(Arc::new(Mutex::new(VecDeque::new())), request_fixture(), appearance),
(
Arc::new(Mutex::new(VecDeque::new())),
request_fixture(),
appearance,
),
);
*prompt.answer = "test-response".into();
prompt.waiting = false;
@@ -755,7 +818,10 @@ mod tests {
fn full_requests_and_expanded_details_keep_the_height_cap() {
let request = request_fixture();
assert_eq!(dialog_height(&request, None, false), 360.);
assert_eq!(dialog_height(&request, Some("Password not accepted"), true), 360.);
assert_eq!(
dialog_height(&request, Some("Password not accepted"), true),
360.
);
assert!(has_details(&request));
let mut short = request;
short.message = "Short request".into();
+113 -32
View File
@@ -37,21 +37,29 @@ impl Api {
static LIBRARIES: OnceLock<Result<(Library, Library), String>> = OnceLock::new();
let (agent, polkit) = LIBRARIES
.get_or_init(|| {
let agent = Library::new("libpolkit-agent-1.so.0").map_err(|e| e.to_string())?;
let polkit = Library::new("libpolkit-gobject-1.so.0").map_err(|e| e.to_string())?;
let agent =
Library::new("libpolkit-agent-1.so.0").map_err(|e| e.to_string())?;
let polkit =
Library::new("libpolkit-gobject-1.so.0").map_err(|e| e.to_string())?;
Ok((agent, polkit))
})
.as_ref()
.map_err(Clone::clone)?;
let user_new = *polkit.get(b"polkit_unix_user_new\0").map_err(|e| e.to_string())?;
let session_new = *agent.get(b"polkit_agent_session_new\0").map_err(|e| e.to_string())?;
let user_new = *polkit
.get(b"polkit_unix_user_new\0")
.map_err(|e| e.to_string())?;
let session_new = *agent
.get(b"polkit_agent_session_new\0")
.map_err(|e| e.to_string())?;
let initiate = *agent
.get(b"polkit_agent_session_initiate\0")
.map_err(|e| e.to_string())?;
let response = *agent
.get(b"polkit_agent_session_response\0")
.map_err(|e| e.to_string())?;
let cancel = *agent.get(b"polkit_agent_session_cancel\0").map_err(|e| e.to_string())?;
let cancel = *agent
.get(b"polkit_agent_session_cancel\0")
.map_err(|e| e.to_string())?;
Ok(Self {
user_new,
@@ -69,7 +77,9 @@ pub fn check() -> Result<(), String> {
}
pub(crate) fn username(uid: u32) -> String {
let output = Command::new("getent").args(["passwd", &uid.to_string()]).output();
let output = Command::new("getent")
.args(["passwd", &uid.to_string()])
.output();
output
.ok()
.filter(|output| output.status.success())
@@ -132,21 +142,32 @@ fn prompt_process(request: AuthenticationRequest) -> Result<PromptProcess, Strin
Ok(process)
}
unsafe extern "C" fn request_signal(_session: Object, prompt: *const c_char, echo: c_int, data: *mut c_void) {
unsafe extern "C" fn request_signal(
_session: Object,
prompt: *const c_char,
echo: c_int,
data: *mut c_void,
) {
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
let prompt = unsafe { CStr::from_ptr(prompt) }.to_string_lossy().into_owned();
let prompt = unsafe { CStr::from_ptr(prompt) }
.to_string_lossy()
.into_owned();
let _ = tx.send(SessionEvent::Request(prompt, echo != 0));
}
unsafe extern "C" fn info(_session: Object, text: *const c_char, data: *mut c_void) {
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
let text = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned();
let text = unsafe { CStr::from_ptr(text) }
.to_string_lossy()
.into_owned();
let _ = tx.send(SessionEvent::Info(text));
}
unsafe extern "C" fn error(_session: Object, text: *const c_char, data: *mut c_void) {
let tx = unsafe { &*(data as *const Sender<SessionEvent>) };
let text = unsafe { CStr::from_ptr(text) }.to_string_lossy().into_owned();
let text = unsafe { CStr::from_ptr(text) }
.to_string_lossy()
.into_owned();
let _ = tx.send(SessionEvent::Error(text));
}
@@ -155,7 +176,12 @@ unsafe extern "C" fn completed(_session: Object, success: c_int, data: *mut c_vo
let _ = tx.send(SessionEvent::Completed(success != 0));
}
unsafe fn connect(session: Object, name: &'static CStr, callback: gobject_ffi::GCallback, data: *mut c_void) {
unsafe fn connect(
session: Object,
name: &'static CStr,
callback: gobject_ffi::GCallback,
data: *mut c_void,
) {
unsafe {
gobject_ffi::g_signal_connect_data(
session.cast(),
@@ -195,7 +221,10 @@ impl Drop for SessionGuard {
}
fn permitted_selection(request: &AuthenticationRequest, uid: u32) -> bool {
request.identities.iter().any(|identity| identity.uid == uid)
request
.identities
.iter()
.any(|identity| identity.uid == uid)
}
fn response_buffer(value: &str) -> Option<Zeroizing<Vec<u8>>> {
@@ -273,7 +302,7 @@ fn run_session(
unsafe extern "C" fn(Object, *const c_char, *mut c_void),
unsafe extern "C" fn(),
>(
info as unsafe extern "C" fn(Object, *const c_char, *mut c_void)
info as unsafe extern "C" fn(Object, *const c_char, *mut c_void),
)),
signal_data,
);
@@ -284,7 +313,7 @@ fn run_session(
unsafe extern "C" fn(Object, *const c_char, *mut c_void),
unsafe extern "C" fn(),
>(
error as unsafe extern "C" fn(Object, *const c_char, *mut c_void)
error as unsafe extern "C" fn(Object, *const c_char, *mut c_void),
)),
signal_data,
);
@@ -295,7 +324,7 @@ fn run_session(
unsafe extern "C" fn(Object, c_int, *mut c_void),
unsafe extern "C" fn(),
>(
completed as unsafe extern "C" fn(Object, c_int, *mut c_void)
completed as unsafe extern "C" fn(Object, c_int, *mut c_void),
)),
signal_data,
);
@@ -322,8 +351,13 @@ fn run_session(
},
)?;
}
SessionEvent::Info(text) => send(&mut process.writer, &PromptEvent::Info { generation, text })?,
SessionEvent::Error(text) => send(&mut process.writer, &PromptEvent::Error { generation, text })?,
SessionEvent::Info(text) => {
send(&mut process.writer, &PromptEvent::Info { generation, text })?
}
SessionEvent::Error(text) => send(
&mut process.writer,
&PromptEvent::Error { generation, text },
)?,
SessionEvent::Completed(success) => outcome = Some(success),
}
}
@@ -368,7 +402,11 @@ fn run_session(
if !stopped
&& (selected_uid.is_some()
|| cancelled.load(Ordering::Acquire)
|| process.child.try_wait().map_err(|e| e.to_string())?.is_some())
|| process
.child
.try_wait()
.map_err(|e| e.to_string())?
.is_some())
{
unsafe { (api.cancel)(session) };
stopped = true;
@@ -402,7 +440,14 @@ pub fn authenticate(
context
.with_thread_default(|| {
let mut process = prompt_process(request.clone())?;
authenticate_sessions(&api, &mut request, &cookie, &context, &mut process, &cancelled)
authenticate_sessions(
&api,
&mut request,
&cookie,
&context,
&mut process,
&cancelled,
)
})
.map_err(|error| error.to_string())?
}
@@ -421,7 +466,9 @@ fn authenticate_sessions(
loop {
match run_session(api, request, cookie, context, process, cancelled) {
Ok(SessionOutcome::Completed(true)) => break Ok(true),
Ok(SessionOutcome::IdentityChanged { uid, generation }) if !cancelled.load(Ordering::Acquire) => {
Ok(SessionOutcome::IdentityChanged { uid, generation })
if !cancelled.load(Ordering::Acquire) =>
{
request.selected_uid = uid;
request.generation = generation;
}
@@ -429,7 +476,9 @@ fn authenticate_sessions(
failures += 1;
// Switching accounts never resets this request's attempt budget.
if failures >= MAX_AUTH_ATTEMPTS {
break Err(format!("Authentication failed after {MAX_AUTH_ATTEMPTS} attempts"));
break Err(format!(
"Authentication failed after {MAX_AUTH_ATTEMPTS} attempts"
));
}
request.generation.attempt += 1;
}
@@ -448,7 +497,12 @@ mod tests {
unsafe extern "C" fn fake_initiate(session: Object) {
unsafe {
gobject_ffi::g_signal_emit_by_name(session.cast(), c"request".as_ptr(), c"Password:".as_ptr(), 0 as c_int);
gobject_ffi::g_signal_emit_by_name(
session.cast(),
c"request".as_ptr(),
c"Password:".as_ptr(),
0 as c_int,
);
}
}
@@ -502,7 +556,8 @@ mod tests {
let mut uid = 1000;
for line in BufReader::new(output).lines() {
let Ok(line) = line else { break };
if let Ok(PromptEvent::Request { generation, .. }) = serde_json::from_str::<PromptEvent>(&line)
if let Ok(PromptEvent::Request { generation, .. }) =
serde_json::from_str::<PromptEvent>(&line)
{
let count = counter.fetch_add(1, Ordering::SeqCst) + 1;
let event = if count == 3 {
@@ -527,7 +582,11 @@ mod tests {
}
}
});
let mut process = PromptProcess { child, writer, input };
let mut process = PromptProcess {
child,
writer,
input,
};
let mut request = request_fixture();
let result = authenticate_sessions(
&api,
@@ -563,13 +622,21 @@ mod tests {
let context = glib::MainContext::new();
context
.with_thread_default(|| {
let mut child = Command::new("sleep").arg("5").stdin(Stdio::piped()).spawn().unwrap();
let mut child = Command::new("sleep")
.arg("5")
.stdin(Stdio::piped())
.spawn()
.unwrap();
let writer = BufWriter::new(child.stdin.take().unwrap());
let cookie = CString::new("test-cookie").unwrap();
let cancelled = AtomicBool::new(false);
let mut request = request_fixture();
let (tx, input) = mpsc::channel();
let mut process = PromptProcess { child, writer, input };
let mut process = PromptProcess {
child,
writer,
input,
};
tx.send(PromptEvent::SelectIdentity {
uid: 1001,
generation: Generation {
@@ -585,7 +652,8 @@ mod tests {
})
.unwrap();
assert_eq!(
run_session(&api, &request, &cookie, &context, &mut process, &cancelled).unwrap(),
run_session(&api, &request, &cookie, &context, &mut process, &cancelled)
.unwrap(),
SessionOutcome::IdentityChanged {
uid: 1001,
generation: Generation {
@@ -631,13 +699,15 @@ mod tests {
})
.unwrap();
assert_eq!(
run_session(&api, &request, &cookie, &context, &mut process, &cancelled).unwrap(),
run_session(&api, &request, &cookie, &context, &mut process, &cancelled)
.unwrap(),
SessionOutcome::Completed(true)
);
assert_eq!(RESPONSES.load(Ordering::SeqCst), 1);
tx.send(PromptEvent::Cancel).unwrap();
assert_eq!(
run_session(&api, &request, &cookie, &context, &mut process, &cancelled).unwrap(),
run_session(&api, &request, &cookie, &context, &mut process, &cancelled)
.unwrap(),
SessionOutcome::Cancelled
);
})
@@ -652,13 +722,24 @@ mod tests {
let context = glib::MainContext::new();
context
.with_thread_default(|| {
let mut child = Command::new("sleep").arg("5").stdin(Stdio::piped()).spawn().unwrap();
let mut child = Command::new("sleep")
.arg("5")
.stdin(Stdio::piped())
.spawn()
.unwrap();
let writer = BufWriter::new(child.stdin.take().unwrap());
let (tx, input) = mpsc::channel();
let mut process = PromptProcess { child, writer, input };
let mut process = PromptProcess {
child,
writer,
input,
};
for (selection, uid) in [(2, 1001), (3, 1000), (1, 1001), (2, 1001)] {
tx.send(PromptEvent::SelectIdentity {
generation: Generation { selection, attempt: 0 },
generation: Generation {
selection,
attempt: 0,
},
uid,
})
.unwrap();