initial mysql support

This commit is contained in:
Nils Domrose 2019-05-26 23:02:41 +02:00 committed by Nils Domrose
parent badd22ac3d
commit ff759397f6
55 changed files with 454 additions and 21 deletions

View File

@ -13,6 +13,8 @@ build = "build.rs"
[features] [features]
# Empty to keep compatibility, prefer to set USE_SYSLOG=true # Empty to keep compatibility, prefer to set USE_SYSLOG=true
enable_syslog = [] enable_syslog = []
mysql = []
sqlite = []
[target."cfg(not(windows))".dependencies] [target."cfg(not(windows))".dependencies]
syslog = "4.0.1" syslog = "4.0.1"
@ -47,8 +49,11 @@ log = "0.4.6"
fern = { version = "0.5.8", features = ["syslog-4"] } fern = { version = "0.5.8", features = ["syslog-4"] }
# A safe, extensible ORM and Query builder # A safe, extensible ORM and Query builder
diesel = { version = "1.4.2", features = ["mysql", "chrono", "r2d2"] } diesel = { version = "1.4.2", features = ["mysql", "sqlite", "chrono", "r2d2"] }
diesel_migrations = { version = "1.4.0", features = ["mysql"] } diesel_migrations = { version = "1.4.0", features = ["mysql", "sqlite"] }
# Bundled SQLite
libsqlite3-sys = { version = "0.12.0", features = ["bundled"] }
# Crypto library # Crypto library
ring = "0.14.6" ring = "0.14.6"

View File

@ -23,6 +23,9 @@ RUN ls
# we need the Rust compiler and Cargo tooling # we need the Rust compiler and Cargo tooling
FROM rust as build FROM rust as build
# set sqlite as default for DB ARG for backward comaptibility
ARG DB=sqlite
# Using bundled SQLite, no need to install it # Using bundled SQLite, no need to install it
# RUN apt-get update && apt-get install -y\ # RUN apt-get update && apt-get install -y\
# sqlite3\ # sqlite3\
@ -31,8 +34,8 @@ FROM rust as build
# Install MySQL package # Install MySQL package
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
libmysql++-dev \ libmariadb-dev\
--no-install-recommends \ --no-install-recommends\
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Creates a dummy project used to grab dependencies # Creates a dummy project used to grab dependencies
@ -47,7 +50,7 @@ COPY ./build.rs ./build.rs
# Builds your dependencies and removes the # Builds your dependencies and removes the
# dummy project, except the target folder # dummy project, except the target folder
# This folder contains the compiled dependencies # This folder contains the compiled dependencies
RUN cargo build --release RUN cargo build --features ${DB} --release
RUN find . -not -path "./target*" -delete RUN find . -not -path "./target*" -delete
# Copies the complete project # Copies the complete project
@ -59,7 +62,7 @@ RUN touch src/main.rs
# Builds again, this time it'll just be # Builds again, this time it'll just be
# your actual source files being built # your actual source files being built
RUN cargo build --release RUN cargo build --features ${DB} --release
######################## RUNTIME IMAGE ######################## ######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image # Create a new stage with a minimal image
@ -74,6 +77,7 @@ ENV ROCKET_WORKERS=10
RUN apt-get update && apt-get install -y\ RUN apt-get update && apt-get install -y\
openssl\ openssl\
ca-certificates\ ca-certificates\
libmariadbclient-dev\
--no-install-recommends\ --no-install-recommends\
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

View File

@ -8,7 +8,7 @@ CREATE TABLE users (
salt BLOB NOT NULL, salt BLOB NOT NULL,
password_iterations INTEGER NOT NULL, password_iterations INTEGER NOT NULL,
password_hint TEXT, password_hint TEXT,
akey TEXT NOT NULL, `key` TEXT NOT NULL,
private_key TEXT, private_key TEXT,
public_key TEXT, public_key TEXT,
totp_secret TEXT, totp_secret TEXT,
@ -24,7 +24,7 @@ CREATE TABLE devices (
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
name TEXT NOT NULL, name TEXT NOT NULL,
atype INTEGER NOT NULL, type INTEGER NOT NULL,
push_token TEXT, push_token TEXT,
refresh_token TEXT NOT NULL refresh_token TEXT NOT NULL
); );
@ -36,7 +36,7 @@ CREATE TABLE ciphers (
user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
folder_uuid VARCHAR(40) REFERENCES folders (uuid), folder_uuid VARCHAR(40) REFERENCES folders (uuid),
organization_uuid VARCHAR(40), organization_uuid VARCHAR(40),
atype INTEGER NOT NULL, type INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
notes TEXT, notes TEXT,
fields TEXT, fields TEXT,

View File

@ -22,9 +22,9 @@ CREATE TABLE users_organizations (
org_uuid VARCHAR(40) NOT NULL REFERENCES organizations (uuid), org_uuid VARCHAR(40) NOT NULL REFERENCES organizations (uuid),
access_all BOOLEAN NOT NULL, access_all BOOLEAN NOT NULL,
akey TEXT NOT NULL, `key` TEXT NOT NULL,
status INTEGER NOT NULL, status INTEGER NOT NULL,
atype INTEGER NOT NULL, type INTEGER NOT NULL,
UNIQUE (user_uuid, org_uuid) UNIQUE (user_uuid, org_uuid)
); );

View File

@ -7,7 +7,7 @@ CREATE TABLE ciphers (
user_uuid VARCHAR(40) REFERENCES users (uuid), -- Make this optional user_uuid VARCHAR(40) REFERENCES users (uuid), -- Make this optional
organization_uuid VARCHAR(40) REFERENCES organizations (uuid), -- Add reference to orgs table organization_uuid VARCHAR(40) REFERENCES organizations (uuid), -- Add reference to orgs table
-- Remove folder_uuid -- Remove folder_uuid
atype INTEGER NOT NULL, type INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
notes TEXT, notes TEXT,
fields TEXT, fields TEXT,
@ -22,8 +22,8 @@ CREATE TABLE folders_ciphers (
PRIMARY KEY (cipher_uuid, folder_uuid) PRIMARY KEY (cipher_uuid, folder_uuid)
); );
INSERT INTO ciphers (uuid, created_at, updated_at, user_uuid, organization_uuid, atype, name, notes, fields, data, favorite) INSERT INTO ciphers (uuid, created_at, updated_at, user_uuid, organization_uuid, type, name, notes, fields, data, favorite)
SELECT uuid, created_at, updated_at, user_uuid, organization_uuid, atype, name, notes, fields, data, favorite FROM oldCiphers; SELECT uuid, created_at, updated_at, user_uuid, organization_uuid, type, name, notes, fields, data, favorite FROM oldCiphers;
INSERT INTO folders_ciphers (cipher_uuid, folder_uuid) INSERT INTO folders_ciphers (cipher_uuid, folder_uuid)
SELECT uuid, folder_uuid FROM oldCiphers WHERE folder_uuid IS NOT NULL; SELECT uuid, folder_uuid FROM oldCiphers WHERE folder_uuid IS NOT NULL;

View File

@ -1,15 +1,15 @@
CREATE TABLE twofactor ( CREATE TABLE twofactor (
uuid VARCHAR(40) NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
atype INTEGER NOT NULL, type INTEGER NOT NULL,
enabled BOOLEAN NOT NULL, enabled BOOLEAN NOT NULL,
data TEXT NOT NULL, data TEXT NOT NULL,
UNIQUE (user_uuid, atype) UNIQUE (user_uuid, type)
); );
INSERT INTO twofactor (uuid, user_uuid, atype, enabled, data) INSERT INTO twofactor (uuid, user_uuid, type, enabled, data)
SELECT UUID(), uuid, 0, 1, u.totp_secret FROM users u where u.totp_secret IS NOT NULL; SELECT UUID(), uuid, 0, 1, u.totp_secret FROM users u where u.totp_secret IS NOT NULL;
UPDATE users SET totp_secret = NULL; -- Instead of recreating the table, just leave the columns empty UPDATE users SET totp_secret = NULL; -- Instead of recreating the table, just leave the columns empty

View File

@ -0,0 +1,3 @@
ALTER TABLE attachments
ADD COLUMN
`key` TEXT;

View File

@ -0,0 +1,7 @@
ALTER TABLE attachments CHANGE COLUMN akey `key` TEXT;
ALTER TABLE ciphers CHANGE COLUMN atype type INTEGER NOT NULL;
ALTER TABLE devices CHANGE COLUMN atype type INTEGER NOT NULL;
ALTER TABLE twofactor CHANGE COLUMN atype type INTEGER NOT NULL;
ALTER TABLE users CHANGE COLUMN akey `key` TEXT;
ALTER TABLE users_organizations CHANGE COLUMN akey `key` TEXT;
ALTER TABLE users_organizations CHANGE COLUMN atype type INTEGER NOT NULL;

View File

@ -0,0 +1,7 @@
ALTER TABLE attachments CHANGE COLUMN `key` akey TEXT;
ALTER TABLE ciphers CHANGE COLUMN type atype INTEGER NOT NULL;
ALTER TABLE devices CHANGE COLUMN type atype INTEGER NOT NULL;
ALTER TABLE twofactor CHANGE COLUMN type atype INTEGER NOT NULL;
ALTER TABLE users CHANGE COLUMN `key` akey TEXT;
ALTER TABLE users_organizations CHANGE COLUMN `key` akey TEXT;
ALTER TABLE users_organizations CHANGE COLUMN type atype INTEGER NOT NULL;

View File

@ -0,0 +1,9 @@
DROP TABLE users;
DROP TABLE devices;
DROP TABLE ciphers;
DROP TABLE attachments;
DROP TABLE folders;

View File

@ -0,0 +1,62 @@
CREATE TABLE users (
uuid TEXT NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
email TEXT NOT NULL UNIQUE,
name TEXT NOT NULL,
password_hash BLOB NOT NULL,
salt BLOB NOT NULL,
password_iterations INTEGER NOT NULL,
password_hint TEXT,
key TEXT NOT NULL,
private_key TEXT,
public_key TEXT,
totp_secret TEXT,
totp_recover TEXT,
security_stamp TEXT NOT NULL,
equivalent_domains TEXT NOT NULL,
excluded_globals TEXT NOT NULL
);
CREATE TABLE devices (
uuid TEXT NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid),
name TEXT NOT NULL,
type INTEGER NOT NULL,
push_token TEXT,
refresh_token TEXT NOT NULL
);
CREATE TABLE ciphers (
uuid TEXT NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid),
folder_uuid TEXT REFERENCES folders (uuid),
organization_uuid TEXT,
type INTEGER NOT NULL,
name TEXT NOT NULL,
notes TEXT,
fields TEXT,
data TEXT NOT NULL,
favorite BOOLEAN NOT NULL
);
CREATE TABLE attachments (
id TEXT NOT NULL PRIMARY KEY,
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid),
file_name TEXT NOT NULL,
file_size INTEGER NOT NULL
);
CREATE TABLE folders (
uuid TEXT NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid),
name TEXT NOT NULL
);

View File

@ -0,0 +1,8 @@
DROP TABLE collections;
DROP TABLE organizations;
DROP TABLE users_collections;
DROP TABLE users_organizations;

View File

@ -0,0 +1,31 @@
CREATE TABLE collections (
uuid TEXT NOT NULL PRIMARY KEY,
org_uuid TEXT NOT NULL REFERENCES organizations (uuid),
name TEXT NOT NULL
);
CREATE TABLE organizations (
uuid TEXT NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
billing_email TEXT NOT NULL
);
CREATE TABLE users_collections (
user_uuid TEXT NOT NULL REFERENCES users (uuid),
collection_uuid TEXT NOT NULL REFERENCES collections (uuid),
PRIMARY KEY (user_uuid, collection_uuid)
);
CREATE TABLE users_organizations (
uuid TEXT NOT NULL PRIMARY KEY,
user_uuid TEXT NOT NULL REFERENCES users (uuid),
org_uuid TEXT NOT NULL REFERENCES organizations (uuid),
access_all BOOLEAN NOT NULL,
key TEXT NOT NULL,
status INTEGER NOT NULL,
type INTEGER NOT NULL,
UNIQUE (user_uuid, org_uuid)
);

View File

@ -0,0 +1,34 @@
ALTER TABLE ciphers RENAME TO oldCiphers;
CREATE TABLE ciphers (
uuid TEXT NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
user_uuid TEXT REFERENCES users (uuid), -- Make this optional
organization_uuid TEXT REFERENCES organizations (uuid), -- Add reference to orgs table
-- Remove folder_uuid
type INTEGER NOT NULL,
name TEXT NOT NULL,
notes TEXT,
fields TEXT,
data TEXT NOT NULL,
favorite BOOLEAN NOT NULL
);
CREATE TABLE folders_ciphers (
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid),
folder_uuid TEXT NOT NULL REFERENCES folders (uuid),
PRIMARY KEY (cipher_uuid, folder_uuid)
);
INSERT INTO ciphers (uuid, created_at, updated_at, user_uuid, organization_uuid, type, name, notes, fields, data, favorite)
SELECT uuid, created_at, updated_at, user_uuid, organization_uuid, type, name, notes, fields, data, favorite FROM oldCiphers;
INSERT INTO folders_ciphers (cipher_uuid, folder_uuid)
SELECT uuid, folder_uuid FROM oldCiphers WHERE folder_uuid IS NOT NULL;
DROP TABLE oldCiphers;
ALTER TABLE users_collections ADD COLUMN read_only BOOLEAN NOT NULL DEFAULT 0; -- False

View File

@ -0,0 +1 @@
DROP TABLE ciphers_collections;

View File

@ -0,0 +1,5 @@
CREATE TABLE ciphers_collections (
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid),
collection_uuid TEXT NOT NULL REFERENCES collections (uuid),
PRIMARY KEY (cipher_uuid, collection_uuid)
);

View File

@ -0,0 +1,14 @@
ALTER TABLE attachments RENAME TO oldAttachments;
CREATE TABLE attachments (
id TEXT NOT NULL PRIMARY KEY,
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid),
file_name TEXT NOT NULL,
file_size INTEGER NOT NULL
);
INSERT INTO attachments (id, cipher_uuid, file_name, file_size)
SELECT id, cipher_uuid, file_name, file_size FROM oldAttachments;
DROP TABLE oldAttachments;

View File

@ -0,0 +1 @@
-- This file should undo anything in `up.sql`

View File

@ -0,0 +1,3 @@
ALTER TABLE devices
ADD COLUMN
twofactor_remember TEXT;

View File

@ -0,0 +1,8 @@
UPDATE users
SET totp_secret = (
SELECT twofactor.data FROM twofactor
WHERE twofactor.type = 0
AND twofactor.user_uuid = users.uuid
);
DROP TABLE twofactor;

View File

@ -0,0 +1,15 @@
CREATE TABLE twofactor (
uuid TEXT NOT NULL PRIMARY KEY,
user_uuid TEXT NOT NULL REFERENCES users (uuid),
type INTEGER NOT NULL,
enabled BOOLEAN NOT NULL,
data TEXT NOT NULL,
UNIQUE (user_uuid, type)
);
INSERT INTO twofactor (uuid, user_uuid, type, enabled, data)
SELECT lower(hex(randomblob(16))) , uuid, 0, 1, u.totp_secret FROM users u where u.totp_secret IS NOT NULL;
UPDATE users SET totp_secret = NULL; -- Instead of recreating the table, just leave the columns empty

View File

@ -0,0 +1,3 @@
ALTER TABLE ciphers
ADD COLUMN
password_history TEXT;

View File

@ -0,0 +1 @@
DROP TABLE invitations;

View File

@ -0,0 +1,3 @@
CREATE TABLE invitations (
email TEXT NOT NULL PRIMARY KEY
);

View File

@ -0,0 +1,7 @@
ALTER TABLE users
ADD COLUMN
client_kdf_type INTEGER NOT NULL DEFAULT 0; -- PBKDF2
ALTER TABLE users
ADD COLUMN
client_kdf_iter INTEGER NOT NULL DEFAULT 5000;

View File

@ -1,3 +1,3 @@
ALTER TABLE attachments ALTER TABLE attachments
ADD COLUMN ADD COLUMN
akey TEXT; key TEXT;

View File

@ -0,0 +1,7 @@
ALTER TABLE attachments RENAME COLUMN akey TO key;
ALTER TABLE ciphers RENAME COLUMN atype TO type;
ALTER TABLE devices RENAME COLUMN atype TO type;
ALTER TABLE twofactor RENAME COLUMN atype TO type;
ALTER TABLE users RENAME COLUMN akey TO key;
ALTER TABLE users_organizations RENAME COLUMN akey TO key;
ALTER TABLE users_organizations RENAME COLUMN atype TO type;

View File

@ -0,0 +1,7 @@
ALTER TABLE attachments RENAME COLUMN key TO akey;
ALTER TABLE ciphers RENAME COLUMN type TO atype;
ALTER TABLE devices RENAME COLUMN type TO atype;
ALTER TABLE twofactor RENAME COLUMN type TO atype;
ALTER TABLE users RENAME COLUMN key TO akey;
ALTER TABLE users_organizations RENAME COLUMN key TO akey;
ALTER TABLE users_organizations RENAME COLUMN type TO atype;

View File

@ -204,8 +204,8 @@ make_config! {
data_folder: String, false, def, "data".to_string(); data_folder: String, false, def, "data".to_string();
/// Database URL /// Database URL
/// docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=bitwarden -p 3306:3306 -d mysql:5.7 /// Database URL
database_url: String, false, auto, |_c| format!("mysql://root:my-secret-pw@0.0.0.0:3306/bitwarden"); database_url: String, false, auto, |c| format!("{}/{}", c.data_folder, "db.sqlite3");
/// Icon chache folder /// Icon chache folder
icon_cache_folder: String, false, auto, |c| format!("{}/{}", c.data_folder, "icon_cache"); icon_cache_folder: String, false, auto, |c| format!("{}/{}", c.data_folder, "icon_cache");
/// Attachments folder /// Attachments folder

View File

@ -2,6 +2,9 @@ use std::ops::Deref;
use diesel::r2d2; use diesel::r2d2;
use diesel::r2d2::ConnectionManager; use diesel::r2d2::ConnectionManager;
#[cfg(feature = "sqlite")]
use diesel::sqlite::SqliteConnection;
#[cfg(feature = "mysql")]
use diesel::mysql::MysqlConnection; use diesel::mysql::MysqlConnection;
use diesel::{Connection as DieselConnection, ConnectionError}; use diesel::{Connection as DieselConnection, ConnectionError};
@ -12,6 +15,9 @@ use rocket::{Outcome, Request, State};
use crate::CONFIG; use crate::CONFIG;
/// An alias to the database connection used /// An alias to the database connection used
#[cfg(feature = "sqlite")]
type Connection = SqliteConnection;
#[cfg(feature = "mysql")]
type Connection = MysqlConnection; type Connection = MysqlConnection;
/// An alias to the type for a pool of Diesel MySQL connections. /// An alias to the type for a pool of Diesel MySQL connections.
@ -21,7 +27,13 @@ type Pool = r2d2::Pool<ConnectionManager<Connection>>;
pub struct DbConn(pub r2d2::PooledConnection<ConnectionManager<Connection>>); pub struct DbConn(pub r2d2::PooledConnection<ConnectionManager<Connection>>);
pub mod models; pub mod models;
#[cfg(feature = "sqlite")]
#[path = "schemas/sqlite/schema.rs"]
pub mod schema; pub mod schema;
#[cfg(feature = "mysql")]
#[path = "schemas/mysql/schema.rs"]
pub mod schema;
/// Initializes a database pool. /// Initializes a database pool.
pub fn init_pool() -> Pool { pub fn init_pool() -> Pool {

View File

@ -0,0 +1,172 @@
table! {
attachments (id) {
id -> Text,
cipher_uuid -> Text,
file_name -> Text,
file_size -> Integer,
akey -> Nullable<Text>,
}
}
table! {
ciphers (uuid) {
uuid -> Text,
created_at -> Timestamp,
updated_at -> Timestamp,
user_uuid -> Nullable<Text>,
organization_uuid -> Nullable<Text>,
atype -> Integer,
name -> Text,
notes -> Nullable<Text>,
fields -> Nullable<Text>,
data -> Text,
favorite -> Bool,
password_history -> Nullable<Text>,
}
}
table! {
ciphers_collections (cipher_uuid, collection_uuid) {
cipher_uuid -> Text,
collection_uuid -> Text,
}
}
table! {
collections (uuid) {
uuid -> Text,
org_uuid -> Text,
name -> Text,
}
}
table! {
devices (uuid) {
uuid -> Text,
created_at -> Timestamp,
updated_at -> Timestamp,
user_uuid -> Text,
name -> Text,
atype -> Integer,
push_token -> Nullable<Text>,
refresh_token -> Text,
twofactor_remember -> Nullable<Text>,
}
}
table! {
folders (uuid) {
uuid -> Text,
created_at -> Timestamp,
updated_at -> Timestamp,
user_uuid -> Text,
name -> Text,
}
}
table! {
folders_ciphers (cipher_uuid, folder_uuid) {
cipher_uuid -> Text,
folder_uuid -> Text,
}
}
table! {
invitations (email) {
email -> Text,
}
}
table! {
organizations (uuid) {
uuid -> Text,
name -> Text,
billing_email -> Text,
}
}
table! {
twofactor (uuid) {
uuid -> Text,
user_uuid -> Text,
atype -> Integer,
enabled -> Bool,
data -> Text,
}
}
table! {
users (uuid) {
uuid -> Text,
created_at -> Timestamp,
updated_at -> Timestamp,
email -> Text,
name -> Text,
password_hash -> Binary,
salt -> Binary,
password_iterations -> Integer,
password_hint -> Nullable<Text>,
akey -> Text,
private_key -> Nullable<Text>,
public_key -> Nullable<Text>,
totp_secret -> Nullable<Text>,
totp_recover -> Nullable<Text>,
security_stamp -> Text,
equivalent_domains -> Text,
excluded_globals -> Text,
client_kdf_type -> Integer,
client_kdf_iter -> Integer,
}
}
table! {
users_collections (user_uuid, collection_uuid) {
user_uuid -> Text,
collection_uuid -> Text,
read_only -> Bool,
}
}
table! {
users_organizations (uuid) {
uuid -> Text,
user_uuid -> Text,
org_uuid -> Text,
access_all -> Bool,
akey -> Text,
status -> Integer,
atype -> Integer,
}
}
joinable!(attachments -> ciphers (cipher_uuid));
joinable!(ciphers -> organizations (organization_uuid));
joinable!(ciphers -> users (user_uuid));
joinable!(ciphers_collections -> ciphers (cipher_uuid));
joinable!(ciphers_collections -> collections (collection_uuid));
joinable!(collections -> organizations (org_uuid));
joinable!(devices -> users (user_uuid));
joinable!(folders -> users (user_uuid));
joinable!(folders_ciphers -> ciphers (cipher_uuid));
joinable!(folders_ciphers -> folders (folder_uuid));
joinable!(twofactor -> users (user_uuid));
joinable!(users_collections -> collections (collection_uuid));
joinable!(users_collections -> users (user_uuid));
joinable!(users_organizations -> organizations (org_uuid));
joinable!(users_organizations -> users (user_uuid));
allow_tables_to_appear_in_same_query!(
attachments,
ciphers,
ciphers_collections,
collections,
devices,
folders,
folders_ciphers,
invitations,
organizations,
twofactor,
users,
users_collections,
users_organizations,
);

View File

@ -191,7 +191,11 @@ fn check_web_vault() {
// https://docs.rs/diesel_migrations/*/diesel_migrations/macro.embed_migrations.html // https://docs.rs/diesel_migrations/*/diesel_migrations/macro.embed_migrations.html
#[allow(unused_imports)] #[allow(unused_imports)]
mod migrations { mod migrations {
embed_migrations!();
#[cfg(feature = "sqlite")]
embed_migrations!("migrations/sqlite");
#[cfg(feature = "mysql")]
embed_migrations!("migrations/mysql");
pub fn run_migrations() { pub fn run_migrations() {
// Make sure the database is up to date (create if it doesn't exist, or run the migrations) // Make sure the database is up to date (create if it doesn't exist, or run the migrations)