add logic for fingerprint verification

This commit is contained in:
Ferdinand Schober
2024-09-27 16:23:31 +02:00
parent 1c7490c58d
commit dedf59d1c7
16 changed files with 182 additions and 57 deletions

View File

@@ -12,7 +12,9 @@ use gtk::{
#[template(resource = "/de/feschber/LanMouse/fingerprint_window.ui")]
pub struct FingerprintWindow {
#[template_child]
pub text: TemplateChild<Text>,
pub description: TemplateChild<Text>,
#[template_child]
pub fingerprint: TemplateChild<Text>,
#[template_child]
pub confirm_button: TemplateChild<Button>,
}
@@ -39,8 +41,9 @@ impl ObjectSubclass for FingerprintWindow {
impl FingerprintWindow {
#[template_callback]
fn handle_confirm(&self, _button: Button) {
let fp = self.text.text().to_string();
self.obj().emit_by_name("confirm-clicked", &[&fp])
let desc = self.description.text().to_string();
let fp = self.fingerprint.text().to_string();
self.obj().emit_by_name("confirm-clicked", &[&fp, &desc])
}
}
@@ -49,7 +52,7 @@ impl ObjectImpl for FingerprintWindow {
static SIGNALS: OnceLock<Vec<Signal>> = OnceLock::new();
SIGNALS.get_or_init(|| {
vec![Signal::builder("confirm-clicked")
.param_types([String::static_type()])
.param_types([String::static_type(), String::static_type()])
.build()]
})
}

View File

@@ -8,8 +8,15 @@ glib::wrapper! {
}
impl KeyObject {
pub fn new(fp: String) -> Self {
Object::builder().property("fingerprint", fp).build()
pub fn new(desc: String, fp: String) -> Self {
Object::builder()
.property("description", desc)
.property("fingerprint", fp)
.build()
}
pub fn get_description(&self) -> String {
self.imp().description.borrow().clone()
}
pub fn get_fingerprint(&self) -> String {

View File

@@ -8,6 +8,8 @@ use gtk::subclass::prelude::*;
#[derive(Properties, Default)]
#[properties(wrapper_type = super::KeyObject)]
pub struct KeyObject {
#[property(name = "description", get, set, type = String)]
pub description: RefCell<String>,
#[property(name = "fingerprint", get, set, type = String)]
pub fingerprint: RefCell<String>,
}

View File

@@ -21,11 +21,17 @@ impl KeyRow {
let mut bindings = self.imp().bindings.borrow_mut();
let title_binding = key_object
.bind_property("fingerprint", self, "title")
.bind_property("description", self, "title")
.sync_create()
.build();
let subtitle_binding = key_object
.bind_property("fingerprint", self, "subtitle")
.sync_create()
.build();
bindings.push(title_binding);
bindings.push(subtitle_binding);
}
pub fn unbind(&self) {

View File

@@ -139,6 +139,9 @@ fn build_ui(app: &Application) {
FrontendEvent::AuthorizedUpdated(keys) => {
window.set_authorized_keys(keys);
}
FrontendEvent::PublicKeyFingerprint(fp) => {
window.set_pk_fp(&fp);
}
}
}
}

View File

@@ -1,6 +1,6 @@
mod imp;
use std::collections::HashSet;
use std::collections::HashMap;
use adw::prelude::*;
use adw::subclass::prelude::*;
@@ -360,8 +360,8 @@ impl Window {
closure_local!(
#[strong(rename_to = parent)]
self,
move |w: FingerprintWindow, fp: String| {
parent.request_fingerprint_add(fp);
move |w: FingerprintWindow, desc: String, fp: String| {
parent.request_fingerprint_add(desc, fp);
w.close();
}
),
@@ -369,12 +369,12 @@ impl Window {
window.present();
}
pub fn request_fingerprint_add(&self, fp: String) {
self.request(FrontendRequest::FingerprintAdd(fp));
pub fn request_fingerprint_add(&self, desc: String, fp: String) {
self.request(FrontendRequest::AuthorizeKey(desc, fp));
}
pub fn request_fingerprint_remove(&self, fp: String) {
self.request(FrontendRequest::FingerprintRemove(fp));
self.request(FrontendRequest::RemoveAuthorizedKey(fp));
}
pub fn request(&self, request: FrontendRequest) {
@@ -411,15 +411,19 @@ impl Window {
.set_visible(!capture || !emulation);
}
pub(crate) fn set_authorized_keys(&self, fingerprints: HashSet<String>) {
pub(crate) fn set_authorized_keys(&self, fingerprints: HashMap<String, String>) {
let authorized = self.authorized();
// clear list
authorized.remove_all();
// insert fingerprints
for fingerprint in fingerprints {
let key_obj = KeyObject::new(fingerprint);
for (description, fingerprint) in fingerprints {
let key_obj = KeyObject::new(description, fingerprint);
authorized.append(&key_obj);
}
self.update_auth_placeholder_visibility();
}
pub(crate) fn set_pk_fp(&self, fingerprint: &str) {
self.imp().fingerprint_row.set_subtitle(fingerprint);
}
}

View File

@@ -14,6 +14,8 @@ pub struct Window {
#[template_child]
pub authorized_placeholder: TemplateChild<ActionRow>,
#[template_child]
pub fingerprint_row: TemplateChild<ActionRow>,
#[template_child]
pub port_edit_apply: TemplateChild<Button>,
#[template_child]
pub port_edit_cancel: TemplateChild<Button>,
@@ -93,6 +95,25 @@ impl Window {
}
}
#[template_callback]
fn handle_copy_fingerprint(&self, button: &Button) {
let fingerprint: String = self.fingerprint_row.property("subtitle");
let display = gdk::Display::default().unwrap();
let clipboard = display.clipboard();
clipboard.set_text(&fingerprint);
button.set_icon_name("emblem-ok-symbolic");
button.set_css_classes(&["success"]);
glib::spawn_future_local(clone!(
#[weak]
button,
async move {
glib::timeout_future_seconds(1).await;
button.set_icon_name("edit-copy-symbolic");
button.set_css_classes(&[]);
}
));
}
#[template_callback]
fn handle_port_changed(&self, _entry: &Entry) {
self.port_edit_apply.set_visible(true);