Struct DeviceConfig

Source
pub struct DeviceConfig {
    connection: RefCell<Connection>,
    credentials: RefCell<HashSet<ConfigCredentials>>,
    interactivity: ConfigInteractivity,
}
Expand description

The configuration for a [NetHsm]

Tracks the [Connection] for a [NetHsm] as well as a set of ConfigCredentials.

Fields§

§connection: RefCell<Connection>§credentials: RefCell<HashSet<ConfigCredentials>>§interactivity: ConfigInteractivity

Implementations§

Source§

impl DeviceConfig

Source

pub fn new( connection: Connection, credentials: Vec<ConfigCredentials>, interactivity: ConfigInteractivity, ) -> Result<DeviceConfig, Error>

Creates a new DeviceConfig

Creates a new DeviceConfig by providing a connection, an optional set of credentials and the interactivity setting.

§Errors

Returns an Error::CredentialsExist if credentials contains duplicates.

§Examples
use nethsm::{Connection, ConnectionSecurity, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};

let connection = Connection::new(
    "https://example.org/api/v1".parse()?,
    ConnectionSecurity::Unsafe,
);

DeviceConfig::new(
    connection.clone(),
    vec![],
    ConfigInteractivity::NonInteractive,
)?;

DeviceConfig::new(
    connection.clone(),
    vec![ConfigCredentials::new(
        UserRole::Operator,
        "user1".parse()?,
        Some("my-passphrase".to_string()),
    )],
    ConfigInteractivity::NonInteractive,
)?;

// this fails because the provided credentials contain duplicates
assert!(
    DeviceConfig::new(
        connection.clone(),
        vec![
            ConfigCredentials::new(
                UserRole::Operator,
                "user1".parse()?,
                Some("my-passphrase".to_string()),
            ),
            ConfigCredentials::new(
                UserRole::Operator,
                "user1".parse()?,
                Some("my-passphrase".to_string()),
            ),
        ],
        ConfigInteractivity::NonInteractive,
    )
    .is_err()
);
Source

pub fn set_config_interactivity(&mut self, config_type: ConfigInteractivity)

Sets the interactivity setting

NOTE: This method is not necessarily useful by itself, as one usually wants to use the same ConfigInteractivity as that of a Config, which holds the DeviceConfig.

Source

pub fn add_credentials( &self, credentials: ConfigCredentials, ) -> Result<(), Error>

Adds credentials to the device

Adds new ConfigCredentials to the DeviceConfig.

§Errors

Returns an Error::CredentialsExist if the credentials exist already.

§Examples
use nethsm::{Connection, ConnectionSecurity, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};

let connection = Connection::new(
    "https://example.org/api/v1".parse()?,
    ConnectionSecurity::Unsafe,
);

let device_config = DeviceConfig::new(
    connection.clone(),
    vec![],
    ConfigInteractivity::NonInteractive,
)?;

device_config.add_credentials(ConfigCredentials::new(
    UserRole::Operator,
    "user1".parse()?,
    Some("my-passphrase".to_string()),
))?;

// this fails because the credentials exist already
assert!(
    device_config
        .add_credentials(ConfigCredentials::new(
            UserRole::Operator,
            "user1".parse()?,
            Some("my-passphrase".to_string()),
        ))
        .is_err()
);
Source

pub fn get_credentials(&self, name: &UserId) -> Result<ConfigCredentials, Error>

Returns credentials by name

Returns existing ConfigCredentials from the DeviceConfig.

§Errors

Returns an Error::CredentialsMissing if no ConfigCredentials match the provided name.

§Examples
use nethsm::{Connection, ConnectionSecurity, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};
let connection = Connection::new(
    "https://example.org/api/v1".parse()?,
    ConnectionSecurity::Unsafe,
);

let device_config = DeviceConfig::new(
    connection.clone(),
    vec![],
    ConfigInteractivity::NonInteractive,
)?;

// this fails because the credentials do not exist
assert!(device_config.get_credentials(&"user1".parse()?).is_err());

device_config.add_credentials(ConfigCredentials::new(
    UserRole::Operator,
    "user1".parse()?,
    Some("my-passphrase".to_string()),
))?;

device_config.get_credentials(&"user1".parse()?)?;
Source

pub fn delete_credentials(&self, name: &UserId) -> Result<(), Error>

Deletes credentials by name

Deletes ConfigCredentials identified by name.

§Errors

Returns an Error::CredentialsMissing if no ConfigCredentials match the provided name.

§Examples
use nethsm::{Connection, ConnectionSecurity, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};

let device_config = DeviceConfig::new(
    Connection::new(
        "https://example.org/api/v1".parse()?,
        ConnectionSecurity::Unsafe,
    ),
    vec![],
    ConfigInteractivity::NonInteractive,
)?;
device_config.add_credentials(ConfigCredentials::new(
    UserRole::Operator,
    "user1".parse()?,
    Some("my-passphrase".to_string()),
))?;

device_config.delete_credentials(&"user1".parse()?)?;

// this fails because the credentials do not exist
assert!(device_config.delete_credentials(&"user1".parse()?).is_err());
Source

pub fn get_matching_credentials( &self, roles: &[UserRole], names: &[UserId], ) -> Result<ConfigCredentials, Error>

Returns credentials machting one or several roles and a optionally a name

Returns ConfigCredentials matching a list of [UserRole]s and/or a list of [UserId]s.

If names is empty, the ConfigCredentials first found matching one of the [UserRole]s provided using roles are returned. If names contains at least one entry, the first ConfigCredentials with a matching [UserId] that have at least one matching [UserRole] are returned.

§Errors

Returns an Error::NoMatchingCredentials if names is empty and no existing credentials match any of the provided roles. Returns an Error::CredentialsMissing if a [UserId] in names does not exist and no ConfigCredentials have been returned yet. Returns an Error::MatchingCredentialsMissing if no ConfigCredentials matching either the provided names or roles can be found.

§Examples
use nethsm::{Connection, ConnectionSecurity, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};

let device_config = DeviceConfig::new(
    Connection::new(
        "https://example.org/api/v1".parse()?,
        ConnectionSecurity::Unsafe,
    ),
    vec![ConfigCredentials::new(
        UserRole::Administrator,
        "admin1".parse()?,
        Some("my-passphrase".to_string()),
    )],
    ConfigInteractivity::NonInteractive,
)?;
device_config.add_credentials(ConfigCredentials::new(
    UserRole::Operator,
    "user1".parse()?,
    Some("my-passphrase".to_string()),
))?;

device_config.get_matching_credentials(&[UserRole::Operator], &["user1".parse()?])?;
device_config.get_matching_credentials(&[UserRole::Administrator], &["admin1".parse()?])?;
assert_eq!(
    device_config
        .get_matching_credentials(&[UserRole::Operator], &[])?
        .get_name(),
    "user1".parse()?
);
assert_eq!(
    device_config
        .get_matching_credentials(&[UserRole::Administrator], &[])?
        .get_name(),
    "admin1".parse()?
);

// this fails because we must provide a role to match against
assert!(
    device_config
        .get_matching_credentials(&[], &["user1".parse()?])
        .is_err()
);

// this fails because no user in the requested role exists
assert!(
    device_config
        .get_matching_credentials(&[UserRole::Metrics], &[])
        .is_err()
);

// this fails because no user with the name first provided exists
assert!(
    device_config
        .get_matching_credentials(&[UserRole::Operator], &["user2".parse()?, "user1".parse()?])
        .is_err()
);

// this fails because no user in the requested role with any of the provided names exists
assert!(
    device_config
        .get_matching_credentials(&[UserRole::Metrics], &["admin1".parse()?, "user1".parse()?])
        .is_err()
);
Source

pub fn nethsm_with_matching_creds( &self, roles: &[UserRole], names: &[UserId], passphrases: &[Passphrase], ) -> Result<NetHsm, Error>

Returns a [NetHsm] based on the DeviceConfig (optionally with one set of credentials)

Creates a [NetHsm] based on the DeviceConfig. Only if roles is not empty, one set of ConfigCredentials based on roles, names and passphrases is added to the [NetHsm].

WARNING: Depending on the ConfigInteractivity chosen when initializing the DeviceConfig this method behaves differently with regards to adding credentials!

§NonInteractive

If roles is not empty, optionally adds one set of ConfigCredentials found by get_matching_credentials to the returned [NetHsm], based on roles and names. If the found ConfigCredentials do not contain a passphrase, a [Passphrase] in pasphrases with the same index as that of the [UserId] in names is used.

§Interactive

If roles is not empty, optionally attempts to add one set of ConfigCredentials with the help of get_matching_credentials to the returned [NetHsm], based on roles and names. If no ConfigCredentials are found by get_matching_credentials, users are interactively prompted for providing a user name. If the found or prompted for [UserId] ConfigCredentials do not contain a passphrase, a [Passphrase] in pasphrases with the same index as that of the [UserId] in names is used. If get_matching_credentials, or those the user has been prompted for provides ConfigCredentials without a passphrase, a [Passphrase] in pasphrases with the same index as that of the [UserId] in names is used. If none is provided (at the right location) in passphrases, the user is prompted for a passphrase interactively.

§Errors

Returns an Error::NoMatchingCredentials, Error::CredentialsMissing, or Error::MatchingCredentialsMissing if the DeviceConfig is initialized with Interactive and get_matching_credentials is unable to return ConfigCredentials based on roles and names.

Returns an Error::NonInteractive if the DeviceConfig is initialized with NonInteractive, but additional data would be requested interactively.

Returns an Error::Prompt if requesting additional data interactively leads to error.

§Examples
use nethsm::{Connection, ConnectionSecurity, Passphrase, UserRole};
use nethsm_config::{ConfigCredentials, ConfigInteractivity, DeviceConfig};

let device_config = DeviceConfig::new(
    Connection::new(
        "https://example.org/api/v1".parse()?,
        ConnectionSecurity::Unsafe,
    ),
    vec![ConfigCredentials::new(
        UserRole::Administrator,
        "admin1".parse()?,
        Some("my-passphrase".to_string()),
    )],
    ConfigInteractivity::NonInteractive,
)?;
device_config.add_credentials(ConfigCredentials::new(
    UserRole::Operator,
    "user1".parse()?,
    None,
))?;

// NetHsm with Operator credentials
// this works non-interactively, although the credentials in the config provide no passphrase, because we provide the passphrase manually
device_config.nethsm_with_matching_creds(
    &[UserRole::Operator],
    &["user1".parse()?],
    &[Passphrase::new("my-passphrase".to_string())],
)?;

// NetHsm with Administrator credentials
// this automatically selects "admin1" as it is the only user in the Administrator role
// this works non-interactively, because the credentials in the config provide a passphrase!
device_config.nethsm_with_matching_creds(
    &[UserRole::Administrator],
    &[],
    &[],
)?;

// a NetHsm without any credentials
device_config.nethsm_with_matching_creds(
    &[],
    &[],
    &[],
)?;

// this fails because the config is non-interactive, the targeted credentials do not offer a passphrase and we also provide none
assert!(device_config.nethsm_with_matching_creds(
    &[UserRole::Operator],
    &["user1".parse()?],
    &[],
).is_err());

// this fails because the config is non-interactive and the targeted credentials do not exist
assert!(device_config.nethsm_with_matching_creds(
    &[UserRole::Operator],
    &["user2".parse()?],
    &[],
).is_err());

// this fails because the config is non-interactive and no user in the targeted role exists
assert!(device_config.nethsm_with_matching_creds(
    &[UserRole::Metrics],
    &[],
    &[],
).is_err());

Trait Implementations§

Source§

impl Clone for DeviceConfig

Source§

fn clone(&self) -> DeviceConfig

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DeviceConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for DeviceConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for DeviceConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl TryFrom<&DeviceConfig> for NetHsm

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(value: &DeviceConfig) -> Result<Self, Error>

Performs the conversion.
Source§

impl TryFrom<DeviceConfig> for NetHsm

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(value: DeviceConfig) -> Result<Self, Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> ErasedDestructor for T
where T: 'static,

§

impl<T> MaybeSendSync for T