bilelmoussaoui / oo7

James Bond went on a new mission as a Secret Service provider
https://bilelmoussaoui.github.io/oo7/oo7/
MIT License
63 stars 12 forks source link

Add schemas #27

Open zecakeh opened 1 year ago

zecakeh commented 1 year ago

In libsecret a schema allows to define the structure of the attributes stored with a secret.

It also allows to request all the items of an app (if the schema ID is unique to the app), because it sets the xdg:schema attribute with the schema ID when the app is not sandboxed.

In Rust it could be a trait that allows to provide a struct instead of a HashMap for the attributes, by making the trait implementors provide conversion methods. There could even be a derive macro that implements the conversion for a simple struct.

bilelmoussaoui commented 1 year ago

If you could do some sketch up of the API as you think it should be, i might look at providing the basic traits for now and we can look at adding a derive macro for it in the future

zecakeh commented 1 year ago

I was thinking of a trait like that:

pub trait Schema {
  // Except for schemas shared amongst apps, this is usually the app ID.
  const SCHEMA_ID: &str;

  fn attributes(&self) -> HashMap<&str, &str>; 

  fn secret(&self) -> &[u8];
}

Then we can add methods on Item:

pub async fn extract_with_schema<S: Schema>(&self) -> Result<S> {}

pub async fn update_with_schema<S: Schema>(&self, schema: S> -> Result<()> {}

And on Keyring:

// To be compatible with libsecret, this method searches for items with the
// `xdg:schema` attribute equal to `SCHEMA_ID` with the D-Bus interface,
// and returns all items with the portal.
pub async fn items_with_schema<S: Schema>(&self) -> Result<Vec<Item>> {}

// For all the methods below, to be compatible with libsecret, the `xdg:schema` attribute
// equal to `SCHEMA_ID` is added to the attribute list with the D-Bus interface only.

pub async fn search_items_with_schema<S: Schema>(&self, attrs: HashMap<&str, &str>) -> Result<Vec<Item>> {}

pub async fn create_item_with_schema<S: Schema>(
    &self,
    label: &str,
    schema: S,
    replace: bool,
) -> Result<()> {}

pub async fn delete_with_schema<S: Schema>(&self, attrs: HashMap<&str, &str>) -> Result <()> {}

Of course this API is in case we want the Schema trait as an alternative to the current API. It could replace the current API, in which case Item could be made generic over the Schema.

A6GibKm commented 1 year ago

In your proposed api S is not being used in the last 3 functions, should it be schema :S instead of attrs: HashMap<...>?

zecakeh commented 1 year ago

No because one might not want to search for all attributes. The Schema is used in the body of the function to add the SCHEMA_ID to the attributes list when the D-Bus interface is used.

There could maybe be another method where we search for all attributes and replace the list with S.