Rework migrations for MySQL

This commit is contained in:
Emil Madsen 2019-05-20 21:12:41 +02:00
parent 85c8a01f4a
commit ab95a69dc8
22 changed files with 154 additions and 321 deletions

View File

@ -1,146 +0,0 @@
## Bitwarden_RS Configuration File
## Uncomment any of the following lines to change the defaults
## Main data folder
# DATA_FOLDER=data
## Individual folders, these override %DATA_FOLDER%
# DATABASE_URL=data/db.sqlite3
# RSA_KEY_FILENAME=data/rsa_key
# ICON_CACHE_FOLDER=data/icon_cache
# ATTACHMENTS_FOLDER=data/attachments
## Templates data folder, by default uses embedded templates
## Check source code to see the format
# TEMPLATES_FOLDER=/path/to/templates
## Automatically reload the templates for every request, slow, use only for development
# RELOAD_TEMPLATES=false
## Cache time-to-live for successfully obtained icons, in seconds (0 is "forever")
# ICON_CACHE_TTL=2592000
## Cache time-to-live for icons which weren't available, in seconds (0 is "forever")
# ICON_CACHE_NEGTTL=259200
## Web vault settings
# WEB_VAULT_FOLDER=web-vault/
# WEB_VAULT_ENABLED=true
## Enables websocket notifications
# WEBSOCKET_ENABLED=false
## Controls the WebSocket server address and port
# WEBSOCKET_ADDRESS=0.0.0.0
# WEBSOCKET_PORT=3012
## Enable extended logging
## This shows timestamps and allows logging to file and to syslog
### To enable logging to file, use the LOG_FILE env variable
### To enable syslog, use the USE_SYSLOG env variable
# EXTENDED_LOGGING=true
## Logging to file
## This requires extended logging
## It's recommended to also set 'ROCKET_CLI_COLORS=off'
# LOG_FILE=/path/to/log
## Logging to Syslog
## This requires extended logging
## It's recommended to also set 'ROCKET_CLI_COLORS=off'
# USE_SYSLOG=false
## Log level
## Change the verbosity of the log output
## Valid values are "trace", "debug", "info", "warn", "error" and "off"
## This requires extended logging
# LOG_LEVEL=Info
## Enable WAL for the DB
## Set to false to avoid enabling WAL during startup.
## Note that if the DB already has WAL enabled, you will also need to disable WAL in the DB,
## this setting only prevents bitwarden_rs from automatically enabling it on start.
## Please read project wiki page about this setting first before changing the value as it can
## cause performance degradation or might render the service unable to start.
# ENABLE_DB_WAL=true
## Disable icon downloading
## Set to true to disable icon downloading, this would still serve icons from $ICON_CACHE_FOLDER,
## but it won't produce any external network request. Needs to set $ICON_CACHE_TTL to 0,
## otherwise it will delete them and they won't be downloaded again.
# DISABLE_ICON_DOWNLOAD=false
## Icon download timeout
## Configure the timeout value when downloading the favicons.
## The default is 10 seconds, but this could be to low on slower network connections
# ICON_DOWNLOAD_TIMEOUT=10
## Icon blacklist Regex
## Any domains or IPs that match this regex won't be fetched by the icon service.
## Useful to hide other servers in the local network. Check the WIKI for more details
# ICON_BLACKLIST_REGEX=192\.168\.1\.[0-9].*^
## Disable 2FA remember
## Enabling this would force the users to use a second factor to login every time.
## Note that the checkbox would still be present, but ignored.
# DISABLE_2FA_REMEMBER=false
## Controls if new users can register
# SIGNUPS_ALLOWED=true
## Token for the admin interface, preferably use a long random string
## One option is to use 'openssl rand -base64 48'
## If not set, the admin panel is disabled
# ADMIN_TOKEN=Vy2VyYTTsKPv8W5aEOWUbB/Bt3DEKePbHmI4m9VcemUMS2rEviDowNAFqYi1xjmp
# DISABLE_ADMIN_TOKEN=false
## Invitations org admins to invite users, even when signups are disabled
# INVITATIONS_ALLOWED=true
## Controls the PBBKDF password iterations to apply on the server
## The change only applies when the password is changed
# PASSWORD_ITERATIONS=100000
## Whether password hint should be sent into the error response when the client request it
# SHOW_PASSWORD_HINT=true
## Domain settings
## The domain must match the address from where you access the server
## It's recommended to configure this value, otherwise certain functionality might not work,
## like attachment downloads, email links and U2F.
## For U2F to work, the server must use HTTPS, you can use Let's Encrypt for free certs
# DOMAIN=https://bw.domain.tld:8443
## Yubico (Yubikey) Settings
## Set your Client ID and Secret Key for Yubikey OTP
## You can generate it here: https://upgrade.yubico.com/getapikey/
## You can optionally specify a custom OTP server
# YUBICO_CLIENT_ID=11111
# YUBICO_SECRET_KEY=AAAAAAAAAAAAAAAAAAAAAAAA
# YUBICO_SERVER=http://yourdomain.com/wsapi/2.0/verify
## Duo Settings
## You need to configure all options to enable global Duo support, otherwise users would need to configure it themselves
## Create an account and protect an application as mentioned in this link (only the first step, not the rest):
## https://help.bitwarden.com/article/setup-two-step-login-duo/#create-a-duo-security-account
## Then set the following options, based on the values obtained from the last step:
# DUO_IKEY=<Integration Key>
# DUO_SKEY=<Secret Key>
# DUO_HOST=<API Hostname>
## After that, you should be able to follow the rest of the guide linked above,
## ignoring the fields that ask for the values that you already configured beforehand.
## Rocket specific settings, check Rocket documentation to learn more
# ROCKET_ENV=staging
# ROCKET_ADDRESS=0.0.0.0 # Enable this to test mobile app
# ROCKET_PORT=8000
# ROCKET_TLS={certs="/path/to/certs.pem",key="/path/to/key.pem"}
## Mail specific settings, set SMTP_HOST and SMTP_FROM to enable the mail service.
## To make sure the email links are pointing to the correct host, set the DOMAIN variable.
## Note: if SMTP_USERNAME is specified, SMTP_PASSWORD is mandatory
# SMTP_HOST=smtp.domain.tld
# SMTP_FROM=bitwarden-rs@domain.tld
# SMTP_FROM_NAME=Bitwarden_RS
# SMTP_PORT=587
# SMTP_SSL=true
# SMTP_USERNAME=username
# SMTP_PASSWORD=password

25
Cargo.lock generated
View File

@ -116,7 +116,6 @@ dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lettre 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "lettre 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lettre_email 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "lettre_email 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -429,8 +428,9 @@ dependencies = [
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "mysqlclient-sys 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1044,16 +1044,6 @@ name = "libc"
version = "0.2.55" version = "0.2.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libsqlite3-sys"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "lock_api" name = "lock_api"
version = "0.1.5" version = "0.1.5"
@ -1250,6 +1240,15 @@ dependencies = [
"twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "mysqlclient-sys"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.3" version = "0.2.3"
@ -2861,7 +2860,6 @@ dependencies = [
"checksum lettre 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "646aee0a55545eaffdf0df1ac19b500b51adb3095ec4dfdc704134e56ea23531" "checksum lettre 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "646aee0a55545eaffdf0df1ac19b500b51adb3095ec4dfdc704134e56ea23531"
"checksum lettre_email 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1b3d43e4bb7beb9974a359cbb3ea4f93dfba6c1c0c6e9c9f82e538e0f9ab9f" "checksum lettre_email 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1b3d43e4bb7beb9974a359cbb3ea4f93dfba6c1c0c6e9c9f82e538e0f9ab9f"
"checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880" "checksum libc 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "42914d39aad277d9e176efbdad68acb1d5443ab65afe0e0e4f0d49352a950880"
"checksum libsqlite3-sys 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd6457c70bbff456d9fe49deaba35ec47c3e598bf8d7950ff0575ceb7a8a6ad1"
"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" "checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
@ -2883,6 +2881,7 @@ dependencies = [
"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" "checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "136eed74cadb9edd2651ffba732b19a450316b680e4f48d6c79e905799e19d01" "checksum multipart 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "136eed74cadb9edd2651ffba732b19a450316b680e4f48d6c79e905799e19d01"
"checksum mysqlclient-sys 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7e9637d93448044078aaafea7419aed69d301b4a12bcc4aa0ae856eb169bef85"
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e" "checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
"checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30" "checksum new_debug_unreachable 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f40f005c60db6e03bae699e414c58bf9aa7ea02a2d0b9bfbcf19286cc4c82b30"

View File

@ -47,11 +47,8 @@ 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 = ["sqlite", "chrono", "r2d2"] } diesel = { version = "1.4.2", features = ["mysql", "chrono", "r2d2"] }
diesel_migrations = { version = "1.4.0", features = ["sqlite"] } diesel_migrations = { version = "1.4.0", features = ["mysql"] }
# Bundled SQLite
libsqlite3-sys = { version = "0.12.0", features = ["bundled"] }
# Crypto library # Crypto library
ring = "0.14.6" ring = "0.14.6"

View File

@ -1,14 +1,14 @@
CREATE TABLE users ( CREATE TABLE users (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
email TEXT NOT NULL UNIQUE, email VARCHAR(255) NOT NULL UNIQUE,
name TEXT NOT NULL, name TEXT NOT NULL,
password_hash BLOB NOT NULL, password_hash BLOB NOT NULL,
salt BLOB NOT NULL, salt BLOB NOT NULL,
password_iterations INTEGER NOT NULL, password_iterations INTEGER NOT NULL,
password_hint TEXT, password_hint TEXT,
key TEXT NOT NULL, akey TEXT NOT NULL,
private_key TEXT, private_key TEXT,
public_key TEXT, public_key TEXT,
totp_secret TEXT, totp_secret TEXT,
@ -19,24 +19,24 @@ CREATE TABLE users (
); );
CREATE TABLE devices ( CREATE TABLE devices (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
name TEXT NOT NULL, name TEXT NOT NULL,
type INTEGER NOT NULL, atype INTEGER NOT NULL,
push_token TEXT, push_token TEXT,
refresh_token TEXT NOT NULL refresh_token TEXT NOT NULL
); );
CREATE TABLE ciphers ( CREATE TABLE ciphers (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
folder_uuid TEXT REFERENCES folders (uuid), folder_uuid VARCHAR(40) REFERENCES folders (uuid),
organization_uuid TEXT, organization_uuid VARCHAR(40),
type INTEGER NOT NULL, atype INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
notes TEXT, notes TEXT,
fields TEXT, fields TEXT,
@ -45,18 +45,18 @@ CREATE TABLE ciphers (
); );
CREATE TABLE attachments ( CREATE TABLE attachments (
id TEXT NOT NULL PRIMARY KEY, id VARCHAR(40) NOT NULL PRIMARY KEY,
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid), cipher_uuid VARCHAR(40) NOT NULL REFERENCES ciphers (uuid),
file_name TEXT NOT NULL, file_name TEXT NOT NULL,
file_size INTEGER NOT NULL file_size INTEGER NOT NULL
); );
CREATE TABLE folders ( CREATE TABLE folders (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
user_uuid TEXT NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
name TEXT NOT NULL name TEXT NOT NULL
); );

View File

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

View File

@ -1,13 +1,13 @@
ALTER TABLE ciphers RENAME TO oldCiphers; ALTER TABLE ciphers RENAME TO oldCiphers;
CREATE TABLE ciphers ( CREATE TABLE ciphers (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
created_at DATETIME NOT NULL, created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL, updated_at DATETIME NOT NULL,
user_uuid TEXT REFERENCES users (uuid), -- Make this optional user_uuid VARCHAR(40) REFERENCES users (uuid), -- Make this optional
organization_uuid TEXT 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
type INTEGER NOT NULL, atype INTEGER NOT NULL,
name TEXT NOT NULL, name TEXT NOT NULL,
notes TEXT, notes TEXT,
fields TEXT, fields TEXT,
@ -16,14 +16,14 @@ CREATE TABLE ciphers (
); );
CREATE TABLE folders_ciphers ( CREATE TABLE folders_ciphers (
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid), cipher_uuid VARCHAR(40) NOT NULL REFERENCES ciphers (uuid),
folder_uuid TEXT NOT NULL REFERENCES folders (uuid), folder_uuid VARCHAR(40) NOT NULL REFERENCES folders (uuid),
PRIMARY KEY (cipher_uuid, folder_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) INSERT INTO ciphers (uuid, created_at, updated_at, user_uuid, organization_uuid, atype, name, notes, fields, data, favorite)
SELECT uuid, created_at, updated_at, user_uuid, organization_uuid, type, name, notes, fields, data, favorite FROM oldCiphers; SELECT uuid, created_at, updated_at, user_uuid, organization_uuid, atype, 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,5 +1,5 @@
CREATE TABLE ciphers_collections ( CREATE TABLE ciphers_collections (
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid), cipher_uuid VARCHAR(40) NOT NULL REFERENCES ciphers (uuid),
collection_uuid TEXT NOT NULL REFERENCES collections (uuid), collection_uuid VARCHAR(40) NOT NULL REFERENCES collections (uuid),
PRIMARY KEY (cipher_uuid, collection_uuid) PRIMARY KEY (cipher_uuid, collection_uuid)
); );

View File

@ -1,8 +1,8 @@
ALTER TABLE attachments RENAME TO oldAttachments; ALTER TABLE attachments RENAME TO oldAttachments;
CREATE TABLE attachments ( CREATE TABLE attachments (
id TEXT NOT NULL PRIMARY KEY, id VARCHAR(40) NOT NULL PRIMARY KEY,
cipher_uuid TEXT NOT NULL REFERENCES ciphers (uuid), cipher_uuid VARCHAR(40) NOT NULL REFERENCES ciphers (uuid),
file_name TEXT NOT NULL, file_name TEXT NOT NULL,
file_size INTEGER NOT NULL file_size INTEGER NOT NULL

View File

@ -1,15 +1,15 @@
CREATE TABLE twofactor ( CREATE TABLE twofactor (
uuid TEXT NOT NULL PRIMARY KEY, uuid VARCHAR(40) NOT NULL PRIMARY KEY,
user_uuid TEXT NOT NULL REFERENCES users (uuid), user_uuid VARCHAR(40) NOT NULL REFERENCES users (uuid),
type INTEGER NOT NULL, atype INTEGER NOT NULL,
enabled BOOLEAN NOT NULL, enabled BOOLEAN NOT NULL,
data TEXT NOT NULL, data TEXT NOT NULL,
UNIQUE (user_uuid, type) UNIQUE (user_uuid, atype)
); );
INSERT INTO twofactor (uuid, user_uuid, type, enabled, data) INSERT INTO twofactor (uuid, user_uuid, atype, enabled, data)
SELECT lower(hex(randomblob(16))) , 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

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

View File

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

View File

@ -204,7 +204,8 @@ make_config! {
data_folder: String, false, def, "data".to_string(); data_folder: String, false, def, "data".to_string();
/// Database URL /// Database URL
database_url: String, false, auto, |c| format!("mysql://root:my-secret-pw@localhost:3306/"); /// docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -e MYSQL_DATABASE=bitwarden -p 3306:3306 -d mysql:5.7
database_url: String, false, auto, |_c| format!("mysql://root:my-secret-pw@0.0.0.0:3306/bitwarden");
/// 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,7 +2,7 @@ use std::ops::Deref;
use diesel::r2d2; use diesel::r2d2;
use diesel::r2d2::ConnectionManager; use diesel::r2d2::ConnectionManager;
use diesel::sqlite::MysqlConnection; use diesel::mysql::MysqlConnection;
use diesel::{Connection as DieselConnection, ConnectionError}; use diesel::{Connection as DieselConnection, ConnectionError};
use rocket::http::Status; use rocket::http::Status;
@ -31,7 +31,9 @@ pub fn init_pool() -> Pool {
} }
pub fn get_connection() -> Result<Connection, ConnectionError> { pub fn get_connection() -> Result<Connection, ConnectionError> {
Connection::establish(&CONFIG.database_url()) let url = CONFIG.database_url();
println!("{}", url.to_string());
Connection::establish(&url)
} }
/// Attempts to retrieve a single connection from the managed database pool. If /// Attempts to retrieve a single connection from the managed database pool. If

View File

@ -12,7 +12,7 @@ pub struct Attachment {
pub cipher_uuid: String, pub cipher_uuid: String,
pub file_name: String, pub file_name: String,
pub file_size: i32, pub file_size: i32,
pub key: Option<String>, pub akey: Option<String>,
} }
/// Local methods /// Local methods
@ -23,7 +23,7 @@ impl Attachment {
cipher_uuid, cipher_uuid,
file_name, file_name,
file_size, file_size,
key: None, akey: None,
} }
} }
@ -43,7 +43,7 @@ impl Attachment {
"FileName": self.file_name, "FileName": self.file_name,
"Size": self.file_size.to_string(), "Size": self.file_size.to_string(),
"SizeName": display_size, "SizeName": display_size,
"Key": self.key, "Key": self.akey,
"Object": "attachment" "Object": "attachment"
}) })
} }

View File

@ -24,7 +24,7 @@ pub struct Cipher {
Card = 3, Card = 3,
Identity = 4 Identity = 4
*/ */
pub type_: i32, pub atype: i32,
pub name: String, pub name: String,
pub notes: Option<String>, pub notes: Option<String>,
pub fields: Option<String>, pub fields: Option<String>,
@ -37,7 +37,7 @@ pub struct Cipher {
/// Local methods /// Local methods
impl Cipher { impl Cipher {
pub fn new(type_: i32, name: String) -> Self { pub fn new(atype: i32, name: String) -> Self {
let now = Utc::now().naive_utc(); let now = Utc::now().naive_utc();
Self { Self {
@ -48,7 +48,7 @@ impl Cipher {
user_uuid: None, user_uuid: None,
organization_uuid: None, organization_uuid: None,
type_, atype,
favorite: false, favorite: false,
name, name,
@ -94,7 +94,7 @@ impl Cipher {
// TODO: ******* Backwards compat start ********** // TODO: ******* Backwards compat start **********
// To remove backwards compatibility, just remove this entire section // To remove backwards compatibility, just remove this entire section
// and remove the compat code from ciphers::update_cipher_from_data // and remove the compat code from ciphers::update_cipher_from_data
if self.type_ == 1 && data_json["Uris"].is_array() { if self.atype == 1 && data_json["Uris"].is_array() {
let uri = data_json["Uris"][0]["Uri"].clone(); let uri = data_json["Uris"][0]["Uri"].clone();
data_json["Uri"] = uri; data_json["Uri"] = uri;
} }
@ -102,7 +102,7 @@ impl Cipher {
let mut json_object = json!({ let mut json_object = json!({
"Id": self.uuid, "Id": self.uuid,
"Type": self.type_, "Type": self.atype,
"RevisionDate": format_date(&self.updated_at), "RevisionDate": format_date(&self.updated_at),
"FolderId": self.get_folder_uuid(&user_uuid, &conn), "FolderId": self.get_folder_uuid(&user_uuid, &conn),
"Favorite": self.favorite, "Favorite": self.favorite,
@ -123,7 +123,7 @@ impl Cipher {
"PasswordHistory": password_history_json, "PasswordHistory": password_history_json,
}); });
let key = match self.type_ { let key = match self.atype {
1 => "Login", 1 => "Login",
2 => "SecureNote", 2 => "SecureNote",
3 => "Card", 3 => "Card",
@ -237,7 +237,7 @@ impl Cipher {
// Cipher owner // Cipher owner
users_organizations::access_all.eq(true).or( users_organizations::access_all.eq(true).or(
// access_all in Organization // access_all in Organization
users_organizations::type_.le(UserOrgType::Admin as i32).or( users_organizations::atype.le(UserOrgType::Admin as i32).or(
// Org admin or owner // Org admin or owner
users_collections::user_uuid.eq(user_uuid).and( users_collections::user_uuid.eq(user_uuid).and(
users_collections::read_only.eq(false), //R/W access to collection users_collections::read_only.eq(false), //R/W access to collection
@ -268,7 +268,7 @@ impl Cipher {
// Cipher owner // Cipher owner
users_organizations::access_all.eq(true).or( users_organizations::access_all.eq(true).or(
// access_all in Organization // access_all in Organization
users_organizations::type_.le(UserOrgType::Admin as i32).or( users_organizations::atype.le(UserOrgType::Admin as i32).or(
// Org admin or owner // Org admin or owner
users_collections::user_uuid.eq(user_uuid), // Access to Collection users_collections::user_uuid.eq(user_uuid), // Access to Collection
), ),
@ -315,7 +315,7 @@ impl Cipher {
)) ))
.filter(ciphers::user_uuid.eq(user_uuid).or( // Cipher owner .filter(ciphers::user_uuid.eq(user_uuid).or( // Cipher owner
users_organizations::access_all.eq(true).or( // access_all in Organization users_organizations::access_all.eq(true).or( // access_all in Organization
users_organizations::type_.le(UserOrgType::Admin as i32).or( // Org admin or owner users_organizations::atype.le(UserOrgType::Admin as i32).or( // Org admin or owner
users_collections::user_uuid.eq(user_uuid).and( // Access to Collection users_collections::user_uuid.eq(user_uuid).and( // Access to Collection
users_organizations::status.eq(UserOrgStatus::Confirmed as i32) users_organizations::status.eq(UserOrgStatus::Confirmed as i32)
) )
@ -365,7 +365,7 @@ impl Cipher {
.filter(ciphers_collections::cipher_uuid.eq(&self.uuid)) .filter(ciphers_collections::cipher_uuid.eq(&self.uuid))
.filter(users_collections::user_uuid.eq(user_id).or( // User has access to collection .filter(users_collections::user_uuid.eq(user_id).or( // User has access to collection
users_organizations::access_all.eq(true).or( // User has access all users_organizations::access_all.eq(true).or( // User has access all
users_organizations::type_.le(UserOrgType::Admin as i32) // User is admin or owner users_organizations::atype.le(UserOrgType::Admin as i32) // User is admin or owner
) )
)) ))
.select(ciphers_collections::collection_uuid) .select(ciphers_collections::collection_uuid)

View File

@ -146,7 +146,7 @@ impl Collection {
.filter( .filter(
users_collections::collection_uuid.eq(uuid).or( // Directly accessed collection users_collections::collection_uuid.eq(uuid).or( // Directly accessed collection
users_organizations::access_all.eq(true).or( // access_all in Organization users_organizations::access_all.eq(true).or( // access_all in Organization
users_organizations::type_.le(UserOrgType::Admin as i32) // Org admin or owner users_organizations::atype.le(UserOrgType::Admin as i32) // Org admin or owner
) )
) )
).select(collections::all_columns) ).select(collections::all_columns)

View File

@ -15,7 +15,7 @@ pub struct Device {
pub name: String, pub name: String,
/// https://github.com/bitwarden/core/tree/master/src/Core/Enums /// https://github.com/bitwarden/core/tree/master/src/Core/Enums
pub type_: i32, pub atype: i32,
pub push_token: Option<String>, pub push_token: Option<String>,
pub refresh_token: String, pub refresh_token: String,
@ -25,7 +25,7 @@ pub struct Device {
/// Local methods /// Local methods
impl Device { impl Device {
pub fn new(uuid: String, user_uuid: String, name: String, type_: i32) -> Self { pub fn new(uuid: String, user_uuid: String, name: String, atype: i32) -> Self {
let now = Utc::now().naive_utc(); let now = Utc::now().naive_utc();
Self { Self {
@ -35,7 +35,7 @@ impl Device {
user_uuid, user_uuid,
name, name,
type_, atype,
push_token: None, push_token: None,
refresh_token: String::new(), refresh_token: String::new(),
@ -70,10 +70,10 @@ impl Device {
let time_now = Utc::now().naive_utc(); let time_now = Utc::now().naive_utc();
self.updated_at = time_now; self.updated_at = time_now;
let orgowner: Vec<_> = orgs.iter().filter(|o| o.type_ == 0).map(|o| o.org_uuid.clone()).collect(); let orgowner: Vec<_> = orgs.iter().filter(|o| o.atype == 0).map(|o| o.org_uuid.clone()).collect();
let orgadmin: Vec<_> = orgs.iter().filter(|o| o.type_ == 1).map(|o| o.org_uuid.clone()).collect(); let orgadmin: Vec<_> = orgs.iter().filter(|o| o.atype == 1).map(|o| o.org_uuid.clone()).collect();
let orguser: Vec<_> = orgs.iter().filter(|o| o.type_ == 2).map(|o| o.org_uuid.clone()).collect(); let orguser: Vec<_> = orgs.iter().filter(|o| o.atype == 2).map(|o| o.org_uuid.clone()).collect();
let orgmanager: Vec<_> = orgs.iter().filter(|o| o.type_ == 3).map(|o| o.org_uuid.clone()).collect(); let orgmanager: Vec<_> = orgs.iter().filter(|o| o.atype == 3).map(|o| o.org_uuid.clone()).collect();
// Create the JWT claims struct, to send to the client // Create the JWT claims struct, to send to the client

View File

@ -23,7 +23,7 @@ pub struct UserOrganization {
pub access_all: bool, pub access_all: bool,
pub key: String, pub key: String,
pub status: i32, pub status: i32,
pub type_: i32, pub atype: i32,
} }
pub enum UserOrgStatus { pub enum UserOrgStatus {
@ -198,7 +198,7 @@ impl UserOrganization {
access_all: false, access_all: false,
key: String::new(), key: String::new(),
status: UserOrgStatus::Accepted as i32, status: UserOrgStatus::Accepted as i32,
type_: UserOrgType::User as i32, atype: UserOrgType::User as i32,
} }
} }
} }
@ -268,7 +268,7 @@ impl UserOrganization {
// These are per user // These are per user
"Key": self.key, "Key": self.key,
"Status": self.status, "Status": self.status,
"Type": self.type_, "Type": self.atype,
"Enabled": true, "Enabled": true,
"Object": "profileOrganization", "Object": "profileOrganization",
@ -285,7 +285,7 @@ impl UserOrganization {
"Email": user.email, "Email": user.email,
"Status": self.status, "Status": self.status,
"Type": self.type_, "Type": self.atype,
"AccessAll": self.access_all, "AccessAll": self.access_all,
"Object": "organizationUserUserDetails", "Object": "organizationUserUserDetails",
@ -315,7 +315,7 @@ impl UserOrganization {
"UserId": self.user_uuid, "UserId": self.user_uuid,
"Status": self.status, "Status": self.status,
"Type": self.type_, "Type": self.atype,
"AccessAll": self.access_all, "AccessAll": self.access_all,
"Collections": coll_uuids, "Collections": coll_uuids,
@ -357,7 +357,7 @@ impl UserOrganization {
} }
pub fn has_full_access(self) -> bool { pub fn has_full_access(self) -> bool {
self.access_all || self.type_ >= UserOrgType::Admin self.access_all || self.atype >= UserOrgType::Admin
} }
pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> { pub fn find_by_uuid(uuid: &str, conn: &DbConn) -> Option<Self> {
@ -405,10 +405,10 @@ impl UserOrganization {
.expect("Error loading user organizations") .expect("Error loading user organizations")
} }
pub fn find_by_org_and_type(org_uuid: &str, type_: i32, conn: &DbConn) -> Vec<Self> { pub fn find_by_org_and_type(org_uuid: &str, atype: i32, conn: &DbConn) -> Vec<Self> {
users_organizations::table users_organizations::table
.filter(users_organizations::org_uuid.eq(org_uuid)) .filter(users_organizations::org_uuid.eq(org_uuid))
.filter(users_organizations::type_.eq(type_)) .filter(users_organizations::atype.eq(atype))
.load::<Self>(&**conn) .load::<Self>(&**conn)
.expect("Error loading user organizations") .expect("Error loading user organizations")
} }

View File

@ -9,7 +9,7 @@ use super::User;
pub struct TwoFactor { pub struct TwoFactor {
pub uuid: String, pub uuid: String,
pub user_uuid: String, pub user_uuid: String,
pub type_: i32, pub atype: i32,
pub enabled: bool, pub enabled: bool,
pub data: String, pub data: String,
} }
@ -32,11 +32,11 @@ pub enum TwoFactorType {
/// Local methods /// Local methods
impl TwoFactor { impl TwoFactor {
pub fn new(user_uuid: String, type_: TwoFactorType, data: String) -> Self { pub fn new(user_uuid: String, atype: TwoFactorType, data: String) -> Self {
Self { Self {
uuid: crate::util::get_uuid(), uuid: crate::util::get_uuid(),
user_uuid, user_uuid,
type_: type_ as i32, atype: atype as i32,
enabled: true, enabled: true,
data, data,
} }
@ -53,7 +53,7 @@ impl TwoFactor {
pub fn to_json_list(&self) -> Value { pub fn to_json_list(&self) -> Value {
json!({ json!({
"Enabled": self.enabled, "Enabled": self.enabled,
"Type": self.type_, "Type": self.atype,
"Object": "twoFactorProvider" "Object": "twoFactorProvider"
}) })
} }
@ -85,15 +85,15 @@ impl TwoFactor {
pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Self> { pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec<Self> {
twofactor::table twofactor::table
.filter(twofactor::user_uuid.eq(user_uuid)) .filter(twofactor::user_uuid.eq(user_uuid))
.filter(twofactor::type_.lt(1000)) // Filter implementation types .filter(twofactor::atype.lt(1000)) // Filter implementation types
.load::<Self>(&**conn) .load::<Self>(&**conn)
.expect("Error loading twofactor") .expect("Error loading twofactor")
} }
pub fn find_by_user_and_type(user_uuid: &str, type_: i32, conn: &DbConn) -> Option<Self> { pub fn find_by_user_and_type(user_uuid: &str, atype: i32, conn: &DbConn) -> Option<Self> {
twofactor::table twofactor::table
.filter(twofactor::user_uuid.eq(user_uuid)) .filter(twofactor::user_uuid.eq(user_uuid))
.filter(twofactor::type_.eq(type_)) .filter(twofactor::atype.eq(atype))
.first::<Self>(&**conn) .first::<Self>(&**conn)
.ok() .ok()
} }

View File

@ -20,7 +20,7 @@ pub struct User {
pub password_iterations: i32, pub password_iterations: i32,
pub password_hint: Option<String>, pub password_hint: Option<String>,
pub key: String, pub akey: String,
pub private_key: Option<String>, pub private_key: Option<String>,
pub public_key: Option<String>, pub public_key: Option<String>,
@ -58,7 +58,7 @@ impl User {
updated_at: now, updated_at: now,
name: email.clone(), name: email.clone(),
email, email,
key: String::new(), akey: String::new(),
password_hash: Vec::new(), password_hash: Vec::new(),
salt: crypto::get_random_64(), salt: crypto::get_random_64(),
@ -140,7 +140,7 @@ impl User {
"MasterPasswordHint": self.password_hint, "MasterPasswordHint": self.password_hint,
"Culture": "en-US", "Culture": "en-US",
"TwoFactorEnabled": twofactor_enabled, "TwoFactorEnabled": twofactor_enabled,
"Key": self.key, "Key": self.akey,
"PrivateKey": self.private_key, "PrivateKey": self.private_key,
"SecurityStamp": self.security_stamp, "SecurityStamp": self.security_stamp,
"Organizations": orgs_json, "Organizations": orgs_json,

View File

@ -1,22 +1,21 @@
table! { table! {
attachments (id) { attachments (id) {
id -> Text, id -> Varchar,
cipher_uuid -> Text, cipher_uuid -> Varchar,
file_name -> Text, file_name -> Text,
file_size -> Integer, file_size -> Integer,
key -> Nullable<Text>, akey -> Nullable<Text>,
} }
} }
table! { table! {
ciphers (uuid) { ciphers (uuid) {
uuid -> Text, uuid -> Varchar,
created_at -> Timestamp, created_at -> Datetime,
updated_at -> Timestamp, updated_at -> Datetime,
user_uuid -> Nullable<Text>, user_uuid -> Nullable<Varchar>,
organization_uuid -> Nullable<Text>, organization_uuid -> Nullable<Varchar>,
#[sql_name = "type"] atype -> Integer,
type_ -> Integer,
name -> Text, name -> Text,
notes -> Nullable<Text>, notes -> Nullable<Text>,
fields -> Nullable<Text>, fields -> Nullable<Text>,
@ -28,28 +27,27 @@ table! {
table! { table! {
ciphers_collections (cipher_uuid, collection_uuid) { ciphers_collections (cipher_uuid, collection_uuid) {
cipher_uuid -> Text, cipher_uuid -> Varchar,
collection_uuid -> Text, collection_uuid -> Varchar,
} }
} }
table! { table! {
collections (uuid) { collections (uuid) {
uuid -> Text, uuid -> Varchar,
org_uuid -> Text, org_uuid -> Varchar,
name -> Text, name -> Text,
} }
} }
table! { table! {
devices (uuid) { devices (uuid) {
uuid -> Text, uuid -> Varchar,
created_at -> Timestamp, created_at -> Datetime,
updated_at -> Timestamp, updated_at -> Datetime,
user_uuid -> Text, user_uuid -> Varchar,
name -> Text, name -> Text,
#[sql_name = "type"] atype -> Integer,
type_ -> Integer,
push_token -> Nullable<Text>, push_token -> Nullable<Text>,
refresh_token -> Text, refresh_token -> Text,
twofactor_remember -> Nullable<Text>, twofactor_remember -> Nullable<Text>,
@ -58,30 +56,30 @@ table! {
table! { table! {
folders (uuid) { folders (uuid) {
uuid -> Text, uuid -> Varchar,
created_at -> Timestamp, created_at -> Datetime,
updated_at -> Timestamp, updated_at -> Datetime,
user_uuid -> Text, user_uuid -> Varchar,
name -> Text, name -> Text,
} }
} }
table! { table! {
folders_ciphers (cipher_uuid, folder_uuid) { folders_ciphers (cipher_uuid, folder_uuid) {
cipher_uuid -> Text, cipher_uuid -> Varchar,
folder_uuid -> Text, folder_uuid -> Varchar,
} }
} }
table! { table! {
invitations (email) { invitations (email) {
email -> Text, email -> Varchar,
} }
} }
table! { table! {
organizations (uuid) { organizations (uuid) {
uuid -> Text, uuid -> Varchar,
name -> Text, name -> Text,
billing_email -> Text, billing_email -> Text,
} }
@ -89,10 +87,9 @@ table! {
table! { table! {
twofactor (uuid) { twofactor (uuid) {
uuid -> Text, uuid -> Varchar,
user_uuid -> Text, user_uuid -> Varchar,
#[sql_name = "type"] atype -> Integer,
type_ -> Integer,
enabled -> Bool, enabled -> Bool,
data -> Text, data -> Text,
} }
@ -100,16 +97,16 @@ table! {
table! { table! {
users (uuid) { users (uuid) {
uuid -> Text, uuid -> Varchar,
created_at -> Timestamp, created_at -> Datetime,
updated_at -> Timestamp, updated_at -> Datetime,
email -> Text, email -> Varchar,
name -> Text, name -> Text,
password_hash -> Binary, password_hash -> Blob,
salt -> Binary, salt -> Blob,
password_iterations -> Integer, password_iterations -> Integer,
password_hint -> Nullable<Text>, password_hint -> Nullable<Text>,
key -> Text, akey -> Text,
private_key -> Nullable<Text>, private_key -> Nullable<Text>,
public_key -> Nullable<Text>, public_key -> Nullable<Text>,
totp_secret -> Nullable<Text>, totp_secret -> Nullable<Text>,
@ -124,41 +121,24 @@ table! {
table! { table! {
users_collections (user_uuid, collection_uuid) { users_collections (user_uuid, collection_uuid) {
user_uuid -> Text, user_uuid -> Varchar,
collection_uuid -> Text, collection_uuid -> Varchar,
read_only -> Bool, read_only -> Bool,
} }
} }
table! { table! {
users_organizations (uuid) { users_organizations (uuid) {
uuid -> Text, uuid -> Varchar,
user_uuid -> Text, user_uuid -> Varchar,
org_uuid -> Text, org_uuid -> Varchar,
access_all -> Bool, access_all -> Bool,
key -> Text, akey -> Text,
status -> Integer, status -> Integer,
#[sql_name = "type"] atype -> Integer,
type_ -> 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!( allow_tables_to_appear_in_same_query!(
attachments, attachments,
ciphers, ciphers,

View File

@ -123,7 +123,8 @@ fn chain_syslog(logger: fern::Dispatch) -> fern::Dispatch {
fn check_db() { fn check_db() {
let url = CONFIG.database_url(); let url = CONFIG.database_url();
println!(url.to_string()); println!("{}", url.to_string());
db::get_connection().expect("Can't conect to DB");
} }
fn check_rsa_keys() { fn check_rsa_keys() {