Skip to content
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
5 changes: 5 additions & 0 deletions i18n/en/cosmic_ext_fprint.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ welcome = Register and/or delete fingerprints
git-description = Git commit {$hash} on {$date}
register = Register
delete = Delete
clear-device = Clear Device
confirm-clear = Are you sure?
clearing-device = Clearing all fingerprints from device for all known users...
device-cleared = Device cleared for all known users.
clear-device-confirm = Are you sure you want to clear fingerprints for ALL known users? Hardware-level orphaned prints may remain.
deleting = Deleting fingerprint...
deleted = Deleted fingerprint.
cancel = Cancel
Expand Down
38 changes: 31 additions & 7 deletions src/app/fprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,43 @@ pub async fn delete_fingerprint_dbus(
res.and(rel_res)
}

pub async fn delete_fingers(
pub async fn clear_all_fingers_dbus(
connection: &zbus::Connection,
path: zbus::zvariant::OwnedObjectPath,
username: String,
usernames: Vec<String>,
) -> zbus::Result<()> {
let device = DeviceProxy::builder(connection).path(path)?.build().await?;
let mut last_error = None;

device.claim(&username).await?;
let enrolled = device.list_enrolled_fingers(&username).await?;
for finger in enrolled {
device.delete_enrolled_finger(&finger).await?;
for username in usernames {
if let Err(e) = device.claim(&username).await {
last_error = Some(e);
continue;
}

match device.list_enrolled_fingers(&username).await {
Ok(fingers) => {
for finger in fingers {
if let Err(e) = device.delete_enrolled_finger(&finger).await {
last_error = Some(e);
}
}
}
Err(e) => {
last_error = Some(e);
}
}

if let Err(e) = device.release().await {
last_error = Some(e);
}
}

if let Some(e) = last_error {
Err(e)
} else {
Ok(())
}
device.release().await
}

pub async fn enroll_fingerprint_process<S>(
Expand Down
2 changes: 2 additions & 0 deletions src/app/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub enum Message {
EnrollStatus(String, bool),
EnrollStop,
DeleteComplete,
ClearDevice,
ClearComplete(Result<(), AppError>),
EnrolledFingers(Vec<String>),
UsersFound(Vec<UserOption>),
UserSelected(UserOption),
Expand Down
67 changes: 63 additions & 4 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use page::{ContextPage, Page};
use message::{Message, UserOption};
use fprint::{
delete_fingerprint_dbus, delete_fingers, enroll_fingerprint_process, find_device,
list_enrolled_fingers_dbus,
clear_all_fingers_dbus,list_enrolled_fingers_dbus,
};
use error::AppError;

Expand Down Expand Up @@ -76,6 +76,8 @@ pub struct AppModel {
selected_user: Option<UserOption>,
// List of enrolled fingers
enrolled_fingers: Vec<String>,
// Confirmation state for clearing the device
confirm_clear: bool,
}

/// Create a COSMIC application from the app model
Expand Down Expand Up @@ -151,6 +153,7 @@ impl cosmic::Application for AppModel {
realname: Arc::new(u.gecos.to_string_lossy().into_owned()),
}),
enrolled_fingers: Vec::new(),
confirm_clear: false,
};

// Create a startup command that sets the window title.
Expand Down Expand Up @@ -352,6 +355,22 @@ impl cosmic::Application for AppModel {

Message::Delete => self.on_delete(),

Message::ClearDevice => self.on_clear_device(),

Message::ClearComplete(res) => {
match res {
Ok(_) => {
self.status = fl!("device-cleared");
self.enrolled_fingers.clear();
}
Err(e) => {
self.status = e.localized_message();
}
}
self.busy = false;
Task::none()
}

Message::Register => self.on_register(),

Message::OpenRepositoryUrl => {
Expand Down Expand Up @@ -393,7 +412,7 @@ impl cosmic::Application for AppModel {
if self.busy {
return Task::none();
}

self.confirm_clear = false;
// Activate the page in the model.
self.nav.activate(id);

Expand Down Expand Up @@ -574,7 +593,7 @@ impl AppModel {
if self.busy {
return Task::none();
}

self.confirm_clear = false;
self.selected_user = Some(user.clone());
self.enrolled_fingers.clear();
self.list_fingers_task()
Expand Down Expand Up @@ -659,6 +678,32 @@ impl AppModel {
Task::none()
}

fn on_clear_device(&mut self) -> Task<cosmic::Action<Message>> {
if !self.confirm_clear {
self.confirm_clear = true;
self.status = fl!("clear-device-confirm");
return Task::none();
}

if let (Some(path), Some(conn)) = (self.device_path.clone(), self.connection.clone()) {
self.status = fl!("clearing-device");
self.busy = true;
self.confirm_clear = false;
let path = (*path).clone();
let usernames: Vec<String> = self.users.iter().map(|u| (*u.username).clone()).collect();
return Task::perform(
async move {
match clear_all_fingers_dbus(&conn, path, usernames).await {
Ok(_) => Message::ClearComplete(Ok(())),
Err(e) => Message::ClearComplete(Err(AppError::from(e))),
}
},
cosmic::Action::App,
);
}
Task::none()
}

fn on_delete(&mut self) -> Task<cosmic::Action<Message>> {
if let Some(page) = self.nav.data::<Page>(self.nav.active())
&& let (Some(path), Some(conn), Some(user)) = (
Expand Down Expand Up @@ -796,6 +841,12 @@ impl AppModel {

let register_btn = widget::button::text(fl!("register"));
let delete_btn = widget::button::text(fl!("delete"));
let clear_text = if self.confirm_clear {
fl!("confirm-clear")
} else {
fl!("clear-device")
};
let clear_btn = widget::button::text(clear_text);

let register_btn = if buttons_enabled && current_finger.is_some() {
register_btn.on_press(Message::Register)
Expand All @@ -809,14 +860,22 @@ impl AppModel {
delete_btn
};

let clear_btn = if !self.busy && self.device_path.is_some() && self.enrolling_finger.is_none()
{
clear_btn.on_press(Message::ClearDevice)
} else {
clear_btn
};

let mut cancel_btn = widget::button::text(fl!("cancel"));
if self.enrolling_finger.is_some() {
cancel_btn = cancel_btn.on_press(Message::EnrollStop);
}

let mut row = widget::row()
.push(register_btn)
.push(delete_btn);
.push(delete_btn)
.push(clear_btn);

if self.enrolling_finger.is_some() {
row = row.push(cancel_btn);
Expand Down