simple_authentication/simple_authentication.rs
1//! # Recommended usage
2//!
3//! `Context::authenticate()` is asynchronous: it returns immediately after *starting*
4//! authentication and delivers the final result via the callback.
5//!
6//! **In GUI applications**, you typically do not need any additional synchronization.
7//! The application's event loop keeps the process alive while the user interacts with
8//! the authentication prompt.
9//!
10//! ```no_run
11//! let context = Context::new(());
12//! context.authenticate(TEXT, &POLICY, |result| {
13//! match result {
14//! Ok(()) => println!("Authentication successful"),
15//! Err(e) => eprintln!("Authentication failed: {:?}", e),
16//! }
17//! });
18//! ```
19//!
20//! # Why this example uses `mpsc::channel()`
21//!
22//! This file is a CLI-style demo. Without an event loop, `main()` would exit before the
23//! authentication completes (especially on Linux where the polkit check runs in the
24//! background). We therefore use an `mpsc::channel()` to wait for the callback.
25//!
26//! # Linux notes
27//!
28//! - Ensure the polkit policy file is installed for the chosen `action_id`
29//! (see README: "Usage on Linux").
30//! - Ensure a polkit authentication agent is running in the current desktop session,
31//! otherwise no prompt will appear and the request will fail with `NoAgent`/`Unavailable`.
32
33use std::sync::mpsc;
34
35use robius_authentication::{
36 AndroidText, BiometricStrength, Context, PolicyBuilder, Text, WindowsText,
37};
38
39const TEXT: Text = Text {
40 android: AndroidText {
41 title: "Title",
42 subtitle: None,
43 description: None,
44 },
45 apple: "authenticate",
46 windows: match WindowsText::new("Title", "Description") {
47 Some(text) => text,
48 None => panic!("Windows text too long"),
49 },
50};
51
52fn main() {
53 let context = Context::new(());
54 let mut policy = PolicyBuilder::new()
55 // On Linux You need to set action_ids.
56 // See: ./org.robius.authentication.policy file settings and (README: "Usage on Linux").
57 .action_ids([
58 "org.robius.authentication",
59 "org.robius.authentication.settings",
60 ])
61 .biometrics(Some(BiometricStrength::Strong))
62 .password(true)
63 .companion(true)
64 .build()
65 .unwrap();
66
67 if let Err(e) = policy.set_action_id("org.robius.authentication.settings") {
68 eprintln!("Invalid action_id: {:?}", e);
69 return;
70 }
71
72 let (tx, rx) = mpsc::channel();
73
74 // Start authentication. `res` only indicates whether the request was successfully
75 // initiated; the final result is delivered via the callback.
76 let res = context.authenticate(TEXT, &policy, move |result| {
77 let _ = tx.send(result);
78 });
79
80 if let Err(e) = res {
81 eprintln!("Failed to start authentication: {:?}", e);
82 return;
83 }
84
85 // Block until the callback produces a result.
86 match rx.recv() {
87 Ok(Ok(_)) => println!("Authentication successful"),
88 Ok(Err(e)) => println!("Authentication failed: {:?}", e),
89 Err(e) => eprintln!("Failed to receive auth result: {:?}", e),
90 }
91}