From d70864ac73400426c729f4aed80dae0fd4ba0f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Thu, 30 Aug 2018 17:43:46 +0200 Subject: [PATCH 1/6] Initial version of websockets notification support. For now only folder notifications are sent (create, rename, delete). The notifications are only tested between two web-vault sessions in different browsers, mobile apps and browser extensions are untested. The websocket server is exposed in port 3012, while the rocket server is exposed in another port (8000 by default). To make notifications work, both should be accessible in the same port, which requires a reverse proxy. My testing is done with Caddy server, and the following config: ``` localhost { # The negotiation endpoint is also proxied to Rocket proxy /notifications/hub/negotiate 0.0.0.0:8000 { transparent } # Notifications redirected to the websockets server proxy /notifications/hub 0.0.0.0:3012 { websocket } # Proxy the Root directory to Rocket proxy / 0.0.0.0:8000 { transparent } } ``` This exposes the service in port 2015. --- Cargo.lock | 537 ++++++++++++++++++++++++++++----------- Cargo.toml | 19 +- src/api/core/folders.rs | 24 +- src/api/mod.rs | 1 + src/api/notifications.rs | 338 +++++++++++++++++++++++- src/db/models/folder.rs | 4 +- src/main.rs | 10 +- 7 files changed, 765 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b8b843..a4f16b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,10 +5,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "aho-corasick" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -34,7 +34,7 @@ name = "base64" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -69,7 +69,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "bitwarden_rs" version = "1.0.0" dependencies = [ - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (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)", @@ -77,20 +79,22 @@ dependencies = [ "jsonwebtoken 4.0.1", "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)", + "multipart 0.15.3 (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.8 (registry+https://github.com/rust-lang/crates.io-index)", "ring 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rmpv 0.4.0 (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 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.75 (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)", + "ws 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -98,9 +102,9 @@ name = "buf_redux" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (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.11 (registry+https://github.com/rust-lang/crates.io-index)", + "slice-deque 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -115,7 +119,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "1.2.4" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -123,13 +127,13 @@ name = "bytes" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (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.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -137,9 +141,18 @@ name = "cfg-if" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "chashmap" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "chrono" -version = "0.4.5" +version = "0.4.6" 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)", @@ -152,6 +165,14 @@ name = "chunked_transfer" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "constant_time_eq" version = "0.1.3" @@ -204,11 +225,11 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.3.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -227,12 +248,12 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.4.3" +version = "0.5.2" 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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (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)", @@ -248,11 +269,8 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "crypto-mac" @@ -273,8 +291,8 @@ name = "diesel" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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)", + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.3.0 (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)", @@ -323,7 +341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -414,7 +432,7 @@ name = "failure_derive" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (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)", @@ -537,7 +555,7 @@ dependencies = [ "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-io 0.1.8 (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)", @@ -562,7 +580,7 @@ dependencies = [ "hyper 0.11.27 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (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-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -621,11 +639,11 @@ name = "jsonwebtoken" version = "4.0.1" dependencies = [ "base64 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (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.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 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.75 (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)", ] @@ -662,6 +680,11 @@ name = "lazycell" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lazycell" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "libc" version = "0.2.43" @@ -673,7 +696,7 @@ 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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -682,11 +705,20 @@ name = "libsqlite3-sys" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "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)", + "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lock_api" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" version = "0.3.9" @@ -718,7 +750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -769,8 +801,8 @@ 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)", - "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)", + "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -780,8 +812,8 @@ version = "2.0.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -803,6 +835,27 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio-extras" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazycell 1.0.0 (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.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "mio-uds" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "miow" version = "0.2.1" @@ -821,7 +874,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "multipart" -version = "0.15.2" +version = "0.15.3" 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)", @@ -903,7 +956,7 @@ 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.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (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)", ] @@ -916,6 +969,14 @@ dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "num-traits" +version = "0.1.43" +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)", +] + [[package]] name = "num-traits" version = "0.2.5" @@ -958,9 +1019,9 @@ name = "openssl-sys" version = "0.9.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.23 (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)", + "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -969,6 +1030,60 @@ name = "ordermap" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "owning_ref" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "owning_ref" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "pear" version = "0.0.20" @@ -990,33 +1105,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "phf" -version = "0.7.22" +version = "0.7.23" 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)", + "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_codegen" -version = "0.7.22" +version = "0.7.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_generator" -version = "0.7.22" +version = "0.7.23" 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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "phf_shared" -version = "0.7.22" +version = "0.7.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1025,7 +1140,7 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1046,7 +1161,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.13" +version = "0.4.15" 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)", @@ -1075,7 +1190,7 @@ name = "quote" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1098,6 +1213,23 @@ dependencies = [ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand_core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rayon" version = "0.7.1" @@ -1127,23 +1259,23 @@ name = "regex" version = "0.2.11" 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)", + "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex" -version = "1.0.2" +version = "1.0.4" 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)", + "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (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.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1192,11 +1324,11 @@ dependencies = [ "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.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (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-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1214,6 +1346,24 @@ dependencies = [ "untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rmp" +version = "0.8.7" +source = "git+https://github.com/dani-garcia/msgpack-rust#3ba7cf4f9b33d78b1fca145c0d4b5600d797387e" +dependencies = [ + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rmpv" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "rmp 0.8.7 (git+https://github.com/dani-garcia/msgpack-rust)", +] + [[package]] name = "rocket" version = "0.3.16" @@ -1225,7 +1375,7 @@ dependencies = [ "hyper-sync-rustls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "isatty 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (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.20 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1258,7 +1408,7 @@ 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.16 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1287,7 +1437,7 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1349,15 +1499,15 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.74" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (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)", ] @@ -1368,8 +1518,8 @@ version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "itoa 0.4.2 (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)", + "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1379,7 +1529,7 @@ 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.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1395,6 +1545,11 @@ dependencies = [ "generic-array 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "sha2" version = "0.5.3" @@ -1419,7 +1574,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "slice-deque" -version = "0.1.11" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1435,6 +1590,11 @@ dependencies = [ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "stable_deref_trait" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "state" version = "0.4.1" @@ -1465,7 +1625,7 @@ name = "syn" version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (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)", ] @@ -1483,7 +1643,7 @@ name = "synstructure" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.15 (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)", @@ -1498,6 +1658,16 @@ dependencies = [ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thread-id" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "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)", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -1522,7 +1692,7 @@ 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.5 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.6 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1531,19 +1701,22 @@ dependencies = [ [[package]] name = "tokio" -version = "0.1.7" +version = "0.1.8" 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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-codec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.4 (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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.5 (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.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1553,7 +1726,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "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)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1567,16 +1740,25 @@ dependencies = [ "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.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-current-thread" +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)", + "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -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)", @@ -1588,13 +1770,13 @@ 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)", - "tokio-io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-io" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1604,15 +1786,19 @@ dependencies = [ [[package]] name = "tokio-reactor" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (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.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (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)", + "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1632,30 +1818,33 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-threadpool" -version = "0.1.5" +version = "0.1.6" 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)", + "crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.5.0 (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.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.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-timer" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.3 (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.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1666,12 +1855,12 @@ dependencies = [ "futures 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.5 (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-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-udp" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1679,8 +1868,24 @@ dependencies = [ "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.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "tokio-uds" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "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)", + "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)", + "mio 0.6.15 (registry+https://github.com/rust-lang/crates.io-index)", + "mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1688,7 +1893,7 @@ name = "toml" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 1.0.74 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1706,7 +1911,7 @@ name = "twoway" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1733,12 +1938,12 @@ 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.4 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.6 (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)", + "chrono 0.4.6 (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.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 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.75 (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)", @@ -1822,7 +2027,7 @@ dependencies = [ [[package]] name = "utf8-ranges" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1916,6 +2121,23 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ws" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.2 (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)", + "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1932,7 +2154,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa" +"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a" "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.8.7 (registry+https://github.com/rust-lang/crates.io-index)" = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14" @@ -1944,23 +2166,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8389c509ec62b9fe8eca58c502a0acaf017737355615243496cde4994f8fa4f9" +"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781" "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 cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c37f0efaa4b9b001fa6f02d4b644dee4af97d3414df07c51e3e4f015f3a3e131" "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 chashmap 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47e651a8c1eb0cbbaa730f705e2531e75276c6f2bbe2eb12662cfd305213dff8" +"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum chunked_transfer 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "498d20a7aaf62625b9bf26e637cf7736417cde1d0c99f1d04d1170229a85cf87" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "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" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" -"checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7" +"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1" "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150" -"checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620" +"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" -"checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" +"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015" "checksum crypto-mac 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dba62c86c26dcba13c278afcaac0c7452486fe604a2668a0dfa4e0edc98d8a9e" "checksum data-encoding 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "67df0571a74bf0d97fb8b2ed22abdd9a48475c96bd327db968b7d9cace99655e" "checksum diesel 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e71e7a348ae6064e86c4cf0709f0e4c3ef6f30e8e7d3dc05737164af4ebd3511" @@ -2007,14 +2231,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "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 lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50" "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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d3711dfd91a1081d2458ad2d06ea30a8755256e74038be2ad927d94e1c955ca8" +"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "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 memchr 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a3b4142ab8738a78c51896f704f83c11df047ff1bda9a92a661aa6361552d93d" "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" @@ -2023,9 +2249,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40" +"checksum mio-uds 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "84c7b5caa3a118a6e34dbac36504503b1e8dc5835e833306b9d6af0e05929f79" "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.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d2745c8c82bc18e8847772ea04bb20d18464e120445a4e3f04771c5cfa24a3e" +"checksum multipart 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bd50d71866514b14d2ca09823d81390d92daa40bc835f83a908c52ab0a802e" "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" @@ -2033,47 +2261,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2" "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-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "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.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 owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc" +"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9" +"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5" +"checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" +"checksum parking_lot_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "06a2b6aae052309c2fd2161ef58f5067bc17bb758377a0de9d4b279d603fdd8a" "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.13 (registry+https://github.com/rust-lang/crates.io-index)" = "104630aa1c83213cbc76db0703630fcb0421dac3585063be4ce9a8a2feeaa745" +"checksum phf 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "cec29da322b242f4c3098852c77a0ca261c9c01b806cae85a5572a1eb94db9a6" +"checksum phf_codegen 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "7d187f00cd98d5afbcd8898f6cf181743a449162aeb329dcd2f3849009e605ad" +"checksum phf_generator 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "03dc191feb9b08b0dc1330d6549b795b9d81aec19efe6b4a45aec8d4caee0c4b" +"checksum phf_shared 0.7.23 (registry+https://github.com/rust-lang/crates.io-index)" = "b539898d22d4273ded07f64a05737649dc69095d92cb87c7097ec68e3f150b93" +"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" "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.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ee5697238f0d893c7f0ecc59c0999f18d2af85e424de441178bcacc9f9e6cf67" +"checksum proc-macro2 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "295af93acfb1d5be29c16ca5b3f82d863836efd9cb0c14fd83811eb9a110e452" "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.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.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" +"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" +"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2" "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" "checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5bbbea44c5490a1e84357ff28b7d518b4619a159fed5d25f6c1de2d19cc42814" +"checksum regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "67d0301b0c6804eca7e3c275119d0b01ff3b7ab9258a65709e608a66312a1025" "checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" "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.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 rmp 0.8.7 (git+https://github.com/dani-garcia/msgpack-rust)" = "" +"checksum rmpv 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29af0205707de955a396a1d3c657677c65f791ebabb63c0596c0b2fec0bf6325" "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 ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7" "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" @@ -2082,16 +2321,18 @@ 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.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 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "22d340507cea0b7e6632900a176101fea959c7065d93ba555072da90aaaafc87" +"checksum serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)" = "234fc8b737737b148ccd625175fc6390f5e4dacfdaa543cb93a3430d984a9119" "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 sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" "checksum sha2 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "84920f9ac881e94e33ec89e1b3dcd36040523a308a92548e01217ce35d8cf6a8" "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 slice-deque 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "79e5bb98247a0eb0cfdedb7e792962ec71ac1003033f70558bd9961f8912e487" "checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d" +"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "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" @@ -2099,22 +2340,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "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-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "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 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fbb6a6e9db2702097bfdfddcb09841211ad423b86c75b5ddaca1d62842ac492c" "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.3 (registry+https://github.com/rust-lang/crates.io-index)" = "424f0c87ecd66b863045d84e384cb7ce0ae384d8b065b9f0363d29c0d1b30b2f" +"checksum tokio-current-thread 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fdfb899688ac16f618076bd09215edbfda0fd5dfecb375b6942636cb31fa8a7" +"checksum tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84823b932d566bc3c6aa644df4ca36cb38593c50b7db06011fd4e12e31e4047e" "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-reactor 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8703a5762ff6913510dc64272c714c4389ffd8c4b3cf602879b8bd14ff06b604" +"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb" +"checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" "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.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1c76b4e97a4f61030edff8bd272364e4f731b9f54c7307eb4eb733c3926eb96a" +"checksum tokio-threadpool 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a5758cecb6e0633cea5d563ac07c975e04961690b946b04fd84e7d6445a8f6af" +"checksum tokio-timer 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d03fa701f9578a01b7014f106b47f0a363b4727a7f3f75d666e312ab7acbbf1c" "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 tokio-udp 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "da941144b816d0dcda4db3a1ba87596e4df5e860a72b70783fe435891f80601c" +"checksum tokio-uds 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "424c1ed15a0132251813ccea50640b224c809d6ceafb88154c1a8775873a0e89" "checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9" "checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" "checksum try-lock 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee2aa4715743892880f70885373966c83d73ef1b0838a664ef0c76fffd35e7c2" @@ -2134,7 +2378,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "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 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 utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" "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" @@ -2148,5 +2392,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum ws 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d2c221321dca56e6a80aa179d562e1fbe6ae116aeaa9205c76fa64e9e3c49dfc" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d60c3b48c9cdec42fb06b3b84b5b087405e1fa1c644a1af3930e4dfafe93de48" diff --git a/Cargo.toml b/Cargo.toml index 13d13c5..0623af2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,18 @@ reqwest = "0.8.8" # multipart/form-data support multipart = "0.15.2" +# WebSockets library +ws = "0.7.8" + +# MessagePack library +rmpv = "0.4.0" + +# Concurrent hashmap implementation +chashmap = "2.2.0" + # A generic serialization/deserialization framework -serde = "1.0.74" -serde_derive = "1.0.74" +serde = "1.0.75" +serde_derive = "1.0.75" serde_json = "1.0.26" # A safe, extensible ORM and Query builder @@ -34,7 +43,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.5" +chrono = "0.4.6" # TOTP library oath = "0.10.2" @@ -58,9 +67,13 @@ lazy_static = "1.1.0" num-traits = "0.2.5" num-derive = "0.2.2" +# Number encoding library +byteorder = "1.2.6" + [patch.crates-io] # Make jwt use ring 0.11, to match rocket jsonwebtoken = { path = "libs/jsonwebtoken" } +rmp = { git = 'https://github.com/dani-garcia/msgpack-rust' } # 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' } diff --git a/src/api/core/folders.rs b/src/api/core/folders.rs index 2f4cf45..47ff226 100644 --- a/src/api/core/folders.rs +++ b/src/api/core/folders.rs @@ -1,9 +1,10 @@ +use rocket::State; use rocket_contrib::{Json, Value}; use db::DbConn; use db::models::*; -use api::{JsonResult, EmptyResult, JsonUpcase}; +use api::{JsonResult, EmptyResult, JsonUpcase, WebSocketUsers, UpdateType}; use auth::Headers; #[get("/folders")] @@ -40,23 +41,24 @@ pub struct FolderData { } #[post("/folders", data = "")] -fn post_folders(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn post_folders(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { let data: FolderData = data.into_inner().data; let mut folder = Folder::new(headers.user.uuid.clone(), data.Name); folder.save(&conn); + ws.send_folder_update(UpdateType::SyncFolderCreate, &folder); Ok(Json(folder.to_json())) } #[post("/folders/", data = "")] -fn post_folder(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - put_folder(uuid, data, headers, conn) +fn post_folder(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { + put_folder(uuid, data, headers, conn, ws) } #[put("/folders/", data = "")] -fn put_folder(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn put_folder(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { let data: FolderData = data.into_inner().data; let mut folder = match Folder::find_by_uuid(&uuid, &conn) { @@ -71,17 +73,18 @@ fn put_folder(uuid: String, data: JsonUpcase, headers: Headers, conn folder.name = data.Name; folder.save(&conn); + ws.send_folder_update(UpdateType::SyncFolderUpdate, &folder); Ok(Json(folder.to_json())) } #[post("/folders//delete")] -fn delete_folder_post(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { - delete_folder(uuid, headers, conn) +fn delete_folder_post(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + delete_folder(uuid, headers, conn, ws) } #[delete("/folders/")] -fn delete_folder(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { +fn delete_folder(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let folder = match Folder::find_by_uuid(&uuid, &conn) { Some(folder) => folder, _ => err!("Invalid folder") @@ -93,7 +96,10 @@ fn delete_folder(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { // Delete the actual folder entry match folder.delete(&conn) { - Ok(()) => Ok(()), + Ok(()) => { + ws.send_folder_update(UpdateType::SyncFolderDelete, &folder); + Ok(()) + } Err(_) => err!("Failed deleting folder") } } diff --git a/src/api/mod.rs b/src/api/mod.rs index d651497..51bf0b8 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -9,6 +9,7 @@ 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; +pub use self::notifications::{start_notification_server, WebSocketUsers, UpdateType}; use rocket::response::status::BadRequest; use rocket_contrib::Json; diff --git a/src/api/notifications.rs b/src/api/notifications.rs index f24fade..ae9721b 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -1,9 +1,9 @@ use rocket::Route; use rocket_contrib::Json; -use db::DbConn; use api::JsonResult; use auth::Headers; +use db::DbConn; pub fn routes() -> Vec { routes![negotiate] @@ -11,10 +11,9 @@ pub fn routes() -> Vec { #[post("/hub/negotiate")] fn negotiate(_headers: Headers, _conn: DbConn) -> JsonResult { - use data_encoding::BASE64URL; use crypto; + use data_encoding::BASE64URL; - // Store this in db? let conn_id = BASE64URL.encode(&crypto::get_random(vec![0u8; 16])); // TODO: Implement transports @@ -23,9 +22,338 @@ fn negotiate(_headers: Headers, _conn: DbConn) -> JsonResult { Ok(Json(json!({ "connectionId": conn_id, "availableTransports":[ - // {"transport":"WebSockets", "transferFormats":["Text","Binary"]}, + {"transport":"WebSockets", "transferFormats":["Text","Binary"]}, // {"transport":"ServerSentEvents", "transferFormats":["Text"]}, // {"transport":"LongPolling", "transferFormats":["Text","Binary"]} ] }))) -} \ No newline at end of file +} + +/// +/// Websockets server +/// +use std::sync::Arc; +use std::thread; + +use ws::{self, util::Token, Factory, Handler, Handshake, Message, Sender, WebSocket}; + +use chashmap::CHashMap; +use chrono::NaiveDateTime; +use serde_json::from_str; + +use db::models::{Cipher, Folder, User}; + +use rmpv::Value; + +fn serialize(val: Value) -> Vec { + use rmpv::encode::write_value; + + let mut buf = Vec::new(); + write_value(&mut buf, &val).expect("Error encoding MsgPack"); + + // Add size bytes at the start + // Extracted from BinaryMessageFormat.js + let mut size = buf.len(); + let mut len_buf: Vec = Vec::new(); + + loop { + let mut size_part = size & 0x7f; + size = size >> 7; + + if size > 0 { + size_part = size_part | 0x80; + } + + len_buf.push(size_part as u8); + + if size <= 0 { + break; + } + } + + len_buf.append(&mut buf); + len_buf +} + +fn serialize_date(date: NaiveDateTime) -> Value { + let seconds: i64 = date.timestamp(); + let nanos: i64 = date.timestamp_subsec_nanos() as i64; + let timestamp = nanos << 34 | seconds; + + use byteorder::{BigEndian, WriteBytesExt}; + + let mut bs = [0u8; 8]; + bs.as_mut() + .write_i64::(timestamp) + .expect("Unable to write"); + + // -1 is Timestamp + // https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-extension-type + Value::Ext(-1, bs.to_vec()) +} + +fn convert_option>(option: Option) -> Value { + match option { + Some(a) => a.into(), + None => Value::Nil, + } +} + +// Server WebSocket handler +pub struct WSHandler { + out: Sender, + user_uuid: Option, + users: WebSocketUsers, +} + +const RECORD_SEPARATOR: u8 = 0x1e; +const INITIAL_RESPONSE: [u8; 3] = [0x7b, 0x7d, RECORD_SEPARATOR]; // {, }, + +#[derive(Deserialize)] +struct InitialMessage { + protocol: String, + version: i32, +} + +const PING_MS: u64 = 15_000; +const PING: Token = Token(1); + +impl Handler for WSHandler { + fn on_open(&mut self, hs: Handshake) -> ws::Result<()> { + // TODO: Improve this split + let path = hs.request.resource(); + let mut query_split: Vec<_> = path.split("?").nth(1).unwrap().split("&").collect(); + query_split.sort(); + let access_token = &query_split[0][13..]; + let _id = &query_split[1][3..]; + + // Validate the user + use auth; + let claims = match auth::decode_jwt(access_token) { + Ok(claims) => claims, + Err(_) => { + return Err(ws::Error::new( + ws::ErrorKind::Internal, + "Invalid access token provided", + )) + } + }; + + // Assign the user to the handler + let user_uuid = claims.sub; + self.user_uuid = Some(user_uuid.clone()); + + // Add the current Sender to the user list + let handler_insert = self.out.clone(); + let handler_update = self.out.clone(); + + self.users.map.upsert( + user_uuid, + || vec![handler_insert], + |ref mut v| v.push(handler_update), + ); + + // Schedule a ping to keep the connection alive + self.out.timeout(PING_MS, PING) + } + + fn on_message(&mut self, msg: Message) -> ws::Result<()> { + println!("Server got message '{}'. ", msg); + + if let Message::Text(text) = msg.clone() { + let json = &text[..text.len() - 1]; // Remove last char + + if let Ok(InitialMessage { protocol, version }) = from_str::(json) { + if &protocol == "messagepack" && version == 1 { + return self.out.send(&INITIAL_RESPONSE[..]); // Respond to initial message + } + } + } + + // If it's not the initial message, just echo the message + self.out.send(msg) + } + + fn on_timeout(&mut self, event: Token) -> ws::Result<()> { + if event == PING { + // send ping + self.out.send(create_ping())?; + + // reschedule the timeout + self.out.timeout(PING_MS, PING) + } else { + Err(ws::Error::new( + ws::ErrorKind::Internal, + "Invalid timeout token provided", + )) + } + } +} + +struct WSFactory { + pub users: WebSocketUsers, +} + +impl WSFactory { + pub fn init() -> Self { + WSFactory { + users: WebSocketUsers { + map: Arc::new(CHashMap::new()), + }, + } + } +} + +impl Factory for WSFactory { + type Handler = WSHandler; + + fn connection_made(&mut self, out: Sender) -> Self::Handler { + println!("WS: Connection made"); + WSHandler { + out, + user_uuid: None, + users: self.users.clone(), + } + } + + fn connection_lost(&mut self, handler: Self::Handler) { + println!("WS: Connection lost"); + + // Remove handler + let user_uuid = &handler.user_uuid.unwrap(); + if let Some(mut user_conn) = self.users.map.get_mut(user_uuid) { + user_conn.remove_item(&handler.out); + } + } +} + +#[derive(Clone)] +pub struct WebSocketUsers { + pub map: Arc>>, +} + +impl WebSocketUsers { + fn send_update(&self, user_uuid: &String, data: Vec) -> ws::Result<()> { + if let Some(user) = self.map.get(user_uuid) { + for sender in user.iter() { + sender.send(data.clone())?; + } + } + Ok(()) + } + + // NOTE: The last modified date needs to be updated before calling these methods + pub fn send_user_update(&self, ut: UpdateType, user: &User) { + let data = create_update( + vec![ + ("UserId".into(), user.uuid.clone().into()), + ("Date".into(), serialize_date(user.updated_at)), + ].into(), + ut, + ); + + self.send_update(&user.uuid.clone(), data).ok(); + } + + pub fn send_folder_update(&self, ut: UpdateType, folder: &Folder) { + let data = create_update( + vec![ + ("Id".into(), folder.uuid.clone().into()), + ("UserId".into(), folder.user_uuid.clone().into()), + ("RevisionDate".into(), serialize_date(folder.updated_at)), + ].into(), + ut, + ); + + self.send_update(&folder.user_uuid, data).ok(); + } + + pub fn send_cipher_update(&self, ut: UpdateType, cipher: &Cipher, user_uuids: &[&String]) { + let user_uuid = convert_option(cipher.user_uuid.clone()); + let org_uuid = convert_option(cipher.organization_uuid.clone()); + + let data = create_update( + vec![ + ("Id".into(), cipher.uuid.clone().into()), + ("UserId".into(), user_uuid), + ("OrganizationId".into(), org_uuid), + ("CollectionIds".into(), Value::Nil), + ("RevisionDate".into(), serialize_date(cipher.updated_at)), + ].into(), + ut, + ); + + for user_uuid in user_uuids { + self.send_update(user_uuid, data.clone()).ok(); + } + } +} + +/* Message Structure +[ + 1, // MessageType.Invocation + {}, // Headers + null, // InvocationId + "ReceiveMessage", // Target + [ // Arguments + { + "ContextId": "app_id", + "Type": ut as i32, + "Payload": {} + } + ] +] +*/ +fn create_update(payload: Vec<(Value, Value)>, ut: UpdateType) -> Vec { + use rmpv::Value as V; + + let value = V::Array(vec![ + 1.into(), + V::Array(vec![]), + V::Nil, + "ReceiveMessage".into(), + V::Array(vec![V::Map(vec![ + ("ContextId".into(), "app_id".into()), + ("Type".into(), (ut as i32).into()), + ("Payload".into(), payload.into()), + ])]), + ]); + + serialize(value) +} + +fn create_ping() -> Vec { + serialize(Value::Array(vec![6.into()])) +} + +#[allow(dead_code)] +pub enum UpdateType { + SyncCipherUpdate = 0, + SyncCipherCreate = 1, + SyncLoginDelete = 2, + SyncFolderDelete = 3, + SyncCiphers = 4, + + SyncVault = 5, + SyncOrgKeys = 6, + SyncFolderCreate = 7, + SyncFolderUpdate = 8, + SyncCipherDelete = 9, + SyncSettings = 10, + + LogOut = 11, +} + +pub fn start_notification_server() -> WebSocketUsers { + let factory = WSFactory::init(); + let users = factory.users.clone(); + + thread::spawn(move || { + WebSocket::new(factory) + .unwrap() + .listen("0.0.0.0:3012") + .unwrap(); + }); + + users +} diff --git a/src/db/models/folder.rs b/src/db/models/folder.rs index 701a7da..95b1bc8 100644 --- a/src/db/models/folder.rs +++ b/src/db/models/folder.rs @@ -82,13 +82,13 @@ impl Folder { } } - pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + 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( folders::table.filter( - folders::uuid.eq(self.uuid) + folders::uuid.eq(&self.uuid) ) ).execute(&**conn).and(Ok(())) } diff --git a/src/main.rs b/src/main.rs index e715031..d64b2c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,13 @@ -#![feature(plugin, custom_derive)] +#![feature(plugin, custom_derive, vec_remove_item)] #![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; extern crate multipart; +extern crate ws; +extern crate rmpv; +extern crate chashmap; extern crate serde; #[macro_use] extern crate serde_derive; @@ -27,6 +30,7 @@ extern crate lazy_static; #[macro_use] extern crate num_derive; extern crate num_traits; +extern crate byteorder; use std::{env, path::Path, process::{exit, Command}}; use rocket::Rocket; @@ -47,6 +51,7 @@ fn init_rocket() -> Rocket { .mount("/icons", api::icons_routes()) .mount("/notifications", api::notifications_routes()) .manage(db::init_pool()) + .manage(api::start_notification_server()) } // Embed the migrations from the migrations folder into the application @@ -69,8 +74,7 @@ fn main() { check_db(); check_rsa_keys(); check_web_vault(); - migrations::run_migrations(); - + migrations::run_migrations(); init_rocket().launch(); } From b6502e9e9df14d9a3719d4fae15395f83cef3e17 Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Fri, 31 Aug 2018 23:30:53 -0500 Subject: [PATCH 2/6] Add support for CipherUpdate notifications --- src/api/core/ciphers.rs | 58 +++++++++++++++++++++------------------- src/api/notifications.rs | 6 ++--- src/db/models/cipher.rs | 17 ++++++++++++ 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index f9e090c..86332ef 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -1,6 +1,7 @@ use std::path::Path; use std::collections::HashSet; +use rocket::State; use rocket::Data; use rocket::http::ContentType; @@ -16,7 +17,7 @@ use db::models::*; use crypto; -use api::{self, PasswordData, JsonResult, EmptyResult, JsonUpcase}; +use api::{self, PasswordData, JsonResult, EmptyResult, JsonUpcase, WebSocketUsers, UpdateType}; use auth::Headers; use CONFIG; @@ -117,22 +118,22 @@ struct CipherData { } #[post("/ciphers/admin", data = "")] -fn post_ciphers_admin(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn post_ciphers_admin(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { // TODO: Implement this correctly - post_ciphers(data, headers, conn) + post_ciphers(data, headers, conn, ws) } #[post("/ciphers", data = "")] -fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { 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, false, &conn)?; + update_cipher_from_data(&mut cipher, data, &headers, false, &conn, &ws)?; 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 { +fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, shared_to_collection: bool, conn: &DbConn, ws: &State) -> 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"), @@ -190,6 +191,7 @@ fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Head cipher.password_history = data.PasswordHistory.map(|f| f.to_string()); cipher.save(&conn); + ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.get_users(&conn)); if cipher.move_to_folder(data.FolderId, &headers.user.uuid, &conn).is_err() { err!("Error saving the folder information") @@ -219,7 +221,7 @@ struct RelationsData { #[post("/ciphers/import", data = "")] -fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { +fn post_ciphers_import(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let data: ImportData = data.into_inner().data; // Read and create the folders @@ -243,7 +245,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, false, &conn)?; + update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &conn, &ws)?; cipher.move_to_folder(folder_uuid, &headers.user.uuid.clone(), &conn).ok(); } @@ -257,22 +259,22 @@ 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) +fn put_cipher_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { + put_cipher(uuid, data, headers, conn, ws) } #[post("/ciphers//admin", data = "")] -fn post_cipher_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - post_cipher(uuid, data, headers, conn) +fn post_cipher_admin(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { + post_cipher(uuid, data, headers, conn, ws) } #[post("/ciphers/", data = "")] -fn post_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { - put_cipher(uuid, data, headers, conn) +fn post_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { + put_cipher(uuid, data, headers, conn, ws) } #[put("/ciphers/", data = "")] -fn put_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn put_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { let data: CipherData = data.into_inner().data; let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { @@ -284,7 +286,7 @@ fn put_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn err!("Cipher is not write accessible") } - update_cipher_from_data(&mut cipher, data, &headers, false, &conn)?; + update_cipher_from_data(&mut cipher, data, &headers, false, &conn, &ws)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } @@ -349,17 +351,17 @@ struct ShareCipherData { } #[post("/ciphers//share", data = "")] -fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn post_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { let data: ShareCipherData = data.into_inner().data; - share_cipher_by_uuid(&uuid, data, &headers, &conn) + share_cipher_by_uuid(&uuid, data, &headers, &conn, &ws) } #[put("/ciphers//share", data = "")] -fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn) -> JsonResult { +fn put_cipher_share(uuid: String, data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> JsonResult { let data: ShareCipherData = data.into_inner().data; - share_cipher_by_uuid(&uuid, data, &headers, &conn) + share_cipher_by_uuid(&uuid, data, &headers, &conn, &ws) } #[derive(Deserialize)] @@ -370,7 +372,7 @@ struct ShareSelectedCipherData { } #[put("/ciphers/share", data = "")] -fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { +fn put_cipher_share_seleted(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let mut data: ShareSelectedCipherData = data.into_inner().data; let mut cipher_ids: Vec = Vec::new(); @@ -402,15 +404,16 @@ fn put_cipher_share_seleted(data: JsonUpcase, headers: }; match shared_cipher_data.Cipher.Id.take() { - Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn)?, + Some(id) => share_cipher_by_uuid(&id, shared_cipher_data , &headers, &conn, &ws)?, None => err!("Request missing ids field") + }; } Ok(()) } -fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn) -> JsonResult { +fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, conn: &DbConn, ws: &State) -> JsonResult { let mut cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => { if cipher.is_write_accessible_to_user(&headers.user.uuid, &conn) { @@ -443,7 +446,7 @@ fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, co } } } - update_cipher_from_data(&mut cipher, data.Cipher, &headers, shared_to_collection, &conn)?; + update_cipher_from_data(&mut cipher, data.Cipher, &headers, shared_to_collection, &conn, &ws)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } @@ -581,7 +584,7 @@ fn delete_cipher_selected_post(data: JsonUpcase, headers: Headers, conn: } #[post("/ciphers/move", data = "")] -fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { +fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let data = data.into_inner().data; let folder_id = match data.get("FolderId") { @@ -627,14 +630,15 @@ fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) err!("Error saving the folder information") } cipher.save(&conn); + ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.get_users(&conn)); } Ok(()) } #[put("/ciphers/move", data = "")] -fn move_cipher_selected_put(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { - move_cipher_selected(data, headers, conn) +fn move_cipher_selected_put(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + move_cipher_selected(data, headers, conn, ws) } #[post("/ciphers/purge", data = "")] diff --git a/src/api/notifications.rs b/src/api/notifications.rs index ae9721b..299d64c 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -268,7 +268,7 @@ impl WebSocketUsers { self.send_update(&folder.user_uuid, data).ok(); } - pub fn send_cipher_update(&self, ut: UpdateType, cipher: &Cipher, user_uuids: &[&String]) { + pub fn send_cipher_update(&self, ut: UpdateType, cipher: &Cipher, user_uuids: &Vec) { let user_uuid = convert_option(cipher.user_uuid.clone()); let org_uuid = convert_option(cipher.organization_uuid.clone()); @@ -283,8 +283,8 @@ impl WebSocketUsers { ut, ); - for user_uuid in user_uuids { - self.send_update(user_uuid, data.clone()).ok(); + for uuid in user_uuids { + self.send_update(&uuid, data.clone()).ok(); } } } diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 917a76e..43c8949 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -358,4 +358,21 @@ impl Cipher { .select(ciphers_collections::collection_uuid) .load::(&**conn).unwrap_or(vec![]) } + + pub fn get_users(&self, conn: &DbConn) -> Vec { + let mut user_uuids = Vec::new(); + match self.user_uuid { + Some(ref user_uuid) => user_uuids.push(user_uuid.clone()), + 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_uuids.push(user_org.user_uuid.clone()) + }); + } + } + }; + user_uuids + } } From d8e5e532737b5245254b28e31bb61cc9f7e8562e Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Sat, 1 Sep 2018 10:59:13 -0500 Subject: [PATCH 3/6] Add notifications for cipher delete and create --- src/api/core/ciphers.rs | 84 +++++++++++++++++++++++------------------ src/db/models/cipher.rs | 33 ++++++---------- 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/api/core/ciphers.rs b/src/api/core/ciphers.rs index 86332ef..e18405f 100644 --- a/src/api/core/ciphers.rs +++ b/src/api/core/ciphers.rs @@ -128,12 +128,12 @@ fn post_ciphers(data: JsonUpcase, headers: Headers, conn: DbConn, ws 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, false, &conn, &ws)?; + update_cipher_from_data(&mut cipher, data, &headers, false, &conn, &ws, UpdateType::SyncCipherCreate)?; 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, ws: &State) -> EmptyResult { +fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Headers, shared_to_collection: bool, conn: &DbConn, ws: &State, ut: UpdateType) -> 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"), @@ -191,7 +191,7 @@ fn update_cipher_from_data(cipher: &mut Cipher, data: CipherData, headers: &Head cipher.password_history = data.PasswordHistory.map(|f| f.to_string()); cipher.save(&conn); - ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.get_users(&conn)); + ws.send_cipher_update(ut, &cipher, &cipher.update_users_revision(&conn)); if cipher.move_to_folder(data.FolderId, &headers.user.uuid, &conn).is_err() { err!("Error saving the folder information") @@ -245,7 +245,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, false, &conn, &ws)?; + update_cipher_from_data(&mut cipher, cipher_data, &headers, false, &conn, &ws, UpdateType::SyncCipherCreate)?; cipher.move_to_folder(folder_uuid, &headers.user.uuid.clone(), &conn).ok(); } @@ -286,7 +286,7 @@ fn put_cipher(uuid: String, data: JsonUpcase, headers: Headers, conn err!("Cipher is not write accessible") } - update_cipher_from_data(&mut cipher, data, &headers, false, &conn, &ws)?; + update_cipher_from_data(&mut cipher, data, &headers, false, &conn, &ws, UpdateType::SyncCipherUpdate)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } @@ -446,7 +446,7 @@ fn share_cipher_by_uuid(uuid: &str, data: ShareCipherData, headers: &Headers, co } } } - update_cipher_from_data(&mut cipher, data.Cipher, &headers, shared_to_collection, &conn, &ws)?; + update_cipher_from_data(&mut cipher, data.Cipher, &headers, shared_to_collection, &conn, &ws, UpdateType::SyncCipherUpdate)?; Ok(Json(cipher.to_json(&headers.host, &headers.user.uuid, &conn))) } @@ -512,53 +512,53 @@ fn post_attachment_admin(uuid: String, data: Data, content_type: &ContentType, h } #[post("/ciphers//attachment//share", format = "multipart/form-data", data = "")] -fn post_attachment_share(uuid: String, attachment_id: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn) -> JsonResult { - _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn)?; +fn post_attachment_share(uuid: String, attachment_id: String, data: Data, content_type: &ContentType, headers: Headers, conn: DbConn, ws: State) -> JsonResult { + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn, &ws)?; post_attachment(uuid, data, content_type, headers, conn) } #[post("/ciphers//attachment//delete-admin")] -fn delete_attachment_post_admin(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { - delete_attachment(uuid, attachment_id, headers, conn) +fn delete_attachment_post_admin(uuid: String, attachment_id: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + delete_attachment(uuid, attachment_id, headers, conn, ws) } #[post("/ciphers//attachment//delete")] -fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { - delete_attachment(uuid, attachment_id, headers, conn) +fn delete_attachment_post(uuid: String, attachment_id: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + delete_attachment(uuid, attachment_id, headers, conn, ws) } #[delete("/ciphers//attachment/")] -fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn: DbConn) -> EmptyResult { - _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn) +fn delete_attachment(uuid: String, attachment_id: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn, &ws) } #[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) +fn delete_attachment_admin(uuid: String, attachment_id: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_attachment_by_id(&uuid, &attachment_id, &headers, &conn, &ws) } #[post("/ciphers//delete")] -fn delete_cipher_post(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { - _delete_cipher_by_uuid(&uuid, &headers, &conn) +fn delete_cipher_post(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_by_uuid(&uuid, &headers, &conn, &ws) } #[post("/ciphers//delete-admin")] -fn delete_cipher_post_admin(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { - _delete_cipher_by_uuid(&uuid, &headers, &conn) +fn delete_cipher_post_admin(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_by_uuid(&uuid, &headers, &conn, &ws) } #[delete("/ciphers/")] -fn delete_cipher(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { - _delete_cipher_by_uuid(&uuid, &headers, &conn) +fn delete_cipher(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_by_uuid(&uuid, &headers, &conn, &ws) } #[delete("/ciphers//admin")] -fn delete_cipher_admin(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult { - _delete_cipher_by_uuid(&uuid, &headers, &conn) +fn delete_cipher_admin(uuid: String, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + _delete_cipher_by_uuid(&uuid, &headers, &conn, &ws) } #[delete("/ciphers", data = "")] -fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { +fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let data: Value = data.into_inner().data; let uuids = match data.get("Ids") { @@ -570,7 +570,7 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon }; for uuid in uuids { - if let error @ Err(_) = _delete_cipher_by_uuid(uuid, &headers, &conn) { + if let error @ Err(_) = _delete_cipher_by_uuid(uuid, &headers, &conn, &ws) { return error; }; } @@ -579,8 +579,8 @@ fn delete_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbCon } #[post("/ciphers/delete", data = "")] -fn delete_cipher_selected_post(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { - delete_cipher_selected(data, headers, conn) +fn delete_cipher_selected_post(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { + delete_cipher_selected(data, headers, conn, ws) } #[post("/ciphers/move", data = "")] @@ -630,7 +630,7 @@ fn move_cipher_selected(data: JsonUpcase, headers: Headers, conn: DbConn, err!("Error saving the folder information") } cipher.save(&conn); - ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.get_users(&conn)); + ws.send_cipher_update(UpdateType::SyncCipherUpdate, &cipher, &cipher.update_users_revision(&conn)); } Ok(()) @@ -642,7 +642,7 @@ fn move_cipher_selected_put(data: JsonUpcase, headers: Headers, conn: DbC } #[post("/ciphers/purge", data = "")] -fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn) -> EmptyResult { +fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn, ws: State) -> EmptyResult { let data: PasswordData = data.into_inner().data; let password_hash = data.MasterPasswordHash; @@ -657,6 +657,9 @@ fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn) -> if cipher.delete(&conn).is_err() { err!("Failed deleting cipher") } + else { + ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn)); + } } // Delete folders @@ -664,13 +667,16 @@ fn delete_all(data: JsonUpcase, headers: Headers, conn: DbConn) -> if f.delete(&conn).is_err() { err!("Failed deleting folder") } + else { + ws.send_folder_update(UpdateType::SyncFolderCreate, &f); + } } Ok(()) } -fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> EmptyResult { - let cipher = match Cipher::find_by_uuid(uuid, conn) { +fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn, ws: &State) -> EmptyResult { + let cipher = match Cipher::find_by_uuid(&uuid, &conn) { Some(cipher) => cipher, None => err!("Cipher doesn't exist"), }; @@ -679,13 +685,16 @@ fn _delete_cipher_by_uuid(uuid: &str, headers: &Headers, conn: &DbConn) -> Empty err!("Cipher can't be deleted by user") } - match cipher.delete(conn) { - Ok(()) => Ok(()), + match cipher.delete(&conn) { + Ok(()) => { + ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn)); + Ok(()) + } Err(_) => err!("Failed deleting cipher") } } -fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &Headers, conn: &DbConn) -> EmptyResult { +fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &Headers, conn: &DbConn, ws: &State) -> EmptyResult { let attachment = match Attachment::find_by_id(&attachment_id, &conn) { Some(attachment) => attachment, None => err!("Attachment doesn't exist") @@ -706,7 +715,10 @@ fn _delete_cipher_attachment_by_id(uuid: &str, attachment_id: &str, headers: &He // Delete attachment match attachment.delete(&conn) { - Ok(()) => Ok(()), + Ok(()) => { + ws.send_cipher_update(UpdateType::SyncCipherDelete, &cipher, &cipher.update_users_revision(&conn)); + Ok(()) + } Err(_) => err!("Deleting attachement failed") } } diff --git a/src/db/models/cipher.rs b/src/db/models/cipher.rs index 43c8949..2941db0 100644 --- a/src/db/models/cipher.rs +++ b/src/db/models/cipher.rs @@ -130,19 +130,25 @@ impl Cipher { json_object } - pub fn update_users_revision(&self, conn: &DbConn) { + pub fn update_users_revision(&self, conn: &DbConn) -> Vec { + let mut user_uuids = Vec::new(); match self.user_uuid { - Some(ref user_uuid) => User::update_uuid_revision(&user_uuid, conn), + Some(ref user_uuid) => { + User::update_uuid_revision(&user_uuid, conn); + user_uuids.push(user_uuid.clone()) + }, 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) + User::update_uuid_revision(&user_org.user_uuid, conn); + user_uuids.push(user_org.user_uuid.clone()) }); } } }; + user_uuids } pub fn save(&mut self, conn: &DbConn) -> bool { @@ -157,7 +163,7 @@ impl Cipher { } } - pub fn delete(self, conn: &DbConn) -> QueryResult<()> { + pub fn delete(&self, conn: &DbConn) -> QueryResult<()> { self.update_users_revision(conn); FolderCipher::delete_all_by_cipher(&self.uuid, &conn)?; @@ -166,7 +172,7 @@ impl Cipher { diesel::delete( ciphers::table.filter( - ciphers::uuid.eq(self.uuid) + ciphers::uuid.eq(&self.uuid) ) ).execute(&**conn).and(Ok(())) } @@ -358,21 +364,4 @@ impl Cipher { .select(ciphers_collections::collection_uuid) .load::(&**conn).unwrap_or(vec![]) } - - pub fn get_users(&self, conn: &DbConn) -> Vec { - let mut user_uuids = Vec::new(); - match self.user_uuid { - Some(ref user_uuid) => user_uuids.push(user_uuid.clone()), - 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_uuids.push(user_org.user_uuid.clone()) - }); - } - } - }; - user_uuids - } } From 422f7ccfa825509f7e80fc8c58b96ac2807ca27b Mon Sep 17 00:00:00 2001 From: "Shane A. Faulkner" Date: Tue, 4 Sep 2018 10:22:17 -0500 Subject: [PATCH 4/6] Expose 3012 in docker build file for notifications --- Dockerfile | 1 + Dockerfile.alpine | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index c2b9f7c..296c3ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -76,6 +76,7 @@ RUN apt-get update && apt-get install -y\ RUN mkdir /data VOLUME /data EXPOSE 80 +EXPOSE 3012 # Copies the files from the context (env file and web-vault) # and the binary from the "build" stage to the current stage diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 3a8b4b1..8785457 100644 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -68,6 +68,7 @@ RUN apk add \ RUN mkdir /data VOLUME /data EXPOSE 80 +EXPOSE 3012 # Copies the files from the context (env file and web-vault) # and the binary from the "build" stage to the current stage From d66d4fd87ff397a9903cabbd6603eeade63cd05d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 11 Sep 2018 17:09:33 +0200 Subject: [PATCH 5/6] Add error message when the proxy doesn't route websockets correctly --- src/api/notifications.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/api/notifications.rs b/src/api/notifications.rs index 299d64c..6e06a5a 100644 --- a/src/api/notifications.rs +++ b/src/api/notifications.rs @@ -6,7 +6,12 @@ use auth::Headers; use db::DbConn; pub fn routes() -> Vec { - routes![negotiate] + routes![negotiate, websockets_err] +} + +#[get("/hub")] +fn websockets_err() -> JsonResult { + err!("'/notifications/hub' should be proxied towards the websocket server, otherwise notifications will not work. Go to the README for more info.") } #[post("/hub/negotiate")] From 67adfee5e54393bcf3a97542bd67f26a2f22d844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Garc=C3=ADa?= Date: Tue, 11 Sep 2018 17:26:00 +0200 Subject: [PATCH 6/6] Some documentation --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 358941a..33f5e04 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ _*Note, that this project is not associated with the [Bitwarden](https://bitward - [Configuring bitwarden service](#configuring-bitwarden-service) - [Disable registration of new users](#disable-registration-of-new-users) - [Enabling HTTPS](#enabling-https) + - [Enabling WebSocket notifications](#enabling-websocket-notifications) - [Enabling U2F authentication](#enabling-u2f-authentication) - [Changing persistent data location](#changing-persistent-data-location) - [/data prefix:](#data-prefix) @@ -158,6 +159,37 @@ docker run -d --name bitwarden \ ``` Note that you need to mount ssl files and you need to forward appropriate port. +### Enabling WebSocket notifications +*Important: This does not apply to the mobile clients, which use push notifications.* + +To enable WebSockets notifications, an external reverse proxy is necessary, and it must be configured to do the following: +- Route the `/notifications/hub` endpoint to the WebSocket server, by default at port `3012`, making sure to pass the `Connection` and `Upgrade` headers. +- Route everything else, including `/notifications/hub/negotiate`, to the standard Rocket server, by default at port `80`. +- If using Docker, you may need to map both ports with the `-p` flag + +An example configuration is included next for a [Caddy](https://caddyserver.com/) proxy server, and assumes the proxy is running in the same computer as `bitwarden_rs`: + +```r +localhost:2015 { + # The negotiation endpoint is also proxied to Rocket + proxy /notifications/hub/negotiate 0.0.0.0:80 { + transparent + } + + # Notifications redirected to the websockets server + proxy /notifications/hub 0.0.0.0:3012 { + websocket + } + + # Proxy the Root directory to Rocket + proxy / 0.0.0.0:80 { + transparent + } +} +``` + +Note: The reason for this workaround is the lack of support for WebSockets from Rocket (though [it's a planned feature](https://github.com/SergioBenitez/Rocket/issues/90)), which forces us to launch a secondary server on a separate port. + ### Enabling U2F authentication To enable U2F authentication, you must be serving bitwarden_rs from an HTTPS domain with a valid certificate (Either using the included HTTPS options or with a reverse proxy). We recommend using a free certificate from Let's Encrypt.