From a291dea16f46f2bca78ddaa4bb7c5fb6fe2f858b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Sat, 21 Jul 2018 17:27:00 +0200 Subject: [PATCH 01/65] Updated dependencies and Docker image to new web-vault --- Cargo.lock | 266 ++++++++++++++------------------ Cargo.toml | 14 +- Dockerfile | 28 ++-- docker/set-vault-baseurl.patch | 16 ++ docker/settings.Production.json | 9 -- rust-toolchain | 2 +- src/api/core/organizations.rs | 2 +- src/main.rs | 1 + 8 files changed, 155 insertions(+), 183 deletions(-) create mode 100644 docker/set-vault-baseurl.patch delete mode 100644 docker/settings.Production.json diff --git a/Cargo.lock b/Cargo.lock index 058703a..634110c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,7 +26,7 @@ dependencies = [ [[package]] name = "ascii" -version = "0.7.1" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -67,7 +67,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitwarden_rs" -version = "0.10.0" +version = "0.11.0" dependencies = [ "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -75,31 +75,32 @@ dependencies = [ "diesel_migrations 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonwebtoken 4.0.1", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "multipart 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)", + "multipart 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "oath 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_codegen 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_contrib 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_codegen 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_contrib 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "u2f 0.1.2 (git+https://github.com/wisespace-io/u2f-rs?rev=193de35093a44)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "buf_redux" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slice-deque 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -136,15 +137,6 @@ name = "cfg-if" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "chrono" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "chrono" version = "0.4.4" @@ -227,7 +219,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -241,7 +233,7 @@ dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -330,8 +322,8 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -580,7 +572,7 @@ name = "idna" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -601,7 +593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 1.8.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 1.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -634,7 +626,7 @@ dependencies = [ "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -659,7 +651,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -688,7 +680,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -709,18 +701,18 @@ dependencies = [ ] [[package]] -name = "matches" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memchr" -version = "1.0.2" +name = "mach" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "matches" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "memchr" version = "2.0.1" @@ -770,7 +762,7 @@ dependencies = [ [[package]] name = "mime_guess" -version = "1.8.5" +version = "1.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -781,7 +773,7 @@ dependencies = [ [[package]] name = "mime_guess" -version = "2.0.0-alpha.5" +version = "2.0.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -826,22 +818,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "multipart" -version = "0.14.2" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "buf_redux 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "buf_redux 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 1.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "nickel 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tiny_http 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny_http 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -885,7 +877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "groupable 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "mustache 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -902,23 +894,13 @@ name = "nodrop" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "num" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-derive" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -931,15 +913,6 @@ dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "num-iter" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "num-traits" version = "0.2.5" @@ -972,7 +945,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -984,7 +957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -995,12 +968,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pear" -version = "0.0.18" +version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pear_codegen" -version = "0.0.18" +version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1049,7 +1022,7 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1070,7 +1043,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1099,7 +1072,7 @@ name = "quote" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1137,19 +1110,18 @@ name = "rayon" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1171,12 +1143,12 @@ dependencies = [ [[package]] name = "regex" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1191,7 +1163,7 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1225,10 +1197,10 @@ dependencies = [ "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1251,7 +1223,7 @@ dependencies = [ [[package]] name = "rocket" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1263,10 +1235,10 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "pear 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "pear_codegen 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "pear 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "pear_codegen 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1277,24 +1249,24 @@ dependencies = [ [[package]] name = "rocket_codegen" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rocket_contrib" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1325,12 +1297,17 @@ name = "safemem" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "safemem" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "schannel" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1382,14 +1359,14 @@ name = "serde_derive" version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1447,6 +1424,16 @@ name = "slab" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "slice-deque" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "mach 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "smallvec" version = "0.2.1" @@ -1454,8 +1441,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "state" @@ -1487,7 +1477,7 @@ name = "syn" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1528,7 +1518,7 @@ name = "thread_local" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1544,15 +1534,15 @@ dependencies = [ [[package]] name = "tiny_http" -version = "0.5.9" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)", + "ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1782,7 +1772,7 @@ dependencies = [ "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1814,7 +1804,7 @@ name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1853,23 +1843,13 @@ name = "untrusted" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "url" -version = "0.2.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "url" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1878,15 +1858,6 @@ name = "utf8-ranges" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "uuid" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "uuid" version = "0.6.5" @@ -1997,20 +1968,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa" "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" -"checksum ascii 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50" +"checksum ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" -"checksum buf_redux 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b9279646319ff816b05fb5897883ece50d7d854d12b59992683d4f8a71b0f949" +"checksum buf_redux 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c6687a26c9ce967594b78038c06139a0d3a5b3005d16572284d543924a01aa" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0919189ba800c7ffe8778278116b7e0de3905ab81c72abb69c85cbfef7991279" "checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" "checksum bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd32989a66957d3f0cba6588f15d4281a733f4e9ffc43fcd2385f57d3bf99ff" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" -"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00" "checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37" "checksum chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" @@ -2068,53 +2038,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739" +"checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" "checksum libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7d4b4c7aff5bac19b956f693d0ea0eade8066deb092186ae954fa6ba14daab98" "checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" -"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" -"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +"checksum mach 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b549fa8738e27dcf6c8c5d6d35211e786aa02715a22b60c33b9488fdd634a90b" +"checksum matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "835511bab37c34c47da5cb44844bea2cfde0236db0b506f90ea4224482c9774a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum migrations_internals 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cf7c8c4f83fa9f47440c0b4af99973502de55e6e7b875f693bd263e03f93e7e" "checksum migrations_macros 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79f12499ef7353bdeca2d081bc61edd8351dac09a33af845952009b5a3d68c1a" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" "checksum mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fe51c8699d2dc522bf8c1ebe26ea2193d151fb54bcdfd7d0318750c189994cd9" -"checksum mime_guess 1.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7287ba93031813826d8974566e54eb5e49d4473752f7df21c610dab289aee8cb" -"checksum mime_guess 2.0.0-alpha.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d1a78b5e2283080d5a8ba68216171b4fe34f6ccdd909bb29be16ce8a9a831341" +"checksum mime_guess 1.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2d4c0961143b8efdcfa29c3ae63281601b446a4a668165454b6c90f8024954c5" +"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" -"checksum multipart 0.14.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1720cbd59d1cbcc184b66f2f74a3287caf524764eee5a8fbb3f5f0e469cd5c00" +"checksum multipart 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c934f2af2afbe9277d5be4c46599116e6dd93339871504c578318eeef725aa64" "checksum mustache 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb004e419334fc9172d0a5ff91c0770bdd6239091b0b343eb5926101f0a7d13" "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" "checksum nickel 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "22b40e35b9f46a076dcbd8193125cea0e4130b1c015f68655038010f3e826e04" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" -"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" "checksum num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c31b75c36a993d30c7a13d70513cb93f02acafdd5b7ba250f9b0e18615de7" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum oath 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6405dc6afe8219020d535f9ad888a12b191bbc8ce1c55f7ee663bde5be80ca" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" "checksum openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)" = "d8abc04833dcedef24221a91852931df2f63e3369ae003134e70aff3645775cc" "checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b" -"checksum pear 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e868f6a0ac6ea21cbc8bcead234c875209523cc50dddc12b082c09c06a84f85a" -"checksum pear_codegen 0.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "758ab26a919053f465d887a454f93c39735c615bc36b5598405f557cc033ae88" +"checksum pear 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc18e7bc730525f5bcc1069487631a94e5d7389c7f7e63c081cda5c3542ea3e" +"checksum pear_codegen 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ac78ce520b1274885d8415a02ae3f1bb06038e0f6862f105aa97060c6a10fd99" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" -"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f" +"checksum pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6a52e4dbc8354505ee07e484ab07127e06d87ca6fa7f0a516a2b294e5ad5ad16" "checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6" +"checksum proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c65b1ea15bb859d922cade2d1765b4b88beac339cbfad545ef2d2ef8c8215ee6" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" @@ -2123,23 +2091,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" -"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8" +"checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e" +"checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54" +"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum reqwest 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2abe46f8e00792693a2488e296c593d1f4ea39bb1178cfce081d6793657575e4" "checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724" -"checksum rocket 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "798935129effaaf50a4647dbd96bf48cedb3d06c16ab645405d9f02fb90a29d0" -"checksum rocket_codegen 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dca5401b057885267f9b0d81138b7f0b926549261b5cc429ee5535166c47b8e8" -"checksum rocket_contrib 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "f04b11a285fb5b0ce426241468aa0494f0b5ca981bda5198facd0106d8edd731" +"checksum rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c9010c81b707444fe8de4f83380e6e18bbc2825aac2da797d5553ce3d5b3e702" +"checksum rocket_codegen 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0109d1692a1a05c267ed1eef94ff018bd360e0b6487c8678da4ebbbdbf02cef7" +"checksum rocket_contrib 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4f5eaf6d3324a58b1d961b92fd1ff19c37074c603b8a095daa372089f644f4" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17727f4b991294da2c84d75a43c003151ff58072212768800f66c56ee46dca43" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" +"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" "checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889" "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" @@ -2148,15 +2117,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" -"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e" +"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" "checksum serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e703cef904312097cfceab9ce131ff6bbe09e8c964a0703345a5f49238757bc1" "checksum sha-1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8347606816471548cd60f0abd5ef0d513a81f5202dbdab9c09f17a15b5248484" "checksum sha2 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "84920f9ac881e94e33ec89e1b3dcd36040523a308a92548e01217ce35d8cf6a8" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" +"checksum slice-deque 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "84f8bc1bafa053290fdd4f40eefa15914cb16cf8bee9793312e4389114d15645" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514" +"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" @@ -2167,7 +2137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" -"checksum tiny_http 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f4d55c9a213880d1f0c89ded183f209c6e45b912ca6c7df6f93c163773572e1" +"checksum tiny_http 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442681f9f72e440be192700eeb2861e4174b9983f16f4877c93a134cb5e5f63" "checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286" "checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" @@ -2200,10 +2170,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum unsafe-any 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" "checksum untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae" -"checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" "checksum vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cbe533e138811704c0e3cbde65a818b35d3240409b4346256c5ede403e082474" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" diff --git a/Cargo.toml b/Cargo.toml index 31445dd..b759db8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,20 +5,20 @@ authors = ["Daniel García "] [dependencies] # Web framework for nightly with a focus on ease-of-use, expressibility, and speed. -rocket = { version = "0.3.14", features = ["tls"] } -rocket_codegen = "0.3.14" -rocket_contrib = "0.3.14" +rocket = { version = "0.3.15", features = ["tls"] } +rocket_codegen = "0.3.15" +rocket_contrib = "0.3.15" # HTTP client reqwest = "0.8.6" # multipart/form-data support -multipart = "0.14.2" +multipart = "0.15.0" # A generic serialization/deserialization framework serde = "1.0.70" serde_derive = "1.0.70" -serde_json = "1.0.22" +serde_json = "1.0.24" # A safe, extensible ORM and Query builder diesel = { version = "1.3.2", features = ["sqlite", "chrono", "r2d2"] } @@ -52,7 +52,7 @@ u2f = "0.1.2" dotenv = { version = "0.13.0", default-features = false } # Lazy static macro -lazy_static = "1.0.1" +lazy_static = "1.0.2" # Numerical libraries num-traits = "0.2.5" @@ -63,4 +63,4 @@ num-derive = "0.2.2" jsonwebtoken = { path = "libs/jsonwebtoken" } # Version 0.1.2 from crates.io lacks a commit that fixes a certificate error -u2f = { git = 'https://github.com/wisespace-io/u2f-rs', rev = '193de35093a44' } \ No newline at end of file +u2f = { git = 'https://github.com/wisespace-io/u2f-rs', rev = '193de35093a44' } diff --git a/Dockerfile b/Dockerfile index 91e1d95..7417d1c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,31 +2,27 @@ # https://docs.docker.com/develop/develop-images/multistage-build/ # https://whitfin.io/speeding-up-rust-docker-builds/ ####################### VAULT BUILD IMAGE ####################### -FROM node:9-alpine as vault +FROM node:8-alpine as vault -ENV VAULT_VERSION "1.27.0" -ENV URL "https://github.com/bitwarden/web/archive/v${VAULT_VERSION}.tar.gz" +#ENV VAULT_VERSION "v1.27.0" +ENV VAULT_VERSION "master" +ENV URL "https://github.com/bitwarden/web.git" RUN apk add --update-cache --upgrade \ curl \ git \ - tar \ - && npm install -g \ - gulp-cli \ - gulp - -RUN mkdir /web-build \ - && cd /web-build \ - && curl -L "${URL}" | tar -xvz --strip-components=1 + tar +RUN git clone -b $VAULT_VERSION --depth 1 $URL web-build WORKDIR /web-build -COPY /docker/settings.Production.json /web-build/ +COPY docker/set-vault-baseurl.patch /web-build/ +RUN git apply set-vault-baseurl.patch -RUN git config --global url."https://github.com/".insteadOf ssh://git@github.com/ \ - && npm install \ - && gulp dist:selfHosted \ - && mv dist /web-vault +RUN npm run sub:init && npm install + +RUN npm run dist \ + && mv build /web-vault ########################## BUILD IMAGE ########################## # We need to use the Rust build image, because diff --git a/docker/set-vault-baseurl.patch b/docker/set-vault-baseurl.patch new file mode 100644 index 0000000..1ce1704 --- /dev/null +++ b/docker/set-vault-baseurl.patch @@ -0,0 +1,16 @@ +--- a/src/app/services/services.module.ts ++++ b/src/app/services/services.module.ts +@@ -114,10 +114,9 @@ containerService.attachToWindow(window); + + export function initFactory(): Function { + return async () => { +- const isDev = platformUtilsService.isDev(); +- if (!isDev && platformUtilsService.isSelfHost()) { +- environmentService.baseUrl = window.location.origin; +- } ++ const isDev = false; ++ environmentService.baseUrl = window.location.origin; ++ + await apiService.setUrls({ + base: isDev ? null : window.location.origin, + api: isDev ? 'http://localhost:4000' : null, diff --git a/docker/settings.Production.json b/docker/settings.Production.json deleted file mode 100644 index a3e5e91..0000000 --- a/docker/settings.Production.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "appSettings": { - "apiUri": "/api", - "identityUri": "/identity", - "iconsUri": "/icons", - "stripeKey": "", - "braintreeKey": "" - } -} diff --git a/rust-toolchain b/rust-toolchain index 1f5db4b..d05d08a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2018-06-26 +nightly-2018-07-18 diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 8c87a1d..74be559 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -17,7 +17,7 @@ struct OrgData { Key: String, Name: String, #[serde(rename = "PlanType")] - _PlanType: String, // Ignored, always use the same plan + _PlanType: NumberOrString, // Ignored, always use the same plan } #[derive(Deserialize, Debug)] diff --git a/src/main.rs b/src/main.rs index 17b6379..c5277f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ #![feature(plugin, custom_derive)] #![plugin(rocket_codegen)] +#![allow(proc_macro_derive_resolution_fallback)] // TODO: Remove this when diesel update fixes warnings extern crate rocket; extern crate rocket_contrib; extern crate reqwest; From 659f6778974ed91dabb933d7875a96914a0045fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Sat, 21 Jul 2018 18:50:54 +0200 Subject: [PATCH 02/65] Add missing slash, to put it like it was at first --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7417d1c..899294f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN apk add --update-cache --upgrade \ RUN git clone -b $VAULT_VERSION --depth 1 $URL web-build WORKDIR /web-build -COPY docker/set-vault-baseurl.patch /web-build/ +COPY /docker/set-vault-baseurl.patch /web-build/ RUN git apply set-vault-baseurl.patch RUN npm run sub:init && npm install From ceb3d0314d3f02cdb406ef6111429361ace938dd Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 27 Jul 2018 10:01:33 +0100 Subject: [PATCH 03/65] Use stable release of v2.0.0 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 899294f..ea63874 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,8 +4,8 @@ ####################### VAULT BUILD IMAGE ####################### FROM node:8-alpine as vault -#ENV VAULT_VERSION "v1.27.0" -ENV VAULT_VERSION "master" +ENV VAULT_VERSION "v2.0.0" + ENV URL "https://github.com/bitwarden/web.git" RUN apk add --update-cache --upgrade \ From 91a23193251366b630b6c25cb2c5d7429604ee7e Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Wed, 1 Aug 2018 03:58:47 +0530 Subject: [PATCH 04/65] Implementing PUT for ciphers/move (#99) --- src/api/core/ciphers.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 29f9e8c..7f268f2 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -483,8 +483,9 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon Ok(()) } -#[post("/ciphers/move", data = "")] +#[put("/ciphers/move", data = "")] fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + println!("{}", "inside put"); let data = data.into_inner().data; let folder_id = match data.get("FolderId") { From fcc485384f37583cb3261e833b5acc91e7f30c65 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Wed, 1 Aug 2018 04:12:46 +0530 Subject: [PATCH 05/65] clean up --- src/api/core/ciphers.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 7f268f2..fe351d7 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -485,7 +485,6 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon #[put("/ciphers/move", data = "")] fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { - println!("{}", "inside put"); let data = data.into_inner().data; let folder_id = match data.get("FolderId") { From 2f6aa3c36381f802bddf97fbb988020a302e7a2b Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Wed, 1 Aug 2018 11:21:05 +0530 Subject: [PATCH 06/65] Reverting removal of 'api/ciphers/move' POST as it is required for backward compatibility --- src/api/core/ciphers.rs | 54 ++++++++++++++++++++++++++++++++++++++++- src/api/core/mod.rs | 1 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index fe351d7..d1450df 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -483,7 +483,7 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon Ok(()) } -#[put("/ciphers/move", data = "")] +#[post("/ciphers/move", data = "")] fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data = data.into_inner().data; @@ -535,6 +535,58 @@ fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) Ok(()) } +#[put("/ciphers/move", data = "")] +fn move_cipher_selected_put(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + let data = data.into_inner().data; + + let folder_id = match data.get("FolderId") { + Some(folder_id) => { + match folder_id.as_str() { + Some(folder_id) => { + match Folder::find_by_uuid(folder_id, &conn) { + Some(folder) => { + if folder.user_uuid != headers.user.uuid { + err!("Folder is not owned by user") + } + Some(folder.uuid) + } + None => err!("Folder doesn't exist") + } + } + None => err!("Folder id provided in wrong format") + } + } + None => None + }; + + let uuids = match data.get("Ids") { + Some(ids) => match ids.as_array() { + Some(ids) => ids.iter().filter_map(|uuid| { uuid.as_str() }), + None => err!("Posted ids field is not an array") + }, + None => err!("Request missing ids field") + }; + + for uuid in uuids { + let mut cipher = match Cipher::find_by_uuid(uuid, &conn) { + Some(cipher) => cipher, + None => err!("Cipher doesn't exist") + }; + + if !cipher.is_accessible_to_user(&headers.user.uuid, &conn) { + err!("Cipher is not accessible by user") + } + + // Move cipher + if cipher.move_to_folder(folder_id.clone(), &headers.user.uuid, &conn).is_err() { + err!("Error saving the folder information") + } + cipher.save(&conn); + } + + Ok(()) +} + #[post("/ciphers/purge", data = "")] fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data: PasswordData = data.into_inner().data; diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 89df7a1..d7387d4 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -46,6 +46,7 @@ pub fn routes() -> Vec { delete_cipher_selected, delete_all, move_cipher_selected, + move_cipher_selected_put, get_folders, get_folder, From 0e095a9fa4c8417ba308cbd0de974278654a65e1 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Wed, 1 Aug 2018 13:50:52 +0530 Subject: [PATCH 07/65] change to reuse the logic for POST in PUT as well --- src/api/core/ciphers.rs | 49 +---------------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index d1450df..12e65de 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -537,54 +537,7 @@ fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) #[put("/ciphers/move", data = "")] fn move_cipher_selected_put(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { - let data = data.into_inner().data; - - let folder_id = match data.get("FolderId") { - Some(folder_id) => { - match folder_id.as_str() { - Some(folder_id) => { - match Folder::find_by_uuid(folder_id, &conn) { - Some(folder) => { - if folder.user_uuid != headers.user.uuid { - err!("Folder is not owned by user") - } - Some(folder.uuid) - } - None => err!("Folder doesn't exist") - } - } - None => err!("Folder id provided in wrong format") - } - } - None => None - }; - - let uuids = match data.get("Ids") { - Some(ids) => match ids.as_array() { - Some(ids) => ids.iter().filter_map(|uuid| { uuid.as_str() }), - None => err!("Posted ids field is not an array") - }, - None => err!("Request missing ids field") - }; - - for uuid in uuids { - let mut cipher = match Cipher::find_by_uuid(uuid, &conn) { - Some(cipher) => cipher, - None => err!("Cipher doesn't exist") - }; - - if !cipher.is_accessible_to_user(&headers.user.uuid, &conn) { - err!("Cipher is not accessible by user") - } - - // Move cipher - if cipher.move_to_folder(folder_id.clone(), &headers.user.uuid, &conn).is_err() { - err!("Error saving the folder information") - } - cipher.save(&conn); - } - - Ok(()) + move_cipher_selected(data, headers, conn) } #[post("/ciphers/purge", data = "")] From 74e2ca81ae5c1a5017ce2f5fc5811611ff71d8b4 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Thu, 2 Aug 2018 00:07:14 +0530 Subject: [PATCH 08/65] Implemented PUT for single cipher sharing (#97) --- src/api/core/ciphers.rs | 5 +++++ src/api/core/mod.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 4880d93..0c8b0a2 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -365,6 +365,11 @@ fn post_cipher_share(uuid: String, data: JsonUpcase, headers: H } } +#[put("/ciphers//share", data = "")] +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + post_cipher_share(uuid, data, headers, conn) +} + #[post("/ciphers//attachment", format = "multipart/form-data", data = "")] fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { let cipher = match Cipher::find_by_uuid(&uuid, &conn) { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 4b8d270..479318c 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -41,6 +41,7 @@ pub fn routes() -> Vec { delete_attachment, post_cipher_admin, post_cipher_share, + put_cipher_share, post_cipher, put_cipher, delete_cipher_post, From 7dfc7596912b4a83253accb1e941f145ef9c3ae9 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Fri, 3 Aug 2018 19:23:27 +0530 Subject: [PATCH 09/65] Implmeneted DELETE on 'api/ciphers' to delete selected ciphers (#98) --- src/api/core/ciphers.rs | 7 ++++++- src/api/core/mod.rs | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 0c8b0a2..95df5a0 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -461,7 +461,7 @@ fn delete_cipher(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { _delete_cipher_by_uuid(&uuid, &headers, &conn) } -#[post("/ciphers/delete", data = "")] +#[delete("/ciphers", data = "")] fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data: Value = data.into_inner().data; @@ -482,6 +482,11 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon Ok(()) } +#[post("/ciphers/delete", data = "")] +fn delete_cipher_selected_post(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + delete_cipher_selected(data, headers, conn) +} + #[post("/ciphers/move", data = "")] fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data = data.into_inner().data; diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 479318c..0f07f60 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -47,6 +47,7 @@ pub fn routes() -> Vec { delete_cipher_post, delete_cipher_post_admin, delete_cipher, + delete_cipher_selected_post, delete_cipher_selected, delete_all, move_cipher_selected, From aac1304b46ccbba909369a74c142c2ef4c577eb5 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Fri, 3 Aug 2018 19:31:01 +0530 Subject: [PATCH 10/65] clean up --- src/api/core/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 0f07f60..e06c36b 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -47,8 +47,8 @@ pub fn routes() -> Vec { delete_cipher_post, delete_cipher_post_admin, delete_cipher, - delete_cipher_selected_post, delete_cipher_selected, + delete_cipher_selected_post, delete_all, move_cipher_selected, move_cipher_selected_put, From fb7b1c8c18aa6d335addf07ca2aadbdd0394a7b9 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Mon, 6 Aug 2018 03:29:44 +0530 Subject: [PATCH 11/65] Implemented bulk cipher share (share selected) #100 --- src/api/core/ciphers.rs | 66 ++++++++++++++++++++++++++++++++++--- src/api/core/mod.rs | 1 + src/db/models/attachment.rs | 6 ++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 95df5a0..a253e20 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -87,6 +87,8 @@ fn get_cipher_details(uuid: String, headers: Headers, conn: DbConn) -> JsonResul #[derive(Deserialize, Debug)] #[allow(non_snake_case)] struct CipherData { + // Id is optional as it is included only in bulk share + Id: Option, // Folder id is not included in import FolderId: Option, // TODO: Some of these might appear all the time, no need for Option @@ -332,6 +334,65 @@ struct ShareCipherData { fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: ShareCipherData = data.into_inner().data; + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[put("/ciphers//share", data = "")] +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + let data: ShareCipherData = data.into_inner().data; + + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct ShareSelectedCipherData { + Ciphers: Vec, + CollectionIds: Vec +} + +#[put("/ciphers/share", data = "")] +fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + let mut data: ShareSelectedCipherData = data.into_inner().data; + let mut cipher_ids: Vec = Vec::new(); + + if data.Ciphers.len() == 0 { + err!("You must select at least one cipher.") + } + + if data.CollectionIds.len() == 0 { + err!("You must select at least one collection.") + } + + for cipher in data.Ciphers.iter() { + match cipher.Id { + Some(ref id) => cipher_ids.push(id.to_string()), + None => err!("Request missing ids field") + }; + } + + let attachments = Attachment::find_by_ciphers(cipher_ids, &conn); + + if attachments.len() > 0 { + err!("Ciphers should not have any attachments.") + } + + while let Some(cipher) = data.Ciphers.pop() { + let mut shared_cipher_data = ShareCipherData { + Cipher: cipher, + CollectionIds: data.CollectionIds.clone() + }; + + match shared_cipher_data.Cipher.Id.take() { + Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn)?, + None => err!("Request missing ids field") + }; + } + + Ok(()) +} + +fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn) -> JsonResult { let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => { if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { @@ -365,11 +426,6 @@ fn post_cipher_share(uuid: String, data: JsonUpcase, headers: H } } -#[put("/ciphers//share", data = "")] -fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - post_cipher_share(uuid, data, headers, conn) -} - #[post("/ciphers//attachment", format = "multipart/form-data", data = "")] fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { let cipher = match Cipher::find_by_uuid(&uuid, &conn) { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index e06c36b..a3d565c 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -42,6 +42,7 @@ pub fn routes() -> Vec { post_cipher_admin, post_cipher_share, put_cipher_share, + put_cipher_share_seleted, post_cipher, put_cipher, delete_cipher_post, diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 1f5e29a..66d5b72 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -111,4 +111,10 @@ impl Attachment { .filter(attachments::cipher_uuid.eq(cipher_uuid)) .load::(&**conn).expect("Error loading attachments") } + + pub fn find_by_ciphers(cipher_uuids: Vec, conn: &DbConn) -> Vec { + attachments::table + .filter(attachments::cipher_uuid.eq_any(cipher_uuids)) + .load::(&**conn).expect("Error loading attachments") + } } From 73a1abed10d282c6ee51dd57b66554e23bb0a806 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 8 Aug 2018 23:15:01 +0200 Subject: [PATCH 12/65] Update vault to latest version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ea63874..860e76c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ####################### VAULT BUILD IMAGE ####################### FROM node:8-alpine as vault -ENV VAULT_VERSION "v2.0.0" +ENV VAULT_VERSION "v2.1.1" ENV URL "https://github.com/bitwarden/web.git" From 039860f87e05999d143fb12cde56a4e5baf1ba1a Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 9 Aug 2018 13:38:40 +0100 Subject: [PATCH 13/65] Fix patch file for v2.1.1 --- docker/set-vault-baseurl.patch | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docker/set-vault-baseurl.patch b/docker/set-vault-baseurl.patch index 1ce1704..104395a 100644 --- a/docker/set-vault-baseurl.patch +++ b/docker/set-vault-baseurl.patch @@ -1,16 +1,15 @@ --- a/src/app/services/services.module.ts +++ b/src/app/services/services.module.ts -@@ -114,10 +114,9 @@ containerService.attachToWindow(window); - +@@ -119,10 +119,8 @@ export function initFactory(): Function { return async () => { + await (storageService as HtmlStorageService).init(); - const isDev = platformUtilsService.isDev(); - if (!isDev && platformUtilsService.isSelfHost()) { - environmentService.baseUrl = window.location.origin; - } + const isDev = false; + environmentService.baseUrl = window.location.origin; -+ await apiService.setUrls({ base: isDev ? null : window.location.origin, api: isDev ? 'http://localhost:4000' : null, From 58c1545707601e7cd394890003addd7e9b4e7e7d Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 10 Aug 2018 17:17:44 +0100 Subject: [PATCH 14/65] Return revision date in miliseconds (fixes #127) --- src/api/core/accounts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index 03315d6..580ece9 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -244,6 +244,6 @@ fn delete_account(data: JsonUpcase, headers: Headers, conn: DbConn #[get("/accounts/revision-date")] fn revision_date(headers: Headers) -> String { - let revision_date = headers.user.updated_at.timestamp(); + let revision_date = headers.user.updated_at.timestamp_millis(); revision_date.to_string() } From ddda86b90d1d4db22ef86a183f00654d9b71271c Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Mon, 6 Aug 2018 03:29:44 +0530 Subject: [PATCH 15/65] Implemented bulk cipher share (share selected) #100 --- src/api/core/ciphers.rs | 66 ++++++++++++++++++++++++++++++++++--- src/api/core/mod.rs | 1 + src/db/models/attachment.rs | 6 ++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 95df5a0..a253e20 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -87,6 +87,8 @@ fn get_cipher_details(uuid: String, headers: Headers, conn: DbConn) -> JsonResul #[derive(Deserialize, Debug)] #[allow(non_snake_case)] struct CipherData { + // Id is optional as it is included only in bulk share + Id: Option, // Folder id is not included in import FolderId: Option, // TODO: Some of these might appear all the time, no need for Option @@ -332,6 +334,65 @@ struct ShareCipherData { fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: ShareCipherData = data.into_inner().data; + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[put("/ciphers//share", data = "")] +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + let data: ShareCipherData = data.into_inner().data; + + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct ShareSelectedCipherData { + Ciphers: Vec, + CollectionIds: Vec +} + +#[put("/ciphers/share", data = "")] +fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + let mut data: ShareSelectedCipherData = data.into_inner().data; + let mut cipher_ids: Vec = Vec::new(); + + if data.Ciphers.len() == 0 { + err!("You must select at least one cipher.") + } + + if data.CollectionIds.len() == 0 { + err!("You must select at least one collection.") + } + + for cipher in data.Ciphers.iter() { + match cipher.Id { + Some(ref id) => cipher_ids.push(id.to_string()), + None => err!("Request missing ids field") + }; + } + + let attachments = Attachment::find_by_ciphers(cipher_ids, &conn); + + if attachments.len() > 0 { + err!("Ciphers should not have any attachments.") + } + + while let Some(cipher) = data.Ciphers.pop() { + let mut shared_cipher_data = ShareCipherData { + Cipher: cipher, + CollectionIds: data.CollectionIds.clone() + }; + + match shared_cipher_data.Cipher.Id.take() { + Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn)?, + None => err!("Request missing ids field") + }; + } + + Ok(()) +} + +fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn) -> JsonResult { let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => { if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { @@ -365,11 +426,6 @@ fn post_cipher_share(uuid: String, data: JsonUpcase, headers: H } } -#[put("/ciphers//share", data = "")] -fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - post_cipher_share(uuid, data, headers, conn) -} - #[post("/ciphers//attachment", format = "multipart/form-data", data = "")] fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { let cipher = match Cipher::find_by_uuid(&uuid, &conn) { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index e06c36b..a3d565c 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -42,6 +42,7 @@ pub fn routes() -> Vec { post_cipher_admin, post_cipher_share, put_cipher_share, + put_cipher_share_seleted, post_cipher, put_cipher, delete_cipher_post, diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 1f5e29a..66d5b72 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -111,4 +111,10 @@ impl Attachment { .filter(attachments::cipher_uuid.eq(cipher_uuid)) .load::(&**conn).expect("Error loading attachments") } + + pub fn find_by_ciphers(cipher_uuids: Vec, conn: &DbConn) -> Vec { + attachments::table + .filter(attachments::cipher_uuid.eq_any(cipher_uuids)) + .load::(&**conn).expect("Error loading attachments") + } } From 5f6d721c091029f02efd6bbacc57fa9847d95dc5 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Fri, 10 Aug 2018 23:19:07 +0530 Subject: [PATCH 16/65] Implemented PUT for /two-factor/authenticator and /two-factor/disable --- src/api/core/mod.rs | 2 ++ src/api/core/two_factor.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index a3d565c..3d130f3 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -66,8 +66,10 @@ pub fn routes() -> Vec { get_recover, recover, disable_twofactor, + disable_twofactor_put, generate_authenticator, activate_authenticator, + activate_authenticator_put, generate_u2f, activate_u2f, diff --git a/src/api/core/two_factor.rs b/src/api/core/two_factor.rs index 420362a..67088aa 100644 --- a/src/api/core/two_factor.rs +++ b/src/api/core/two_factor.rs @@ -112,6 +112,15 @@ fn disable_twofactor( }))) } +#[put("/two-factor/disable", data = "")] +fn disable_twofactor_put( + data: JsonUpcase, + headers: Headers, + conn: DbConn, +) -> JsonResult { + disable_twofactor(data, headers, conn) +} + #[post("/two-factor/get-authenticator", data = "")] fn generate_authenticator( data: JsonUpcase, @@ -194,6 +203,15 @@ fn activate_authenticator( }))) } +#[put("/two-factor/authenticator", data = "")] +fn activate_authenticator_put( + data: JsonUpcase, + headers: Headers, + conn: DbConn, +) -> JsonResult { + activate_authenticator(data, headers, conn) +} + fn _generate_recover_code(user: &mut User, conn: &DbConn) { if user.totp_recover.is_none() { let totp_recover = BASE32.encode(&crypto::get_random(vec![0u8; 20])); From 3fd3d8d5e9e424ebe976a33a86d8fa42e8d8b7f6 Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Fri, 10 Aug 2018 23:49:34 +0530 Subject: [PATCH 17/65] Merge branch 'beta' of https://github.com/krankur/bitwarden_rs into beta --- src/api/core/ciphers.rs | 66 +++---------------------------------- src/api/core/mod.rs | 1 - src/db/models/attachment.rs | 6 ---- 3 files changed, 5 insertions(+), 68 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index a253e20..95df5a0 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -87,8 +87,6 @@ fn get_cipher_details(uuid: String, headers: Headers, conn: DbConn) -> JsonResul #[derive(Deserialize, Debug)] #[allow(non_snake_case)] struct CipherData { - // Id is optional as it is included only in bulk share - Id: Option, // Folder id is not included in import FolderId: Option, // TODO: Some of these might appear all the time, no need for Option @@ -334,65 +332,6 @@ struct ShareCipherData { fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: ShareCipherData = data.into_inner().data; - share_cipher_by_uuid(&uuid, data, &headers, &conn) -} - -#[put("/ciphers//share", data = "")] -fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - let data: ShareCipherData = data.into_inner().data; - - share_cipher_by_uuid(&uuid, data, &headers, &conn) -} - -#[derive(Deserialize)] -#[allow(non_snake_case)] -struct ShareSelectedCipherData { - Ciphers: Vec, - CollectionIds: Vec -} - -#[put("/ciphers/share", data = "")] -fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { - let mut data: ShareSelectedCipherData = data.into_inner().data; - let mut cipher_ids: Vec = Vec::new(); - - if data.Ciphers.len() == 0 { - err!("You must select at least one cipher.") - } - - if data.CollectionIds.len() == 0 { - err!("You must select at least one collection.") - } - - for cipher in data.Ciphers.iter() { - match cipher.Id { - Some(ref id) => cipher_ids.push(id.to_string()), - None => err!("Request missing ids field") - }; - } - - let attachments = Attachment::find_by_ciphers(cipher_ids, &conn); - - if attachments.len() > 0 { - err!("Ciphers should not have any attachments.") - } - - while let Some(cipher) = data.Ciphers.pop() { - let mut shared_cipher_data = ShareCipherData { - Cipher: cipher, - CollectionIds: data.CollectionIds.clone() - }; - - match shared_cipher_data.Cipher.Id.take() { - Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn)?, - None => err!("Request missing ids field") - }; - } - - Ok(()) -} - -fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn) -> JsonResult { let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => { if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { @@ -426,6 +365,11 @@ fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, co } } +#[put("/ciphers//share", data = "")] +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + post_cipher_share(uuid, data, headers, conn) +} + #[post("/ciphers//attachment", format = "multipart/form-data", data = "")] fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { let cipher = match Cipher::find_by_uuid(&uuid, &conn) { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 3d130f3..6b988fc 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -42,7 +42,6 @@ pub fn routes() -> Vec { post_cipher_admin, post_cipher_share, put_cipher_share, - put_cipher_share_seleted, post_cipher, put_cipher, delete_cipher_post, diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 66d5b72..1f5e29a 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -111,10 +111,4 @@ impl Attachment { .filter(attachments::cipher_uuid.eq(cipher_uuid)) .load::(&**conn).expect("Error loading attachments") } - - pub fn find_by_ciphers(cipher_uuids: Vec, conn: &DbConn) -> Vec { - attachments::table - .filter(attachments::cipher_uuid.eq_any(cipher_uuids)) - .load::(&**conn).expect("Error loading attachments") - } } From 3f5a99916a3d8487df00e196e19627b25616e930 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 13 Aug 2018 10:58:39 +0100 Subject: [PATCH 18/65] Implement update_revision trigger --- src/api/core/ciphers.rs | 6 +++++- src/db/models/user.rs | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 95df5a0..43c5c78 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -242,7 +242,11 @@ fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbC cipher.move_to_folder(folder_uuid, &headers.user.uuid.clone(), &conn).ok(); } - Ok(()) + let mut user = headers.user; + match user.update_revision(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed to update the revision, please log out and log back in to finish import.") + } } #[post("/ciphers//admin", data = "")] diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 2c30c52..9378824 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -154,6 +154,16 @@ impl User { } } + pub fn update_revision(&mut self, conn: &DbConn) -> QueryResult<()> { + diesel::update( + users::table.filter( + users::uuid.eq(&self.uuid) + ) + ) + .set(users::updated_at.eq(Utc::now().naive_utc())) + .execute(&**conn).and(Ok(())) + } + pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option { let lower_mail = mail.to_lowercase(); users::table From c0f554311b31de95c19587596af589b72d0269ac Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 13 Aug 2018 12:01:52 +0100 Subject: [PATCH 19/65] Extend documentation --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index aa0790a..10ce58b 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ _*Note, that this project is not associated with the [Bitwarden](https://bitward - [icons cache](#icons-cache) - [Changing the API request size limit](#changing-the-api-request-size-limit) - [Changing the number of workers](#changing-the-number-of-workers) + - [Disabling or overriding the Vault interface hosting](#disabling-or-overriding-the-vault-interface-hosting) - [Other configuration](#other-configuration) - [Building your own image](#building-your-own-image) - [Building binary](#building-binary) @@ -33,6 +34,10 @@ _*Note, that this project is not associated with the [Bitwarden](https://bitward - [3. the key files](#3-the-key-files) - [4. Icon Cache](#4-icon-cache) - [Running the server with non-root user](#running-the-server-with-non-root-user) +- [Differences from upstream API implementation](#differences-from-upstream-api-implementation) + - [Changing user email](#changing-user-email) + - [Creating organization](#creating-organization) + - [Inviting users into organization](#inviting-users-into-organization) - [Get in touch](#get-in-touch) ## Features @@ -248,6 +253,30 @@ docker run -d --name bitwarden \ mprasil/bitwarden:latest ``` +### Disabling or overriding the Vault interface hosting + +As a convenience bitwarden_rs image will also host static files for Vault web interface. You can disable this static file hosting completely by setting the WEB_VAULT_ENABLED variable. + +```sh +docker run -d --name bitwarden \ + -e WEB_VAULT_ENABLED=false \ + -v /bw-data/:/data/ \ + -p 80:80 \ + mprasil/bitwarden:latest +``` + +Alternatively you can override the Vault files and provide your own static files to host. You can do that by mounting a path with your files over the `/web-vault` directory in the container. Just make sure the directory contains at least `index.html` file. + +```sh +docker run -d --name bitwarden \ + -v /path/to/static/files_directory:/web-vault \ + -v /bw-data/:/data/ \ + -p 80:80 \ + mprasil/bitwarden:latest +``` + +Note that you can also change the path where bitwarden_rs looks for static files by providing the `WEB_VAULT_FOLDER` environment variable with the path. + ### Other configuration Though this is unlikely to be required in small deployment, you can fine-tune some other settings like number of workers using environment variables that are processed by [Rocket](https://rocket.rs), please see details in [documentation](https://rocket.rs/guide/configuration/#environment-variables). @@ -313,6 +342,21 @@ docker run -d --name bitwarden \ -p 80:8080 \ mprasil/bitwarden:latest ``` + +## Differences from upstream API implementation + +### Changing user email + +Because we don't have any SMTP functionality at the moment, there's no way to deliver the verification token when you try to change the email. User just needs to enter any random token to continue and the change will be applied. + +### Creating organization + +We use upstream Vault interface directly without any (significant) changes, this is why user is presented with paid options when creating organization. To create an organization, just use the free option, none of the limits apply when using bitwarden_rs as back-end API and after the organization is created it should behave like Enterprise organization. + +### Inviting users into organization + +The users must already be registered on your server to invite them, because we can't send the invitation via email. The invited users won't get the invitation email, instead they will appear in the interface as if they already accepted the invitation. Organization admin then just needs to confirm them to be proper Organization members and to give them access to the shared secrets. + ## Get in touch To ask an question, [raising an issue](https://github.com/dani-garcia/bitwarden_rs/issues/new) is fine, also please report any bugs spotted here. From 626a3c93ba21862e35cc6b01ebd8a076dc14ec82 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 13 Aug 2018 12:35:41 +0100 Subject: [PATCH 20/65] Revert "Merge branch 'beta' of https://github.com/krankur/bitwarden_rs into beta" This reverts commit 3fd3d8d5e9e424ebe976a33a86d8fa42e8d8b7f6. --- src/api/core/ciphers.rs | 66 ++++++++++++++++++++++++++++++++++--- src/api/core/mod.rs | 1 + src/db/models/attachment.rs | 6 ++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 95df5a0..a253e20 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -87,6 +87,8 @@ fn get_cipher_details(uuid: String, headers: Headers, conn: DbConn) -> JsonResul #[derive(Deserialize, Debug)] #[allow(non_snake_case)] struct CipherData { + // Id is optional as it is included only in bulk share + Id: Option, // Folder id is not included in import FolderId: Option, // TODO: Some of these might appear all the time, no need for Option @@ -332,6 +334,65 @@ struct ShareCipherData { fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: ShareCipherData = data.into_inner().data; + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[put("/ciphers//share", data = "")] +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + let data: ShareCipherData = data.into_inner().data; + + share_cipher_by_uuid(&uuid, data, &headers, &conn) +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct ShareSelectedCipherData { + Ciphers: Vec, + CollectionIds: Vec +} + +#[put("/ciphers/share", data = "")] +fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + let mut data: ShareSelectedCipherData = data.into_inner().data; + let mut cipher_ids: Vec = Vec::new(); + + if data.Ciphers.len() == 0 { + err!("You must select at least one cipher.") + } + + if data.CollectionIds.len() == 0 { + err!("You must select at least one collection.") + } + + for cipher in data.Ciphers.iter() { + match cipher.Id { + Some(ref id) => cipher_ids.push(id.to_string()), + None => err!("Request missing ids field") + }; + } + + let attachments = Attachment::find_by_ciphers(cipher_ids, &conn); + + if attachments.len() > 0 { + err!("Ciphers should not have any attachments.") + } + + while let Some(cipher) = data.Ciphers.pop() { + let mut shared_cipher_data = ShareCipherData { + Cipher: cipher, + CollectionIds: data.CollectionIds.clone() + }; + + match shared_cipher_data.Cipher.Id.take() { + Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn)?, + None => err!("Request missing ids field") + }; + } + + Ok(()) +} + +fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn) -> JsonResult { let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => { if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { @@ -365,11 +426,6 @@ fn post_cipher_share(uuid: String, data: JsonUpcase, headers: H } } -#[put("/ciphers//share", data = "")] -fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - post_cipher_share(uuid, data, headers, conn) -} - #[post("/ciphers//attachment", format = "multipart/form-data", data = "")] fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { let cipher = match Cipher::find_by_uuid(&uuid, &conn) { diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 1bf81ab..2a74581 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -43,6 +43,7 @@ pub fn routes() -> Vec { post_cipher_admin, post_cipher_share, put_cipher_share, + put_cipher_share_seleted, post_cipher, put_cipher, delete_cipher_post, diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 1f5e29a..66d5b72 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -111,4 +111,10 @@ impl Attachment { .filter(attachments::cipher_uuid.eq(cipher_uuid)) .load::(&**conn).expect("Error loading attachments") } + + pub fn find_by_ciphers(cipher_uuids: Vec, conn: &DbConn) -> Vec { + attachments::table + .filter(attachments::cipher_uuid.eq_any(cipher_uuids)) + .load::(&**conn).expect("Error loading attachments") + } } From d3f357b7089fc649ff95eb067cd061e2fc3a608b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Mon, 13 Aug 2018 15:26:01 +0200 Subject: [PATCH 21/65] Implemented PUT for u2f registration --- src/api/core/mod.rs | 1 + src/api/core/two_factor.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 2a74581..4d37f24 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -73,6 +73,7 @@ pub fn routes() -> Vec { activate_authenticator_put, generate_u2f, activate_u2f, + activate_u2f_put, get_organization, create_organization, diff --git a/src/api/core/two_factor.rs b/src/api/core/two_factor.rs index 67088aa..875dec2 100644 --- a/src/api/core/two_factor.rs +++ b/src/api/core/two_factor.rs @@ -374,6 +374,11 @@ fn activate_u2f(data: JsonUpcase, headers: Headers, conn: DbConn) } } +#[put("/two-factor/u2f", data = "")] +fn activate_u2f_put(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + activate_u2f(data,headers, conn) +} + fn _create_u2f_challenge(user_uuid: &str, type_: TwoFactorType, conn: &DbConn) -> Challenge { let challenge = U2F.generate_challenge().unwrap(); From 6ede1743ac837b67586ebc7190e91a523d000826 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 13 Aug 2018 16:00:10 +0100 Subject: [PATCH 22/65] add alias for PUT collections-admin --- src/api/core/ciphers.rs | 5 +++++ src/api/core/mod.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 0e2d5a7..2c60f0d 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -291,6 +291,11 @@ fn post_collections_update(uuid: String, data: JsonUpcase, post_collections_admin(uuid, data, headers, conn) } +#[put("/ciphers//collections-admin", data = "")] +fn put_collections_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + post_collections_admin(uuid, data, headers, conn) +} + #[post("/ciphers//collections-admin", data = "")] fn post_collections_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data: CollectionsAdminData = data.into_inner().data; diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 4d37f24..f165931 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -90,6 +90,7 @@ pub fn routes() -> Vec { post_organization_collection_delete, post_collections_update, post_collections_admin, + put_collections_admin, get_org_details, get_org_users, send_invite, From 0dfd9c7670fabc794e967cfe141277b52ae6582f Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 13 Aug 2018 16:45:30 +0100 Subject: [PATCH 23/65] Add couple more aliases for PUTs and DELETEs --- src/api/core/mod.rs | 6 ++++ src/api/core/organizations.rs | 56 +++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index f165931..6c2966c 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -78,6 +78,7 @@ pub fn routes() -> Vec { get_organization, create_organization, delete_organization, + post_delete_organization, leave_organization, get_user_collections, get_org_collections, @@ -85,8 +86,11 @@ pub fn routes() -> Vec { get_collection_users, post_organization, post_organization_collections, + delete_organization_collection_user, post_organization_collection_delete_user, post_organization_collection_update, + put_organization_collection_update, + delete_organization_collection, post_organization_collection_delete, post_collections_update, post_collections_admin, @@ -97,7 +101,9 @@ pub fn routes() -> Vec { confirm_invite, get_user, edit_user, + put_organization_user, delete_user, + post_delete_user, clear_device_token, put_device_token, diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 74be559..fe7313e 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -55,7 +55,7 @@ fn create_organization(headers: Headers, data: JsonUpcase, conn: DbConn Ok(Json(org.to_json())) } -#[post("/organizations//delete", data = "")] +#[delete("/organizations/", data = "")] fn delete_organization(org_id: String, data: JsonUpcase, headers: OwnerHeaders, conn: DbConn) -> EmptyResult { let data: PasswordData = data.into_inner().data; let password_hash = data.MasterPasswordHash; @@ -73,6 +73,11 @@ fn delete_organization(org_id: String, data: JsonUpcase, headers: } } +#[post("/organizations//delete", data = "")] +fn post_delete_organization(org_id: String, data: JsonUpcase, headers: OwnerHeaders, conn: DbConn) -> EmptyResult { + delete_organization(org_id, data, headers, conn) +} + #[post("/organizations//leave")] fn leave_organization(org_id: String, headers: Headers, conn: DbConn) -> EmptyResult { match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { @@ -164,6 +169,11 @@ fn post_organization_collections(org_id: String, _headers: AdminHeaders, data: J Ok(Json(collection.to_json())) } +#[put("/organizations//collections/", data = "")] +fn put_organization_collection_update(org_id: String, col_id: String, headers: AdminHeaders, data: JsonUpcase, conn: DbConn) -> JsonResult { + post_organization_collection_update(org_id, col_id, headers, data, conn) +} + #[post("/organizations//collections/", data = "")] fn post_organization_collection_update(org_id: String, col_id: String, _headers: AdminHeaders, data: JsonUpcase, conn: DbConn) -> JsonResult { let data: NewCollectionData = data.into_inner().data; @@ -188,8 +198,9 @@ fn post_organization_collection_update(org_id: String, col_id: String, _headers: Ok(Json(collection.to_json())) } -#[post("/organizations//collections//delete-user/")] -fn post_organization_collection_delete_user(org_id: String, col_id: String, org_user_id: String, _headers: AdminHeaders, conn: DbConn) -> EmptyResult { + +#[delete("/organizations//collections//user/")] +fn delete_organization_collection_user(org_id: String, col_id: String, org_user_id: String, _headers: AdminHeaders, conn: DbConn) -> EmptyResult { let collection = match Collection::find_by_uuid(&col_id, &conn) { None => err!("Collection not found"), Some(collection) => if collection.org_uuid == org_id { @@ -215,17 +226,13 @@ fn post_organization_collection_delete_user(org_id: String, col_id: String, org_ } } -#[derive(Deserialize, Debug)] -#[allow(non_snake_case)] -struct DeleteCollectionData { - Id: String, - OrgId: String, +#[post("/organizations//collections//delete-user/")] +fn post_organization_collection_delete_user(org_id: String, col_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + delete_organization_collection_user(org_id, col_id, org_user_id, headers, conn) } -#[post("/organizations//collections//delete", data = "")] -fn post_organization_collection_delete(org_id: String, col_id: String, _headers: AdminHeaders, data: JsonUpcase, conn: DbConn) -> EmptyResult { - let _data: DeleteCollectionData = data.into_inner().data; - +#[delete("/organizations//collections/")] +fn delete_organization_collection(org_id: String, col_id: String, _headers: AdminHeaders, conn: DbConn) -> EmptyResult { match Collection::find_by_uuid(&col_id, &conn) { None => err!("Collection not found"), Some(collection) => if collection.org_uuid == org_id { @@ -239,6 +246,18 @@ fn post_organization_collection_delete(org_id: String, col_id: String, _headers: } } +#[derive(Deserialize, Debug)] +#[allow(non_snake_case)] +struct DeleteCollectionData { + Id: String, + OrgId: String, +} + +#[post("/organizations//collections//delete", data = "<_data>")] +fn post_organization_collection_delete(org_id: String, col_id: String, headers: AdminHeaders, _data: JsonUpcase, conn: DbConn) -> EmptyResult { + delete_organization_collection(org_id, col_id, headers, conn) +} + #[get("/organizations//collections//details")] fn get_org_collection_detail(org_id: String, coll_id: String, headers: AdminHeaders, conn: DbConn) -> JsonResult { match Collection::find_by_uuid_and_user(&coll_id, &headers.user.uuid, &conn) { @@ -428,6 +447,12 @@ struct EditUserData { AccessAll: bool, } + +#[put("/organizations//users/", data = "", rank = 1)] +fn put_organization_user(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + edit_user(org_id, user_id, data, headers, conn) +} + #[post("/organizations//users/", data = "", rank = 1)] fn edit_user(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { let data: EditUserData = data.into_inner().data; @@ -494,7 +519,7 @@ fn edit_user(org_id: String, user_id: String, data: JsonUpcase, he Ok(()) } -#[post("/organizations//users//delete")] +#[delete("/organizations//users/")] fn delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { let user_to_delete = match UserOrganization::find_by_uuid(&user_id, &conn) { Some(user) => user, @@ -521,4 +546,9 @@ fn delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbC Ok(()) => Ok(()), Err(_) => err!("Failed deleting user from organization") } +} + +#[post("/organizations//users//delete")] +fn post_delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + delete_user(org_id, user_id, headers, conn) } \ No newline at end of file From 00b882935f160e6d7567d9a4d2618e02bba96e78 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 14 Aug 2018 11:06:42 +0100 Subject: [PATCH 24/65] Deserialize "null" to empty Vec for Collections --- src/api/core/organizations.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index fe7313e..a456856 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -8,6 +8,8 @@ use db::models::*; use api::{PasswordData, JsonResult, EmptyResult, NumberOrString, JsonUpcase}; use auth::{Headers, AdminHeaders, OwnerHeaders}; +use serde::{Deserialize, Deserializer}; + #[derive(Deserialize)] #[allow(non_snake_case)] @@ -327,6 +329,14 @@ fn get_org_users(org_id: String, headers: AdminHeaders, conn: DbConn) -> JsonRes }))) } +fn deserialize_collections<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + // Deserialize null to empty Vec + Deserialize::deserialize(deserializer).or(Ok(vec![])) +} + #[derive(Deserialize)] #[allow(non_snake_case)] struct CollectionData { @@ -339,6 +349,7 @@ struct CollectionData { struct InviteData { Emails: Vec, Type: NumberOrString, + #[serde(deserialize_with = "deserialize_collections")] Collections: Vec, AccessAll: Option, } @@ -443,11 +454,11 @@ fn get_user(org_id: String, user_id: String, _headers: AdminHeaders, conn: DbCon #[allow(non_snake_case)] struct EditUserData { Type: NumberOrString, + #[serde(deserialize_with = "deserialize_collections")] Collections: Vec, AccessAll: bool, } - #[put("/organizations//users/", data = "", rank = 1)] fn put_organization_user(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { edit_user(org_id, user_id, data, headers, conn) From 5ecafb157d44978ce29b6af6fa290e01063a980d Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 14 Aug 2018 21:48:56 +0100 Subject: [PATCH 25/65] Disable analytics via patch to Vault --- docker/set-vault-baseurl.patch | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docker/set-vault-baseurl.patch b/docker/set-vault-baseurl.patch index 104395a..492f6b6 100644 --- a/docker/set-vault-baseurl.patch +++ b/docker/set-vault-baseurl.patch @@ -1,6 +1,14 @@ --- a/src/app/services/services.module.ts +++ b/src/app/services/services.module.ts -@@ -119,10 +119,8 @@ +@@ -116,17 +116,15 @@ const exportService = new ExportService(folderService, cipherService, apiService + const importService = new ImportService(cipherService, folderService, apiService, i18nService, collectionService); + const auditService = new AuditService(cryptoFunctionService, apiService); + +-const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), ++const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost() || true, + platformUtilsService, storageService, appIdService); + containerService.attachToWindow(window); + export function initFactory(): Function { return async () => { await (storageService as HtmlStorageService).init(); From 80bad9f66dfa43d108288c81eaa8ec7f78151231 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 15 Aug 2018 11:18:34 +0100 Subject: [PATCH 26/65] Cleaned up HTTPS example --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 10ce58b..0ab98eb 100644 --- a/README.md +++ b/README.md @@ -139,10 +139,9 @@ Where: ```sh docker run -d --name bitwarden \ - -e ROCKET_TLS={certs='"/ssl/certs.pem",key="/ssl/key.pem"}' \ + -e ROCKET_TLS='{certs="/ssl/certs.pem",key="/ssl/key.pem"}' \ -v /ssl/keys/:/ssl/ \ -v /bw-data/:/data/ \ - -v /icon_cache/ \ -p 443:80 \ mprasil/bitwarden:latest ``` From f2fec345ec0fa25a4a07d661f6760c85df6be8fa Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 15 Aug 2018 14:27:37 +0100 Subject: [PATCH 27/65] Add PUT alias for editing cipher --- src/api/core/ciphers.rs | 7 ++++++- src/api/core/mod.rs | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 2c60f0d..beb68e0 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -251,9 +251,14 @@ fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbC } } + +#[put("/ciphers//admin", data = "")] +fn put_cipher_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + put_cipher(uuid, data, headers, conn) +} + #[post("/ciphers//admin", data = "")] fn post_cipher_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - // TODO: Implement this correctly post_cipher(uuid, data, headers, conn) } diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 6c2966c..079460a 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -32,6 +32,7 @@ pub fn routes() -> Vec { get_cipher_admin, get_cipher_details, post_ciphers, + put_cipher_admin, post_ciphers_admin, post_ciphers_import, post_attachment, From b3f3fd81aca91b0d14b71b5a3feea1cf298436cc Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 15 Aug 2018 15:50:07 +0100 Subject: [PATCH 28/65] Update theerror format to show message in new Vault --- src/util.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/util.rs b/src/util.rs index 4a18680..c5bade6 100644 --- a/src/util.rs +++ b/src/util.rs @@ -3,19 +3,20 @@ /// #[macro_export] macro_rules! err { - ($err:expr, $err_desc:expr, $msg:expr) => {{ + ($err:expr, $msg:expr) => {{ println!("ERROR: {}", $msg); err_json!(json!({ - "error": $err, - "error_description": $err_desc, - "ErrorModel": { - "Message": $msg, - "ValidationErrors": null, - "Object": "error" - } + "Message": $err, + "ValidationErrors": { + "": [$msg,], + }, + "ExceptionMessage": null, + "ExceptionStackTrace": null, + "InnerExceptionMessage": null, + "Object": "error", })) }}; - ($msg:expr) => { err!("default_error", "default_error_description", $msg) } + ($msg:expr) => { err!("The model state is invalid", $msg) } } #[macro_export] From 12a2dc0901d9b4daeff4a6534ded1daa5edaeb87 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 15 Aug 2018 16:10:40 +0100 Subject: [PATCH 29/65] Add PUT alias for profile update --- src/api/core/accounts.rs | 5 +++++ src/api/core/mod.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index fe26c4d..cb6f83f 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -73,6 +73,11 @@ struct ProfileData { Name: String, } +#[put("/accounts/profile", data = "")] +fn put_profile(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { + post_profile(data, headers, conn) +} + #[post("/accounts/profile", data = "")] fn post_profile(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { let data: ProfileData = data.into_inner().data; diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 6c2966c..b0c1912 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -14,6 +14,7 @@ pub fn routes() -> Vec { routes![ register, profile, + put_profile, post_profile, get_public_keys, post_keys, From 4fb09c5b4d2ca1e6e2f263df3b27eacedf86422a Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 10:36:04 +0100 Subject: [PATCH 30/65] Actually update the revision date for user struct, not just in DB --- src/db/models/user.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 9378824..94becf7 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -155,12 +155,13 @@ impl User { } pub fn update_revision(&mut self, conn: &DbConn) -> QueryResult<()> { + self.updated_at = Utc::now().naive_utc(); diesel::update( users::table.filter( users::uuid.eq(&self.uuid) ) ) - .set(users::updated_at.eq(Utc::now().naive_utc())) + .set(users::updated_at.eq(&self.updated_at)) .execute(&**conn).and(Ok(())) } From a5ef8aef0f7e6051578fc8138ec7dc627808aa40 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 12:20:55 +0100 Subject: [PATCH 31/65] Update affected users revision when there are collection changes --- src/db/models/collection.rs | 12 ++++++++++++ src/db/models/user.rs | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs index fa16ec2..2bf116c 100644 --- a/src/db/models/collection.rs +++ b/src/db/models/collection.rs @@ -185,6 +185,8 @@ impl CollectionUser { } pub fn save(user_uuid: &str, collection_uuid: &str, read_only:bool, conn: &DbConn) -> QueryResult<()> { + User::update_uuid_revision(&user_uuid, conn); + diesel::replace_into(users_collections::table) .values(( users_collections::user_uuid.eq(user_uuid), @@ -194,6 +196,8 @@ impl CollectionUser { } pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + User::update_uuid_revision(&self.user_uuid, conn); + diesel::delete(users_collections::table .filter(users_collections::user_uuid.eq(&self.user_uuid)) .filter(users_collections::collection_uuid.eq(&self.collection_uuid))) @@ -216,12 +220,20 @@ impl CollectionUser { } pub fn delete_all_by_collection(collection_uuid: &str, conn: &DbConn) -> QueryResult<()> { + CollectionUser::find_by_collection(&collection_uuid, conn) + .iter() + .for_each(|collection| { + User::update_uuid_revision(&collection.user_uuid, conn) + }); + diesel::delete(users_collections::table .filter(users_collections::collection_uuid.eq(collection_uuid)) ).execute(&**conn).and(Ok(())) } pub fn delete_all_by_user(user_uuid: &str, conn: &DbConn) -> QueryResult<()> { + User::update_uuid_revision(&user_uuid, conn); + diesel::delete(users_collections::table .filter(users_collections::user_uuid.eq(user_uuid)) ).execute(&**conn).and(Ok(())) diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 9378824..dff34d5 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -154,6 +154,14 @@ impl User { } } + pub fn update_uuid_revision(uuid: &str, conn: &DbConn) { + if let Some(mut user) = User::find_by_uuid(&uuid, conn) { + if user.update_revision(conn).is_err(){ + println!("Warning: Failed to update revision for {}", user.email); + }; + }; + } + pub fn update_revision(&mut self, conn: &DbConn) -> QueryResult<()> { diesel::update( users::table.filter( From 40d09ddd2a7cdf5db79646121fe7ffb1f8d2b236 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 13:25:52 +0100 Subject: [PATCH 32/65] Add PUT alias for Organization updates --- src/api/core/mod.rs | 1 + src/api/core/organizations.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 4206aca..907b053 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -86,6 +86,7 @@ pub fn routes() -> Vec { get_org_collections, get_org_collection_detail, get_collection_users, + put_organization, post_organization, post_organization_collections, delete_organization_collection_user, diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index a456856..c2ecde2 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -111,6 +111,11 @@ fn get_organization(org_id: String, _headers: OwnerHeaders, conn: DbConn) -> Jso } } +#[put("/organizations/", data = "")] +fn put_organization(org_id: String, headers: OwnerHeaders, data: JsonUpcase, conn: DbConn) -> JsonResult { + post_organization(org_id, headers, data, conn) +} + #[post("/organizations/", data = "")] fn post_organization(org_id: String, _headers: OwnerHeaders, data: JsonUpcase, conn: DbConn) -> JsonResult { let data: OrganizationUpdateData = data.into_inner().data; From 9eea0151ba73213f6e2f3f66f7abc415e19e1d65 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 13:26:22 +0100 Subject: [PATCH 33/65] Update user revision timestamp on Organization changes --- src/db/models/organization.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index 4bb5591..78e381f 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -1,6 +1,7 @@ use serde_json::Value as JsonValue; use uuid::Uuid; +use super::{User, CollectionUser}; #[derive(Debug, Identifiable, Queryable, Insertable)] #[table_name = "organizations"] @@ -114,6 +115,12 @@ use db::schema::users_organizations; /// Database methods impl Organization { pub fn save(&mut self, conn: &DbConn) -> bool { + UserOrganization::find_by_org(&self.uuid, conn) + .iter() + .for_each(|user_org| { + User::update_uuid_revision(&user_org.user_uuid, conn); + }); + match diesel::replace_into(organizations::table) .values(&*self) .execute(&**conn) { @@ -172,7 +179,6 @@ impl UserOrganization { } pub fn to_json_user_details(&self, conn: &DbConn) -> JsonValue { - use super::User; let user = User::find_by_uuid(&self.user_uuid, conn).unwrap(); json!({ @@ -190,7 +196,6 @@ impl UserOrganization { } pub fn to_json_collection_user_details(&self, read_only: &bool, conn: &DbConn) -> JsonValue { - use super::User; let user = User::find_by_uuid(&self.user_uuid, conn).unwrap(); json!({ @@ -209,7 +214,6 @@ impl UserOrganization { let coll_uuids = if self.access_all { vec![] // If we have complete access, no need to fill the array } else { - use super::CollectionUser; let collections = CollectionUser::find_by_organization_and_user_uuid(&self.org_uuid, &self.user_uuid, conn); collections.iter().map(|c| json!({"Id": c.collection_uuid, "ReadOnly": c.read_only})).collect() }; @@ -228,6 +232,8 @@ impl UserOrganization { } pub fn save(&mut self, conn: &DbConn) -> bool { + User::update_uuid_revision(&self.user_uuid, conn); + match diesel::replace_into(users_organizations::table) .values(&*self) .execute(&**conn) { @@ -237,7 +243,7 @@ impl UserOrganization { } pub fn delete(self, conn: &DbConn) -> QueryResult<()> { - use super::CollectionUser; + User::update_uuid_revision(&self.user_uuid, conn); CollectionUser::delete_all_by_user(&self.user_uuid, &conn)?; From 2b2401be197e7a706e4669c9192d80fbcf16ffbb Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 17:31:01 +0100 Subject: [PATCH 34/65] Update affected users revision on cipher and folder change --- src/db/models/cipher.rs | 23 ++++++++++++++++++++++- src/db/models/folder.rs | 2 ++ src/db/models/organization.rs | 23 +++++++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 899e5dd..3faf1ae 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -3,7 +3,7 @@ use serde_json::Value as JsonValue; use uuid::Uuid; -use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrgType, UserOrgStatus}; +use super::{User, Organization, Attachment, FolderCipher, CollectionCipher, UserOrganization, UserOrgType, UserOrgStatus}; #[derive(Debug, Identifiable, Queryable, Insertable, Associations)] #[table_name = "ciphers"] @@ -122,7 +122,23 @@ impl Cipher { json_object } + pub fn update_users_revision(&self, conn: &DbConn) { + match self.user_uuid { + Some(ref user_uuid) => User::update_uuid_revision(&user_uuid, conn), + None => { // Belongs to Organization, need to update affected users + if let Some(ref org_uuid) = self.organization_uuid { + UserOrganization::find_by_cipher_and_org(&self.uuid, &org_uuid, conn) + .iter() + .for_each(|user_org| { + User::update_uuid_revision(&user_org.user_uuid, conn) + }); + } + } + }; + } + pub fn save(&mut self, conn: &DbConn) -> bool { + self.update_users_revision(conn); self.updated_at = Utc::now().naive_utc(); match diesel::replace_into(ciphers::table) @@ -134,6 +150,8 @@ impl Cipher { } pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + self.update_users_revision(conn); + FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?; CollectionCipher::delete_all_by_cipher(&self.uuid, &conn)?; Attachment::delete_all_by_cipher(&self.uuid, &conn)?; @@ -157,6 +175,7 @@ impl Cipher { None => { match folder_uuid { Some(new_folder) => { + self.update_users_revision(conn); let folder_cipher = FolderCipher::new(&new_folder, &self.uuid); folder_cipher.save(&conn).or(Err("Couldn't save folder setting")) }, @@ -169,6 +188,7 @@ impl Cipher { if current_folder == new_folder { Ok(()) //nothing to do } else { + self.update_users_revision(conn); match FolderCipher::find_by_folder_and_cipher(¤t_folder, &self.uuid, &conn) { Some(current_folder) => { current_folder.delete(&conn).or(Err("Failed removing old folder mapping")) @@ -181,6 +201,7 @@ impl Cipher { } }, None => { + self.update_users_revision(conn); match FolderCipher::find_by_folder_and_cipher(¤t_folder, &self.uuid, &conn) { Some(current_folder) => { current_folder.delete(&conn).or(Err("Failed removing old folder mapping")) diff --git a/src/db/models/folder.rs b/src/db/models/folder.rs index d9b90bf..701a7da 100644 --- a/src/db/models/folder.rs +++ b/src/db/models/folder.rs @@ -71,6 +71,7 @@ use db::schema::{folders, folders_ciphers}; /// Database methods impl Folder { pub fn save(&mut self, conn: &DbConn) -> bool { + User::update_uuid_revision(&self.user_uuid, conn); self.updated_at = Utc::now().naive_utc(); match diesel::replace_into(folders::table) @@ -82,6 +83,7 @@ impl Folder { } pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + User::update_uuid_revision(&self.user_uuid, conn); FolderCipher::delete_all_by_folder(&self.uuid, &conn)?; diesel::delete( diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index 78e381f..d46d15d 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -109,8 +109,7 @@ impl UserOrganization { use diesel; use diesel::prelude::*; use db::DbConn; -use db::schema::organizations; -use db::schema::users_organizations; +use db::schema::{organizations, users_organizations, users_collections, ciphers_collections}; /// Database methods impl Organization { @@ -297,6 +296,26 @@ impl UserOrganization { .filter(users_organizations::org_uuid.eq(org_uuid)) .first::(&**conn).ok() } + + pub fn find_by_cipher_and_org(cipher_uuid: &str, org_uuid: &str, conn: &DbConn) -> Vec { + users_organizations::table + .filter(users_organizations::org_uuid.eq(org_uuid)) + .left_join(users_collections::table.on( + users_collections::user_uuid.eq(users_organizations::user_uuid) + )) + .left_join(ciphers_collections::table.on( + ciphers_collections::collection_uuid.eq(users_collections::collection_uuid).and( + ciphers_collections::cipher_uuid.eq(&cipher_uuid) + ) + )) + .filter( + users_organizations::access_all.eq(true).or( // AccessAll.. + ciphers_collections::cipher_uuid.eq(&cipher_uuid) // ..or access to collection with cipher + ) + ) + .select(users_organizations::all_columns) + .load::(&**conn).expect("Error loading user organizations") + } } From df041108f61b9f4b832bd2247d2cd5b12328847e Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 21:13:56 +0100 Subject: [PATCH 35/65] Bump version to 0.13.0 - latest Vault v1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fb5adaf..d37fc88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitwarden_rs" -version = "0.12.0" +version = "0.13.0" authors = ["Daniel García "] [dependencies] From 69a18255c682a7b45f47fd05c73610c817068d0e Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 21 Aug 2018 21:21:54 +0100 Subject: [PATCH 36/65] Bump up version to 1.0.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7a430ea..ea30198 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bitwarden_rs" -version = "0.13.0" +version = "1.0.0" authors = ["Daniel García "] [dependencies] From 346c7630c913bcf95286130e64a1594d8a4235fb Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 17 Aug 2018 14:30:25 +0100 Subject: [PATCH 37/65] Initial implementation of musl build on top of Alpine --- Dockerfile | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/Dockerfile b/Dockerfile index 860e76c..8e7e43d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,19 +25,11 @@ RUN npm run dist \ && mv build /web-vault ########################## BUILD IMAGE ########################## -# We need to use the Rust build image, because -# we need the Rust compiler and Cargo tooling -FROM rust as build - -# Using bundled SQLite, no need to install it -# RUN apt-get update && apt-get install -y\ -# sqlite3\ -# --no-install-recommends\ -# && rm -rf /var/lib/apt/lists/* +# Musl build image for statically compiled binary +FROM clux/muslrust:nightly-2018-06-26 as build # Creates a dummy project used to grab dependencies -RUN USER=root cargo new --bin app -WORKDIR /app +RUN USER=root cargo init --bin # Copies over *only* your manifests and vendored dependencies COPY ./Cargo.* ./ @@ -61,17 +53,15 @@ RUN cargo build --release ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM debian:stretch-slim +FROM alpine:3.8 ENV ROCKET_ENV "staging" ENV ROCKET_WORKERS=10 # Install needed libraries -RUN apt-get update && apt-get install -y\ +RUN apk add \ openssl\ - ca-certificates\ - --no-install-recommends\ - && rm -rf /var/lib/apt/lists/* + ca-certificates RUN mkdir /data VOLUME /data @@ -82,7 +72,7 @@ EXPOSE 80 COPY .env . COPY Rocket.toml . COPY --from=vault /web-vault ./web-vault -COPY --from=build app/target/release/bitwarden_rs . +COPY --from=build /volume/target/x86_64-unknown-linux-musl/release/bitwarden_rs . # Configures the startup! CMD ./bitwarden_rs From ca8e1c646df058fe7ea92653b57c7a00c604708c Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 17 Aug 2018 16:32:37 +0100 Subject: [PATCH 38/65] Update build image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8e7e43d..262d841 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ RUN npm run dist \ ########################## BUILD IMAGE ########################## # Musl build image for statically compiled binary -FROM clux/muslrust:nightly-2018-06-26 as build +FROM clux/muslrust:nightly-2018-07-18 as build # Creates a dummy project used to grab dependencies RUN USER=root cargo init --bin From ef2413a5aa3ca20005558087212ce572b6c26f17 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Fri, 17 Aug 2018 21:25:08 +0100 Subject: [PATCH 39/65] Fix SSL issue, rm cache --- Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 262d841..ed9edbc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,11 +57,13 @@ FROM alpine:3.8 ENV ROCKET_ENV "staging" ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs # Install needed libraries RUN apk add \ - openssl\ - ca-certificates + openssl\ + ca-certificates \ + && rm /var/cache/apk/* RUN mkdir /data VOLUME /data From 007e053e2fdac2327b657c38193da6a3478c4b6a Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 23 Aug 2018 11:06:32 +0100 Subject: [PATCH 40/65] Update the build instruction for new Vault --- BUILD.md | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/BUILD.md b/BUILD.md index 0dcc89f..b8d5fa5 100644 --- a/BUILD.md +++ b/BUILD.md @@ -19,26 +19,20 @@ When run, the server is accessible in [http://localhost:80](http://localhost:80) ### Install the web-vault Download the latest official release from the [releases page](https://github.com/bitwarden/web/releases) and extract it. -Modify `web-vault/settings.Production.json` to look like this: -```json -{ - "appSettings": { - "apiUri": "/api", - "identityUri": "/identity", - "iconsUri": "/icons", - "stripeKey": "", - "braintreeKey": "" - } -} -``` - -Then, run the following from the `web-vault` directory: +Apply the patch file from `docker/set-vault-baseurl.patch`: ```sh -npm install -npx gulp dist:selfHosted +# In the Vault repository directory +git apply /path/to/bitwarden_rs/docker/set-vault-baseurl.patch ``` -Finally copy the contents of the `web-vault/dist` folder into the `bitwarden_rs/web-vault` folder. +Then, build the Vault: +```sh +npm run sub:init +npm install +npm run dist +``` + +Finally copy the contents of the `build` folder into the `bitwarden_rs/web-vault` folder. # Configuration The available configuration options are documented in the default `.env` file, and they can be modified by uncommenting the desired options in that file or by setting their respective environment variables. Look at the README file for the main configuration options available. From 9fad541c87436ca96325a05c22e9fcc72ee90f15 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 23 Aug 2018 12:08:54 +0100 Subject: [PATCH 41/65] Clone repository instead of downloading as suggested by @mqus --- BUILD.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/BUILD.md b/BUILD.md index b8d5fa5..2750124 100644 --- a/BUILD.md +++ b/BUILD.md @@ -17,7 +17,14 @@ cargo build --release When run, the server is accessible in [http://localhost:80](http://localhost:80). ### Install the web-vault -Download the latest official release from the [releases page](https://github.com/bitwarden/web/releases) and extract it. +Clone the git repository at [bitwarden/web](https://github.com/bitwarden/web) and checkout the latest release tag (e.g. v2.1.1): +```sh +# clone the repository +git clone https://github.com/bitwarden/web.git web-vault +cd web-vault +# switch to the latest tag +git checkout "$(git tag | tail -n1)" +``` Apply the patch file from `docker/set-vault-baseurl.patch`: ```sh From 39891e86a07b2a8e686766aa29e1f52bcf1a9279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 24 Aug 2018 17:07:11 +0200 Subject: [PATCH 42/65] Updated dependencies, added Travis CI integration and some badges --- .travis.yml | 7 + Cargo.lock | 557 +++++++++++++++++++++++-------------------------- Cargo.toml | 22 +- README.md | 12 +- rust-toolchain | 2 +- 5 files changed, 290 insertions(+), 310 deletions(-) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c37ede5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +# Copied from Rocket's .travis.yml +language: rust +sudo: required # so we get a VM with higher specs +dist: trusty # so we get a VM with higher specs +cache: cargo +rust: +- nightly diff --git a/Cargo.lock b/Cargo.lock index 634110c..3b8b843 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,7 @@ name = "base64" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -42,7 +42,7 @@ name = "base64" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -51,7 +51,7 @@ name = "base64" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -62,33 +62,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitflags" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bitwarden_rs" -version = "0.11.0" +version = "1.0.0" dependencies = [ - "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "jsonwebtoken 4.0.1", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "multipart 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", + "multipart 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "oath 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_codegen 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket_contrib 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_codegen 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket_contrib 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "u2f 0.1.2 (git+https://github.com/wisespace-io/u2f-rs?rev=193de35093a44)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -100,7 +100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slice-deque 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "slice-deque 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -115,31 +115,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.2.3" +version = "1.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "cc" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chrono" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -174,7 +174,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -182,7 +182,7 @@ name = "core-foundation-sys" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -217,9 +217,9 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -231,9 +231,9 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -243,7 +243,7 @@ name = "crossbeam-utils" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -251,7 +251,7 @@ name = "crossbeam-utils" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -273,10 +273,10 @@ name = "diesel" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libsqlite3-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -321,8 +321,8 @@ name = "dotenv" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -390,10 +390,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "encoding_rs" -version = "0.7.2" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -403,20 +403,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "failure" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "failure_derive" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -442,7 +443,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -523,21 +524,20 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -555,7 +555,7 @@ dependencies = [ [[package]] name = "hyper-tls" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -572,7 +572,7 @@ name = "idna" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -582,7 +582,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -606,7 +606,7 @@ name = "isatty" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -621,12 +621,12 @@ name = "jsonwebtoken" version = "4.0.1" dependencies = [ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -651,8 +651,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "lazycell" @@ -661,7 +664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.42" +version = "0.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -670,18 +673,18 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libsqlite3-sys" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -689,28 +692,28 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mach" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "matches" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -718,7 +721,7 @@ name = "memchr" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -754,7 +757,7 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -776,7 +779,7 @@ name = "mime_guess" version = "2.0.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -792,11 +795,11 @@ dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -818,19 +821,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "multipart" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "buf_redux 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "nickel 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "tiny_http 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -852,7 +855,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", "schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", @@ -865,8 +868,8 @@ name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -877,7 +880,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "groupable 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "mustache 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -900,9 +903,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -923,7 +926,7 @@ name = "num_cpus" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -945,20 +948,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.33" +version = "0.9.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -968,12 +971,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pear" -version = "0.0.19" +version = "0.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "pear_codegen" -version = "0.0.19" +version = "0.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1008,7 +1011,7 @@ version = "0.7.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1016,13 +1019,13 @@ name = "phf_shared" version = "0.7.22" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "pkg-config" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1043,7 +1046,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.8" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1069,10 +1072,10 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1081,27 +1084,17 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.3.22" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1119,8 +1112,8 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1137,7 +1130,7 @@ dependencies = [ "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1149,7 +1142,7 @@ dependencies = [ "aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1187,21 +1180,21 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1216,14 +1209,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rocket" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1235,10 +1228,10 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", - "pear 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)", - "pear_codegen 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "pear 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "pear_codegen 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)", "rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1249,24 +1242,24 @@ dependencies = [ [[package]] name = "rocket_codegen" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rocket_contrib" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "rocket 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1292,6 +1285,11 @@ dependencies = [ "webpki 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ryu" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "safemem" version = "0.2.0" @@ -1307,7 +1305,7 @@ name = "schannel" version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1336,7 +1334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1346,42 +1344,42 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde" -version = "1.0.70" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.70" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_urlencoded" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1411,37 +1409,27 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slab" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slab" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slice-deque" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", - "mach 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "mach 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "smallvec" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "smallvec" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1474,11 +1462,11 @@ dependencies = [ [[package]] name = "syn" -version = "0.14.4" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1492,34 +1480,30 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "take" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "tempdir" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "thread_local" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1527,7 +1511,7 @@ name = "time" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1538,10 +1522,10 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ascii 0.8.7 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1552,13 +1536,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1567,7 +1551,7 @@ name = "tokio-codec" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1577,22 +1561,22 @@ name = "tokio-core" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1600,7 +1584,7 @@ dependencies = [ [[package]] name = "tokio-fs" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1613,38 +1597,21 @@ name = "tokio-io" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-proto" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-reactor" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1658,15 +1625,15 @@ dependencies = [ [[package]] name = "tokio-tcp" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1676,19 +1643,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1707,13 +1674,13 @@ name = "tokio-udp" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1721,7 +1688,7 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1766,13 +1733,13 @@ version = "0.1.2" source = "git+https://github.com/wisespace-io/u2f-rs?rev=193de35093a44#193de35093a44576edba6cc94d9b54f2a1cbdcd1" dependencies = [ "base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "webpki 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1804,7 +1771,7 @@ name = "unicode-bidi" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1849,7 +1816,7 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1863,13 +1830,13 @@ name = "uuid" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vcpkg" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1888,7 +1855,7 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1973,15 +1940,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "85415d2594767338a74a30c1d370b2f3262ec1b4ed2d7bba5b3faf4de40467d9" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum buf_redux 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20c6687a26c9ce967594b78038c06139a0d3a5b3005d16572284d543924a01aa" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" "checksum byte-tools 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0919189ba800c7ffe8778278116b7e0de3905ab81c72abb69c85cbfef7991279" -"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9" -"checksum bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd32989a66957d3f0cba6588f15d4281a733f4e9ffc43fcd2385f57d3bf99ff" -"checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" -"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" -"checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37" +"checksum byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9" +"checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8" +"checksum cc 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "3cc738b39aea615873af94099619ed6915a82575880ed5cdfbf17b63307f1b14" +"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" +"checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" "checksum chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "477eb650753e319be2ae77ec368a58c638f9f0c4d941c39bad95e950fb1d1d0d" @@ -2010,10 +1977,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98fd0f24d1fb71a4a6b9330c8ca04cbd4e7cc5d846b54ca74ff376bc7c9f798d" +"checksum encoding_rs 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2a91912d6f37c6a8fef8a2316a862542d036f13c923ad518b5aca7bcaac7544c" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" -"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" +"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9" +"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" @@ -2029,7 +1996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2" "checksum hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)" = "34a590ca09d341e94cddf8e5af0bbccde205d5fbc2fa3c09dd67c7f85cea59d7" "checksum hyper-sync-rustls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6df6f419a9f116cc93b5f39a5ded1161e088a2c8424c8fcd1d4049193424a4" -"checksum hyper-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a5aa51f6ae9842239b0fac14af5f22123b8432b4cc774a44ff059fcba0f675ca" +"checksum hyper-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffb1bd5e518d3065840ab315dbbf44e4420e5f7d80e2cb93fa6ffffc50522378" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" "checksum iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8e17268922834707e1c29e8badbf9c712c9c43378e1b6a3388946baff10be2" @@ -2038,27 +2005,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3" +"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7" "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" -"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1" +"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum libflate 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7d4b4c7aff5bac19b956f693d0ea0eade8066deb092186ae954fa6ba14daab98" -"checksum libsqlite3-sys 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda" +"checksum libsqlite3-sys 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d3711dfd91a1081d2458ad2d06ea30a8755256e74038be2ad927d94e1c955ca8" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2" -"checksum mach 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b549fa8738e27dcf6c8c5d6d35211e786aa02715a22b60c33b9488fdd634a90b" -"checksum matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "835511bab37c34c47da5cb44844bea2cfde0236db0b506f90ea4224482c9774a" +"checksum log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cba860f648db8e6f269df990180c2217f333472b4a6e901e97446858487971e2" +"checksum mach 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "977262a11cfd76b94da10b8898cea6e9ac391301ab74741e6da6bee13d7df46d" +"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" "checksum migrations_internals 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8cf7c8c4f83fa9f47440c0b4af99973502de55e6e7b875f693bd263e03f93e7e" "checksum migrations_macros 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "79f12499ef7353bdeca2d081bc61edd8351dac09a33af845952009b5a3d68c1a" "checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fe51c8699d2dc522bf8c1ebe26ea2193d151fb54bcdfd7d0318750c189994cd9" +"checksum mime 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4b082692d3f6cf41b453af73839ce3dfc212c4411cbb2441dff80a716e38bd79" "checksum mime_guess 1.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2d4c0961143b8efdcfa29c3ae63281601b446a4a668165454b6c90f8024954c5" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" "checksum mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4fcfcb32d63961fb6f367bfd5d21e4600b92cd310f71f9dca25acae196eb1560" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58" -"checksum multipart 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c934f2af2afbe9277d5be4c46599116e6dd93339871504c578318eeef725aa64" +"checksum multipart 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2745c8c82bc18e8847772ea04bb20d18464e120445a4e3f04771c5cfa24a3e" "checksum mustache 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb004e419334fc9172d0a5ff91c0770bdd6239091b0b343eb5926101f0a7d13" "checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" @@ -2070,26 +2037,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum oath 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6405dc6afe8219020d535f9ad888a12b191bbc8ce1c55f7ee663bde5be80ca" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)" = "d8abc04833dcedef24221a91852931df2f63e3369ae003134e70aff3645775cc" +"checksum openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)" = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129" "checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b" -"checksum pear 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "7fc18e7bc730525f5bcc1069487631a94e5d7389c7f7e63c081cda5c3542ea3e" -"checksum pear_codegen 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ac78ce520b1274885d8415a02ae3f1bb06038e0f6862f105aa97060c6a10fd99" +"checksum pear 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "353fe88ff7a430c0f39ca4ec19e1f8fa0062f696370e8df3080ac40139a63301" +"checksum pear_codegen 0.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0f3ef1db2d855e0c00fad8e5a8216a70df6d9c1c7f7a7ac9f1cf50675142b7" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2" "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b" "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998" "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930" -"checksum pkg-config 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6a52e4dbc8354505ee07e484ab07127e06d87ca6fa7f0a516a2b294e5ad5ad16" +"checksum pkg-config 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "104630aa1c83213cbc76db0703630fcb0421dac3585063be4ce9a8a2feeaa745" "checksum plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a6a0dc3910bc8db877ffed8e457763b317cf880df4ae19109b9f77d277cf6e0" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c65b1ea15bb859d922cade2d1765b4b88beac339cbfad545ef2d2ef8c8215ee6" +"checksum proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035" +"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" "checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" -"checksum rand 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "15a732abf9d20f0ad8eeb6f909bf6868722d9a06e1e50802b6a70351f40b4eb1" -"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" +"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rayon 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a77c51c07654ddd93f6cb543c7a849863b03abc7e82591afda6dc8ad4ac3ac4a" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1" @@ -2099,14 +2065,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d" "checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum reqwest 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2abe46f8e00792693a2488e296c593d1f4ea39bb1178cfce081d6793657575e4" +"checksum reqwest 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "738769ec83daf6c1929dc9dae7d69ed3779b55ae5c356e989dcd3aa677d8486e" "checksum ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2a6dc7fc06a05e6de183c5b97058582e9da2de0c136eafe49609769c507724" -"checksum rocket 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c9010c81b707444fe8de4f83380e6e18bbc2825aac2da797d5553ce3d5b3e702" -"checksum rocket_codegen 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0109d1692a1a05c267ed1eef94ff018bd360e0b6487c8678da4ebbbdbf02cef7" -"checksum rocket_contrib 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4f5eaf6d3324a58b1d961b92fd1ff19c37074c603b8a095daa372089f644f4" +"checksum rocket 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc32be1d093e7b2f9718983318c6bf5a14f43d7ea01a0b5143c3450c90725b9" +"checksum rocket_codegen 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc94e7781a8bc502f3614521ae94b562f209c7537671cb6169cbbe9dbcc6c5e" +"checksum rocket_contrib 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "c1bae00c367de4599157febc585431c7c647c5f0ffa8fa0e9e875edbbb0bd929" "checksum rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0ceb8ce7a5e520de349e1fa172baeba4a9e8d5ef06c47471863530bc4972ee1e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum rustls 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17727f4b991294da2c84d75a43c003151ff58072212768800f66c56ee46dca43" +"checksum ryu 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e7c066b8e2923f05d4718a06d2622f189ff362bc642bfade6c6629f0440f3827" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f" @@ -2115,41 +2082,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920" -"checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124" -"checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2" -"checksum serde_urlencoded 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e703cef904312097cfceab9ce131ff6bbe09e8c964a0703345a5f49238757bc1" +"checksum serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)" = "f218becd0d51dd24297ef804cb9b2de179dcdc2a3ddf8a73b04b4d595d9e6338" +"checksum serde_derive 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)" = "47e3375b02728fa6f8c53cb8c1ad3dea7689e12793b6af399ad1e0e202f91c18" +"checksum serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "44dd2cfde475037451fa99b7e5df77aa3cfd1536575fa8e7a538ab36dcde49ae" +"checksum serde_urlencoded 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "aaed41d9fb1e2f587201b863356590c90c1157495d811430a0c0325fe8169650" "checksum sha-1 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8347606816471548cd60f0abd5ef0d513a81f5202dbdab9c09f17a15b5248484" "checksum sha2 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "84920f9ac881e94e33ec89e1b3dcd36040523a308a92548e01217ce35d8cf6a8" -"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" -"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" -"checksum slice-deque 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "84f8bc1bafa053290fdd4f40eefa15914cb16cf8bee9793312e4389114d15645" -"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" -"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8" +"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" +"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d" +"checksum slice-deque 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d9a5f495de574fc059720e2d7b865676d3812aac26d51f0542a0ef8580a1f2ca" +"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" "checksum state 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" -"checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea" +"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" -"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" +"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" "checksum tiny_http 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a442681f9f72e440be192700eeb2861e4174b9983f16f4877c93a134cb5e5f63" "checksum tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ee337e5f4e501fc32966fec6fe0ca0cc1c237b0b1b14a335f8bfe3c5f06e286" "checksum tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "881e9645b81c2ce95fcb799ded2c29ffb9f25ef5bef909089a420e5961dd8ccb" "checksum tokio-core 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "aeeffbbb94209023feaef3c196a41cbcdafa06b4a6f893f68779bb5e53796f71" -"checksum tokio-executor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8cac2a7883ff3567e9d66bb09100d09b33d90311feca0206c7ca034bc0c55113" -"checksum tokio-fs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "40697ecbea5660df15b15d50a077386477d2f6a35002adf01ce76ff9dd9dce48" +"checksum tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "424f0c87ecd66b863045d84e384cb7ce0ae384d8b065b9f0363d29c0d1b30b2f" +"checksum tokio-fs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b5cbe4ca6e71cb0b62a66e4e6f53a8c06a6eefe46cc5f665ad6f274c9906f135" "checksum tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a5c9635ee806f26d302b8baa1e145689a280d8f5aa8d0552e7344808da54cc21" -"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" -"checksum tokio-reactor 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e00ec63bbec2c97ce1178cb0587b2c438b2f6b09d3ee54a33c45a9cf0d530810" +"checksum tokio-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" -"checksum tokio-tcp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ec9b094851aadd2caf83ba3ad8e8c4ce65a42104f7b94d9e6550023f0407853f" +"checksum tokio-tcp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5b4c329b47f071eb8a746040465fa751bd95e4716e98daef6a9b4e434c17d565" "checksum tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "24ab84f574027b0e875378f31575cf175360891919e93a3490f07e76e00e4efb" -"checksum tokio-timer 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "028b94314065b90f026a21826cffd62a4e40a92cda3e5c069cc7b02e5945f5e9" +"checksum tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c76b4e97a4f61030edff8bd272364e4f731b9f54c7307eb4eb733c3926eb96a" "checksum tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "772f4b04e560117fe3b0a53e490c16ddc8ba6ec437015d91fa385564996ed913" "checksum tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43eb534af6e8f37d43ab1b612660df14755c42bd003c5f8d2475ee78cc4600c0" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" @@ -2173,7 +2136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -"checksum vcpkg 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cbe533e138811704c0e3cbde65a818b35d3240409b4346256c5ede403e082474" +"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum version_check 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7716c242968ee87e5542f8021178248f267f295a5c4803beae8b8b7fd9bc6051" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" diff --git a/Cargo.toml b/Cargo.toml index ea30198..13d13c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,27 +5,27 @@ authors = ["Daniel García "] [dependencies] # Web framework for nightly with a focus on ease-of-use, expressibility, and speed. -rocket = { version = "0.3.15", features = ["tls"] } -rocket_codegen = "0.3.15" -rocket_contrib = "0.3.15" +rocket = { version = "0.3.16", features = ["tls"] } +rocket_codegen = "0.3.16" +rocket_contrib = "0.3.16" # HTTP client -reqwest = "0.8.6" +reqwest = "0.8.8" # multipart/form-data support -multipart = "0.15.0" +multipart = "0.15.2" # A generic serialization/deserialization framework -serde = "1.0.70" -serde_derive = "1.0.70" -serde_json = "1.0.24" +serde = "1.0.74" +serde_derive = "1.0.74" +serde_json = "1.0.26" # A safe, extensible ORM and Query builder diesel = { version = "1.3.2", features = ["sqlite", "chrono", "r2d2"] } diesel_migrations = { version = "1.3.0", features = ["sqlite"] } # Bundled SQLite -libsqlite3-sys = { version = "0.9.1", features = ["bundled"] } +libsqlite3-sys = { version = "0.9.3", features = ["bundled"] } # Crypto library ring = { version = "= 0.11.0", features = ["rsa_signing"] } @@ -34,7 +34,7 @@ ring = { version = "= 0.11.0", features = ["rsa_signing"] } uuid = { version = "0.6.5", features = ["v4"] } # Date and time library for Rust -chrono = "0.4.4" +chrono = "0.4.5" # TOTP library oath = "0.10.2" @@ -52,7 +52,7 @@ u2f = "0.1.2" dotenv = { version = "0.13.0", default-features = false } # Lazy static macro -lazy_static = "1.0.2" +lazy_static = "1.1.0" # Numerical libraries num-traits = "0.2.5" diff --git a/README.md b/README.md index 0ab98eb..3791821 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,19 @@ -This is Bitwarden server API implementation written in rust compatible with [upstream Bitwarden clients](https://bitwarden.com/#download)*, ideal for self-hosted deployment where running official resource-heavy service might not be ideal. +### This is a Bitwarden server API implementation written in Rust compatible with [upstream Bitwarden clients](https://bitwarden.com/#download)*, perfect for self-hosted deployment where running the official resource-heavy service might not be ideal. + +--- + +[![Travis Build Status](https://travis-ci.org/dani-garcia/bitwarden_rs.svg?branch=master)](https://travis-ci.org/dani-garcia/bitwarden_rs) +[![Dependency Status](https://deps.rs/repo/github/dani-garcia/bitwarden_rs/status.svg)](https://deps.rs/repo/github/dani-garcia/bitwarden_rs) +[![GitHub Release](https://img.shields.io/github/release/dani-garcia/bitwarden_rs.svg)](https://github.com/dani-garcia/bitwarden_rs/releases/latest) +[![GPL-3.0 Licensed](https://img.shields.io/github/license/dani-garcia/bitwarden_rs.svg)](https://github.com/dani-garcia/bitwarden_rs/blob/master/LICENSE.txt) +[![Matrix Chat](https://matrix.to/img/matrix-badge.svg)](https://matrix.to/#/#bitwarden_rs:matrix.org) Image is based on [Rust implementation of Bitwarden API](https://github.com/dani-garcia/bitwarden_rs). _*Note, that this project is not associated with the [Bitwarden](https://bitwarden.com/) project nor 8bit Solutions LLC._ +--- + **Table of contents** - [Features](#features) diff --git a/rust-toolchain b/rust-toolchain index d05d08a..509617a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2018-07-18 +nightly-2018-08-23 From c91f80c456b9f7f55cc75a61cf835ab56d9f0a59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 24 Aug 2018 17:11:52 +0200 Subject: [PATCH 43/65] Fixed rust toolchain date --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 509617a..87a7076 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2018-08-23 +nightly-2018-08-24 From 8d1ee859f28563b72fd57011eef230de5834d314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Fri, 24 Aug 2018 19:02:34 +0200 Subject: [PATCH 44/65] Implemented basic support for prelogin and notification negotiation --- src/api/core/accounts.rs | 28 ++++++++++++++++++++++++++++ src/api/core/mod.rs | 1 + src/api/mod.rs | 2 ++ src/api/notifications.rs | 31 +++++++++++++++++++++++++++++++ src/main.rs | 1 + 5 files changed, 63 insertions(+) create mode 100644 src/api/notifications.rs diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index cb6f83f..a551a86 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -275,3 +275,31 @@ fn password_hint(data: JsonUpcase, conn: DbConn) -> EmptyResul None => Ok(()), } } + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct PreloginData { + Email: String, +} + +#[post("/accounts/prelogin", data = "")] +fn prelogin(data: JsonUpcase, conn: DbConn) -> JsonResult { + let data: PreloginData = data.into_inner().data; + + match User::find_by_mail(&data.Email, &conn) { + Some(user) => { + let kdf_type = 0; // PBKDF2: 0 + + let _server_iter = user.password_iterations; + let client_iter = 5000; // TODO: Make iterations user configurable + + + Ok(Json(json!({ + "Kdf": kdf_type, + "KdfIterations": client_iter + }))) + }, + None => err!("Invalid user"), + } +} + diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index 907b053..f465a44 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -25,6 +25,7 @@ pub fn routes() -> Vec { delete_account, revision_date, password_hint, + prelogin, sync, diff --git a/src/api/mod.rs b/src/api/mod.rs index 15f6778..d651497 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -2,11 +2,13 @@ pub(crate) mod core; mod icons; mod identity; mod web; +mod notifications; pub use self::core::routes as core_routes; pub use self::icons::routes as icons_routes; pub use self::identity::routes as identity_routes; pub use self::web::routes as web_routes; +pub use self::notifications::routes as notifications_routes; use rocket::response::status::BadRequest; use rocket_contrib::Json; diff --git a/src/api/notifications.rs b/src/api/notifications.rs new file mode 100644 index 0000000..f24fade --- /dev/null +++ b/src/api/notifications.rs @@ -0,0 +1,31 @@ +use rocket::Route; +use rocket_contrib::Json; + +use db::DbConn; +use api::JsonResult; +use auth::Headers; + +pub fn routes() -> Vec { + routes![negotiate] +} + +#[post("/hub/negotiate")] +fn negotiate(_headers: Headers, _conn: DbConn) -> JsonResult { + use data_encoding::BASE64URL; + use crypto; + + // Store this in db? + let conn_id = BASE64URL.encode(&crypto::get_random(vec![0u8; 16])); + + // TODO: Implement transports + // Rocket WS support: https://github.com/SergioBenitez/Rocket/issues/90 + // Rocket SSE support: https://github.com/SergioBenitez/Rocket/issues/33 + Ok(Json(json!({ + "connectionId": conn_id, + "availableTransports":[ + // {"transport":"WebSockets", "transferFormats":["Text","Binary"]}, + // {"transport":"ServerSentEvents", "transferFormats":["Text"]}, + // {"transport":"LongPolling", "transferFormats":["Text","Binary"]} + ] + }))) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 324d7be..e715031 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,6 +45,7 @@ fn init_rocket() -> Rocket { .mount("/api", api::core_routes()) .mount("/identity", api::identity_routes()) .mount("/icons", api::icons_routes()) + .mount("/notifications", api::notifications_routes()) .manage(db::init_pool()) } From ffec0b065ba6091897f7298a63593f73fe1219a5 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Sat, 25 Aug 2018 09:29:50 +0100 Subject: [PATCH 45/65] Updated build image version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ed9edbc..95f5724 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ RUN npm run dist \ ########################## BUILD IMAGE ########################## # Musl build image for statically compiled binary -FROM clux/muslrust:nightly-2018-07-18 as build +FROM clux/muslrust:nightly-2018-08-24 as build # Creates a dummy project used to grab dependencies RUN USER=root cargo init --bin From c386b3bcf78ae591eab2f4ac5ad4bf26f158140a Mon Sep 17 00:00:00 2001 From: Baelyk Date: Sat, 25 Aug 2018 17:07:59 -0500 Subject: [PATCH 46/65] Add IP and Username to failed login attempts Resolves #119 --- src/api/identity.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/api/identity.rs b/src/api/identity.rs index fb6120e..e1994c0 100644 --- a/src/api/identity.rs +++ b/src/api/identity.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use rocket::request::{self, Form, FormItems, FromForm, FromRequest, Request}; use rocket::{Outcome, Route}; @@ -21,12 +22,12 @@ pub fn routes() -> Vec { } #[post("/connect/token", data = "")] -fn login(connect_data: Form, device_type: DeviceType, conn: DbConn) -> JsonResult { +fn login(connect_data: Form, device_type: DeviceType, conn: DbConn, socket: Option) -> JsonResult { let data = connect_data.get(); match data.grant_type { GrantType::RefreshToken => _refresh_login(data, device_type, conn), - GrantType::Password => _password_login(data, device_type, conn), + GrantType::Password => _password_login(data, device_type, conn, socket), } } @@ -57,7 +58,13 @@ fn _refresh_login(data: &ConnectData, _device_type: DeviceType, conn: DbConn) -> }))) } -fn _password_login(data: &ConnectData, device_type: DeviceType, conn: DbConn) -> JsonResult { +fn _password_login(data: &ConnectData, device_type: DeviceType, conn: DbConn, remote: Option) -> JsonResult { + // Get the ip for error reporting + let ip = match remote { + Some(ip) => ip.ip(), + None => IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), + }; + // Validate scope let scope = data.get("scope"); if scope != "api offline_access" { @@ -68,13 +75,19 @@ fn _password_login(data: &ConnectData, device_type: DeviceType, conn: DbConn) -> let username = data.get("username"); let user = match User::find_by_mail(username, &conn) { Some(user) => user, - None => err!("Username or password is incorrect. Try again."), + None => err!(format!( + "Username or password is incorrect. Try again. IP: {}. Username: {}.", + ip, username + )), }; // Check password let password = data.get("password"); if !user.check_valid_password(password) { - err!("Username or password is incorrect. Try again.") + err!(format!( + "Username or password is incorrect. Try again. IP: {}. Username: {}.", + ip, username + )) } // Let's only use the header and ignore the 'devicetype' parameter From 781056152a4b8e5b6bc70031aafd65bf9d59fd1c Mon Sep 17 00:00:00 2001 From: Kumar Ankur Date: Tue, 28 Aug 2018 02:38:58 +0530 Subject: [PATCH 47/65] Support password history #155 (#156) * Password History Support (#155) * down.sql logic not required as per review comments --- migrations/2018-08-27-172114_update_ciphers/down.sql | 0 migrations/2018-08-27-172114_update_ciphers/up.sql | 3 +++ src/api/core/ciphers.rs | 4 ++++ src/db/models/cipher.rs | 8 ++++++++ src/db/schema.rs | 1 + 5 files changed, 16 insertions(+) create mode 100644 migrations/2018-08-27-172114_update_ciphers/down.sql create mode 100644 migrations/2018-08-27-172114_update_ciphers/up.sql diff --git a/migrations/2018-08-27-172114_update_ciphers/down.sql b/migrations/2018-08-27-172114_update_ciphers/down.sql new file mode 100644 index 0000000..e69de29 diff --git a/migrations/2018-08-27-172114_update_ciphers/up.sql b/migrations/2018-08-27-172114_update_ciphers/up.sql new file mode 100644 index 0000000..624efd6 --- /dev/null +++ b/migrations/2018-08-27-172114_update_ciphers/up.sql @@ -0,0 +1,3 @@ +ALTER TABLE ciphers + ADD COLUMN + password_history TEXT; \ No newline at end of file diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index beb68e0..eefd167 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -112,6 +112,8 @@ struct CipherData { Identity: Option, Favorite: Option, + + PasswordHistory: Option, } #[post("/ciphers/admin", data = "")] @@ -177,6 +179,7 @@ fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Head type_data["Name"] = Value::String(data.Name.clone()); type_data["Notes"] = data.Notes.clone().map(Value::String).unwrap_or(Value::Null); type_data["Fields"] = data.Fields.clone().unwrap_or(Value::Null); + type_data["PasswordHistory"] = data.PasswordHistory.clone().unwrap_or(Value::Null); // TODO: ******* Backwards compat end ********** cipher.favorite = data.Favorite.unwrap_or(false); @@ -184,6 +187,7 @@ fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Head cipher.notes = data.Notes; cipher.fields = data.Fields.map(|f| f.to_string()); cipher.data = type_data.to_string(); + cipher.password_history = data.PasswordHistory.map(|f| f.to_string()); cipher.save(&conn); diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 3faf1ae..917a76e 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -32,6 +32,7 @@ pub struct Cipher { pub data: String, pub favorite: bool, + pub password_history: Option, } /// Local methods @@ -55,6 +56,7 @@ impl Cipher { fields: None, data: String::new(), + password_history: None, } } } @@ -77,6 +79,10 @@ impl Cipher { let fields_json: JsonValue = if let Some(ref fields) = self.fields { serde_json::from_str(fields).unwrap() } else { JsonValue::Null }; + + let password_history_json: JsonValue = if let Some(ref password_history) = self.password_history { + serde_json::from_str(password_history).unwrap() + } else { JsonValue::Null }; let mut data_json: JsonValue = serde_json::from_str(&self.data).unwrap(); @@ -108,6 +114,8 @@ impl Cipher { "Object": "cipher", "Edit": true, + + "PasswordHistory": password_history_json, }); let key = match self.type_ { diff --git a/src/db/schema.rs b/src/db/schema.rs index f39701b..5382e69 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -21,6 +21,7 @@ table! { fields -> Nullable, data -> Text, favorite -> Bool, + password_history -> Nullable, } } From 6660b0aef391f6bc20ce1991ff843a85d63b3afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 28 Aug 2018 03:21:22 +0200 Subject: [PATCH 48/65] Updated web vault to version 2.2 --- Dockerfile | 6 +++--- docker/set-vault-baseurl.patch | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 860e76c..9ec3355 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ####################### VAULT BUILD IMAGE ####################### FROM node:8-alpine as vault -ENV VAULT_VERSION "v2.1.1" +ENV VAULT_VERSION "v2.2.0" ENV URL "https://github.com/bitwarden/web.git" @@ -47,7 +47,7 @@ COPY ./rust-toolchain ./rust-toolchain # Builds your dependencies and removes the # dummy project, except the target folder # This folder contains the compiled dependencies -RUN cargo build --release +RUN cargo build --release --features vendored_openssl RUN find . -not -path "./target*" -delete # Copies the complete project @@ -56,7 +56,7 @@ COPY . . # Builds again, this time it'll just be # your actual source files being built -RUN cargo build --release +RUN cargo build --release --features vendored_openssl ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image diff --git a/docker/set-vault-baseurl.patch b/docker/set-vault-baseurl.patch index 492f6b6..5e87202 100644 --- a/docker/set-vault-baseurl.patch +++ b/docker/set-vault-baseurl.patch @@ -1,7 +1,7 @@ --- a/src/app/services/services.module.ts +++ b/src/app/services/services.module.ts -@@ -116,17 +116,15 @@ const exportService = new ExportService(folderService, cipherService, apiService - const importService = new ImportService(cipherService, folderService, apiService, i18nService, collectionService); +@@ -120,20 +120,17 @@ const notificationsService = new NotificationsService(userService, syncService, + const environmentService = new EnvironmentService(apiService, storageService, notificationsService); const auditService = new AuditService(cryptoFunctionService, apiService); -const analytics = new Analytics(window, () => platformUtilsService.isDev() || platformUtilsService.isSelfHost(), @@ -15,9 +15,14 @@ - const isDev = platformUtilsService.isDev(); - if (!isDev && platformUtilsService.isSelfHost()) { - environmentService.baseUrl = window.location.origin; +- } else { +- environmentService.notificationsUrl = isDev ? 'http://localhost:61840' : +- 'https://notifications.bitwarden.com'; // window.location.origin + '/notifications'; - } + const isDev = false; + environmentService.baseUrl = window.location.origin; ++ environmentService.notificationsUrl = window.location.origin + '/notifications'; ++ await apiService.setUrls({ base: isDev ? null : window.location.origin, api: isDev ? 'http://localhost:4000' : null, From 761a0a3393f2ea296762b119531974505e6c8bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 28 Aug 2018 12:54:57 +0200 Subject: [PATCH 49/65] Removed accidental change to Dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9ec3355..c2b9f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,7 +47,7 @@ COPY ./rust-toolchain ./rust-toolchain # Builds your dependencies and removes the # dummy project, except the target folder # This folder contains the compiled dependencies -RUN cargo build --release --features vendored_openssl +RUN cargo build --release RUN find . -not -path "./target*" -delete # Copies the complete project @@ -56,7 +56,7 @@ COPY . . # Builds again, this time it'll just be # your actual source files being built -RUN cargo build --release --features vendored_openssl +RUN cargo build --release ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image From 3cfdf9b5858b7c2e5c0868fc4bc42f9fd1a14f80 Mon Sep 17 00:00:00 2001 From: mprasil Date: Tue, 28 Aug 2018 23:48:53 +0100 Subject: [PATCH 50/65] Add DELETE handlers fo cipher and attachment deletion (fixes #158) (#160) --- src/api/core/ciphers.rs | 10 ++++++++++ src/api/core/mod.rs | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index eefd167..21b01bb 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -520,6 +520,11 @@ fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn) } +#[delete("/ciphers//attachment//admin")] +fn delete_attachment_admin(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn) +} + #[post("/ciphers//delete")] fn delete_cipher_post(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { _delete_cipher_by_uuid(&uuid, &headers, &conn) @@ -535,6 +540,11 @@ fn delete_cipher(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { _delete_cipher_by_uuid(&uuid, &headers, &conn) } +#[delete("/ciphers//admin")] +fn delete_cipher_admin(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { + _delete_cipher_by_uuid(&uuid, &headers, &conn) +} + #[delete("/ciphers", data = "")] fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { let data: Value = data.into_inner().data; diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index f465a44..d2ad208 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -43,6 +43,7 @@ pub fn routes() -> Vec { delete_attachment_post, delete_attachment_post_admin, delete_attachment, + delete_attachment_admin, post_cipher_admin, post_cipher_share, put_cipher_share, @@ -52,6 +53,7 @@ pub fn routes() -> Vec { delete_cipher_post, delete_cipher_post_admin, delete_cipher, + delete_cipher_admin, delete_cipher_selected, delete_cipher_selected_post, delete_all, From 062ae4dd59a4e851900d63d0ba04a46e20a9f49d Mon Sep 17 00:00:00 2001 From: mprasil Date: Wed, 29 Aug 2018 14:22:03 +0100 Subject: [PATCH 51/65] Allow non-Admin user to share to collection (fixes #157) (#159) * Allow non-Admin user to share to collection (fixes #157) * Better handling of collection sharing --- src/api/core/ciphers.rs | 42 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 21b01bb..fe6caf4 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -127,26 +127,24 @@ fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn) -> let data: CipherData = data.into_inner().data; let mut cipher = Cipher::new(data.Type, data.Name.clone()); - update_cipher_from_data(&mut cipher, data, &headers, true, &conn)?; + update_cipher_from_data(&mut cipher, data, &headers, false, &conn)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } -fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, is_new_or_shared: bool, conn: &DbConn) -> EmptyResult { - if is_new_or_shared { - if let Some(org_id) = data.OrganizationId { - match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { - None => err!("You don't have permission to add item to organization"), - Some(org_user) => if org_user.has_full_access() { - cipher.organization_uuid = Some(org_id); - cipher.user_uuid = None; - } else { - err!("You don't have permission to add cipher directly to organization") - } +fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, shared_to_collection: bool, conn: &DbConn) -> EmptyResult { + if let Some(org_id) = data.OrganizationId { + match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { + None => err!("You don't have permission to add item to organization"), + Some(org_user) => if shared_to_collection || org_user.has_full_access() { + cipher.organization_uuid = Some(org_id); + cipher.user_uuid = None; + } else { + err!("You don't have permission to add cipher directly to organization") } - } else { - cipher.user_uuid = Some(headers.user.uuid.clone()); } + } else { + cipher.user_uuid = Some(headers.user.uuid.clone()); } if let Some(ref folder_id) = data.FolderId { @@ -243,7 +241,7 @@ fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbC .map(|i| folders[*i].uuid.clone()); let mut cipher = Cipher::new(cipher_data.Type, cipher_data.Name.clone()); - update_cipher_from_data(&mut cipher, cipher_data, &headers, true, &conn)?; + update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &conn)?; cipher.move_to_folder(folder_uuid, &headers.user.uuid.clone(), &conn).ok(); } @@ -422,22 +420,28 @@ fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, co None => err!("Cipher doesn't exist") }; - match data.Cipher.OrganizationId { + match data.Cipher.OrganizationId.clone() { None => err!("Organization id not provided"), - Some(_) => { - update_cipher_from_data(&mut cipher, data.Cipher, &headers, true, &conn)?; + Some(organization_uuid) => { + let mut shared_to_collection = false; for uuid in &data.CollectionIds { match Collection::find_by_uuid(uuid, &conn) { None => err!("Invalid collection ID provided"), Some(collection) => { if collection.is_writable_by_user(&headers.user.uuid, &conn) { - CollectionCipher::save(&cipher.uuid.clone(), &collection.uuid, &conn); + if collection.org_uuid == organization_uuid { + CollectionCipher::save(&cipher.uuid.clone(), &collection.uuid, &conn); + shared_to_collection = true; + } else { + err!("Collection does not belong to organization") + } } else { err!("No rights to modify the collection") } } } } + update_cipher_from_data(&mut cipher, data.Cipher, &headers, shared_to_collection, &conn)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } From fe473b9e75342c76a2002f9a24bff4b218e91aae Mon Sep 17 00:00:00 2001 From: Baelyk Date: Wed, 29 Aug 2018 08:22:19 -0500 Subject: [PATCH 52/65] `Attachment::save()` returns Result instead of bool (#161) Returning a result instead of a bool as per #6 --- src/api/core/ciphers.rs | 13 ++++++++----- src/db/models/attachment.rs | 12 +++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index fe6caf4..f7d74d8 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -375,11 +375,11 @@ fn put_cipher_share_seleted(data: JsonUpcase, headers: if data.Ciphers.len() == 0 { err!("You must select at least one cipher.") } - + if data.CollectionIds.len() == 0 { err!("You must select at least one collection.") } - + for cipher in data.Ciphers.iter() { match cipher.Id { Some(ref id) => cipher_ids.push(id.to_string()), @@ -388,7 +388,7 @@ fn put_cipher_share_seleted(data: JsonUpcase, headers: } let attachments = Attachment::find_by_ciphers(cipher_ids, &conn); - + if attachments.len() > 0 { err!("Ciphers should not have any attachments.") } @@ -492,7 +492,10 @@ fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers }; let attachment = Attachment::new(file_name, cipher.uuid.clone(), name, size); - attachment.save(&conn); + match attachment.save(&conn) { + Ok(()) => (), + Err(_) => println!("Error: failed to save attachment") + }; }).expect("Error processing multipart data"); Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) @@ -654,7 +657,7 @@ fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn) -> for f in Folder::find_by_user(&user.uuid, &conn) { if f.delete(&conn).is_err() { err!("Failed deleting folder") - } + } } Ok(()) diff --git a/src/db/models/attachment.rs b/src/db/models/attachment.rs index 66d5b72..9c8eeef 100644 --- a/src/db/models/attachment.rs +++ b/src/db/models/attachment.rs @@ -53,13 +53,11 @@ use db::schema::attachments; /// Database methods impl Attachment { - pub fn save(&self, conn: &DbConn) -> bool { - match diesel::replace_into(attachments::table) + pub fn save(&self, conn: &DbConn) -> QueryResult<()> { + diesel::replace_into(attachments::table) .values(self) - .execute(&**conn) { - Ok(1) => true, // One row inserted - _ => false, - } + .execute(&**conn) + .and(Ok(())) } pub fn delete(self, conn: &DbConn) -> QueryResult<()> { @@ -67,7 +65,7 @@ impl Attachment { use std::{thread, time}; let mut retries = 10; - + loop { match diesel::delete( attachments::table.filter( From 1a5c1979e3a00515e4b23c0757e6d3379f268146 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 30 Aug 2018 10:38:38 +0100 Subject: [PATCH 53/65] Move Alpine Dockerfile to separate file --- Dockerfile | 28 +++++++++++------ Dockerfile.alpine | 80 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 Dockerfile.alpine diff --git a/Dockerfile b/Dockerfile index 3a8b4b1..c2b9f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,11 +25,19 @@ RUN npm run dist \ && mv build /web-vault ########################## BUILD IMAGE ########################## -# Musl build image for statically compiled binary -FROM clux/muslrust:nightly-2018-08-24 as build +# We need to use the Rust build image, because +# we need the Rust compiler and Cargo tooling +FROM rust as build + +# Using bundled SQLite, no need to install it +# RUN apt-get update && apt-get install -y\ +# sqlite3\ +# --no-install-recommends\ +# && rm -rf /var/lib/apt/lists/* # Creates a dummy project used to grab dependencies -RUN USER=root cargo init --bin +RUN USER=root cargo new --bin app +WORKDIR /app # Copies over *only* your manifests and vendored dependencies COPY ./Cargo.* ./ @@ -53,17 +61,17 @@ RUN cargo build --release ######################## RUNTIME IMAGE ######################## # Create a new stage with a minimal image # because we already have a binary built -FROM alpine:3.8 +FROM debian:stretch-slim ENV ROCKET_ENV "staging" ENV ROCKET_WORKERS=10 -ENV SSL_CERT_DIR=/etc/ssl/certs # Install needed libraries -RUN apk add \ - openssl\ - ca-certificates \ - && rm /var/cache/apk/* +RUN apt-get update && apt-get install -y\ + openssl\ + ca-certificates\ + --no-install-recommends\ + && rm -rf /var/lib/apt/lists/* RUN mkdir /data VOLUME /data @@ -74,7 +82,7 @@ EXPOSE 80 COPY .env . COPY Rocket.toml . COPY --from=vault /web-vault ./web-vault -COPY --from=build /volume/target/x86_64-unknown-linux-musl/release/bitwarden_rs . +COPY --from=build app/target/release/bitwarden_rs . # Configures the startup! CMD ./bitwarden_rs diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 0000000..3a8b4b1 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,80 @@ +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +FROM node:8-alpine as vault + +ENV VAULT_VERSION "v2.2.0" + +ENV URL "https://github.com/bitwarden/web.git" + +RUN apk add --update-cache --upgrade \ + curl \ + git \ + tar + +RUN git clone -b $VAULT_VERSION --depth 1 $URL web-build +WORKDIR /web-build + +COPY /docker/set-vault-baseurl.patch /web-build/ +RUN git apply set-vault-baseurl.patch + +RUN npm run sub:init && npm install + +RUN npm run dist \ + && mv build /web-vault + +########################## BUILD IMAGE ########################## +# Musl build image for statically compiled binary +FROM clux/muslrust:nightly-2018-08-24 as build + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo init --bin + +# Copies over *only* your manifests and vendored dependencies +COPY ./Cargo.* ./ +COPY ./libs ./libs +COPY ./rust-toolchain ./rust-toolchain + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +RUN cargo build --release +RUN find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Builds again, this time it'll just be +# your actual source files being built +RUN cargo build --release + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM alpine:3.8 + +ENV ROCKET_ENV "staging" +ENV ROCKET_WORKERS=10 +ENV SSL_CERT_DIR=/etc/ssl/certs + +# Install needed libraries +RUN apk add \ + openssl\ + ca-certificates \ + && rm /var/cache/apk/* + +RUN mkdir /data +VOLUME /data +EXPOSE 80 + +# Copies the files from the context (env file and web-vault) +# and the binary from the "build" stage to the current stage +COPY .env . +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build /volume/target/x86_64-unknown-linux-musl/release/bitwarden_rs . + +# Configures the startup! +CMD ./bitwarden_rs From d336d89b83906ed33c8774e9b191ca4b3c47b643 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 30 Aug 2018 11:12:29 +0100 Subject: [PATCH 54/65] Fix editing shared cipher (fixes #164) --- src/api/core/ciphers.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index f7d74d8..f9e090c 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -136,7 +136,9 @@ fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Head if let Some(org_id) = data.OrganizationId { match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { None => err!("You don't have permission to add item to organization"), - Some(org_user) => if shared_to_collection || org_user.has_full_access() { + Some(org_user) => if shared_to_collection + || org_user.has_full_access() + || cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { cipher.organization_uuid = Some(org_id); cipher.user_uuid = None; } else { From 1bced97e0495023b2140396ec1370b3f93066c4d Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 3 Sep 2018 10:53:52 +0100 Subject: [PATCH 55/65] Add info on running over HTTP (documentation for #153) --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 3791821..1447c80 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ _*Note, that this project is not associated with the [Bitwarden](https://bitward - [Changing user email](#changing-user-email) - [Creating organization](#creating-organization) - [Inviting users into organization](#inviting-users-into-organization) + - [Running on unencrypted connection](#running-on-unencrypted-connection) - [Get in touch](#get-in-touch) ## Features @@ -366,6 +367,12 @@ We use upstream Vault interface directly without any (significant) changes, this The users must already be registered on your server to invite them, because we can't send the invitation via email. The invited users won't get the invitation email, instead they will appear in the interface as if they already accepted the invitation. Organization admin then just needs to confirm them to be proper Organization members and to give them access to the shared secrets. +### Running on unencrypted connection + +It is strongly recommended to run bitwarden_rs service over HTTPS. However the server itself while supporting it does not strictly require such setup. This makes it a bit easier to spin up the service in cases where you can generally trust the connection (internal and secure network, access over VPN,..) or when you want to put the service behind HTTP proxy, that will do the encryption on the proxy end. + +Running over HTTP is still reasonably secure provided you use really strong master password and that you avoid using web Vault over connection that is vulnerable to MITM attacks where attacker could inject javascript into your interface. However some forms of 2FA might not work in this setup and [Vault doesn't work in this configuration in Chrome](https://github.com/bitwarden/web/issues/254). + ## Get in touch To ask an question, [raising an issue](https://github.com/dani-garcia/bitwarden_rs/issues/new) is fine, also please report any bugs spotted here. From 53e8f78af600faf8eb813a3364ac7c48353dc8fc Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 3 Sep 2018 10:59:59 +0100 Subject: [PATCH 56/65] Link to the https setup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1447c80..358941a 100644 --- a/README.md +++ b/README.md @@ -369,7 +369,7 @@ The users must already be registered on your server to invite them, because we c ### Running on unencrypted connection -It is strongly recommended to run bitwarden_rs service over HTTPS. However the server itself while supporting it does not strictly require such setup. This makes it a bit easier to spin up the service in cases where you can generally trust the connection (internal and secure network, access over VPN,..) or when you want to put the service behind HTTP proxy, that will do the encryption on the proxy end. +It is strongly recommended to run bitwarden_rs service over HTTPS. However the server itself while [supporting it](#enabling-https) does not strictly require such setup. This makes it a bit easier to spin up the service in cases where you can generally trust the connection (internal and secure network, access over VPN,..) or when you want to put the service behind HTTP proxy, that will do the encryption on the proxy end. Running over HTTP is still reasonably secure provided you use really strong master password and that you avoid using web Vault over connection that is vulnerable to MITM attacks where attacker could inject javascript into your interface. However some forms of 2FA might not work in this setup and [Vault doesn't work in this configuration in Chrome](https://github.com/bitwarden/web/issues/254). From 049aa33f179076a6b1ba3b71351b5d7b95ef4fdc Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 4 Sep 2018 11:24:53 +0100 Subject: [PATCH 57/65] Fix editing users in Organization --- src/api/core/organizations.rs | 47 +++++++++++++++++++---------------- src/db/models/organization.rs | 7 ++++++ 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index c2ecde2..dd0db2c 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -408,11 +408,11 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade Ok(()) } -#[post("/organizations//users//confirm", data = "")] -fn confirm_invite(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { +#[post("/organizations//users//confirm", data = "")] +fn confirm_invite(org_id: String, org_user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { let data = data.into_inner().data; - let mut user_to_confirm = match UserOrganization::find_by_uuid(&user_id, &conn) { + let mut user_to_confirm = match UserOrganization::find_by_uuid(&org_user_id, &conn) { Some(user) => user, None => err!("Failed to find user membership") }; @@ -441,9 +441,9 @@ fn confirm_invite(org_id: String, user_id: String, data: JsonUpcase, head Ok(()) } -#[get("/organizations//users/")] -fn get_user(org_id: String, user_id: String, _headers: AdminHeaders, conn: DbConn) -> JsonResult { - let user = match UserOrganization::find_by_uuid(&user_id, &conn) { +#[get("/organizations//users/")] +fn get_user(org_id: String, org_user_id: String, _headers: AdminHeaders, conn: DbConn) -> JsonResult { + let user = match UserOrganization::find_by_uuid(&org_user_id, &conn) { Some(user) => user, None => err!("Failed to find user membership") }; @@ -464,13 +464,13 @@ struct EditUserData { AccessAll: bool, } -#[put("/organizations//users/", data = "", rank = 1)] -fn put_organization_user(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { - edit_user(org_id, user_id, data, headers, conn) +#[put("/organizations//users/", data = "", rank = 1)] +fn put_organization_user(org_id: String, org_user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + edit_user(org_id, org_user_id, data, headers, conn) } -#[post("/organizations//users/", data = "", rank = 1)] -fn edit_user(org_id: String, user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { +#[post("/organizations//users/", data = "", rank = 1)] +fn edit_user(org_id: String, org_user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { let data: EditUserData = data.into_inner().data; let new_type = match UserOrgType::from_str(&data.Type.into_string()) { @@ -478,19 +478,22 @@ fn edit_user(org_id: String, user_id: String, data: JsonUpcase, he None => err!("Invalid type") }; - let mut user_to_edit = match UserOrganization::find_by_uuid(&user_id, &conn) { + let mut user_to_edit = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { Some(user) => user, None => err!("The specified user isn't member of the organization") }; - if new_type != UserOrgType::User as i32 && + if new_type != user_to_edit.type_ as i32 && ( + user_to_edit.type_ >= UserOrgType::Admin as i32 || + new_type >= UserOrgType::Admin as i32 + ) && headers.org_user_type != UserOrgType::Owner as i32 { - err!("Only Owners can grant Admin or Owner type") + err!("Only Owners can grant and remove Admin or Owner privileges") } - if user_to_edit.type_ != UserOrgType::User as i32 && + if user_to_edit.type_ == UserOrgType::Owner as i32 && headers.org_user_type != UserOrgType::Owner as i32 { - err!("Only Owners can edit Admin or Owner") + err!("Only Owners can edit Owner users") } if user_to_edit.type_ == UserOrgType::Owner as i32 && @@ -535,9 +538,9 @@ fn edit_user(org_id: String, user_id: String, data: JsonUpcase, he Ok(()) } -#[delete("/organizations//users/")] -fn delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { - let user_to_delete = match UserOrganization::find_by_uuid(&user_id, &conn) { +#[delete("/organizations//users/")] +fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + let user_to_delete = match UserOrganization::find_by_uuid(&org_user_id, &conn) { Some(user) => user, None => err!("User to delete isn't member of the organization") }; @@ -564,7 +567,7 @@ fn delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbC } } -#[post("/organizations//users//delete")] -fn post_delete_user(org_id: String, user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { - delete_user(org_id, user_id, headers, conn) +#[post("/organizations//users//delete")] +fn post_delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { + delete_user(org_id, org_user_id, headers, conn) } \ No newline at end of file diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index d46d15d..18ac2a0 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -270,6 +270,13 @@ impl UserOrganization { .first::(&**conn).ok() } + pub fn find_by_uuid_and_org(uuid: &str, org_uuid: &str, conn: &DbConn) -> Option { + users_organizations::table + .filter(users_organizations::uuid.eq(uuid)) + .filter(users_organizations::org_uuid.eq(org_uuid)) + .first::(&**conn).ok() + } + pub fn find_by_user(user_uuid: &str, conn: &DbConn) -> Vec { users_organizations::table .filter(users_organizations::user_uuid.eq(user_uuid)) From db111ae2a09f7921a0c81f49cd7538d7002f6139 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 4 Sep 2018 13:37:44 +0100 Subject: [PATCH 58/65] Check properly the user membership in Organization --- src/api/core/organizations.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index dd0db2c..449f15f 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -217,7 +217,7 @@ fn delete_organization_collection_user(org_id: String, col_id: String, org_user_ } }; - match UserOrganization::find_by_uuid(&org_user_id, &conn) { + match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { None => err!("User not found in organization"), Some(user_org) => { match CollectionUser::find_by_collection_and_user(&collection.uuid, &user_org.user_uuid, &conn) { @@ -412,15 +412,11 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade fn confirm_invite(org_id: String, org_user_id: String, data: JsonUpcase, headers: AdminHeaders, conn: DbConn) -> EmptyResult { let data = data.into_inner().data; - let mut user_to_confirm = match UserOrganization::find_by_uuid(&org_user_id, &conn) { + let mut user_to_confirm = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { Some(user) => user, - None => err!("Failed to find user membership") + None => err!("The specified user isn't a member of the organization") }; - if user_to_confirm.org_uuid != org_id { - err!("The specified user isn't a member of the organization") - } - if user_to_confirm.type_ != UserOrgType::User as i32 && headers.org_user_type != UserOrgType::Owner as i32 { err!("Only Owners can confirm Admins or Owners") @@ -443,15 +439,11 @@ fn confirm_invite(org_id: String, org_user_id: String, data: JsonUpcase, #[get("/organizations//users/")] fn get_user(org_id: String, org_user_id: String, _headers: AdminHeaders, conn: DbConn) -> JsonResult { - let user = match UserOrganization::find_by_uuid(&org_user_id, &conn) { + let user = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { Some(user) => user, - None => err!("Failed to find user membership") + None => err!("The specified user isn't a member of the organization") }; - if user.org_uuid != org_id { - err!("The specified user isn't a member of the organization") - } - Ok(Json(user.to_json_details(&conn))) } @@ -540,7 +532,7 @@ fn edit_user(org_id: String, org_user_id: String, data: JsonUpcase #[delete("/organizations//users/")] fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { - let user_to_delete = match UserOrganization::find_by_uuid(&org_user_id, &conn) { + let user_to_delete = match UserOrganization::find_by_uuid_and_org(&org_user_id, &org_id, &conn) { Some(user) => user, None => err!("User to delete isn't member of the organization") }; From c58682e3fbcf76ffa0e99ae6ab342d8c794ce0a5 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 4 Sep 2018 16:10:26 +0100 Subject: [PATCH 59/65] Fix the logic in user edditing --- src/api/core/organizations.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 449f15f..3253eb5 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -476,8 +476,8 @@ fn edit_user(org_id: String, org_user_id: String, data: JsonUpcase }; if new_type != user_to_edit.type_ as i32 && ( - user_to_edit.type_ >= UserOrgType::Admin as i32 || - new_type >= UserOrgType::Admin as i32 + user_to_edit.type_ <= UserOrgType::Admin as i32 || + new_type <= UserOrgType::Admin as i32 ) && headers.org_user_type != UserOrgType::Owner as i32 { err!("Only Owners can grant and remove Admin or Owner privileges") From ec05f14f5a6bfb598252744a27332dea3fae5944 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Mon, 10 Sep 2018 14:51:40 +0100 Subject: [PATCH 60/65] Implement poor man's invitation via Organization invitation --- README.md | 17 ++++- .../2018-09-10-111213_add_invites/down.sql | 1 + .../2018-09-10-111213_add_invites/up.sql | 3 + src/api/core/accounts.rs | 34 +++++++--- src/api/core/organizations.rs | 66 ++++++++++++------- src/db/models/mod.rs | 2 +- src/db/models/organization.rs | 9 ++- src/db/models/user.rs | 50 +++++++++++++- src/db/schema.rs | 6 ++ src/main.rs | 2 + 10 files changed, 155 insertions(+), 35 deletions(-) create mode 100644 migrations/2018-09-10-111213_add_invites/down.sql create mode 100644 migrations/2018-09-10-111213_add_invites/up.sql diff --git a/README.md b/README.md index 358941a..4b27f35 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ _*Note, that this project is not associated with the [Bitwarden](https://bitward - [Updating the bitwarden image](#updating-the-bitwarden-image) - [Configuring bitwarden service](#configuring-bitwarden-service) - [Disable registration of new users](#disable-registration-of-new-users) + - [Disable invitations](#disable-invitations) - [Enabling HTTPS](#enabling-https) - [Enabling U2F authentication](#enabling-u2f-authentication) - [Changing persistent data location](#changing-persistent-data-location) @@ -136,6 +137,20 @@ docker run -d --name bitwarden \ -p 80:80 \ mprasil/bitwarden:latest ``` +Note: While users can't register on their own, they can still be invited by already registered users. Read bellow if you also want to disable that. + +### Disable invitations + +Even when registration is disabled, organization administrators or owners can invite users to join organization. This won't send email invitation to the users, but after they are invited, they can register with the invited email even if `SIGNUPS_ALLOWED` is actually set to `false`. You can disable this functionality completely by setting `INVITATIONS_ALLOWED` env variable to `false`: + +```sh +docker run -d --name bitwarden \ + -e SIGNUPS_ALLOWED=false \ + -e INVITATIONS_ALLOWED=false \ + -v /bw-data/:/data/ \ + -p 80:80 \ + mprasil/bitwarden:latest +``` ### Enabling HTTPS To enable HTTPS, you need to configure the `ROCKET_TLS`. @@ -365,7 +380,7 @@ We use upstream Vault interface directly without any (significant) changes, this ### Inviting users into organization -The users must already be registered on your server to invite them, because we can't send the invitation via email. The invited users won't get the invitation email, instead they will appear in the interface as if they already accepted the invitation. Organization admin then just needs to confirm them to be proper Organization members and to give them access to the shared secrets. +If you have [invitations disabled](#disable-invitations), the users must already be registered on your server to invite them. The invited users won't get the invitation email, instead they will appear in the interface as if they already accepted the invitation. (if the user has already registered) Organization admin then just needs to confirm them to be proper Organization members and to give them access to the shared secrets. ### Running on unencrypted connection diff --git a/migrations/2018-09-10-111213_add_invites/down.sql b/migrations/2018-09-10-111213_add_invites/down.sql new file mode 100644 index 0000000..af3776c --- /dev/null +++ b/migrations/2018-09-10-111213_add_invites/down.sql @@ -0,0 +1 @@ +DROP TABLE invitations; \ No newline at end of file diff --git a/migrations/2018-09-10-111213_add_invites/up.sql b/migrations/2018-09-10-111213_add_invites/up.sql new file mode 100644 index 0000000..b42e9a2 --- /dev/null +++ b/migrations/2018-09-10-111213_add_invites/up.sql @@ -0,0 +1,3 @@ +CREATE TABLE invitations ( + email TEXT NOT NULL PRIMARY KEY +); \ No newline at end of file diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index a551a86..ef0e917 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -30,15 +30,33 @@ struct KeysData { fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { let data: RegisterData = data.into_inner().data; - if !CONFIG.signups_allowed { - err!("Signups not allowed") - } - if User::find_by_mail(&data.Email, &conn).is_some() { - err!("Email already exists") - } - - let mut user = User::new(data.Email, data.Key, data.MasterPasswordHash); + let mut user = match User::find_by_mail(&data.Email, &conn) { + Some(mut user) => { + if Invitation::take(&data.Email, &conn) { + for mut user_org in UserOrganization::find_invited_by_user(&user.uuid, &conn).iter_mut() { + user_org.status = UserOrgStatus::Accepted as i32; + user_org.save(&conn); + }; + user.set_password(&data.MasterPasswordHash); + user.key = data.Key; + user + } else { + if CONFIG.signups_allowed { + err!("Account with this email already exists") + } else { + err!("Registration not allowed") + } + } + }, + None => { + if CONFIG.signups_allowed || Invitation::take(&data.Email, &conn) { + User::new(data.Email, data.Key, data.MasterPasswordHash) + } else { + err!("Registration not allowed") + } + } + }; // Add extra fields if present if let Some(name) = data.Name { diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 3253eb5..b8067b6 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -1,7 +1,7 @@ #![allow(unused_imports)] use rocket_contrib::{Json, Value}; - +use CONFIG; use db::DbConn; use db::models::*; @@ -373,36 +373,56 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade err!("Only Owners can invite Admins or Owners") } - for user_opt in data.Emails.iter().map(|email| User::find_by_mail(email, &conn)) { - match user_opt { - None => err!("User email does not exist"), - Some(user) => { - if UserOrganization::find_by_user_and_org(&user.uuid, &org_id, &conn).is_some() { - err!("User already in organization") + for email in data.Emails.iter() { + let mut user_org_status = UserOrgStatus::Accepted as i32; + let user = match User::find_by_mail(&email, &conn) { + None => if CONFIG.invitations_allowed { // Invite user if that's enabled + let mut invitation = Invitation::new(email.clone()); + match invitation.save(&conn) { + Ok(()) => { + let mut user = User::new_invited(email.clone()); + if user.save(&conn) { + user_org_status = UserOrgStatus::Invited as i32; + user + } else { + err!("Failed to create placeholder for invited user") + } + } + Err(_) => err!(format!("Failed to invite: {}", email)) } + + } else { + err!(format!("User email does not exist: {}", email)) + }, + Some(user) => if UserOrganization::find_by_user_and_org(&user.uuid, &org_id, &conn).is_some() { + err!(format!("User already in organization: {}", email)) + } else { + user + } - let mut new_user = UserOrganization::new(user.uuid.clone(), org_id.clone()); - let access_all = data.AccessAll.unwrap_or(false); - new_user.access_all = access_all; - new_user.type_ = new_type; + }; - // If no accessAll, add the collections received - if !access_all { - for col in &data.Collections { - match Collection::find_by_uuid_and_org(&col.Id, &org_id, &conn) { - None => err!("Collection not found in Organization"), - Some(collection) => { - if CollectionUser::save(&user.uuid, &collection.uuid, col.ReadOnly, &conn).is_err() { - err!("Failed saving collection access for user") - } - } + let mut new_user = UserOrganization::new(user.uuid.clone(), org_id.clone()); + let access_all = data.AccessAll.unwrap_or(false); + new_user.access_all = access_all; + new_user.type_ = new_type; + new_user.status = user_org_status; + + // If no accessAll, add the collections received + if !access_all { + for col in &data.Collections { + match Collection::find_by_uuid_and_org(&col.Id, &org_id, &conn) { + None => err!("Collection not found in Organization"), + Some(collection) => { + if CollectionUser::save(&user.uuid, &collection.uuid, col.ReadOnly, &conn).is_err() { + err!("Failed saving collection access for user") } } } - - new_user.save(&conn); } } + + new_user.save(&conn); } Ok(()) diff --git a/src/db/models/mod.rs b/src/db/models/mod.rs index 7032a39..1f8d10a 100644 --- a/src/db/models/mod.rs +++ b/src/db/models/mod.rs @@ -12,7 +12,7 @@ pub use self::attachment::Attachment; pub use self::cipher::Cipher; pub use self::device::Device; pub use self::folder::{Folder, FolderCipher}; -pub use self::user::User; +pub use self::user::{User, Invitation}; pub use self::organization::Organization; pub use self::organization::{UserOrganization, UserOrgStatus, UserOrgType}; pub use self::collection::{Collection, CollectionUser, CollectionCipher}; diff --git a/src/db/models/organization.rs b/src/db/models/organization.rs index 18ac2a0..a2d9f5c 100644 --- a/src/db/models/organization.rs +++ b/src/db/models/organization.rs @@ -27,7 +27,7 @@ pub struct UserOrganization { } pub enum UserOrgStatus { - _Invited = 0, // Unused, users are accepted automatically + Invited = 0, Accepted = 1, Confirmed = 2, } @@ -284,6 +284,13 @@ impl UserOrganization { .load::(&**conn).unwrap_or(vec![]) } + pub fn find_invited_by_user(user_uuid: &str, conn: &DbConn) -> Vec { + users_organizations::table + .filter(users_organizations::user_uuid.eq(user_uuid)) + .filter(users_organizations::status.eq(UserOrgStatus::Invited as i32)) + .load::(&**conn).unwrap_or(vec![]) + } + pub fn find_by_org(org_uuid: &str, conn: &DbConn) -> Vec { users_organizations::table .filter(users_organizations::org_uuid.eq(org_uuid)) diff --git a/src/db/models/user.rs b/src/db/models/user.rs index e100d89..312c274 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -73,6 +73,10 @@ impl User { } } + pub fn new_invited(mail: String) -> Self { + Self::new(mail,"".to_string(),"".to_string()) + } + pub fn check_valid_password(&self, password: &str) -> bool { crypto::verify_password_hash(password.as_bytes(), &self.salt, @@ -103,7 +107,7 @@ impl User { use diesel; use diesel::prelude::*; use db::DbConn; -use db::schema::users; +use db::schema::{users, invitations}; /// Database methods impl User { @@ -186,3 +190,47 @@ impl User { .first::(&**conn).ok() } } + +#[derive(Debug, Identifiable, Queryable, Insertable)] +#[table_name = "invitations"] +#[primary_key(email)] +pub struct Invitation { + pub email: String, +} + +impl Invitation { + pub fn new(email: String) -> Self { + Self { + email + } + } + + pub fn save(&mut self, conn: &DbConn) -> QueryResult<()> { + diesel::replace_into(invitations::table) + .values(&*self) + .execute(&**conn) + .and(Ok(())) + } + + pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + diesel::delete(invitations::table.filter( + invitations::email.eq(self.email))) + .execute(&**conn) + .and(Ok(())) + } + + pub fn find_by_mail(mail: &str, conn: &DbConn) -> Option { + let lower_mail = mail.to_lowercase(); + invitations::table + .filter(invitations::email.eq(lower_mail)) + .first::(&**conn).ok() + } + + pub fn take(mail: &str, conn: &DbConn) -> bool { + CONFIG.invitations_allowed && + match Self::find_by_mail(mail, &conn) { + Some(invitation) => invitation.delete(&conn).is_ok(), + None => false + } + } +} \ No newline at end of file diff --git a/src/db/schema.rs b/src/db/schema.rs index 5382e69..457b84c 100644 --- a/src/db/schema.rs +++ b/src/db/schema.rs @@ -113,6 +113,12 @@ table! { } } +table! { + invitations (email) { + email -> Text, + } +} + table! { users_collections (user_uuid, collection_uuid) { user_uuid -> Text, diff --git a/src/main.rs b/src/main.rs index e715031..2a68c0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -170,6 +170,7 @@ pub struct Config { local_icon_extractor: bool, signups_allowed: bool, + invitations_allowed: bool, password_iterations: i32, show_password_hint: bool, domain: String, @@ -199,6 +200,7 @@ impl Config { local_icon_extractor: util::parse_option_string(env::var("LOCAL_ICON_EXTRACTOR").ok()).unwrap_or(false), signups_allowed: util::parse_option_string(env::var("SIGNUPS_ALLOWED").ok()).unwrap_or(true), + invitations_allowed: util::parse_option_string(env::var("INVITATIONS_ALLOWED").ok()).unwrap_or(true), password_iterations: util::parse_option_string(env::var("PASSWORD_ITERATIONS").ok()).unwrap_or(100_000), show_password_hint: util::parse_option_string(env::var("SHOW_PASSWORD_HINT").ok()).unwrap_or(true), From c1cd4d9a6bfd1e588852e3ec48288efcbc77c71c Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Tue, 11 Sep 2018 14:25:12 +0100 Subject: [PATCH 61/65] Modify User::new to be keyless and paswordless --- src/api/core/accounts.rs | 7 ++++--- src/api/core/organizations.rs | 2 +- src/db/models/user.rs | 11 +++-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index ef0e917..94fd48e 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -38,8 +38,6 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { user_org.status = UserOrgStatus::Accepted as i32; user_org.save(&conn); }; - user.set_password(&data.MasterPasswordHash); - user.key = data.Key; user } else { if CONFIG.signups_allowed { @@ -51,13 +49,16 @@ fn register(data: JsonUpcase, conn: DbConn) -> EmptyResult { }, None => { if CONFIG.signups_allowed || Invitation::take(&data.Email, &conn) { - User::new(data.Email, data.Key, data.MasterPasswordHash) + User::new(data.Email) } else { err!("Registration not allowed") } } }; + user.set_password(&data.MasterPasswordHash); + user.key = data.Key; + // Add extra fields if present if let Some(name) = data.Name { user.name = name; diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index b8067b6..5852ea1 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -380,7 +380,7 @@ fn send_invite(org_id: String, data: JsonUpcase, headers: AdminHeade let mut invitation = Invitation::new(email.clone()); match invitation.save(&conn) { Ok(()) => { - let mut user = User::new_invited(email.clone()); + let mut user = User::new(email.clone()); if user.save(&conn) { user_org_status = UserOrgStatus::Invited as i32; user diff --git a/src/db/models/user.rs b/src/db/models/user.rs index 312c274..0d958b5 100644 --- a/src/db/models/user.rs +++ b/src/db/models/user.rs @@ -39,13 +39,12 @@ pub struct User { /// Local methods impl User { - pub fn new(mail: String, key: String, password: String) -> Self { + pub fn new(mail: String) -> Self { let now = Utc::now().naive_utc(); let email = mail.to_lowercase(); let iterations = CONFIG.password_iterations; let salt = crypto::get_random_64(); - let password_hash = crypto::hash_password(password.as_bytes(), &salt, iterations as u32); Self { uuid: Uuid::new_v4().to_string(), @@ -53,9 +52,9 @@ impl User { updated_at: now, name: email.clone(), email, - key, + key: String::new(), - password_hash, + password_hash: Vec::new(), salt, password_iterations: iterations, @@ -73,10 +72,6 @@ impl User { } } - pub fn new_invited(mail: String) -> Self { - Self::new(mail,"".to_string(),"".to_string()) - } - pub fn check_valid_password(&self, password: &str) -> bool { crypto::verify_password_hash(password.as_bytes(), &self.salt, From 5f7b220eb43f85b4286c9a32f3798f35678fdac9 Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Thu, 30 Aug 2018 17:35:02 +0100 Subject: [PATCH 62/65] Initial shot as cross compilation --- Dockerfile.armv7 | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Dockerfile.armv7 diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 new file mode 100644 index 0000000..965a20f --- /dev/null +++ b/Dockerfile.armv7 @@ -0,0 +1,113 @@ +# Using multistage build: +# https://docs.docker.com/develop/develop-images/multistage-build/ +# https://whitfin.io/speeding-up-rust-docker-builds/ +####################### VAULT BUILD IMAGE ####################### +FROM node:8-alpine as vault + +ENV VAULT_VERSION "v2.2.0" + +ENV URL "https://github.com/bitwarden/web.git" + +RUN apk add --update-cache --upgrade \ + curl \ + git \ + tar + +RUN git clone -b $VAULT_VERSION --depth 1 $URL web-build +WORKDIR /web-build + +COPY /docker/set-vault-baseurl.patch /web-build/ +RUN git apply set-vault-baseurl.patch + +RUN npm run sub:init && npm install + +RUN npm run dist \ + && mv build /web-vault + +########################## BUILD IMAGE ########################## +# We need to use the Rust build image, because +# we need the Rust compiler and Cargo tooling +FROM rust as build + +RUN apt-get update \ + && apt-get install -y \ + gcc-arm-linux-gnueabihf \ + && mkdir -p ~/.cargo \ + && echo '[target.armv7-unknown-linux-gnueabihf]' >> ~/.cargo/config \ + && echo 'linker = "arm-linux-gnueabihf-gcc"' >> ~/.cargo/config + +ENV CARGO_HOME "/root/.cargo" +ENV USER "root" + +# Creates a dummy project used to grab dependencies +RUN USER=root cargo new --bin app +WORKDIR /app + +# Copies over *only* your manifests and vendored dependencies +COPY ./Cargo.* ./ +COPY ./libs ./libs +COPY ./rust-toolchain ./rust-toolchain + +# Prepare openssl armhf libs +RUN sed 's/^deb/deb-src/' /etc/apt/sources.list > \ + /etc/apt/sources.list.d/deb-src.list \ + && dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y \ + libssl-dev:armhf \ + libc6-dev:armhf + +ENV CC_armv7_unknown_linux_gnueabihf="/usr/bin/arm-linux-gnueabihf-gcc" +ENV CROSS_COMPILE="1" +ENV OPENSSL_INCLUDE_DIR="/usr/include/arm-linux-gnueabihf" +ENV OPENSSL_LIB_DIR="/usr/lib/arm-linux-gnueabihf" + +# Builds your dependencies and removes the +# dummy project, except the target folder +# This folder contains the compiled dependencies +COPY . . +RUN rustup target add armv7-unknown-linux-gnueabihf +RUN cargo build --release --target=armv7-unknown-linux-gnueabihf -v +RUN find . -not -path "./target*" -delete + +# Copies the complete project +# To avoid copying unneeded files, use .dockerignore +COPY . . + +# Builds again, this time it'll just be +# your actual source files being built +RUN cargo build --release --target=armv7-unknown-linux-gnueabihf -v + +######################## RUNTIME IMAGE ######################## +# Create a new stage with a minimal image +# because we already have a binary built +FROM resin/armv7hf-debian:stretch + +ENV ROCKET_ENV "staging" +ENV ROCKET_WORKERS=10 + +RUN [ "cross-build-start" ] + +# Install needed libraries +RUN apt-get update && apt-get install -y\ + openssl\ + ca-certificates\ + --no-install-recommends\ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir /data + +RUN [ "cross-build-end" ] + +VOLUME /data +EXPOSE 80 + +# Copies the files from the context (env file and web-vault) +# and the binary from the "build" stage to the current stage +COPY .env . +COPY Rocket.toml . +COPY --from=vault /web-vault ./web-vault +COPY --from=build app/target/release/bitwarden_rs . + +# Configures the startup! +CMD ./bitwarden_rs \ No newline at end of file From bc8ff14695ec314e38abc5fc06ac388a8036fe4e Mon Sep 17 00:00:00 2001 From: Miroslav Prasil Date: Wed, 12 Sep 2018 13:51:43 +0100 Subject: [PATCH 63/65] Fix the binary path --- Dockerfile.armv7 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.armv7 b/Dockerfile.armv7 index 965a20f..7cf6508 100644 --- a/Dockerfile.armv7 +++ b/Dockerfile.armv7 @@ -107,7 +107,7 @@ EXPOSE 80 COPY .env . COPY Rocket.toml . COPY --from=vault /web-vault ./web-vault -COPY --from=build app/target/release/bitwarden_rs . +COPY --from=build /app/target/armv7-unknown-linux-gnueabihf/release/bitwarden_rs . # Configures the startup! CMD ./bitwarden_rs \ No newline at end of file From 3e1afb139c80f32f2b187af4ca8ea04aa86cb977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Wed, 12 Sep 2018 23:58:02 +0200 Subject: [PATCH 64/65] Remove unnecessary return --- src/api/core/accounts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs index e8c4f7e..3e54577 100644 --- a/src/api/core/accounts.rs +++ b/src/api/core/accounts.rs @@ -288,7 +288,7 @@ fn password_hint(data: JsonUpcase, conn: DbConn) -> EmptyResul let data: PasswordHintData = data.into_inner().data; if !is_valid_email(&data.Email) { - return err!("This email address is not valid..."); + err!("This email address is not valid..."); } let user = User::find_by_mail(&data.Email, &conn); From f397f0cbd0a5d32b78c6e0f139acef598e737ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Thu, 13 Sep 2018 15:16:24 +0200 Subject: [PATCH 65/65] Implement organization import for admins and owners (Fixes #178) --- src/api/core/ciphers.rs | 12 +++--- src/api/core/mod.rs | 1 + src/api/core/organizations.rs | 81 +++++++++++++++++++++++++++++++---- 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index f9e090c..b0bf574 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -86,7 +86,7 @@ fn get_cipher_details(uuid: String, headers: Headers, conn: DbConn) -> JsonResul #[derive(Deserialize, Debug)] #[allow(non_snake_case)] -struct CipherData { +pub struct CipherData { // Id is optional as it is included only in bulk share Id: Option, // Folder id is not included in import @@ -100,8 +100,8 @@ struct CipherData { Card = 3, Identity = 4 */ - Type: i32, // TODO: Change this to NumberOrString - Name: String, + pub Type: i32, // TODO: Change this to NumberOrString + pub Name: String, Notes: Option, Fields: Option, @@ -132,7 +132,7 @@ fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn) -> Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } -fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, shared_to_collection: bool, conn: &DbConn) -> EmptyResult { +pub fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, shared_to_collection: bool, conn: &DbConn) -> EmptyResult { if let Some(org_id) = data.OrganizationId { match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { None => err!("You don't have permission to add item to organization"), @@ -560,7 +560,7 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon let uuids = match data.get("Ids") { Some(ids) => match ids.as_array() { - Some(ids) => ids.iter().filter_map(|uuid| { uuid.as_str() }), + Some(ids) => ids.iter().filter_map(Value::as_str), None => err!("Posted ids field is not an array") }, None => err!("Request missing ids field") @@ -606,7 +606,7 @@ fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) let uuids = match data.get("Ids") { Some(ids) => match ids.as_array() { - Some(ids) => ids.iter().filter_map(|uuid| { uuid.as_str() }), + Some(ids) => ids.iter().filter_map(Value::as_str), None => err!("Posted ids field is not an array") }, None => err!("Request missing ids field") diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs index d2ad208..31e4d60 100644 --- a/src/api/core/mod.rs +++ b/src/api/core/mod.rs @@ -110,6 +110,7 @@ pub fn routes() -> Vec { put_organization_user, delete_user, post_delete_user, + post_org_import, clear_device_token, put_device_token, diff --git a/src/api/core/organizations.rs b/src/api/core/organizations.rs index 5852ea1..4d47eab 100644 --- a/src/api/core/organizations.rs +++ b/src/api/core/organizations.rs @@ -1,5 +1,3 @@ -#![allow(unused_imports)] - use rocket_contrib::{Json, Value}; use CONFIG; use db::DbConn; @@ -140,9 +138,8 @@ fn get_user_collections(headers: Headers, conn: DbConn) -> JsonResult { "Data": Collection::find_by_user_uuid(&headers.user.uuid, &conn) .iter() - .map(|collection| { - collection.to_json() - }).collect::(), + .map(Collection::to_json) + .collect::(), "Object": "list" }))) } @@ -153,9 +150,8 @@ fn get_org_collections(org_id: String, _headers: AdminHeaders, conn: DbConn) -> "Data": Collection::find_by_organization(&org_id, &conn) .iter() - .map(|collection| { - collection.to_json() - }).collect::(), + .map(Collection::to_json) + .collect::(), "Object": "list" }))) } @@ -582,4 +578,73 @@ fn delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: #[post("/organizations//users//delete")] fn post_delete_user(org_id: String, org_user_id: String, headers: AdminHeaders, conn: DbConn) -> EmptyResult { delete_user(org_id, org_user_id, headers, conn) +} + +use super::ciphers::CipherData; +use super::ciphers::update_cipher_from_data; + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct ImportData { + Ciphers: Vec, + Collections: Vec, + CollectionRelationships: Vec, +} + +#[derive(Deserialize)] +#[allow(non_snake_case)] +struct RelationsData { + // Cipher index + Key: usize, + // Collection index + Value: usize, +} + +#[post("/ciphers/import-organization?", data = "")] +fn post_org_import(query: OrgIdData, data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { + let data: ImportData = data.into_inner().data; + let org_id = query.organizationId; + + let org_user = match UserOrganization::find_by_user_and_org(&headers.user.uuid, &org_id, &conn) { + Some(user) => user, + None => err!("User is not part of the organization") + }; + + if org_user.type_ > UserOrgType::Admin as i32 { + err!("Only admins or owners can import into an organization") + } + + // Read and create the collections + let collections: Vec<_> = data.Collections.into_iter().map(|coll| { + let mut collection = Collection::new(org_id.clone(), coll.Name); + collection.save(&conn); + collection + }).collect(); + + // Read the relations between collections and ciphers + let mut relations = Vec::new(); + for relation in data.CollectionRelationships { + relations.push((relation.Key, relation.Value)); + } + + // Read and create the ciphers + let ciphers: Vec<_> = data.Ciphers.into_iter().map(|cipher_data| { + let mut cipher = Cipher::new(cipher_data.Type, cipher_data.Name.clone()); + update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &conn).ok(); + cipher + }).collect(); + + // Assign the collections + for (cipher_index, coll_index) in relations { + let cipher_id = &ciphers[cipher_index].uuid; + let coll_id = &collections[coll_index].uuid; + + CollectionCipher::save(cipher_id, coll_id, &conn); + } + + let mut user = headers.user; + match user.update_revision(&conn) { + Ok(()) => Ok(()), + Err(_) => err!("Failed to update the revision, please log out and log back in to finish import.") + } } \ No newline at end of file