geforkt von mirrored/vaultwarden
Fixed cipher import, created missing data structs instead of using generic Value, and fixed some warnings
Dieser Commit ist enthalten in:
Ursprung
c8b45f5fe5
Commit
dfefbf1f31
13 geänderte Dateien mit 190 neuen und 131 gelöschten Zeilen
32
Cargo.lock
generiert
32
Cargo.lock
generiert
|
@ -181,7 +181,7 @@ dependencies = [
|
||||||
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ring 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)",
|
||||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -503,12 +503,12 @@ dependencies = [
|
||||||
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper"
|
name = "hyper"
|
||||||
version = "0.11.18"
|
version = "0.11.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -546,7 +546,7 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"native-tls 0.1.5 (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.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -587,7 +587,7 @@ dependencies = [
|
||||||
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -866,7 +866,7 @@ dependencies = [
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"typemap 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -943,12 +943,12 @@ dependencies = [
|
||||||
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"openssl-sys 0.9.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
"openssl-sys 0.9.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.25"
|
version = "0.9.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1153,7 +1153,7 @@ dependencies = [
|
||||||
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1165,7 +1165,7 @@ dependencies = [
|
||||||
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tokio-io 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tokio-tls 0.1.4 (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.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1202,7 +1202,7 @@ dependencies = [
|
||||||
"state 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"state 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"yansi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"yansi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -1347,7 +1347,7 @@ dependencies = [
|
||||||
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1650,7 +1650,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "1.6.0"
|
version = "1.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1829,7 +1829,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum hmac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb5aa9647ba4711e9d6968dc1c810cd23989ed435443ca962e1bf6d8b8b83ff"
|
"checksum hmac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb5aa9647ba4711e9d6968dc1c810cd23989ed435443ca962e1bf6d8b8b83ff"
|
||||||
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
|
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
|
||||||
"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
|
"checksum hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)" = "368cb56b2740ebf4230520e2b90ebb0461e69034d85d1945febd9b3971426db2"
|
||||||
"checksum hyper 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)" = "c4f9b276c87e3fc1902a8bdfcce264c3f7c8a1c35e5e0c946062739f55026664"
|
"checksum hyper 0.11.19 (registry+https://github.com/rust-lang/crates.io-index)" = "47659bb1cb7ef3cd7b4f9bd2a11349b8d92097d34f9597a3c09e9bcefaf92b61"
|
||||||
"checksum hyper-sync-rustls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6df6f419a9f116cc93b5f39a5ded1161e088a2c8424c8fcd1d4049193424a4"
|
"checksum hyper-sync-rustls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6df6f419a9f116cc93b5f39a5ded1161e088a2c8424c8fcd1d4049193424a4"
|
||||||
"checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985"
|
"checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985"
|
||||||
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
|
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
|
||||||
|
@ -1873,7 +1873,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
|
"checksum 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 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 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985"
|
||||||
"checksum openssl-sys 0.9.25 (registry+https://github.com/rust-lang/crates.io-index)" = "93b3cbfaccf11969aea8c2041bfafc43c81666c1ce673476e19395c92cc77bf4"
|
"checksum openssl-sys 0.9.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5a41ce2f5f2d939c80decde8fcfcf5837c203ca6c06a553510a2fcb84fa3ef1"
|
||||||
"checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b"
|
"checksum ordermap 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "b81cf3b8cb96aa0e73bbedfcdc9708d09fec2854ba8d474be4e6f666d7379e8b"
|
||||||
"checksum pear 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c2dabd6c1650d9bfac8e46be7b518b31c3885ab4412de1aca330938616c5bd"
|
"checksum pear 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "b5c2dabd6c1650d9bfac8e46be7b518b31c3885ab4412de1aca330938616c5bd"
|
||||||
"checksum pear_codegen 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "df863bb78b3ee6b049278324eea8df6b2553a8db9a3504c0e32cfcc17bc8d18c"
|
"checksum pear_codegen 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "df863bb78b3ee6b049278324eea8df6b2553a8db9a3504c0e32cfcc17bc8d18c"
|
||||||
|
@ -1955,7 +1955,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 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 untrusted 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f392d7819dbe58833e26872f5f6f0d68b7bbbe90fc3667e98731c4a15ad9a7ae"
|
||||||
"checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068"
|
"checksum url 0.2.38 (registry+https://github.com/rust-lang/crates.io-index)" = "cbaa8377a162d88e7d15db0cf110c8523453edcbc5bc66d2b6fffccffa34a068"
|
||||||
"checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2"
|
"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"
|
||||||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||||||
"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f"
|
"checksum uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "78c590b5bd79ed10aad8fb75f078a59d8db445af6c743e55c4a53227fc01c13f"
|
||||||
"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
|
"checksum uuid 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc7e3b898aa6f6c08e5295b6c89258d1331e9ac578cc992fb818759951bdc22"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use rocket_contrib::{Json, Value};
|
use rocket_contrib::Json;
|
||||||
|
|
||||||
use db::DbConn;
|
use db::DbConn;
|
||||||
use db::models::*;
|
use db::models::*;
|
||||||
|
|
||||||
use api::{JsonResult, EmptyResult};
|
use api::{PasswordData, JsonResult, EmptyResult};
|
||||||
use auth::Headers;
|
use auth::Headers;
|
||||||
|
|
||||||
use CONFIG;
|
use CONFIG;
|
||||||
|
@ -33,15 +33,12 @@ fn register(data: Json<RegisterData>, conn: DbConn) -> EmptyResult {
|
||||||
if !CONFIG.signups_allowed {
|
if !CONFIG.signups_allowed {
|
||||||
err!(format!("Signups not allowed"))
|
err!(format!("Signups not allowed"))
|
||||||
}
|
}
|
||||||
println!("DEBUG - {:#?}", data);
|
|
||||||
|
|
||||||
if let Some(_) = User::find_by_mail(&data.email, &conn) {
|
if let Some(_) = User::find_by_mail(&data.email, &conn) {
|
||||||
err!("Email already exists")
|
err!("Email already exists")
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut user = User::new(data.email,
|
let mut user = User::new(data.email, data.key, data.masterPasswordHash);
|
||||||
data.key,
|
|
||||||
data.masterPasswordHash);
|
|
||||||
|
|
||||||
// Add extra fields if present
|
// Add extra fields if present
|
||||||
if let Some(name) = data.name {
|
if let Some(name) = data.name {
|
||||||
|
@ -81,32 +78,36 @@ fn post_keys(data: Json<KeysData>, headers: Headers, conn: DbConn) -> JsonResult
|
||||||
Ok(Json(user.to_json()))
|
Ok(Json(user.to_json()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/accounts/password", data = "<data>")]
|
#[derive(Deserialize)]
|
||||||
fn post_password(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
#[allow(non_snake_case)]
|
||||||
let key = data["key"].as_str().unwrap();
|
struct ChangePassData {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
masterPasswordHash: String,
|
||||||
let new_password_hash = data["newMasterPasswordHash"].as_str().unwrap();
|
newMasterPasswordHash: String,
|
||||||
|
key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/accounts/password", data = "<data>")]
|
||||||
|
fn post_password(data: Json<ChangePassData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
|
let data: ChangePassData = data.into_inner();
|
||||||
let mut user = headers.user;
|
let mut user = headers.user;
|
||||||
|
|
||||||
if !user.check_valid_password(password_hash) {
|
if !user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
user.set_password(new_password_hash);
|
user.set_password(&data.newMasterPasswordHash);
|
||||||
user.key = key.to_string();
|
user.key = data.key;
|
||||||
user.save(&conn);
|
user.save(&conn);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/accounts/security-stamp", data = "<data>")]
|
#[post("/accounts/security-stamp", data = "<data>")]
|
||||||
fn post_sstamp(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn post_sstamp(data: Json<PasswordData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
let data: PasswordData = data.into_inner();
|
||||||
|
|
||||||
let mut user = headers.user;
|
let mut user = headers.user;
|
||||||
|
|
||||||
if !user.check_valid_password(password_hash) {
|
if !user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,34 +117,39 @@ fn post_sstamp(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/accounts/email-token", data = "<data>")]
|
#[derive(Deserialize)]
|
||||||
fn post_email(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
#[allow(non_snake_case)]
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
struct ChangeEmailData {
|
||||||
let new_email = data["newEmail"].as_str().unwrap();
|
masterPasswordHash: String,
|
||||||
|
newEmail: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[post("/accounts/email-token", data = "<data>")]
|
||||||
|
fn post_email(data: Json<ChangeEmailData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
|
let data: ChangeEmailData = data.into_inner();
|
||||||
let mut user = headers.user;
|
let mut user = headers.user;
|
||||||
|
|
||||||
if !user.check_valid_password(password_hash) {
|
if !user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
if User::find_by_mail(new_email, &conn).is_some() {
|
if User::find_by_mail(&data.newEmail, &conn).is_some() {
|
||||||
err!("Email already in use");
|
err!("Email already in use");
|
||||||
}
|
}
|
||||||
|
|
||||||
user.email = new_email.to_string();
|
user.email = data.newEmail;
|
||||||
user.save(&conn);
|
user.save(&conn);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/accounts/delete", data = "<data>")]
|
#[post("/accounts/delete", data = "<data>")]
|
||||||
fn delete_account(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn delete_account(data: Json<PasswordData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
let data: PasswordData = data.into_inner();
|
||||||
|
|
||||||
let user = headers.user;
|
let user = headers.user;
|
||||||
|
|
||||||
if !user.check_valid_password(password_hash) {
|
if !user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use db::models::*;
|
||||||
use util;
|
use util;
|
||||||
use crypto;
|
use crypto;
|
||||||
|
|
||||||
use api::{self, JsonResult, EmptyResult};
|
use api::{self, PasswordData, JsonResult, EmptyResult};
|
||||||
use auth::Headers;
|
use auth::Headers;
|
||||||
|
|
||||||
use CONFIG;
|
use CONFIG;
|
||||||
|
@ -74,7 +74,9 @@ fn get_cipher(uuid: String, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
struct CipherData {
|
struct CipherData {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
type_: i32,
|
type_: i32,
|
||||||
|
// Folder id is not included in import
|
||||||
folderId: Option<String>,
|
folderId: Option<String>,
|
||||||
|
// TODO: Some of these might appear all the time, no need for Option
|
||||||
organizationId: Option<String>,
|
organizationId: Option<String>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
notes: Option<String>,
|
notes: Option<String>,
|
||||||
|
@ -182,38 +184,62 @@ fn copy_values(from: &Value, to: &mut Value) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use super::folders::FolderData;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct ImportData {
|
||||||
|
ciphers: Vec<CipherData>,
|
||||||
|
folders: Vec<FolderData>,
|
||||||
|
folderRelationships: Vec<RelationsData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct RelationsData {
|
||||||
|
// Cipher id
|
||||||
|
key: u32,
|
||||||
|
// Folder id
|
||||||
|
value: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/ciphers/import", data = "<data>")]
|
#[post("/ciphers/import", data = "<data>")]
|
||||||
fn post_ciphers_import(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn post_ciphers_import(data: Json<ImportData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let data: Value = data.into_inner();
|
let data: ImportData = data.into_inner();
|
||||||
let folders_value = data["folders"].as_array().unwrap();
|
|
||||||
let ciphers_value = data["ciphers"].as_array().unwrap();
|
|
||||||
let relations_value = data["folderRelationships"].as_array().unwrap();
|
|
||||||
|
|
||||||
// Read and create the folders
|
// Read and create the folders
|
||||||
let folders: Vec<_> = folders_value.iter().map(|f| {
|
let folders: Vec<_> = data.folders.iter().map(|folder| {
|
||||||
let name = f["name"].as_str().unwrap().to_string();
|
let mut folder = Folder::new(headers.user.uuid.clone(), folder.name.clone());
|
||||||
let mut folder = Folder::new(headers.user.uuid.clone(), name);
|
|
||||||
folder.save(&conn);
|
folder.save(&conn);
|
||||||
folder
|
folder
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
// Read the relations between folders and ciphers
|
// Read the relations between folders and ciphers
|
||||||
let relations = relations_value.iter().map(|r| r["value"].as_u64().unwrap() as usize);
|
use std::collections::HashMap;
|
||||||
|
let mut relations_map = HashMap::new();
|
||||||
|
|
||||||
|
for relation in data.folderRelationships {
|
||||||
|
relations_map.insert(relation.key, relation.value);
|
||||||
|
}
|
||||||
|
|
||||||
// Read and create the ciphers
|
// Read and create the ciphers
|
||||||
use serde::Deserialize;
|
let mut index = 0;
|
||||||
ciphers_value.iter().zip(
relations).map(|(c, fp)| {
|
for cipher_data in data.ciphers {
|
||||||
let folder_uuid = folders[fp].uuid.clone();
|
let folder_uuid = relations_map.get(&index)
|
||||||
let data = CipherData::deserialize(c.clone()).unwrap();
|
.map(|i| folders[*i as usize].uuid.clone());
|
||||||
|
|
||||||
let user_uuid = headers.user.uuid.clone();
|
let user_uuid = headers.user.uuid.clone();
|
||||||
let favorite = data.favorite.unwrap_or(false);
|
let favorite = cipher_data.favorite.unwrap_or(false);
|
||||||
let mut cipher = Cipher::new(user_uuid, data.type_, favorite);
|
let mut cipher = Cipher::new(user_uuid, cipher_data.type_, favorite);
|
||||||
|
|
||||||
if update_cipher_from_data(&mut cipher, data, &headers, &conn).is_err() { return; }
|
if update_cipher_from_data(&mut cipher, cipher_data, &headers, &conn).is_err() { err!("Error creating cipher") }
|
||||||
|
|
||||||
|
cipher.folder_uuid = folder_uuid;
|
||||||
|
|
||||||
cipher.save(&conn);
|
cipher.save(&conn);
|
||||||
});
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -279,7 +305,7 @@ fn post_attachment(uuid: String, data: Data, content_type: &ContentType, headers
|
||||||
let attachment = Attachment::new(file_name, cipher.uuid.clone(), name, size);
|
let attachment = Attachment::new(file_name, cipher.uuid.clone(), name, size);
|
||||||
println!("Attachment: {:#?}", attachment);
|
println!("Attachment: {:#?}", attachment);
|
||||||
attachment.save(&conn);
|
attachment.save(&conn);
|
||||||
});
|
}).expect("Error processing multipart data");
|
||||||
|
|
||||||
Ok(Json(cipher.to_json(&headers.host, &conn)))
|
Ok(Json(cipher.to_json(&headers.host, &conn)))
|
||||||
}
|
}
|
||||||
|
@ -340,13 +366,14 @@ fn delete_cipher(uuid: String, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/ciphers/delete", data = "<data>")]
|
#[post("/ciphers/purge", data = "<data>")]
|
||||||
fn delete_all(data: Json<Value>, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn delete_all(data: Json<PasswordData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
let data: PasswordData = data.into_inner();
|
||||||
|
let password_hash = data.masterPasswordHash;
|
||||||
|
|
||||||
let user = headers.user;
|
let user = headers.user;
|
||||||
|
|
||||||
if !user.check_valid_password(password_hash) {
|
if !user.check_valid_password(&password_hash) {
|
||||||
err!("Invalid password")
|
err!("Invalid password")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,15 +32,16 @@ fn get_folder(uuid: String, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
Ok(Json(folder.to_json()))
|
Ok(Json(folder.to_json()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct FolderData {
|
||||||
|
pub name: String
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/folders", data = "<data>")]
|
#[post("/folders", data = "<data>")]
|
||||||
fn post_folders(data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult {
|
fn post_folders(data: Json<FolderData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
let name = &data["name"].as_str();
|
let data: FolderData = data.into_inner();
|
||||||
|
|
||||||
if name.is_none() {
|
let mut folder = Folder::new(headers.user.uuid.clone(), data.name);
|
||||||
err!("Invalid name")
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut folder = Folder::new(headers.user.uuid.clone(), name.unwrap().into());
|
|
||||||
|
|
||||||
folder.save(&conn);
|
folder.save(&conn);
|
||||||
|
|
||||||
|
@ -48,12 +49,14 @@ fn post_folders(data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/folders/<uuid>", data = "<data>")]
|
#[post("/folders/<uuid>", data = "<data>")]
|
||||||
fn post_folder(uuid: String, data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult {
|
fn post_folder(uuid: String, data: Json<FolderData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
put_folder(uuid, data, headers, conn)
|
put_folder(uuid, data, headers, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/folders/<uuid>", data = "<data>")]
|
#[put("/folders/<uuid>", data = "<data>")]
|
||||||
fn put_folder(uuid: String, data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult {
|
fn put_folder(uuid: String, data: Json<FolderData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
|
let data: FolderData = data.into_inner();
|
||||||
|
|
||||||
let mut folder = match Folder::find_by_uuid(&uuid, &conn) {
|
let mut folder = match Folder::find_by_uuid(&uuid, &conn) {
|
||||||
Some(folder) => folder,
|
Some(folder) => folder,
|
||||||
_ => err!("Invalid folder")
|
_ => err!("Invalid folder")
|
||||||
|
@ -63,13 +66,7 @@ fn put_folder(uuid: String, data: Json<Value>, headers: Headers, conn: DbConn) -
|
||||||
err!("Folder belongs to another user")
|
err!("Folder belongs to another user")
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = &data["name"].as_str();
|
folder.name = data.name;
|
||||||
|
|
||||||
if name.is_none() {
|
|
||||||
err!("Invalid name")
|
|
||||||
}
|
|
||||||
|
|
||||||
folder.name = name.unwrap().into();
|
|
||||||
|
|
||||||
folder.save(&conn);
|
folder.save(&conn);
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub fn routes() -> Vec<Route> {
|
||||||
|
|
||||||
use rocket::Route;
|
use rocket::Route;
|
||||||
|
|
||||||
use rocket_contrib::{Json, Value};
|
use rocket_contrib::Json;
|
||||||
|
|
||||||
use db::DbConn;
|
use db::DbConn;
|
||||||
|
|
||||||
|
@ -84,14 +84,6 @@ fn put_device_token(uuid: String, conn: DbConn) -> JsonResult {
|
||||||
err!("Not implemented")
|
err!("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
struct EquivDomainData {
|
|
||||||
ExcludedGlobalEquivalentDomains: Option<Vec<i32>>,
|
|
||||||
EquivalentDomains: Option<Vec<Vec<String>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
struct GlobalDomain {
|
struct GlobalDomain {
|
||||||
|
@ -123,6 +115,14 @@ fn get_eq_domains(headers: Headers) -> JsonResult {
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct EquivDomainData {
|
||||||
|
ExcludedGlobalEquivalentDomains: Option<Vec<i32>>,
|
||||||
|
EquivalentDomains: Option<Vec<Vec<String>>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/settings/domains", data = "<data>")]
|
#[post("/settings/domains", data = "<data>")]
|
||||||
fn post_eq_domains(data: Json<EquivDomainData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
fn post_eq_domains(data: Json<EquivDomainData>, headers: Headers, conn: DbConn) -> EmptyResult {
|
||||||
let data: EquivDomainData = data.into_inner();
|
let data: EquivDomainData = data.into_inner();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
use rocket_contrib::{Json, Value};
|
use rocket_contrib::{Json, Value};
|
||||||
|
|
||||||
use db::DbConn;
|
use db::DbConn;
|
||||||
|
|
|
@ -4,13 +4,11 @@ use data_encoding::BASE32;
|
||||||
|
|
||||||
use db::DbConn;
|
use db::DbConn;
|
||||||
|
|
||||||
use util;
|
|
||||||
use crypto;
|
use crypto;
|
||||||
|
|
||||||
use api::{JsonResult, EmptyResult};
|
use api::{PasswordData, JsonResult};
|
||||||
use auth::Headers;
|
use auth::Headers;
|
||||||
|
|
||||||
|
|
||||||
#[get("/two-factor")]
|
#[get("/two-factor")]
|
||||||
fn get_twofactor(headers: Headers) -> JsonResult {
|
fn get_twofactor(headers: Headers) -> JsonResult {
|
||||||
let data = if headers.user.totp_secret.is_none() {
|
let data = if headers.user.totp_secret.is_none() {
|
||||||
|
@ -30,10 +28,10 @@ fn get_twofactor(headers: Headers) -> JsonResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/two-factor/get-recover", data = "<data>")]
|
#[post("/two-factor/get-recover", data = "<data>")]
|
||||||
fn get_recover(data: Json<Value>, headers: Headers) -> JsonResult {
|
fn get_recover(data: Json<PasswordData>, headers: Headers) -> JsonResult {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
let data: PasswordData = data.into_inner();
|
||||||
|
|
||||||
if !headers.user.check_valid_password(password_hash) {
|
if !headers.user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password");
|
err!("Invalid password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,29 +41,33 @@ fn get_recover(data: Json<Value>, headers: Headers) -> JsonResult {
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct RecoverTwoFactor {
|
||||||
|
masterPasswordHash: String,
|
||||||
|
email: String,
|
||||||
|
recoveryCode: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/two-factor/recover", data = "<data>")]
|
#[post("/two-factor/recover", data = "<data>")]
|
||||||
fn recover(data: Json<Value>, conn: DbConn) -> JsonResult {
|
fn recover(data: Json<RecoverTwoFactor>, conn: DbConn) -> JsonResult {
|
||||||
println!("{:#?}", data);
|
let data: RecoverTwoFactor = data.into_inner();
|
||||||
|
|
||||||
use db::models::User;
|
use db::models::User;
|
||||||
|
|
||||||
// Get the user
|
// Get the user
|
||||||
let username = data["email"].as_str().unwrap();
|
let mut user = match User::find_by_mail(&data.email, &conn) {
|
||||||
let mut user = match User::find_by_mail(username, &conn) {
|
|
||||||
Some(user) => user,
|
Some(user) => user,
|
||||||
None => err!("Username or password is incorrect. Try again.")
|
None => err!("Username or password is incorrect. Try again.")
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check password
|
// Check password
|
||||||
let password = data["masterPasswordHash"].as_str().unwrap();
|
if !user.check_valid_password(&data.masterPasswordHash) {
|
||||||
if !user.check_valid_password(password) {
|
|
||||||
err!("Username or password is incorrect. Try again.")
|
err!("Username or password is incorrect. Try again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if recovery code is correct
|
// Check if recovery code is correct
|
||||||
let recovery_code = data["recoveryCode"].as_str().unwrap();
|
if !user.check_valid_recovery_code(&data.recoveryCode) {
|
||||||
|
|
||||||
if !user.check_valid_recovery_code(recovery_code) {
|
|
||||||
err!("Recovery code is incorrect. Try again.")
|
err!("Recovery code is incorrect. Try again.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,10 +79,10 @@ fn recover(data: Json<Value>, conn: DbConn) -> JsonResult {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/two-factor/get-authenticator", data = "<data>")]
|
#[post("/two-factor/get-authenticator", data = "<data>")]
|
||||||
fn generate_authenticator(data: Json<Value>, headers: Headers) -> JsonResult {
|
fn generate_authenticator(data: Json<PasswordData>, headers: Headers) -> JsonResult {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
let data: PasswordData = data.into_inner();
|
||||||
|
|
||||||
if !headers.user.check_valid_password(password_hash) {
|
if !headers.user.check_valid_password(&data.masterPasswordHash) {
|
||||||
err!("Invalid password");
|
err!("Invalid password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,15 +98,24 @@ fn generate_authenticator(data: Json<Value>, headers: Headers) -> JsonResult {
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/two-factor/authenticator", data = "<data>")]
|
#[derive(Deserialize)]
|
||||||
fn activate_authenticator(data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult {
|
#[allow(non_snake_case)]
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
struct EnableTwoFactorData {
|
||||||
|
masterPasswordHash: String,
|
||||||
|
key: String,
|
||||||
|
token: u64,
|
||||||
|
}
|
||||||
|
|
||||||
if !headers.user.check_valid_password(password_hash) {
|
#[post("/two-factor/authenticator", data = "<data>")]
|
||||||
|
fn activate_authenticator(data: Json<EnableTwoFactorData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
|
let data: EnableTwoFactorData = data.into_inner();
|
||||||
|
let password_hash = data.masterPasswordHash;
|
||||||
|
let key = data.key;
|
||||||
|
let token = data.token;
|
||||||
|
|
||||||
|
if !headers.user.check_valid_password(&password_hash) {
|
||||||
err!("Invalid password");
|
err!("Invalid password");
|
||||||
}
|
}
|
||||||
let token = data["token"].as_str();
|
|
||||||
let key = data["key"].as_str().unwrap();
|
|
||||||
|
|
||||||
// Validate key as base32 and 20 bytes length
|
// Validate key as base32 and 20 bytes length
|
||||||
let decoded_key: Vec<u8> = match BASE32.decode(key.as_bytes()) {
|
let decoded_key: Vec<u8> = match BASE32.decode(key.as_bytes()) {
|
||||||
|
@ -121,7 +132,7 @@ fn activate_authenticator(data: Json<Value>, headers: Headers, conn: DbConn) ->
|
||||||
user.totp_secret = Some(key.to_uppercase());
|
user.totp_secret = Some(key.to_uppercase());
|
||||||
|
|
||||||
// Validate the token provided with the key
|
// Validate the token provided with the key
|
||||||
if !user.check_totp_code(util::parse_option_string(token)) {
|
if !user.check_totp_code(Some(token)) {
|
||||||
err!("Invalid totp code")
|
err!("Invalid totp code")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,12 +149,20 @@ fn activate_authenticator(data: Json<Value>, headers: Headers, conn: DbConn) ->
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/two-factor/disable", data = "<data>")]
|
#[derive(Deserialize)]
|
||||||
fn disable_authenticator(data: Json<Value>, headers: Headers, conn: DbConn) -> JsonResult {
|
#[allow(non_snake_case)]
|
||||||
let _type = &data["type"];
|
struct DisableTwoFactorData {
|
||||||
let password_hash = data["masterPasswordHash"].as_str().unwrap();
|
masterPasswordHash: String,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_: u32,
|
||||||
|
}
|
||||||
|
|
||||||
if !headers.user.check_valid_password(password_hash) {
|
#[post("/two-factor/disable", data = "<data>")]
|
||||||
|
fn disable_authenticator(data: Json<DisableTwoFactorData>, headers: Headers, conn: DbConn) -> JsonResult {
|
||||||
|
let data: DisableTwoFactorData = data.into_inner();
|
||||||
|
let password_hash = data.masterPasswordHash;
|
||||||
|
|
||||||
|
if !headers.user.check_valid_password(&password_hash) {
|
||||||
err!("Invalid password");
|
err!("Invalid password");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ use db::models::*;
|
||||||
|
|
||||||
use util;
|
use util;
|
||||||
|
|
||||||
use api::{JsonResult, EmptyResult};
|
use api::JsonResult;
|
||||||
|
|
||||||
pub fn routes() -> Vec<Route> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes![ login]
|
routes![ login]
|
||||||
|
|
|
@ -11,5 +11,13 @@ pub use self::web::routes as web_routes;
|
||||||
use rocket::response::status::BadRequest;
|
use rocket::response::status::BadRequest;
|
||||||
use rocket_contrib::Json;
|
use rocket_contrib::Json;
|
||||||
|
|
||||||
|
// Type aliases for API methods results
|
||||||
type JsonResult = Result<Json, BadRequest<Json>>;
|
type JsonResult = Result<Json, BadRequest<Json>>;
|
||||||
type EmptyResult = Result<(), BadRequest<Json>>;
|
type EmptyResult = Result<(), BadRequest<Json>>;
|
||||||
|
|
||||||
|
// Common structs representing JSON data received
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
struct PasswordData {
|
||||||
|
masterPasswordHash: String
|
||||||
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for Headers {
|
||||||
// Check JWT token is valid and get device and user from it
|
// Check JWT token is valid and get device and user from it
|
||||||
let claims: JWTClaims = match decode_jwt(access_token) {
|
let claims: JWTClaims = match decode_jwt(access_token) {
|
||||||
Ok(claims) => claims,
|
Ok(claims) => claims,
|
||||||
Err(msg) => err_handler!("Invalid claim")
|
Err(_) => err_handler!("Invalid claim")
|
||||||
};
|
};
|
||||||
|
|
||||||
let device_uuid = claims.device;
|
let device_uuid = claims.device;
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub fn get_random_64() -> Vec<u8> {
|
||||||
pub fn get_random(mut array: Vec<u8>) -> Vec<u8> {
|
pub fn get_random(mut array: Vec<u8>) -> Vec<u8> {
|
||||||
use ring::rand::{SecureRandom, SystemRandom};
|
use ring::rand::{SecureRandom, SystemRandom};
|
||||||
|
|
||||||
SystemRandom::new().fill(&mut array);
|
SystemRandom::new().fill(&mut array).expect("Error generating random values");
|
||||||
|
|
||||||
array
|
array
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![allow(unused)]
|
#![allow(unused_variables, dead_code)]
|
||||||
|
|
||||||
#![feature(plugin, custom_derive)]
|
#![feature(plugin, custom_derive)]
|
||||||
#![cfg_attr(test, plugin(stainless))]
|
#![cfg_attr(test, plugin(stainless))]
|
||||||
|
@ -31,9 +31,7 @@ extern crate lazy_static;
|
||||||
|
|
||||||
|
|
||||||
use std::{io, env};
|
use std::{io, env};
|
||||||
|
use rocket::Rocket;
|
||||||
use rocket::{Data, Request, Rocket};
|
|
||||||
use rocket::fairing::{Fairing, Info, Kind};
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
|
|
@ -61,7 +61,9 @@ pub fn delete_file(path: &str) -> bool {
|
||||||
let res = fs::remove_file(path).is_ok();
|
let res = fs::remove_file(path).is_ok();
|
||||||
|
|
||||||
if let Some(parent) = Path::new(path).parent() {
|
if let Some(parent) = Path::new(path).parent() {
|
||||||
fs::remove_dir(parent); // Only removes if the directory is empty
|
// If the directory isn't empty, this returns an error, which we ignore
|
||||||
|
// We only want to delete the folder if it's empty
|
||||||
|
fs::remove_dir(parent).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
|
Laden …
In neuem Issue referenzieren