mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2025-09-12 03:25:58 +03:00
Upload and download attachments, and added License file
This commit is contained in:
93
src/db/models/attachment.rs
Normal file
93
src/db/models/attachment.rs
Normal file
@@ -0,0 +1,93 @@
|
||||
use serde_json::Value as JsonValue;
|
||||
|
||||
use super::Cipher;
|
||||
use CONFIG;
|
||||
|
||||
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
|
||||
#[table_name = "attachments"]
|
||||
#[belongs_to(Cipher, foreign_key = "cipher_uuid")]
|
||||
#[primary_key(id)]
|
||||
pub struct Attachment {
|
||||
pub id: String,
|
||||
pub cipher_uuid: String,
|
||||
pub file_name: String,
|
||||
pub file_size: i32,
|
||||
}
|
||||
|
||||
/// Local methods
|
||||
impl Attachment {
|
||||
pub fn new(id: String, cipher_uuid: String, file_name: String, file_size: i32) -> Self {
|
||||
Self {
|
||||
id,
|
||||
cipher_uuid,
|
||||
file_name,
|
||||
file_size,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_file_path(&self) -> String {
|
||||
format!("{}/{}/{}", CONFIG.attachments_folder, self.cipher_uuid, self.id)
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> JsonValue {
|
||||
use util::get_display_size;
|
||||
use CONFIG;
|
||||
|
||||
// TODO: Change all references to localhost (maybe put it in .env?)
|
||||
let host = "http://localhost:8000";
|
||||
|
||||
let web_path = format!("{}/attachments/{}/{}", host, self.cipher_uuid, self.id);
|
||||
|
||||
let file_path = self.get_file_path();
|
||||
let display_size = get_display_size(self.file_size);
|
||||
|
||||
json!({
|
||||
"Id": self.id,
|
||||
"Url": web_path,
|
||||
"FileName": self.file_name,
|
||||
"Size": self.file_size.to_string(),
|
||||
"SizeName": display_size,
|
||||
"Object": "attachment"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use diesel;
|
||||
use diesel::prelude::*;
|
||||
use db::DbConn;
|
||||
use db::schema::attachments;
|
||||
|
||||
/// Database methods
|
||||
impl Attachment {
|
||||
pub fn save(&self, conn: &DbConn) -> bool {
|
||||
// TODO: Update modified date
|
||||
|
||||
match diesel::replace_into(attachments::table)
|
||||
.values(self)
|
||||
.execute(&**conn) {
|
||||
Ok(1) => true, // One row inserted
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn delete(self, conn: &DbConn) -> bool {
|
||||
match diesel::delete(attachments::table.filter(
|
||||
attachments::id.eq(self.id)))
|
||||
.execute(&**conn) {
|
||||
Ok(1) => true, // One row deleted
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_id(id: &str, conn: &DbConn) -> Option<Self> {
|
||||
attachments::table
|
||||
.filter(attachments::id.eq(id))
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
|
||||
pub fn find_by_cipher(cipher_uuid: &str, conn: &DbConn) -> Vec<Self> {
|
||||
attachments::table
|
||||
.filter(attachments::cipher_uuid.eq(cipher_uuid))
|
||||
.load::<Self>(&**conn).expect("Error loading attachments")
|
||||
}
|
||||
}
|
@@ -4,8 +4,11 @@ use serde_json::Value as JsonValue;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Queryable, Insertable, Identifiable)]
|
||||
use super::User;
|
||||
|
||||
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
|
||||
#[table_name = "ciphers"]
|
||||
#[belongs_to(User, foreign_key = "user_uuid")]
|
||||
#[primary_key(uuid)]
|
||||
pub struct Cipher {
|
||||
pub uuid: String,
|
||||
@@ -24,15 +27,14 @@ pub struct Cipher {
|
||||
|
||||
pub data: String,
|
||||
pub favorite: bool,
|
||||
pub attachments: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
/// Local methods
|
||||
impl Cipher {
|
||||
pub fn new(user_uuid: String, type_: i32, favorite: bool) -> Cipher {
|
||||
pub fn new(user_uuid: String, type_: i32, favorite: bool) -> Self {
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
Cipher {
|
||||
Self {
|
||||
uuid: Uuid::new_v4().to_string(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
@@ -45,30 +47,8 @@ impl Cipher {
|
||||
favorite,
|
||||
|
||||
data: String::new(),
|
||||
attachments: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> JsonValue {
|
||||
use serde_json;
|
||||
use util::format_date;
|
||||
|
||||
let data: JsonValue = serde_json::from_str(&self.data).unwrap();
|
||||
|
||||
json!({
|
||||
"Id": self.uuid,
|
||||
"Type": self.type_,
|
||||
"RevisionDate": format_date(&self.updated_at),
|
||||
"FolderId": self.folder_uuid,
|
||||
"Favorite": self.favorite,
|
||||
"OrganizationId": "",
|
||||
"Attachments": self.attachments,
|
||||
"OrganizationUseTotp": false,
|
||||
"Data": data,
|
||||
"Object": "cipher",
|
||||
"Edit": true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use diesel;
|
||||
@@ -78,6 +58,31 @@ use db::schema::ciphers;
|
||||
|
||||
/// Database methods
|
||||
impl Cipher {
|
||||
pub fn to_json(&self, conn: &DbConn) -> JsonValue {
|
||||
use serde_json;
|
||||
use util::format_date;
|
||||
use super::Attachment;
|
||||
|
||||
let data_json: JsonValue = serde_json::from_str(&self.data).unwrap();
|
||||
|
||||
let attachments = Attachment::find_by_cipher(&self.uuid, conn);
|
||||
let attachments_json: Vec<JsonValue> = attachments.iter().map(|c| c.to_json()).collect();
|
||||
|
||||
json!({
|
||||
"Id": self.uuid,
|
||||
"Type": self.type_,
|
||||
"RevisionDate": format_date(&self.updated_at),
|
||||
"FolderId": self.folder_uuid,
|
||||
"Favorite": self.favorite,
|
||||
"OrganizationId": "",
|
||||
"Attachments": attachments_json,
|
||||
"OrganizationUseTotp": false,
|
||||
"Data": data_json,
|
||||
"Object": "cipher",
|
||||
"Edit": true,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn save(&self, conn: &DbConn) -> bool {
|
||||
// TODO: Update modified date
|
||||
|
||||
@@ -98,15 +103,15 @@ impl Cipher {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Cipher> {
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
||||
ciphers::table
|
||||
.filter(ciphers::uuid.eq(uuid))
|
||||
.first::<Cipher>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
|
||||
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Cipher> {
|
||||
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Self> {
|
||||
ciphers::table
|
||||
.filter(ciphers::user_uuid.eq(user_uuid))
|
||||
.load::<Cipher>(&**conn).expect("Error loading ciphers")
|
||||
.load::<Self>(&**conn).expect("Error loading ciphers")
|
||||
}
|
||||
}
|
||||
|
@@ -4,8 +4,11 @@ use serde_json::Value as JsonValue;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Queryable, Insertable, Identifiable)]
|
||||
use super::User;
|
||||
|
||||
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
|
||||
#[table_name = "devices"]
|
||||
#[belongs_to(User, foreign_key = "user_uuid")]
|
||||
#[primary_key(uuid)]
|
||||
pub struct Device {
|
||||
pub uuid: String,
|
||||
@@ -24,10 +27,10 @@ pub struct Device {
|
||||
|
||||
/// Local methods
|
||||
impl Device {
|
||||
pub fn new(uuid: String, user_uuid: String, name: String, type_: i32) -> Device {
|
||||
pub fn new(uuid: String, user_uuid: String, name: String, type_: i32) -> Self {
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
Device {
|
||||
Self {
|
||||
uuid,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
@@ -103,15 +106,15 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Device> {
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
||||
devices::table
|
||||
.filter(devices::uuid.eq(uuid))
|
||||
.first::<Device>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
|
||||
pub fn find_by_refresh_token(refresh_token: &str, conn: &DbConn) -> Option<Device> {
|
||||
pub fn find_by_refresh_token(refresh_token: &str, conn: &DbConn) -> Option<Self> {
|
||||
devices::table
|
||||
.filter(devices::refresh_token.eq(refresh_token))
|
||||
.first::<Device>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
}
|
||||
|
@@ -4,8 +4,11 @@ use serde_json::Value as JsonValue;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Queryable, Insertable, Identifiable)]
|
||||
use super::User;
|
||||
|
||||
#[derive(Debug, Identifiable, Queryable, Insertable, Associations)]
|
||||
#[table_name = "folders"]
|
||||
#[belongs_to(User, foreign_key = "user_uuid")]
|
||||
#[primary_key(uuid)]
|
||||
pub struct Folder {
|
||||
pub uuid: String,
|
||||
@@ -17,10 +20,10 @@ pub struct Folder {
|
||||
|
||||
/// Local methods
|
||||
impl Folder {
|
||||
pub fn new(user_uuid: String, name: String) -> Folder {
|
||||
pub fn new(user_uuid: String, name: String) -> Self {
|
||||
let now = Utc::now().naive_utc();
|
||||
|
||||
Folder {
|
||||
Self {
|
||||
uuid: Uuid::new_v4().to_string(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
@@ -69,15 +72,15 @@ impl Folder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Folder> {
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
||||
folders::table
|
||||
.filter(folders::uuid.eq(uuid))
|
||||
.first::<Folder>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
|
||||
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Folder> {
|
||||
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Self> {
|
||||
folders::table
|
||||
.filter(folders::user_uuid.eq(user_uuid))
|
||||
.load::<Folder>(&**conn).expect("Error loading folders")
|
||||
.load::<Self>(&**conn).expect("Error loading folders")
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,10 @@
|
||||
mod attachment;
|
||||
mod cipher;
|
||||
mod device;
|
||||
mod folder;
|
||||
mod user;
|
||||
|
||||
pub use self::attachment::Attachment;
|
||||
pub use self::cipher::Cipher;
|
||||
pub use self::device::Device;
|
||||
pub use self::folder::Folder;
|
||||
|
@@ -6,7 +6,7 @@ use uuid::Uuid;
|
||||
|
||||
use CONFIG;
|
||||
|
||||
#[derive(Queryable, Insertable, Identifiable)]
|
||||
#[derive(Debug, Identifiable, Queryable, Insertable)]
|
||||
#[table_name = "users"]
|
||||
#[primary_key(uuid)]
|
||||
pub struct User {
|
||||
@@ -28,11 +28,14 @@ pub struct User {
|
||||
pub totp_secret: Option<String>,
|
||||
pub totp_recover: Option<String>,
|
||||
pub security_stamp: String,
|
||||
|
||||
pub equivalent_domains: String,
|
||||
pub excluded_globals: String,
|
||||
}
|
||||
|
||||
/// Local methods
|
||||
impl User {
|
||||
pub fn new(mail: String, key: String, password: String) -> User {
|
||||
pub fn new(mail: String, key: String, password: String) -> Self {
|
||||
let now = Utc::now().naive_utc();
|
||||
let email = mail.to_lowercase();
|
||||
|
||||
@@ -42,7 +45,7 @@ impl User {
|
||||
let salt = crypto::get_random_64();
|
||||
let password_hash = crypto::hash_password(password.as_bytes(), &salt, iterations as u32);
|
||||
|
||||
User {
|
||||
Self {
|
||||
uuid: Uuid::new_v4().to_string(),
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
@@ -61,6 +64,9 @@ impl User {
|
||||
public_key: None,
|
||||
totp_secret: None,
|
||||
totp_recover: None,
|
||||
|
||||
equivalent_domains: "[]".to_string(),
|
||||
excluded_globals: "[]".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,16 +150,16 @@ impl User {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option<User> {
|
||||
pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option<Self> {
|
||||
let lower_mail = mail.to_lowercase();
|
||||
users::table
|
||||
.filter(users::email.eq(lower_mail))
|
||||
.first::<User>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<User> {
|
||||
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
|
||||
users::table
|
||||
.filter(users::uuid.eq(uuid))
|
||||
.first::<User>(&**conn).ok()
|
||||
.first::<Self>(&**conn).ok()
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,12 @@
|
||||
table! {
|
||||
attachments (id) {
|
||||
id -> Text,
|
||||
cipher_uuid -> Text,
|
||||
file_name -> Text,
|
||||
file_size -> Integer,
|
||||
}
|
||||
}
|
||||
|
||||
table! {
|
||||
ciphers (uuid) {
|
||||
uuid -> Text,
|
||||
@@ -10,7 +19,6 @@ table! {
|
||||
type_ -> Integer,
|
||||
data -> Text,
|
||||
favorite -> Bool,
|
||||
attachments -> Nullable<Binary>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,15 +63,19 @@ table! {
|
||||
totp_secret -> Nullable<Text>,
|
||||
totp_recover -> Nullable<Text>,
|
||||
security_stamp -> Text,
|
||||
equivalent_domains -> Text,
|
||||
excluded_globals -> Text,
|
||||
}
|
||||
}
|
||||
|
||||
joinable!(attachments -> ciphers (cipher_uuid));
|
||||
joinable!(ciphers -> folders (folder_uuid));
|
||||
joinable!(ciphers -> users (user_uuid));
|
||||
joinable!(devices -> users (user_uuid));
|
||||
joinable!(folders -> users (user_uuid));
|
||||
|
||||
allow_tables_to_appear_in_same_query!(
|
||||
attachments,
|
||||
ciphers,
|
||||
devices,
|
||||
folders,
|
||||
|
Reference in New Issue
Block a user