aboutsummaryrefslogtreecommitdiff
path: root/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/device.rs')
-rw-r--r--src/device.rs68
1 files changed, 66 insertions, 2 deletions
diff --git a/src/device.rs b/src/device.rs
index 684f64a..1201540 100644
--- a/src/device.rs
+++ b/src/device.rs
@@ -54,7 +54,7 @@ enum Model {
#[derive(Debug)]
pub enum DeviceWrapper {
/// A Nitrokey Storage device.
- Storage(()),
+ Storage(Storage),
/// A Nitrokey Pro device.
Pro(Pro),
}
@@ -101,6 +101,48 @@ pub enum DeviceWrapper {
#[derive(Debug)]
pub struct Pro {}
+/// A Nitrokey Storage device without user or admin authentication.
+///
+/// Use the global function [`connect`][] to obtain an instance wrapper or the method
+/// [`connect`][`Storage::connect`] to directly obtain an instance. If you want to execute a
+/// command that requires user or admin authentication, use [`authenticate_admin`][] or
+/// [`authenticate_user`][].
+///
+/// # Examples
+///
+/// Authentication with error handling:
+///
+/// ```no_run
+/// use nitrokey::{Authenticate, User, Storage};
+/// # use nitrokey::CommandError;
+///
+/// fn perform_user_task(device: &User<Storage>) {}
+/// fn perform_other_task(device: &Storage) {}
+///
+/// # fn try_main() -> Result<(), CommandError> {
+/// let device = nitrokey::Storage::connect()?;
+/// let device = match device.authenticate_user("123456") {
+/// Ok(user) => {
+/// perform_user_task(&user);
+/// user.device()
+/// },
+/// Err((device, err)) => {
+/// println!("Could not authenticate as user: {:?}", err);
+/// device
+/// },
+/// };
+/// perform_other_task(&device);
+/// # Ok(())
+/// # }
+/// ```
+///
+/// [`authenticate_admin`]: trait.Authenticate.html#method.authenticate_admin
+/// [`authenticate_user`]: trait.Authenticate.html#method.authenticate_user
+/// [`connect`]: fn.connect.html
+/// [`Storage::connect`]: #method.connect
+#[derive(Debug)]
+pub struct Storage {}
+
/// A Nitrokey device.
///
/// This trait provides the commands that can be executed without authentication and that are
@@ -368,7 +410,7 @@ fn connect_model(model: Model) -> bool {
impl DeviceWrapper {
fn device(&self) -> &Device {
match *self {
- DeviceWrapper::Storage(_) => panic!("..."),
+ DeviceWrapper::Storage(ref storage) => storage,
DeviceWrapper::Pro(ref pro) => pro,
}
}
@@ -415,3 +457,25 @@ impl Drop for Pro {
impl Device for Pro {}
impl GenerateOtp for Pro {}
+
+impl Storage {
+ pub fn connect() -> Result<Storage, CommandError> {
+ // TODO: maybe Option instead of Result?
+ match connect_model(Model::Storage) {
+ true => Ok(Storage {}),
+ false => Err(CommandError::Unknown),
+ }
+ }
+}
+
+impl Drop for Storage {
+ fn drop(&mut self) {
+ unsafe {
+ nitrokey_sys::NK_logout();
+ }
+ }
+}
+
+impl Device for Storage {}
+
+impl GenerateOtp for Storage {}