Skip to content

Commit 1918352

Browse files
authored
Merge pull request #63 from linux-credentials/cleanup
Cleanup
2 parents b8d9742 + 1bf5864 commit 1918352

27 files changed

Lines changed: 790 additions & 1813 deletions

creds-lib/Cargo.lock

Lines changed: 3 additions & 366 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

creds-lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ license = "LGPL-3.0-only"
99
futures-lite = "2.6.0"
1010
libwebauthn = "0.2"
1111
serde = { version = "1", features = ["derive"] }
12-
zbus = "5.9.0"
12+
zvariant = "5.6.0"

creds-lib/src/client.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use futures_lite::Stream;
55
use crate::model::{BackgroundEvent, Device};
66

77
/// Used for communication from trusted UI to credential service
8-
pub trait CredentialServiceClient {
8+
pub trait FlowController {
99
fn get_available_public_key_devices(
1010
&self,
1111
) -> impl Future<Output = Result<Vec<Device>, ()>> + Send;

creds-lib/src/model.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Display;
22

33
use serde::{Deserialize, Serialize};
4-
use zbus::zvariant::{SerializeDict, Type};
4+
use zvariant::{SerializeDict, Type};
55

66
pub use libwebauthn::ops::webauthn::{
77
Assertion, GetAssertionRequest, MakeCredentialRequest, MakeCredentialResponse,
@@ -22,8 +22,8 @@ pub enum CredentialRequest {
2222

2323
#[derive(Clone, Debug)]
2424
pub enum CredentialResponse {
25-
CreatePublicKeyCredentialResponse(MakeCredentialResponseInternal),
26-
GetPublicKeyCredentialResponse(GetAssertionResponseInternal),
25+
CreatePublicKeyCredentialResponse(Box<MakeCredentialResponseInternal>),
26+
GetPublicKeyCredentialResponse(Box<GetAssertionResponseInternal>),
2727
}
2828

2929
impl CredentialResponse {
@@ -32,17 +32,18 @@ impl CredentialResponse {
3232
transports: &[&str],
3333
modality: &str,
3434
) -> CredentialResponse {
35-
CredentialResponse::CreatePublicKeyCredentialResponse(MakeCredentialResponseInternal::new(
36-
response.clone(),
37-
transports.iter().map(|s| s.to_string()).collect(),
38-
modality.to_string(),
35+
CredentialResponse::CreatePublicKeyCredentialResponse(Box::new(
36+
MakeCredentialResponseInternal::new(
37+
response.clone(),
38+
transports.iter().map(|s| s.to_string()).collect(),
39+
modality.to_string(),
40+
),
3941
))
4042
}
4143

4244
pub fn from_get_assertion(assertion: &Assertion, modality: &str) -> CredentialResponse {
43-
CredentialResponse::GetPublicKeyCredentialResponse(GetAssertionResponseInternal::new(
44-
assertion.clone(),
45-
modality.to_string(),
45+
CredentialResponse::GetPublicKeyCredentialResponse(Box::new(
46+
GetAssertionResponseInternal::new(assertion.clone(), modality.to_string()),
4647
))
4748
}
4849
}
@@ -260,6 +261,7 @@ pub enum UsbState {
260261
Failed(Error),
261262
}
262263

264+
#[derive(Debug)]
263265
pub enum BackgroundEvent {
264266
UsbStateChanged(UsbState),
265267
HybridQrStateChanged(HybridState),

creds-lib/src/server.rs

Lines changed: 4 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
//! Types for serializing across D-Bus instances
2+
13
use std::collections::HashMap;
24

35
use serde::{Deserialize, Serialize};
4-
use zbus::zvariant::{self, DeserializeDict, LE, Optional, OwnedValue, SerializeDict, Type, Value};
6+
use zvariant::{self, DeserializeDict, LE, Optional, OwnedValue, SerializeDict, Type, Value};
57

6-
use crate::model::{Operation, ViewUpdate};
8+
use crate::model::Operation;
79

810
#[derive(Clone, Debug, Serialize, Deserialize, Type)]
911
pub enum BackgroundEvent {
@@ -96,89 +98,6 @@ impl From<CreatePublicKeyCredentialResponse> for CreateCredentialResponse {
9698
}
9799
}
98100

99-
/// Updates to send to the client
100-
#[derive(Serialize, Deserialize, Type)]
101-
pub enum ClientUpdate {
102-
SetTitle(OwnedValue),
103-
SetDevices(OwnedValue),
104-
SetCredentials(OwnedValue),
105-
106-
WaitingForDevice(OwnedValue),
107-
SelectingDevice(OwnedValue),
108-
109-
UsbNeedsPin(OwnedValue),
110-
UsbNeedsUserVerification(OwnedValue),
111-
UsbNeedsUserPresence(OwnedValue),
112-
113-
HybridNeedsQrCode(OwnedValue),
114-
HybridConnecting(OwnedValue),
115-
HybridConnected(OwnedValue),
116-
117-
Completed(OwnedValue),
118-
Failed(OwnedValue),
119-
}
120-
121-
impl TryFrom<ClientUpdate> for ViewUpdate {
122-
type Error = zvariant::Error;
123-
fn try_from(value: ClientUpdate) -> std::result::Result<ViewUpdate, Self::Error> {
124-
match value {
125-
ClientUpdate::SetTitle(v) => v.try_into().map(Self::SetTitle),
126-
ClientUpdate::SetDevices(v) => {
127-
let dbus_devices: Vec<Device> = Value::<'_>::from(v).try_into()?;
128-
let devices: std::result::Result<Vec<crate::model::Device>, zvariant::Error> =
129-
dbus_devices
130-
.into_iter()
131-
.map(|d| {
132-
d.try_into().map_err(|_| {
133-
zvariant::Error::Message(
134-
"Could not deserialize devices".to_string(),
135-
)
136-
})
137-
})
138-
.collect();
139-
Ok(Self::SetDevices(devices?))
140-
}
141-
ClientUpdate::SetCredentials(v) => {
142-
let dbus_credentials: Vec<Credential> = Value::<'_>::from(v).try_into()?;
143-
let credentials: std::result::Result<
144-
Vec<crate::model::Credential>,
145-
zvariant::Error,
146-
> = dbus_credentials
147-
.into_iter()
148-
.map(|creds| Ok(creds.into()))
149-
.collect();
150-
Ok(Self::SetCredentials(credentials?))
151-
}
152-
153-
ClientUpdate::WaitingForDevice(v) => {
154-
let dbus_device: Device = Value::<'_>::from(v).try_into()?;
155-
let device: crate::model::Device = dbus_device.try_into().map_err(|_| {
156-
zvariant::Error::Message("Could not deserialize device".to_string())
157-
})?;
158-
Ok(Self::WaitingForDevice(device))
159-
}
160-
ClientUpdate::SelectingDevice(_) => Ok(Self::SelectingDevice),
161-
162-
ClientUpdate::UsbNeedsPin(v) => v.try_into().map(|x: i32| {
163-
let attempts_left = if x == -1 { None } else { Some(x as u32) };
164-
Self::UsbNeedsPin { attempts_left }
165-
}),
166-
ClientUpdate::UsbNeedsUserVerification(v) => v.try_into().map(|x: i32| {
167-
let attempts_left = if x == -1 { None } else { Some(x as u32) };
168-
Self::UsbNeedsUserVerification { attempts_left }
169-
}),
170-
ClientUpdate::UsbNeedsUserPresence(_) => Ok(Self::UsbNeedsUserPresence),
171-
172-
ClientUpdate::HybridNeedsQrCode(v) => v.try_into().map(Self::HybridNeedsQrCode),
173-
ClientUpdate::HybridConnecting(_) => Ok(Self::HybridConnecting),
174-
ClientUpdate::HybridConnected(_) => Ok(Self::HybridConnected),
175-
176-
ClientUpdate::Completed(_) => Ok(Self::Completed),
177-
ClientUpdate::Failed(v) => v.try_into().map(Self::Failed),
178-
}
179-
}
180-
}
181-
182101
#[derive(SerializeDict, DeserializeDict, Type, Value)]
183102
#[zvariant(signature = "dict")]
184103
pub struct Credential {
@@ -207,18 +126,6 @@ impl From<crate::model::Credential> for Credential {
207126
}
208127
}
209128

210-
/*
211-
impl TryFrom<Value<'_>> for Credential {
212-
type Error = zvariant::Error;
213-
fn try_from(value: Value<'_>) -> std::result::Result<Self, Self::Error> {
214-
let ctx = zvariant::serialized::Context::new_dbus(LE, 0);
215-
let encoded = zvariant::to_bytes(ctx, &value)?;
216-
let credential: Credential = encoded.deserialize()?.0;
217-
Ok(credential)
218-
}
219-
}
220-
*/
221-
222129
#[derive(SerializeDict, DeserializeDict, Type)]
223130
#[zvariant(signature = "a{sv}")]
224131
pub struct Device {

creds-ui/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

creds-ui/src/client.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use async_std::stream::Stream;
2-
use creds_lib::client::CredentialServiceClient;
2+
use creds_lib::client::FlowController;
33
use futures_lite::StreamExt;
44
use zbus::{Connection, zvariant};
55

@@ -20,7 +20,7 @@ impl DbusCredentialClient {
2020
}
2121
}
2222

23-
impl CredentialServiceClient for DbusCredentialClient {
23+
impl FlowController for DbusCredentialClient {
2424
async fn get_available_public_key_devices(
2525
&self,
2626
) -> std::result::Result<Vec<creds_lib::model::Device>, ()> {
@@ -81,7 +81,7 @@ impl CredentialServiceClient for DbusCredentialClient {
8181
.initiate_event_stream()
8282
.await
8383
.map_err(|err| tracing::error!("Failed to initialize event stream: {err}"))
84-
.and_then(|_| Ok(stream))
84+
.map(|_| stream)
8585
}
8686

8787
async fn enter_client_pin(&mut self, pin: String) -> std::result::Result<(), ()> {

creds-ui/src/dbus.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pub trait FlowControlService {
2727

2828
pub struct UiControlService {
2929
pub request_tx: Sender<crate::dbus::ViewRequest>,
30-
// pub update_tx: Sender<BackgroundEvent>,
3130
}
3231

3332
/// These methods are called by the credential service to control the UI.
@@ -40,5 +39,4 @@ impl UiControlService {
4039
.await
4140
.map_err(|_| fdo::Error::Failed("UI failed to launch".to_string()))
4241
}
43-
// fn send_state_changed(&self, event: BackgroundEvent) {}
4442
}

creds-ui/src/gui/mod.rs

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,32 @@ use std::{sync::Arc, thread::JoinHandle};
66
use async_std::{channel::Receiver, sync::Mutex as AsyncMutex};
77

88
use creds_lib::server::ViewRequest;
9-
use creds_lib::{
10-
client::CredentialServiceClient,
11-
model::{Operation, ViewUpdate},
12-
};
9+
use creds_lib::{client::FlowController, model::ViewUpdate};
1310

1411
use view_model::ViewEvent;
1512

16-
pub(super) fn start_gui_thread<C: CredentialServiceClient + Send + Sync + 'static>(
13+
pub(super) fn start_gui_thread<F: FlowController + Send + Sync + 'static>(
1714
rx: Receiver<ViewRequest>,
18-
client: C,
15+
flow_controller: F,
1916
) -> Result<JoinHandle<()>, std::io::Error> {
2017
thread::Builder::new().name("gui".into()).spawn(move || {
21-
let client = Arc::new(AsyncMutex::new(client));
18+
let flow_controller = Arc::new(AsyncMutex::new(flow_controller));
2219
// D-Bus received a request and needs a window open
2320
while let Ok(view_request) = rx.recv_blocking() {
24-
run_gui(client.clone(), view_request);
21+
run_gui(flow_controller.clone(), view_request);
2522
}
2623
})
2724
}
2825

29-
fn run_gui<C: CredentialServiceClient + Send + Sync + 'static>(
30-
client: Arc<AsyncMutex<C>>,
26+
fn run_gui<F: FlowController + Send + Sync + 'static>(
27+
flow_controller: Arc<AsyncMutex<F>>,
3128
request: ViewRequest,
3229
) {
3330
let operation = request.operation;
3431
let (tx_update, rx_update) = async_std::channel::unbounded::<ViewUpdate>();
3532
let (tx_event, rx_event) = async_std::channel::unbounded::<ViewEvent>();
3633
let event_loop = async_std::task::spawn(async move {
37-
let mut vm = view_model::ViewModel::new(operation, client, rx_event, tx_update);
34+
let mut vm = view_model::ViewModel::new(operation, flow_controller, rx_event, tx_update);
3835
vm.start_event_loop().await;
3936
println!("event loop ended?");
4037
});
@@ -43,38 +40,3 @@ fn run_gui<C: CredentialServiceClient + Send + Sync + 'static>(
4340

4441
async_std::task::block_on(event_loop.cancel());
4542
}
46-
47-
trait GuiClient {
48-
/// Mark the GUI as ready to receive events from credential service.
49-
/// Returns a queue of updates for updating the GUI state.
50-
async fn initiate_event_stream(&self) -> Result<Receiver<ViewUpdate>, ()>;
51-
52-
/// Select a authenticator or transport to interact with a credential.
53-
async fn select_device(&self, device_id: String) -> Result<(), ()>;
54-
55-
/// Send the client PIN to an authenticator.
56-
async fn enter_client_pin(&self, pin: String) -> Result<(), ()>;
57-
58-
/// Confirm user's credential selection when an authenticator returns multiple credentials.
59-
async fn select_credential(&self, credential_id: String) -> Result<(), ()>;
60-
}
61-
62-
struct InProcessGuiClient {}
63-
64-
impl GuiClient for InProcessGuiClient {
65-
async fn initiate_event_stream(&self) -> Result<Receiver<ViewUpdate>, ()> {
66-
todo!()
67-
}
68-
69-
async fn select_device(&self, device_id: String) -> Result<(), ()> {
70-
todo!()
71-
}
72-
73-
async fn enter_client_pin(&self, pin: String) -> Result<(), ()> {
74-
todo!()
75-
}
76-
77-
async fn select_credential(&self, credential_id: String) -> Result<(), ()> {
78-
todo!()
79-
}
80-
}

creds-ui/src/gui/view_model/gtk/application.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ use gtk::prelude::*;
66
use gtk::subclass::prelude::*;
77
use gtk::{gdk, gio, glib};
88

9-
use super::{window::ExampleApplicationWindow, ViewModel};
9+
use super::{ViewModel, window::ExampleApplicationWindow};
1010
use crate::config::{APP_ID, PKGDATADIR, PROFILE, VERSION};
1111
use crate::gui::view_model::{ViewEvent, ViewUpdate};
1212

1313
mod imp {
1414
use super::*;
15-
use glib::{clone, WeakRef};
15+
use glib::{WeakRef, clone};
1616
use std::{
1717
cell::{OnceCell, RefCell},
1818
time::Duration,
@@ -142,15 +142,13 @@ impl ExampleApplication {
142142
fn show_about_dialog(&self) {
143143
let dialog = gtk::AboutDialog::builder()
144144
.logo_icon_name(APP_ID)
145-
// Insert your license of choice here
146-
// .license_type(gtk::License::MitX11)
147-
.website("https://github.com/iinuwa/linux-webauthn-portal-api")
145+
.license_type(gtk::License::Lgpl30Only)
146+
.website("https://github.com/linux-credentials/linux-webauthn-portal-api")
148147
.version(VERSION)
149148
.transient_for(&self.main_window())
150149
.translator_credits(gettext("translator-credits"))
151150
.modal(true)
152-
.authors(vec!["Isaiah Inuwa"])
153-
.artists(vec!["Isaiah Inuwa"])
151+
.authors(vec!["Isaiah Inuwa <isaiah.inuwa@gmail.com>"])
154152
.build();
155153

156154
dialog.present();

0 commit comments

Comments
 (0)