Skip to content

Commit

Permalink
Wire up repository to sync
Browse files Browse the repository at this point in the history
  • Loading branch information
Hinton committed Mar 11, 2024
1 parent 21e6143 commit 87a736d
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 18 deletions.
6 changes: 2 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@ bld/
.idea
xcuserdata/

# Added by cargo
#
# already existing elements were commented out
# Databases
*.sqlite

#/target
node_modules/
clients/python/env/

Expand Down
1 change: 0 additions & 1 deletion crates/bitwarden/src/.gitignore

This file was deleted.

27 changes: 26 additions & 1 deletion crates/bitwarden/src/client/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::path::PathBuf;
use std::{
path::PathBuf,
sync::{Arc, Mutex},
};

#[cfg(feature = "internal")]
pub use bitwarden_crypto::Kdf;
Expand All @@ -7,6 +10,7 @@ use bitwarden_crypto::SymmetricCryptoKey;
use bitwarden_crypto::{AsymmetricEncString, EncString};
use chrono::Utc;
use reqwest::header::{self, HeaderValue};
use rusqlite::Connection;
use uuid::Uuid;

use super::AccessToken;
Expand All @@ -26,6 +30,7 @@ use crate::{
encryption_settings::EncryptionSettings,
},
error::{Error, Result},
vault::{CipherRepository, CipherSqliteRepository},
};

#[derive(Debug)]
Expand Down Expand Up @@ -89,6 +94,19 @@ pub struct Client {
pub(crate) __api_configurations: ApiConfigurations,

encryption_settings: Option<EncryptionSettings>,

pub(crate) repositories: Arc<Mutex<ClientRepositories>>,
}

#[cfg(feature = "internal")]
pub struct ClientRepositories {
pub(crate) cipher: Box<dyn CipherRepository + Send>,
}

impl std::fmt::Debug for ClientRepositories {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ClientRepositories").finish()
}

Check warning on line 109 in crates/bitwarden/src/client/client.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden/src/client/client.rs#L107-L109

Added lines #L107 - L109 were not covered by tests
}

impl Client {
Expand Down Expand Up @@ -139,6 +157,12 @@ impl Client {
api_key: None,
};

let conn = Connection::open("test.sqlite").unwrap();

let repositories = ClientRepositories {
cipher: Box::new(CipherSqliteRepository::new(conn)),
};

Self {
token: None,
refresh_token: None,
Expand All @@ -153,6 +177,7 @@ impl Client {
device_type: settings.device_type,
},
encryption_settings: None,
repositories: Arc::new(Mutex::new(repositories)),
}
}

Expand Down
10 changes: 9 additions & 1 deletion crates/bitwarden/src/platform/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@ pub(crate) async fn sync(client: &mut Client, input: &SyncRequest) -> Result<Syn

let enc = client.initialize_org_crypto(org_keys)?;

SyncResponse::process_response(sync, enc)
let res = SyncResponse::process_response(sync, enc)?;

Check warning on line 41 in crates/bitwarden/src/platform/sync.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden/src/platform/sync.rs#L41

Added line #L41 was not covered by tests

let mut repositories = client.repositories.lock().unwrap();

let ciphers = res.ciphers.as_slice();

repositories.cipher.as_mut().replace_all(ciphers)?;

Check warning on line 47 in crates/bitwarden/src/platform/sync.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden/src/platform/sync.rs#L43-L47

Added lines #L43 - L47 were not covered by tests

Ok(res)

Check warning on line 49 in crates/bitwarden/src/platform/sync.rs

View check run for this annotation

Codecov / codecov/patch

crates/bitwarden/src/platform/sync.rs#L49

Added line #L49 was not covered by tests
}

#[derive(Serialize, Deserialize, Debug, JsonSchema)]
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden/src/vault/cipher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ pub use attachment::{
};
pub use cipher::{Cipher, CipherListView, CipherRepromptType, CipherType, CipherView};
pub use field::FieldView;
pub use repository::{CipherRepository, CipherSqliteRepository};
pub use secure_note::SecureNoteType;
34 changes: 23 additions & 11 deletions crates/bitwarden/src/vault/cipher/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ use crate::error::Error;

use super::Cipher;

pub trait CipherRepository {
fn save(&self, cipher: &Cipher) -> Result<(), Error>;
/// Replace all ciphers in the repository with the given ciphers.
///
/// Typically used during a sync operation.
fn replace_all(&mut self, ciphers: &[Cipher]) -> Result<(), Error>;
fn delete_by_id(&self, id: Uuid) -> Result<(), Error>;
fn get_all(&self) -> Result<Vec<Cipher>, Error>;
}

struct CipherRow {
id: Uuid,
value: String,
}

struct CipherSqliteRepository {
pub struct CipherSqliteRepository {
conn: Connection,
}

Expand All @@ -28,8 +38,10 @@ impl CipherSqliteRepository {

Self { conn }
}
}

pub fn save(&self, cipher: &Cipher) -> Result<(), Error> {
impl CipherRepository for CipherSqliteRepository {
fn save(&self, cipher: &Cipher) -> Result<(), Error> {
let id = cipher.id.unwrap();
let serialized = serde_json::to_string(cipher)?;

Expand All @@ -46,10 +58,7 @@ impl CipherSqliteRepository {
Ok(())
}

/// Replace all ciphers in the repository with the given ciphers.
///
/// Typically used during a sync operation.
pub fn replace_all(&mut self, ciphers: &[&Cipher]) -> Result<(), Error> {
fn replace_all(&mut self, ciphers: &[Cipher]) -> Result<(), Error> {
let tx = self.conn.transaction()?;
{
tx.execute("DELETE FROM ciphers", [])?;
Expand All @@ -73,14 +82,14 @@ impl CipherSqliteRepository {
Ok(())
}

pub fn delete_by_id(&self, id: Uuid) -> Result<(), Error> {
fn delete_by_id(&self, id: Uuid) -> Result<(), Error> {
let mut stmt = self.conn.prepare("DELETE FROM ciphers WHERE id = ?1")?;
stmt.execute(params![id])?;

Ok(())
}

pub fn get_all(&self) -> Result<Vec<Cipher>, Error> {
fn get_all(&self) -> Result<Vec<Cipher>, Error> {
let mut stmt = self.conn.prepare("SELECT id, value FROM ciphers")?;
let rows = stmt.query_map([], |row| {
Ok(CipherRow {
Expand Down Expand Up @@ -181,11 +190,14 @@ mod tests {
assert_eq!(ciphers.len(), 1);
assert_eq!(ciphers[0].id, old_cipher.id);

let new_cipher = mock_cipher("d55d65d7-c161-40a4-94ca-b0d20184d91c".parse().unwrap());
repo.replace_all(&[&new_cipher]).unwrap();
let new_ciphers = vec![mock_cipher(
"d55d65d7-c161-40a4-94ca-b0d20184d91c".parse().unwrap(),
)];

repo.replace_all(new_ciphers.as_slice()).unwrap();

let ciphers = repo.get_all().unwrap();
assert_eq!(ciphers.len(), 1);
assert_eq!(ciphers[0].id, new_cipher.id);
assert_eq!(ciphers[0].id, new_ciphers[0].id);
}
}

0 comments on commit 87a736d

Please sign in to comment.