aboutsummaryrefslogtreecommitdiffstats
path: root/src/api.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-04-19 23:00:47 -0400
committerJesse Luehrs <doy@tozt.net>2020-04-19 23:00:47 -0400
commit6f10a47adc2fb42ffc965b954b9285123a82c094 (patch)
tree725b2b8cce4fe6e7c0b51f96d3d65a43928d1f2f /src/api.rs
parent7a32c43713514c02f783d3c8e0835229e7f59a83 (diff)
downloadrbw-6f10a47adc2fb42ffc965b954b9285123a82c094.tar.gz
rbw-6f10a47adc2fb42ffc965b954b9285123a82c094.zip
implement adding into a folder
Diffstat (limited to 'src/api.rs')
-rw-r--r--src/api.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/api.rs b/src/api.rs
index aa36f47..8fe0d68 100644
--- a/src/api.rs
+++ b/src/api.rs
@@ -141,6 +141,8 @@ struct SyncResPasswordHistory {
struct CiphersPostReq {
#[serde(rename = "type")]
ty: u32, // XXX what are the valid types?
+ #[serde(rename = "folderId")]
+ folder_id: Option<String>,
name: String,
notes: Option<String>,
login: CiphersPostReqLogin,
@@ -183,6 +185,25 @@ struct CiphersPutReqHistory {
password: String,
}
+#[derive(serde::Deserialize, Debug)]
+struct FoldersRes {
+ #[serde(rename = "Data")]
+ data: Vec<FoldersResData>,
+}
+
+#[derive(serde::Deserialize, Debug)]
+struct FoldersResData {
+ #[serde(rename = "Id")]
+ id: String,
+ #[serde(rename = "Name")]
+ name: String,
+}
+
+#[derive(serde::Serialize, Debug)]
+struct FoldersPostReq {
+ name: String,
+}
+
#[derive(Debug)]
pub struct Client {
base_url: String,
@@ -299,9 +320,11 @@ impl Client {
password: Option<&str>,
notes: Option<&str>,
uris: &[String],
+ folder_id: Option<&str>,
) -> Result<()> {
let req = CiphersPostReq {
ty: 1,
+ folder_id: folder_id.map(std::string::ToString::to_string),
name: name.to_string(),
notes: notes.map(std::string::ToString::to_string),
login: CiphersPostReqLogin {
@@ -396,6 +419,65 @@ impl Client {
}
}
+ pub fn folders(
+ &self,
+ access_token: &str,
+ ) -> Result<Vec<(String, String)>> {
+ let client = reqwest::blocking::Client::new();
+ let res = client
+ .get(&self.api_url("/folders"))
+ .header("Authorization", format!("Bearer {}", access_token))
+ .send()
+ .context(crate::error::Reqwest)?;
+ match res.status() {
+ reqwest::StatusCode::OK => {
+ let folders_res: FoldersRes =
+ res.json().context(crate::error::Reqwest)?;
+ Ok(folders_res
+ .data
+ .iter()
+ .map(|folder| (folder.id.clone(), folder.name.clone()))
+ .collect())
+ }
+ reqwest::StatusCode::UNAUTHORIZED => {
+ Err(Error::RequestUnauthorized)
+ }
+ _ => Err(Error::RequestFailed {
+ status: res.status().as_u16(),
+ }),
+ }
+ }
+
+ pub fn create_folder(
+ &self,
+ access_token: &str,
+ name: &str,
+ ) -> Result<String> {
+ let req = FoldersPostReq {
+ name: name.to_string(),
+ };
+ let client = reqwest::blocking::Client::new();
+ let res = client
+ .post(&self.api_url("/folders"))
+ .header("Authorization", format!("Bearer {}", access_token))
+ .json(&req)
+ .send()
+ .context(crate::error::Reqwest)?;
+ match res.status() {
+ reqwest::StatusCode::OK => {
+ let folders_res: FoldersResData =
+ res.json().context(crate::error::Reqwest)?;
+ Ok(folders_res.id)
+ }
+ reqwest::StatusCode::UNAUTHORIZED => {
+ Err(Error::RequestUnauthorized)
+ }
+ _ => Err(Error::RequestFailed {
+ status: res.status().as_u16(),
+ }),
+ }
+ }
+
pub fn exchange_refresh_token(
&self,
refresh_token: &str,