connect_1password/lib.rs
1#![deny(missing_docs)]
2#![deny(missing_debug_implementations)]
3#![forbid(unsafe_code)]
4#![deny(private_in_public, unstable_features)]
5#![warn(rust_2018_idioms, future_incompatible, nonstandard_style)]
6
7//! connect-1password is a Rust SDK for 1Password Connect.
8//!
9//! # High-level features
10//!
11//! - Based on [`tokio`], [`hyper`] and [`hyper_rustls`] by default.
12//! - [`hyper`] can be replaced using the [`HTTPClient`](client::HTTPClient) interface.
13//!
14//! # Examples
15//!
16//! ## Create a Login item
17//!
18//! To create a Login item, make sure to use the Trait [`LoginItem`](models::item::LoginItem), so as to be able to call
19//! respective methods (enforced by the interface) on [`ItemBuilder`](models::item::ItemBuilder).
20//!
21//! ```
22//! use connect_1password::{
23//! error::Error,
24//! client::{Client, HTTPClient},
25//! models::{
26//! item::{LoginItem, FullItem, ItemBuilder, ItemCategory},
27//! },
28//! vaults,
29//! items,
30//! };
31//!
32//! const SLEEP_DELAY: u64 = 4; // seconds
33//!
34//! #[tokio::main]
35//! async fn main() -> Result<(), Error> {
36//! let client = Client::default();
37//!
38//! let (vaults, _) = vaults::all(&client).await?;
39//! assert!(!vaults.is_empty());
40//!
41//! let item: FullItem = ItemBuilder::new(&vaults[0].id, ItemCategory::Login)
42//! .title("Secure server login")
43//! .username("Bob")
44//! .password("")
45//! .build()
46//! .unwrap();
47//!
48//! let (new_item, _) = items::add(&client, item).await?;
49//! assert_eq!(new_item.title, "Secure server login");
50//!
51//! // Just as a clean up measure, we remove the item created in the this example
52//! tokio::time::sleep(std::time::Duration::new(SLEEP_DELAY, 0)).await;
53//!
54//! items::remove(&client, &vaults[0].id, &new_item.id)
55//! .await?;
56//!
57//! Ok(())
58//! }
59//! ```
60//!
61//! ## Create an API Credential item
62//!
63//! This is ideally used for programmatic access, and potentially the main interface required for
64//! this entire API wrapper.
65//!
66//! In the example below, since we have not provided a specific API key value, one is generated for
67//! us by the Connect API.
68//!
69//! ```
70//! use connect_1password::{
71//! error::Error,
72//! client::{Client, HTTPClient},
73//! models::{
74//! item::{ApiCredentialItem, FullItem, ItemBuilder, ItemCategory, FieldObject},
75//! },
76//! vaults,
77//! items,
78//! };
79//!
80//! const SLEEP_DELAY: u64 = 4; // seconds
81//!
82//! #[tokio::main]
83//! async fn main() -> Result<(), Error> {
84//! let client = Client::default();
85//!
86//! let (vaults, _) = vaults::all(&client).await?;
87//! assert!(!vaults.is_empty());
88//!
89//! let item: FullItem = ItemBuilder::new(&vaults[0].id, ItemCategory::ApiCredential)
90//! .api_key("", "Dell XYZ")
91//! .build()
92//! .unwrap();
93//!
94//! let client = Client::default();
95//! let (new_item, _) = items::add(&client, item).await?;
96//! assert_eq!(new_item.title, "Dell XYZ");
97//!
98//! tokio::time::sleep(std::time::Duration::new(SLEEP_DELAY, 0)).await;
99//!
100//! let (item, _) = items::get(&client, &vaults[0].id, &new_item.id).await?;
101//! let fields: Vec<_> = item.fields.into_iter().filter(|r| r.value.is_some()).collect();
102//! assert_eq!(fields.len(), 1);
103//! dbg!(&fields);
104//!
105//! let default_value = "".to_string();
106//! let api_value = fields[0].value.as_ref().unwrap_or(&default_value);
107//! let field_type = fields[0].r#type.as_ref().unwrap_or(&default_value);
108//! assert_eq!(field_type, "CONCEALED");
109//! assert!(!api_value.is_empty());
110//!
111//! // Just as a clean up measure, we remove the item created in the this example
112//! tokio::time::sleep(std::time::Duration::new(SLEEP_DELAY, 0)).await;
113//!
114//! items::remove(&client, &vaults[0].id, &new_item.id)
115//! .await?;
116//!
117//! Ok(())
118//! }
119//! ```
120//!
121//! However, if we provide a specific key, this is the value persisted into 1Password.
122//!
123//! ```
124//! use connect_1password::{
125//! error::Error,
126//! client::{Client, HTTPClient},
127//! models::{
128//! item::{ApiCredentialItem, FullItem, ItemBuilder, ItemCategory, FieldObject},
129//! },
130//! vaults,
131//! items,
132//! };
133//!
134//! const SLEEP_DELAY: u64 = 4; // seconds
135//!
136//! #[tokio::main]
137//! async fn main() -> Result<(), Error> {
138//! let client = Client::default();
139//!
140//! let (vaults, _) = vaults::all(&client).await?;
141//! assert!(!vaults.is_empty());
142//!
143//! let item: FullItem = ItemBuilder::new(&vaults[0].id, ItemCategory::ApiCredential)
144//! .api_key("smelly-socks", "Dell XYZ")
145//! .build()
146//! .unwrap();
147//!
148//! let (new_item, _) = items::add(&client, item).await?;
149//! assert_eq!(new_item.title, "Dell XYZ");
150//!
151//! tokio::time::sleep(std::time::Duration::new(SLEEP_DELAY, 0)).await;
152//!
153//! let client = Client::default();
154//! let (item, _) = items::get(&client, &vaults[0].id, &new_item.id).await?;
155//! let fields: Vec<_> = item.fields.into_iter().filter(|r| r.value.is_some()).collect();
156//! assert_eq!(fields.len(), 1);
157//! dbg!(&fields);
158//!
159//! let default_value = "".to_string();
160//! let api_value = fields[0].value.as_ref().unwrap_or(&default_value);
161//! let field_type = fields[0].r#type.as_ref().unwrap_or(&default_value);
162//! assert_eq!(field_type, "CONCEALED");
163//! assert_eq!(api_value, "smelly-socks");
164//!
165//! // Just as a clean up measure, we remove the item created in the this example
166//! tokio::time::sleep(std::time::Duration::new(SLEEP_DELAY, 0)).await;
167//!
168//! items::remove(&client, &vaults[0].id, &new_item.id)
169//! .await?;
170//!
171//! Ok(())
172//! }
173//! ```
174
175pub mod client;
176pub mod error;
177pub mod items;
178pub mod models;
179pub mod vaults;
180
181#[cfg(test)]
182fn get_test_client() -> client::Client {
183 client::Client::default()
184}