1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
use std::{collections::HashMap, path::PathBuf};
use zbus::zvariant::{OwnedObjectPath, OwnedValue, Value};
use crate::{types::ConnectionFlags, Error};
/// A connection profile.
///
/// See [`Device::reapply()`](crate::device::Device::reapply()) for the difference between a
/// [`Connection`] and an [`AppliedConnection`].
#[derive(Clone, Debug)]
pub struct Connection {
pub(crate) zbus: zbus::Connection,
pub(crate) path: OwnedObjectPath,
}
crate::zproxy_pathed!(
Connection,
crate::raw::settings_connection::SettingsConnectionProxy<'_>
);
impl Connection {
/// Update the connection with new settings and properties and save the connection to disk.
///
/// This replaces all previous settings and properties.
///
/// Secrets may be part of the update request, and will be either stored in persistent storage
/// or sent to a Secret Agent for storage, depending on the flags associated with each secret.
pub async fn update(
&self,
properties: HashMap<&str, HashMap<&str, Value<'_>>>,
) -> Result<(), Error> {
self.raw()
.await?
.update(properties)
.await
.map_err(Error::ZBus)
}
/// Update the connection with new settings and properties, but do not immediately save the connection to disk.
///
/// This replaces all previous settings and properties.
///
/// Secrets may be part of the update request and may sent to a Secret Agent for storage,
/// depending on the flags associated with each secret.
///
/// Use the [`Connection::save()`] method to save these changes to disk.
///
/// Note that unsaved changes will be lost if the connection is reloaded from disk (either
/// automatically on file change or due to an explicit `ReloadConnections` call).
pub async fn update_in_memory(
&self,
properties: HashMap<&str, HashMap<&str, Value<'_>>>,
) -> Result<(), Error> {
self.raw()
.await?
.update_unsaved(properties)
.await
.map_err(Error::ZBus)
}
/// Delete the connection.
pub async fn delete(&self) -> Result<(), Error> {
self.raw().await?.delete().await.map_err(Error::ZBus)
}
/// Get the settings maps describing this network configuration.
///
/// This will never include any secrets required for connection to the network, as those are
/// often protected. Secrets must be requested separately using the `GetSecrets` call.
pub async fn settings(&self) -> Result<HashMap<String, HashMap<String, OwnedValue>>, Error> {
self.raw().await?.get_settings().await.map_err(Error::ZBus)
}
/// Get the secrets belonging to this network configuration.
///
/// Only secrets from persistent storage or a Secret Agent running in the requestor's session
/// will be returned. The user will never be prompted for secrets as a result of this request.
pub async fn secrets(&self) -> Result<HashMap<String, HashMap<String, OwnedValue>>, Error> {
self.secrets_for_setting("").await
}
/// Get the secrets belonging to this network configuration, for a particular setting.
///
/// Only secrets from persistent storage or a Secret Agent running in the requestor's session
/// will be returned. The user will never be prompted for secrets as a result of this request.
pub async fn secrets_for_setting(
&self,
setting_name: &str,
) -> Result<HashMap<String, HashMap<String, OwnedValue>>, Error> {
self.raw()
.await?
.get_secrets(setting_name)
.await
.map_err(Error::ZBus)
}
/// Clear the secrets belonging to this network connection profile.
pub async fn clear_secrets(&self) -> Result<(), Error> {
self.raw().await?.clear_secrets().await.map_err(Error::ZBus)
}
/// Save a connection previously updated with [`Connection::update_in_memory()`] to persistent storage.
pub async fn save(&self) -> Result<(), Error> {
self.raw().await?.save().await.map_err(Error::ZBus)
}
// TODO: Update2
/// Indicates whether the in-memory state of the connection matches the on-disk state.
///
/// This flag will be unset when [`Connection::update_in_memory()`] is called or when any
/// connection details change, and set when the connection is saved to disk via
/// [`Connection::save()`] or from internal operations.
pub async fn is_saved(&self) -> Result<bool, Error> {
self.raw()
.await?
.unsaved()
.await
.map(|flag| !flag)
.map_err(Error::ZBus)
}
/// Additional flags of the connection profile.
pub async fn flags(&self) -> Result<ConnectionFlags, Error> {
let value = self.raw().await?.flags().await?;
Ok(ConnectionFlags::from_bits_retain(value))
}
/// File that stores the connection when the connection is file-backed.
pub async fn filename(&self) -> Result<PathBuf, Error> {
self.raw()
.await?
.filename()
.await
.map(|path| path.into())
.map_err(Error::ZBus)
}
}