Skip to content

Commit

Permalink
dbus: Expose Properties if unstable
Browse files Browse the repository at this point in the history
Also implements Deserialize & add getters
Would be useful for writing the server bits
  • Loading branch information
bilelmoussaoui committed Jan 20, 2024
1 parent bca4412 commit 199c9e6
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 19 deletions.
3 changes: 3 additions & 0 deletions client/src/dbus/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ mod session;
pub use collection::Collection;
pub use item::Item;
pub(crate) use prompt::Prompt;
#[cfg(not(feature = "unstable"))]
pub(crate) use properties::Properties;
#[cfg(feature = "unstable")]
pub use properties::Properties;
pub use secret::Secret;
pub use service::Service;
pub use session::Session;
77 changes: 58 additions & 19 deletions client/src/dbus/api/properties.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::collections::HashMap;

use serde::ser::{Serialize, SerializeMap};
use zbus::zvariant::{Type, Value};
use serde::{
ser::{Serialize, SerializeMap},
Deserialize,
};
use zbus::zvariant::{self, OwnedValue, Type, Value};

const ITEM_PROPERTY_LABEL: &str = "org.freedesktop.Secret.Item.Label";
const ITEM_PROPERTY_ATTRIBUTES: &str = "org.freedesktop.Secret.Item.Attributes";
Expand All @@ -10,45 +13,55 @@ const COLLECTION_PROPERTY_LABEL: &str = "org.freedesktop.Secret.Collection.Label

#[derive(Debug, Type)]
#[zvariant(signature = "a{sv}")]
pub struct Properties<'a> {
label: &'a str,
attributes: Option<&'a HashMap<&'a str, &'a str>>,
is_collection: bool,
pub struct Properties {
label: String,
attributes: Option<HashMap<String, String>>,
}

impl<'a> Properties<'a> {
pub fn for_item(label: &'a str, attributes: &'a HashMap<&'a str, &'a str>) -> Self {
impl Properties {
pub fn for_item(label: &str, attributes: &HashMap<&str, &str>) -> Self {
Self {
label,
attributes: Some(attributes),
is_collection: false,
label: label.to_owned(),
attributes: Some(
attributes
.iter()
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect(),
),
}
}

pub fn for_collection(label: &'a str) -> Self {
pub fn for_collection(label: &str) -> Self {
Self {
label,
label: label.to_owned(),
attributes: None,
is_collection: true,
}
}

pub fn label(&self) -> &str {
&self.label
}

pub fn attributes(&self) -> Option<&HashMap<String, String>> {
self.attributes.as_ref()
}
}

impl<'a> Serialize for Properties<'a> {
impl Serialize for Properties {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if self.is_collection {
if self.attributes.is_none() {
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_entry(COLLECTION_PROPERTY_LABEL, &Value::from(self.label))?;
map.serialize_entry(COLLECTION_PROPERTY_LABEL, &Value::from(&self.label))?;
map.end()
} else {
let mut map = serializer.serialize_map(Some(2))?;
map.serialize_entry(ITEM_PROPERTY_LABEL, &Value::from(self.label))?;
map.serialize_entry(ITEM_PROPERTY_LABEL, &Value::from(&self.label))?;
let mut dict = zbus::zvariant::Dict::new(String::signature(), String::signature());

if let Some(attributes) = self.attributes {
if let Some(attributes) = &self.attributes {
for (key, value) in attributes {
dict.add(key, value).expect("Key/Value of correct types");
}
Expand All @@ -60,6 +73,32 @@ impl<'a> Serialize for Properties<'a> {
}
}

impl<'de> Deserialize<'de> for Properties {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let map: HashMap<&str, Value<'_>> = HashMap::deserialize(deserializer)?;
if map.contains_key(COLLECTION_PROPERTY_LABEL) {
let label =
zvariant::Str::try_from(map.get(COLLECTION_PROPERTY_LABEL).unwrap()).unwrap();
Ok(Self::for_collection(&label))
} else {
let label = zvariant::Str::try_from(map.get(ITEM_PROPERTY_LABEL).unwrap()).unwrap();
let attributes = HashMap::<String, String>::try_from(
map.get(ITEM_PROPERTY_ATTRIBUTES).unwrap().clone(),
)
.unwrap();
let attributes = attributes
.iter()
.map(|(key, val)| (key.as_str(), val.as_str()))
.collect::<HashMap<_, _>>();

Ok(Self::for_item(&label, &attributes))
}
}
}

#[cfg(test)]
mod tests {
use byteorder::LE;
Expand Down

0 comments on commit 199c9e6

Please sign in to comment.