Browse Source

Refactor to support item imports

pull/6916/head
Matt Aaron 3 days ago
committed by user
parent
commit
dc91445e9a
  1. 19
      src/api/core/ciphers.rs
  2. 2
      src/config.rs
  3. 34
      src/db/models/archive.rs
  4. 15
      src/db/models/cipher.rs

19
src/api/core/ciphers.rs

@ -295,6 +295,7 @@ pub struct CipherData {
// when using older client versions, or if the operation doesn't involve
// updating an existing cipher.
last_known_revision_date: Option<String>,
archived_date: Option<String>,
}
#[derive(Debug, Deserialize)]
@ -534,6 +535,17 @@ pub async fn update_cipher_from_data(
cipher.save(conn).await?;
cipher.move_to_folder(data.folder_id, &headers.user.uuid, conn).await?;
cipher.set_favorite(data.favorite, &headers.user.uuid, conn).await?;
let archived_at = match data.archived_date {
Some(dt_str) => match NaiveDateTime::parse_from_str(&dt_str, "%+") {
Ok(dt) => Some(dt),
Err(err) => {
warn!("Error parsing ArchivedDate '{dt_str}': {err}");
None
}
},
None => None,
};
cipher.set_archived_at(archived_at, &headers.user.uuid, conn).await?;
if ut != UpdateType::None {
// Only log events for organizational ciphers
@ -1971,7 +1983,12 @@ async fn set_archived_cipher_by_uuid(
err!("Cipher is not accessible for the current user")
}
cipher.set_archived(archived, &headers.user.uuid, conn).await?;
let archived_at = if archived {
Some(Utc::now().naive_utc())
} else {
None
};
cipher.set_archived_at(archived_at, &headers.user.uuid, conn).await?;
if !multi_archive {
nt.send_cipher_update(

2
src/config.rs

@ -1053,7 +1053,7 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> {
// Webauthn Related Origins
"pm-30529-webauthn-related-origins",
// Innovation Team
"pm-19148-innovation-archive"
"pm-19148-innovation-archive",
];
let configured_flags = parse_experimental_client_feature_flags(&cfg.experimental_client_feature_flags);
let invalid_flags: Vec<_> = configured_flags.keys().filter(|flag| !KNOWN_FLAGS.contains(&flag.as_str())).collect();

34
src/db/models/archive.rs

@ -1,4 +1,4 @@
use chrono::{NaiveDateTime, Utc};
use chrono::NaiveDateTime;
use diesel::prelude::*;
use super::{CipherId, User, UserId};
@ -18,7 +18,7 @@ pub struct Archive {
impl Archive {
// Returns the date the specified cipher was archived
pub async fn get_archived_date(cipher_uuid: &CipherId, user_uuid: &UserId, conn: &DbConn) -> Option<NaiveDateTime> {
pub async fn get_archived_at(cipher_uuid: &CipherId, user_uuid: &UserId, conn: &DbConn) -> Option<NaiveDateTime> {
db_run! { conn: {
archives::table
.filter(archives::cipher_uuid.eq(cipher_uuid))
@ -29,28 +29,44 @@ impl Archive {
}
// Sets the specified cipher to be archived or unarchived
pub async fn set_archived(
archived: bool,
pub async fn set_archived_at(
archived_at: Option<NaiveDateTime>,
cipher_uuid: &CipherId,
user_uuid: &UserId,
conn: &DbConn,
) -> EmptyResult {
let (old, new) = (Self::get_archived_date(cipher_uuid, user_uuid, conn).await.is_some(), archived);
match (old, new) {
(false, true) => {
let existing = Self::get_archived_at(cipher_uuid, user_uuid, conn).await;
match (existing, archived_at) {
// Not archived - archive at the provided timestamp
(None, Some(dt)) => {
User::update_uuid_revision(user_uuid, conn).await;
db_run! { conn: {
diesel::insert_into(archives::table)
.values((
archives::user_uuid.eq(user_uuid),
archives::cipher_uuid.eq(cipher_uuid),
archives::archived_at.eq(Utc::now().naive_utc()),
archives::archived_at.eq(dt),
))
.execute(conn)
.map_res("Error archiving")
}}
}
(true, false) => {
// Already archived - update with the provided timestamp
(Some(_), Some(dt)) => {
User::update_uuid_revision(user_uuid, conn).await;
db_run! { conn: {
diesel::update(
archives::table
.filter(archives::user_uuid.eq(user_uuid))
.filter(archives::cipher_uuid.eq(cipher_uuid))
)
.set(archives::archived_at.eq(dt))
.execute(conn)
.map_res("Error updating archive date")
}}
}
(Some(_), None) => {
User::update_uuid_revision(user_uuid, conn).await;
db_run! { conn: {
diesel::delete(

15
src/db/models/cipher.rs

@ -383,7 +383,7 @@ impl Cipher {
json_object["archivedDate"] = json!(if let Some(cipher_sync_data) = cipher_sync_data {
cipher_sync_data.cipher_archives.get(&self.uuid).map_or(Value::Null, |d| Value::String(format_date(d)))
} else {
self.get_archived_date(user_uuid, conn).await.map_or(Value::Null, |d| Value::String(format_date(&d)))
self.get_archived_at(user_uuid, conn).await.map_or(Value::Null, |d| Value::String(format_date(&d)))
});
// These values are true by default, but can be false if the
// cipher belongs to a collection or group where the org owner has enabled
@ -742,12 +742,17 @@ impl Cipher {
}
}
pub async fn get_archived_date(&self, user_uuid: &UserId, conn: &DbConn) -> Option<NaiveDateTime> {
Archive::get_archived_date(&self.uuid, user_uuid, conn).await
pub async fn get_archived_at(&self, user_uuid: &UserId, conn: &DbConn) -> Option<NaiveDateTime> {
Archive::get_archived_at(&self.uuid, user_uuid, conn).await
}
pub async fn set_archived(&self, archived: bool, user_uuid: &UserId, conn: &DbConn) -> EmptyResult {
Archive::set_archived(archived, &self.uuid, user_uuid, conn).await
pub async fn set_archived_at(
&self,
archived_at: Option<NaiveDateTime>,
user_uuid: &UserId,
conn: &DbConn,
) -> EmptyResult {
Archive::set_archived_at(archived_at, &self.uuid, user_uuid, conn).await
}
pub async fn get_folder_uuid(&self, user_uuid: &UserId, conn: &DbConn) -> Option<FolderId> {

Loading…
Cancel
Save