From 4a9a46a781ff4b469bd83f3f3aaa688170c246a8 Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Fri, 27 Sep 2019 09:46:03 -0700 Subject: [PATCH 1/9] wip --- Cargo.lock | 159 ++++++++++++++++++++++++++++++++++++++++----- Cargo.toml | 2 +- make_hawk_token.py | 58 +++++++++++++++++ src/web/auth.rs | 17 +++-- 4 files changed, 212 insertions(+), 24 deletions(-) create mode 100644 make_hawk_token.py diff --git a/Cargo.lock b/Cargo.lock index deacaa37f3..a9f57e5b6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,6 +411,11 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "bumpalo" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "byte-tools" version = "0.3.1" @@ -998,14 +1003,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hawk" version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1216,6 +1229,14 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "js-sys" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "kernel32-sys" version = "0.2.2" @@ -1525,11 +1546,8 @@ dependencies = [ [[package]] name = "once_cell" -version = "0.1.8" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "opaque-debug" @@ -1963,14 +1981,15 @@ dependencies = [ [[package]] name = "ring" -version = "0.14.6" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2322,6 +2341,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "sourcefile" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "spin" version = "0.5.2" @@ -2404,7 +2428,7 @@ dependencies = [ "google-spanner1 1.0.10+20190613 (registry+https://github.com/rust-lang/crates.io-index)", "googleapis-raw 0.0.1", "grpcio 0.5.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "hawk 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hawk 3.0.0", "hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2798,6 +2822,11 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unicode-segmentation" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.0.4" @@ -2815,7 +2844,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "untrusted" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2919,6 +2948,90 @@ name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "wasm-bindgen" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "wasm-bindgen-webidl" +version = "0.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "web-sys" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "weedle" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "which" version = "2.0.1" @@ -3065,6 +3178,7 @@ dependencies = [ "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" @@ -3130,7 +3244,7 @@ dependencies = [ "checksum grpcio-sys 0.5.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c6e956b8080cd5610a834bee17ab729d4cca2ce05db6987dfbeab18faf98d" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" -"checksum hawk 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7afdba594720e9250e3d3609ec309f8adb26fa18ce39834aeb6724a30bc2431c" +"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" @@ -3152,6 +3266,7 @@ dependencies = [ "checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc9a97d7cec30128fd8b28a7c1f9df1c001ceb9b441e2b755e24130a6b43c79" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" @@ -3189,7 +3304,7 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" +"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" @@ -3237,7 +3352,7 @@ dependencies = [ "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6d896143a583047512e59ac54a215cb203c29cc941917343edea3be8df9c78" "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" -"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" +"checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" @@ -3278,6 +3393,7 @@ dependencies = [ "checksum slog-term 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb9b3fd9a3c2c86580fce3558a98ed7c69039da0288b08a3f15b371635254e08" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" +"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" @@ -3321,10 +3437,11 @@ dependencies = [ "checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" +"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" +"checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" @@ -3336,6 +3453,14 @@ dependencies = [ "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" +"checksum wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "cd34c5ba0d228317ce388e87724633c57edca3e7531feb4e25e35aaa07a656af" +"checksum wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "927196b315c23eed2748442ba675a4c54a1a079d90d9bdc5ad16ce31cf90b15b" +"checksum wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "92c2442bf04d89792816650820c3fb407af8da987a9f10028d5317f5b04c2b4a" +"checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" +"checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" +"checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" +"checksum web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "c84440699cd02ca23bed6f045ffb1497bc18a3c2628bd13e2093186faaaacf6b" +"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index 2b6d03cee2..dc5c1dadb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ grpcio = { version = "0.5.0-alpha.1", optional = true } lazy_static = "1.4.0" # XXX: switch to this line google-apis-rs support #hawk = { version = "3.0.0", default_features = false, features = ["use_openssl"] } -hawk = "3.0.0" +hawk = { version = "3.0.0", path = "../../rust/rust-hawk" } hkdf = "0.8.0" hmac = "0.7" log = "0.4" diff --git a/make_hawk_token.py b/make_hawk_token.py new file mode 100644 index 0000000000..e55acf92d2 --- /dev/null +++ b/make_hawk_token.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +"""Create a Hawk token for tests + +requires hawkauthlib, tokenlib, webob + +""" +import hmac +import time +from datetime import timedelta +from hashlib import sha256 + +import hawkauthlib +import tokenlib +from webob.request import Request + +LEGACY_UID = 1 +FXA_UID = "319b98f9961ff1dbdd07313cd6ba925a" +FXA_KID = "XXX" +DEVICE_ID = "XXX" +NODE = "http://localhost:5000" +# 10 years +DURATION = timedelta(days=10 * 365).total_seconds() + +SECRET = "Ted Koppel is a robot" +HMAC_KEY = b"foo" + + +def create_token(): + expires = int(time.time()) + DURATION + token_data = { + 'uid': LEGACY_UID, + 'node': NODE, + 'expires': expires, + 'fxa_uid': FXA_UID, + 'fxa_kid': FXA_KID, + 'hashed_fxa_uid': metrics_hash(FXA_UID), + 'hashed_device_id': metrics_hash(DEVICE_ID), + } + token = tokenlib.make_token(token_data, secret=SECRET) + key = tokenlib.get_derived_secret(token, secret=SECRET) + return token, key, expires + + +def metrics_hash(value): + hasher = hmac.new(HMAC_KEY, b'', sha256) + # value may be an email address, in which case we only want the first part + hasher.update(value.encode('utf-8').split(b"@", 1)[0]) + return hasher.hexdigest() + +def main(): + token, key, expires = create_token() + req = Request.blank("https://localhost:5000/storage/1.5/1/storage/col2") + header = hawkauthlib.sign_request(req, token, key) + print("Hawk Authorization Header: ", header) + print("Expires: ", expires) + +if __name__ == '__main__': + main() diff --git a/src/web/auth.rs b/src/web/auth.rs index e55361aa54..8af403fec0 100644 --- a/src/web/auth.rs +++ b/src/web/auth.rs @@ -116,6 +116,8 @@ impl HawkPayload { // Comment the following to disable auth verify_hmac(payload, &secrets.signing_secret, signature)?; + eprintln!("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); + dbg!(std::str::from_utf8(payload).unwrap()); let payload: HawkPayload = serde_json::from_slice(payload)?; if expiry == 0 || (payload.expires.round() as u64) > expiry { @@ -194,6 +196,9 @@ mod tests { #[test] fn valid_header() { + use env_logger; + env_logger::init(); + let fixture = TestFixture::new(); let result = HawkPayload::new( @@ -454,10 +459,10 @@ mod tests { fn new() -> TestFixture { TestFixture { header: HawkHeader::new( - "eyJub2RlIjogImh0dHA6Ly9sb2NhbGhvc3Q6NTAwMCIsICJ1aWQiOiAxLCAiZXhwaXJlcyI6IDE1MzYxOTkyNzQsICJmeGFfdWlkIjogIjMxOWI5OGY5OTYxZmYxZGJkZDA3MzEzY2Q2YmE5MjVhIiwgInNhbHQiOiAiYjAyNjBlIiwgImRldmljZV9pZCI6ICJjMDlkMjZmYWYyYjQ5YWI2NGEyODgyOTA3MjA2ZDBiNSJ96drmQ_KNFOe7U3g1D8ZX5-he2Bv2aRvKZzBPrCjHKO4=", - "+1oGdzqpxYndK5ejQLdnZpXgGSt/IlxNh5MvcR6j7t4=", - "omxLZWE=", - 1_536_198_980, + "eyJ1aWQiOiAxLCAibm9kZSI6ICJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCAiZXhwaXJlcyI6IDE4ODQ4OTc5NDUuMCwgImZ4YV91aWQiOiAiMzE5Yjk4Zjk5NjFmZjFkYmRkMDczMTNjZDZiYTkyNWEiLCAiZnhhX2tpZCI6ICJYWFgiLCAiaGFzaGVkX2Z4YV91aWQiOiAiMGU4ZGY1ZDQxMzk4YTM4OTkxM2JkODQwMjQzNTY0OTUxOGFmNDY0OTNkYTFkNGE0MzdhNDZkYzE3ODRjNTAxYSIsICJoYXNoZWRfZGV2aWNlX2lkIjogIjZjODFiNTYwNDFkMzFjZTdjNjEzZGE5Njk5NDUwYjc1YzI4YzkxMWI5ZTkxZWFiMGZhZDI1NGZkNzEyYWRjOTkiLCAic2FsdCI6ICJjMmRhMDAiffgQor4EjvbKT_MZX8lLAy7jSy62Sy_4JagNj9hSzRXD", + "4y7ad0wDSUaGmSUMUxi6JRpyxF2/q3iqZAGSxtT/2ds=", + "bYV1OrQ=", + 1884897945, ), request: Request::new( "GET", @@ -477,9 +482,9 @@ mod tests { ..Default::default() }, expected: HawkPayload { - expires: 1_536_199_274.0, + expires: 1884897945.0, node: "http://localhost:5000".to_string(), - salt: "b0260e".to_string(), + salt: "c2da00".to_string(), user_id: 1, }, } From 00ceea5c79a610234d766f10daa2a4ab814e99c4 Mon Sep 17 00:00:00 2001 From: Philip Jenvey Date: Fri, 27 Sep 2019 11:23:33 -0700 Subject: [PATCH 2/9] more --- Cargo.lock | 159 +++++---------------------------------------- Cargo.toml | 2 +- make_hawk_token.py | 34 ++++++++-- src/web/auth.rs | 22 +++---- 4 files changed, 55 insertions(+), 162 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9f57e5b6f..deacaa37f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,11 +411,6 @@ dependencies = [ "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bumpalo" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byte-tools" version = "0.3.1" @@ -1003,22 +998,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hawk" version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "heck" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1229,14 +1216,6 @@ name = "itoa" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "js-sys" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "kernel32-sys" version = "0.2.2" @@ -1546,8 +1525,11 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.2.0" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "opaque-debug" @@ -1981,15 +1963,14 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.9" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", + "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2341,11 +2322,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "sourcefile" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "spin" version = "0.5.2" @@ -2428,7 +2404,7 @@ dependencies = [ "google-spanner1 1.0.10+20190613 (registry+https://github.com/rust-lang/crates.io-index)", "googleapis-raw 0.0.1", "grpcio 0.5.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", - "hawk 3.0.0", + "hawk 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2822,11 +2798,6 @@ dependencies = [ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "unicode-segmentation" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "unicode-xid" version = "0.0.4" @@ -2844,7 +2815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "untrusted" -version = "0.7.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -2948,90 +2919,6 @@ name = "wasi" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "wasm-bindgen" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "wasm-bindgen-webidl" -version = "0.2.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "web-sys" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", - "wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "weedle" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "which" version = "2.0.1" @@ -3178,7 +3065,6 @@ dependencies = [ "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -"checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" @@ -3244,7 +3130,7 @@ dependencies = [ "checksum grpcio-sys 0.5.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2c6e956b8080cd5610a834bee17ab729d4cca2ce05db6987dfbeab18faf98d" "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" "checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" -"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +"checksum hawk 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7afdba594720e9250e3d3609ec309f8adb26fa18ce39834aeb6724a30bc2431c" "checksum hkdf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3fa08a006102488bd9cd5b8013aabe84955cf5ae22e304c2caf655b633aefae3" "checksum hmac 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" @@ -3266,7 +3152,6 @@ dependencies = [ "checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" -"checksum js-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc9a97d7cec30128fd8b28a7c1f9df1c001ceb9b441e2b755e24130a6b43c79" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" @@ -3304,7 +3189,7 @@ dependencies = [ "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" -"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" +"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37" "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" "checksum openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)" = "8152bb5a9b5b721538462336e3bef9a539f892715e5037fda0f984577311af15" "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" @@ -3352,7 +3237,7 @@ dependencies = [ "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6d896143a583047512e59ac54a215cb203c29cc941917343edea3be8df9c78" "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" -"checksum ring 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6747f8da1f2b1fabbee1aaa4eb8a11abf9adef0bf58a41cee45db5d59cecdfac" +"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" @@ -3393,7 +3278,6 @@ dependencies = [ "checksum slog-term 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb9b3fd9a3c2c86580fce3558a98ed7c69039da0288b08a3f15b371635254e08" "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" -"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" @@ -3437,11 +3321,10 @@ dependencies = [ "checksum unicase 2.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" -"checksum untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece" +"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" "checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea" @@ -3453,14 +3336,6 @@ dependencies = [ "checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" -"checksum wasm-bindgen 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "cd34c5ba0d228317ce388e87724633c57edca3e7531feb4e25e35aaa07a656af" -"checksum wasm-bindgen-backend 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "927196b315c23eed2748442ba675a4c54a1a079d90d9bdc5ad16ce31cf90b15b" -"checksum wasm-bindgen-macro 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "92c2442bf04d89792816650820c3fb407af8da987a9f10028d5317f5b04c2b4a" -"checksum wasm-bindgen-macro-support 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9c075d27b7991c68ca0f77fe628c3513e64f8c477d422b859e03f28751b46fc5" -"checksum wasm-bindgen-shared 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "83d61fe986a7af038dd8b5ec660e5849cbd9f38e7492b9404cc48b2b4df731d1" -"checksum wasm-bindgen-webidl 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)" = "9b979afb0535fe4749906a674082db1211de8aef466331d43232f63accb7c07c" -"checksum web-sys 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)" = "c84440699cd02ca23bed6f045ffb1497bc18a3c2628bd13e2093186faaaacf6b" -"checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" diff --git a/Cargo.toml b/Cargo.toml index dc5c1dadb4..2b6d03cee2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ grpcio = { version = "0.5.0-alpha.1", optional = true } lazy_static = "1.4.0" # XXX: switch to this line google-apis-rs support #hawk = { version = "3.0.0", default_features = false, features = ["use_openssl"] } -hawk = { version = "3.0.0", path = "../../rust/rust-hawk" } +hawk = "3.0.0" hkdf = "0.8.0" hmac = "0.7" log = "0.4" diff --git a/make_hawk_token.py b/make_hawk_token.py index e55acf92d2..6b649a0967 100644 --- a/make_hawk_token.py +++ b/make_hawk_token.py @@ -3,9 +3,17 @@ requires hawkauthlib, tokenlib, webob +Creates the hawk headers for auth::tests, in particular valid_header and +valid_header_with_querystring. + +The latter modifies the query string which changes the mac/nonce and +potentially ts values (in the Hawk header). + """ import hmac +import os import time +from binascii import hexlify from datetime import timedelta from hashlib import sha256 @@ -15,8 +23,8 @@ LEGACY_UID = 1 FXA_UID = "319b98f9961ff1dbdd07313cd6ba925a" -FXA_KID = "XXX" -DEVICE_ID = "XXX" +FXA_KID = "de697ad66d845b2873c9d7e13b8971af" +DEVICE_ID = "device1" NODE = "http://localhost:5000" # 10 years DURATION = timedelta(days=10 * 365).total_seconds() @@ -24,6 +32,8 @@ SECRET = "Ted Koppel is a robot" HMAC_KEY = b"foo" +SALT = hexlify(os.urandom(3)).decode('ascii') + def create_token(): expires = int(time.time()) + DURATION @@ -35,10 +45,11 @@ def create_token(): 'fxa_kid': FXA_KID, 'hashed_fxa_uid': metrics_hash(FXA_UID), 'hashed_device_id': metrics_hash(DEVICE_ID), + 'salt': SALT, } token = tokenlib.make_token(token_data, secret=SECRET) key = tokenlib.get_derived_secret(token, secret=SECRET) - return token, key, expires + return token, key, expires, SALT def metrics_hash(value): @@ -48,11 +59,22 @@ def metrics_hash(value): return hasher.hexdigest() def main(): - token, key, expires = create_token() - req = Request.blank("https://localhost:5000/storage/1.5/1/storage/col2") + token, key, expires, salt = create_token() + path = "http://localhost:5000/storage/1.5/1/storage/col2" + req = Request.blank(path) header = hawkauthlib.sign_request(req, token, key) - print("Hawk Authorization Header: ", header) print("Expires: ", expires) + print("Salt: ", salt) + print("\nPath: ", path) + print("Hawk Authorization Header: ", header) + + path = ("http://localhost:5000/storage/1.5/1/storage/col2" + "?batch=MTUzNjE5ODk3NjkyMQ==&commit=true") + req = Request.blank(path, POST="") + header = hawkauthlib.sign_request(req, token, key) + print("\nPath: ", path) + print("Hawk Authorization Header: ", header) + if __name__ == '__main__': main() diff --git a/src/web/auth.rs b/src/web/auth.rs index 8af403fec0..bc1c6e4a06 100644 --- a/src/web/auth.rs +++ b/src/web/auth.rs @@ -116,7 +116,6 @@ impl HawkPayload { // Comment the following to disable auth verify_hmac(payload, &secrets.signing_secret, signature)?; - eprintln!("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); dbg!(std::str::from_utf8(payload).unwrap()); let payload: HawkPayload = serde_json::from_slice(payload)?; @@ -196,9 +195,6 @@ mod tests { #[test] fn valid_header() { - use env_logger; - env_logger::init(); - let fixture = TestFixture::new(); let result = HawkPayload::new( @@ -220,9 +216,9 @@ mod tests { #[test] fn valid_header_with_querystring() { let mut fixture = TestFixture::new(); - fixture.header.mac = "xRVjP7607eZUWCBxJKwTo1CsLcNf4TZwUUNrLPUqkdQ=".to_string(); - fixture.header.nonce = "1d4mRs0=".to_string(); - fixture.header.ts = 1_536_198_978; + fixture.header.mac = "E7j1UjN7//mh7pYXsgGi3n0KGR+sUPpuyogDVzJWaHg=".to_string(); + fixture.header.nonce = "4Rj7c+0=".to_string(); + fixture.header.ts = 1_569_608_439; fixture.request.method = "POST".to_string(); fixture .request @@ -459,10 +455,10 @@ mod tests { fn new() -> TestFixture { TestFixture { header: HawkHeader::new( - "eyJ1aWQiOiAxLCAibm9kZSI6ICJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCAiZXhwaXJlcyI6IDE4ODQ4OTc5NDUuMCwgImZ4YV91aWQiOiAiMzE5Yjk4Zjk5NjFmZjFkYmRkMDczMTNjZDZiYTkyNWEiLCAiZnhhX2tpZCI6ICJYWFgiLCAiaGFzaGVkX2Z4YV91aWQiOiAiMGU4ZGY1ZDQxMzk4YTM4OTkxM2JkODQwMjQzNTY0OTUxOGFmNDY0OTNkYTFkNGE0MzdhNDZkYzE3ODRjNTAxYSIsICJoYXNoZWRfZGV2aWNlX2lkIjogIjZjODFiNTYwNDFkMzFjZTdjNjEzZGE5Njk5NDUwYjc1YzI4YzkxMWI5ZTkxZWFiMGZhZDI1NGZkNzEyYWRjOTkiLCAic2FsdCI6ICJjMmRhMDAiffgQor4EjvbKT_MZX8lLAy7jSy62Sy_4JagNj9hSzRXD", - "4y7ad0wDSUaGmSUMUxi6JRpyxF2/q3iqZAGSxtT/2ds=", - "bYV1OrQ=", - 1884897945, + "eyJ1aWQiOiAxLCAibm9kZSI6ICJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCAiZXhwaXJlcyI6IDE4ODQ5Njg0MzkuMCwgImZ4YV91aWQiOiAiMzE5Yjk4Zjk5NjFmZjFkYmRkMDczMTNjZDZiYTkyNWEiLCAiZnhhX2tpZCI6ICJkZTY5N2FkNjZkODQ1YjI4NzNjOWQ3ZTEzYjg5NzFhZiIsICJoYXNoZWRfZnhhX3VpZCI6ICIwZThkZjVkNDEzOThhMzg5OTEzYmQ4NDAyNDM1NjQ5NTE4YWY0NjQ5M2RhMWQ0YTQzN2E0NmRjMTc4NGM1MDFhIiwgImhhc2hlZF9kZXZpY2VfaWQiOiAiMmJjYjkyZjRkNDY5OGMzZDdiMDgzYTNjNjk4YTE2Y2NkNzhiYzJhOGQyMGE5NmU0YmIxMjhkZGNlYWY0ZTBiNiIsICJzYWx0IjogIjJiMzA3YiJ9lXaC5pIOenf7qL1AWlgKFvYH63nakyniTXP-7acS5cw=", + "UwDpC+DSrHCSTQSfMOWlueB6kM6gHb0Hsv8eU9ZcTVs=", + "h1Ch4vo=", + 1_569_608_439, ), request: Request::new( "GET", @@ -482,9 +478,9 @@ mod tests { ..Default::default() }, expected: HawkPayload { - expires: 1884897945.0, + expires: 1_884_968_439.0, node: "http://localhost:5000".to_string(), - salt: "c2da00".to_string(), + salt: "2b307b".to_string(), user_id: 1, }, } From 64a1f5366db2ce8910d25e2a695f93ec941b4a58 Mon Sep 17 00:00:00 2001 From: jrconlin Date: Fri, 27 Sep 2019 16:17:45 -0700 Subject: [PATCH 3/9] f Add "kid" column to database * May want to use alternate "sync_kid" db. DSN: spanner://projects/sync-spanner-dev-225401/instances/spanner-test/databases/sync_kid * switched over index to use "fxa_id" (kid), and pass HawkParameter when possible Issue #170 --- src/db/spanner/models.rs | 177 ++++++++++++++++++++------------------- src/server/test.rs | 2 +- 2 files changed, 93 insertions(+), 86 deletions(-) diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index b9f24e713a..b228f7b055 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -22,7 +22,7 @@ use crate::db::{ Db, DbFuture, Sorting, FIRST_CUSTOM_COLLECTION_ID, }; -use crate::web::extractors::BsoQueryParams; +use crate::web::extractors::{BsoQueryParams, HawkIdentifier}; use super::{ batch, @@ -60,10 +60,10 @@ struct SpannerDbSession { /// CURRENT_TIMESTAMP() from Spanner, used for timestamping this session's /// operations timestamp: Option, - /// Cache of collection modified timestamps per (user_id, collection_id) - coll_modified_cache: HashMap<(u32, i32), SyncTimestamp>, + /// Cache of collection modified timestamps per (fxa_id, collection_id) + coll_modified_cache: HashMap<(String, i32), SyncTimestamp>, /// Currently locked collections - coll_locks: HashMap<(u32, i32), CollectionLock>, + coll_locks: HashMap<(String, i32), CollectionLock>, #[cfg(feature = "google_grpc")] transaction: Option, #[cfg(not(feature = "google_grpc"))] @@ -183,7 +183,7 @@ impl SpannerDb { // Begin a transaction self.begin(false)?; - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.fxa_id; let collection_id = self.get_collection_id(¶ms.collection) .or_else(|e| match e.kind() { @@ -199,7 +199,7 @@ impl SpannerDb { .session .borrow() .coll_locks - .get(&(user_id, collection_id)) + .get(&(user_id.clone(), collection_id)) .is_some() { return Ok(()); @@ -208,7 +208,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_locks - .insert((user_id, collection_id), CollectionLock::Read); + .insert((user_id.clone(), collection_id), CollectionLock::Read); Ok(()) } @@ -217,22 +217,22 @@ impl SpannerDb { // Begin a transaction self.begin(true)?; - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.fxa_id; let collection_id = self.get_or_create_collection_id(¶ms.collection)?; if let Some(CollectionLock::Read) = self .inner .session .borrow() .coll_locks - .get(&(user_id, collection_id)) + .get(&(user_id.clone(), collection_id)) { Err(DbError::internal("Can't escalate read-lock to write-lock"))? } let result = self - .sql("SELECT CURRENT_TIMESTAMP(), last_modified FROM user_collections WHERE userid=@userid AND collection=@collectionid")? + .sql("SELECT CURRENT_TIMESTAMP(), last_modified FROM user_collections WHERE kid=@kid AND collection=@collectionid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.clone(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -243,7 +243,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_modified_cache - .insert((user_id, collection_id), modified); + .insert((user_id.clone(), collection_id), modified); SyncTimestamp::from_rfc3339(result[0].get_string_value())? } else { let result = self @@ -257,7 +257,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_locks - .insert((user_id, collection_id), CollectionLock::Write); + .insert((user_id.clone(), collection_id), CollectionLock::Write); Ok(()) } @@ -475,7 +475,7 @@ impl SpannerDb { &self, params: params::GetCollectionTimestamp, ) -> Result { - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.fxa_id; dbg!("!!QQQ get_collection_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; @@ -483,15 +483,15 @@ impl SpannerDb { .session .borrow() .coll_modified_cache - .get(&(user_id, collection_id)) + .get(&(user_id.clone(), collection_id)) { return Ok(*modified); } let result = self - .sql("SELECT last_modified FROM user_collections WHERE userid=@userid AND collection=@collectionid")? + .sql("SELECT last_modified FROM user_collections WHERE kid=@kid AND collection=@collectionid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.clone(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -505,10 +505,10 @@ impl SpannerDb { &self, user_id: params::GetCollectionTimestamps, ) -> Result { - let user_id = user_id.legacy_id as u32; + let user_id = user_id.fxa_id; let modifieds = self - .sql("SELECT collection, last_modified FROM user_collections WHERE userid=@userid")? - .params(params! {"userid" => user_id.to_string()}) + .sql("SELECT collection, last_modified FROM user_collections WHERE kid=@kid")? + .params(params! {"kid" => user_id}) .execute(&self.conn)? .map(|row| { let collection_id = row[0] @@ -580,10 +580,10 @@ impl SpannerDb { &self, user_id: params::GetCollectionCounts, ) -> Result { - let user_id = user_id.legacy_id as u32; + let user_id = user_id.fxa_id; let counts = self - .sql("SELECT collection, COUNT(collection) FROM bso WHERE userid=@userid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection")? - .params(params! {"userid" => user_id.to_string()}) + .sql("SELECT collection, COUNT(collection) FROM bso WHERE kid=@kid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection")? + .params(params! {"kid" => user_id}) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -604,10 +604,10 @@ impl SpannerDb { &self, user_id: params::GetCollectionUsage, ) -> Result { - let user_id = user_id.legacy_id as u32; + let user_id = user_id.fxa_id; let usages = self - .sql("SELECT collection, SUM(LENGTH(payload)) FROM bso WHERE userid=@userid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection")? - .params(params! {"userid" => user_id.to_string()}) + .sql("SELECT collection, SUM(LENGTH(payload)) FROM bso WHERE kid=@kid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection")? + .params(params! {"kid" => user_id}) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -628,11 +628,11 @@ impl SpannerDb { &self, user_id: params::GetStorageTimestamp, ) -> Result { - let user_id = user_id.legacy_id as u32; + let user_id = user_id.fxa_id; let ts0 = "0001-01-01T00:00:00Z"; let result = self - .sql(&format!("SELECT COALESCE(MAX(last_modified), TIMESTAMP '{}') FROM user_collections WHERE userid=@userid", ts0))? - .params(params! {"userid" => user_id.to_string()}) + .sql(&format!("SELECT COALESCE(MAX(last_modified), TIMESTAMP '{}') FROM user_collections WHERE kid=@kid", ts0))? + .params(params! {"kid" => user_id}) .execute(&self.conn)? .one_or_none()?; if let Some(result) = result { @@ -653,10 +653,10 @@ impl SpannerDb { &self, user_id: params::GetStorageUsage, ) -> Result { - let user_id = user_id.legacy_id as u32; + let user_id = user_id.fxa_id; let result = self - .sql("SELECT SUM(LENGTH(payload)) FROM bso WHERE userid=@userid AND ttl > CURRENT_TIMESTAMP() GROUP BY userid")? - .params(params! {"userid" => user_id.to_string()}) + .sql("SELECT SUM(LENGTH(payload)) FROM bso WHERE kid=@kid AND ttl > CURRENT_TIMESTAMP() GROUP BY kid")? + .params(params! {"kid" => user_id}) .execute(&self.conn)? .one_or_none()?; if let Some(result) = result { @@ -670,20 +670,23 @@ impl SpannerDb { } } - fn erect_tombstone(&self, user_id: u32) -> Result<()> { + fn erect_tombstone(&self, user_id: &HawkIdentifier) -> Result<()> { // Delete the old tombstone (if it exists) - self.sql("DELETE from user_collections where userid=@userid and collection=@collection")? + let legacy = user_id.legacy_id as i32; + let kid = user_id.fxa_id.clone(); + self.sql("DELETE from user_collections where kid=@kid and collection=@collection")? .params(params! { - "userid" => user_id.to_string(), + "kid" => kid.clone(), "collection" => TOMBSTONE.to_string(), }) .param_types(param_types! { "collection" => SpannerType::Int64, }) .execute(&self.conn)?; - self.sql("INSERT INTO user_collections (userid, collection, last_modified) values (@userid, @collection, @modified)")? + self.sql("INSERT INTO user_collections (userid, kid, collection, last_modified) values (@userid, @kid, @collection, @modified)")? .params(params!{ - "userid" => user_id.to_string(), + "userid" => legacy.to_string(), + "kid" => kid, "collection" => TOMBSTONE.to_string(), "modified" => self.timestamp()?.as_rfc3339()?}) .param_types(param_types!{ @@ -695,12 +698,12 @@ impl SpannerDb { } pub fn delete_storage_sync(&self, user_id: params::DeleteStorage) -> Result<()> { - let user_id = user_id.legacy_id as u32; - self.sql("DELETE FROM user_collections WHERE userid=@userid")? - .params(params! {"userid" => user_id.to_string()}) + let user_id = user_id.fxa_id; + self.sql("DELETE FROM user_collections WHERE kid=@kid")? + .params(params! {"kid" => user_id.clone()}) .execute(&self.conn)?; - self.sql("DELETE FROM bso WHERE userid=@userid")? - .params(params! {"userid" => user_id.to_string()}) + self.sql("DELETE FROM bso WHERE kid=@kid")? + .params(params! {"kid" => user_id.clone()}) .execute(&self.conn)?; Ok(()) } @@ -716,27 +719,27 @@ impl SpannerDb { &self, params: params::DeleteCollection, ) -> Result { - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.fxa_id.clone(); let collection_id = self.get_collection_id(¶ms.collection)?; - self.sql("DELETE FROM bso WHERE userid=@userid AND collection=@collectionid")? + self.sql("DELETE FROM bso WHERE kid=@kid AND collection=@collectionid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.clone(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)?; - self.sql("DELETE FROM user_collections WHERE userid=@userid AND collection=@collectionid")? + self.sql("DELETE FROM user_collections WHERE kid=@kid AND collection=@collectionid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.clone(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)?; - self.erect_tombstone(user_id)?; + self.erect_tombstone(¶ms.user_id)?; self.get_storage_timestamp_sync(params.user_id) } pub(super) fn touch_collection( &self, - user_id: u32, + user_id: &HawkIdentifier, collection_id: i32, ) -> Result { // NOTE: Spanner supports upserts via its InsertOrUpdate mutation but @@ -750,9 +753,9 @@ impl SpannerDb { // transaction Commit. let timestamp = self.timestamp()?; let result = self - .sql("SELECT 1 as count FROM user_collections WHERE userid = @userid AND collection = @collectionid;")? + .sql("SELECT 1 as count FROM user_collections WHERE kid = @kid AND collection = @collectionid;")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.fxa_id.clone(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -761,9 +764,9 @@ impl SpannerDb { if exists { self - .sql("UPDATE user_collections SET last_modified=@last_modified WHERE userid=@userid AND collection=@collectionid")? + .sql("UPDATE user_collections SET last_modified=@last_modified WHERE kid=@kid AND collection=@collectionid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.fxa_id.clone(), "collectionid" => collection_id.to_string(), "last_modified" => timestamp.as_rfc3339()?, }) @@ -774,9 +777,10 @@ impl SpannerDb { Ok(timestamp) } else { self - .sql("INSERT INTO user_collections (userid, collection, last_modified) VALUES (@userid, @collectionid, @modified)")? + .sql("INSERT INTO user_collections (userid, kid, collection, last_modified) VALUES (@legacy, @kid, @collectionid, @modified)")? .params(params! { - "userid" => user_id.to_string(), + "legacy" => user_id.legacy_id.to_string(), + "kid" => user_id.fxa_id.clone(), "collectionid" => collection_id.to_string(), "modified" => timestamp.as_rfc3339()?, }) @@ -789,14 +793,14 @@ impl SpannerDb { } pub fn delete_bso_sync(&self, params: params::DeleteBso) -> Result { - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.clone(); let collection_id = self.get_collection_id(¶ms.collection)?; - let touch = self.touch_collection(user_id as u32, collection_id)?; + let touch = self.touch_collection(¶ms.user_id, collection_id)?; let result = self - .sql("DELETE FROM bso WHERE userid=@userid AND collection=@collectionid AND id=@bsoid")? + .sql("DELETE FROM bso WHERE kid=@kid AND collection=@collectionid AND id=@bsoid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id.fxa_id.clone(), "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -809,23 +813,24 @@ impl SpannerDb { } pub fn delete_bsos_sync(&self, params: params::DeleteBsos) -> Result { - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.clone(); let collection_id = self.get_collection_id(¶ms.collection)?; let mut sqlparams = params! { - "userid" => user_id.to_string(), + "kid" => user_id.fxa_id, "collectionid" => collection_id.to_string(), }; sqlparams.insert("ids".to_owned(), as_list_value(params.ids.into_iter())); - self - .sql("DELETE FROM bso WHERE userid=@userid AND collection=@collectionid AND id IN UNNEST(@ids)")? - .params(sqlparams) - .execute(&self.conn)?; - self.touch_collection(user_id, collection_id) + self.sql( + "DELETE FROM bso WHERE kid=@kid AND collection=@collectionid AND id IN UNNEST(@ids)", + )? + .params(sqlparams) + .execute(&self.conn)?; + self.touch_collection(¶ms.user_id, collection_id) } pub fn get_bsos_sync(&self, params: params::GetBsos) -> Result { - let user_id = params.user_id.legacy_id as i32; + let user_id = params.user_id.fxa_id.clone(); let collection_id = self.get_collection_id(¶ms.collection)?; let BsoQueryParams { newer, @@ -837,9 +842,9 @@ impl SpannerDb { .. } = params.params; - let mut query = "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso WHERE userid = @userid AND collection = @collectionid AND ttl > CURRENT_TIMESTAMP()".to_string(); + let mut query = "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso WHERE kid = @kid AND collection = @collectionid AND ttl > CURRENT_TIMESTAMP()".to_string(); let mut sqlparams = params! { - "userid" => user_id.to_string(), + "kid" => user_id, "collectionid" => collection_id.to_string(), }; let mut sqltypes = HashMap::new(); @@ -927,13 +932,13 @@ impl SpannerDb { } pub fn get_bso_sync(&self, params: params::GetBso) -> Result> { - let user_id = params.user_id.legacy_id; + let user_id = params.user_id.fxa_id; let collection_id = self.get_collection_id(¶ms.collection)?; let result = self. - sql("SELECT id, modified, payload, coalesce(sortindex, NULL), ttl FROM bso WHERE userid=@userid AND collection=@collectionid AND id=@bsoid AND ttl > CURRENT_TIMESTAMP()")? + sql("SELECT id, modified, payload, coalesce(sortindex, NULL), ttl FROM bso WHERE kid=@kid AND collection=@collectionid AND id=@bsoid AND ttl > CURRENT_TIMESTAMP()")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id, "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -947,14 +952,14 @@ impl SpannerDb { } pub fn get_bso_timestamp_sync(&self, params: params::GetBsoTimestamp) -> Result { - let user_id = params.user_id.legacy_id as u32; + let user_id = params.user_id.fxa_id; dbg!("!!QQQ get_bso_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; let result = self - .sql("SELECT modified FROM bso WHERE collection=@collectionid AND userid=@userid AND id=@bsoid AND ttl > CURRENT_TIMESTAMP()")? + .sql("SELECT modified FROM bso WHERE collection=@collectionid AND kid=@kid AND id=@bsoid AND ttl > CURRENT_TIMESTAMP()")? .params(params! { - "userid" => user_id.to_string(), + "kid" => user_id, "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -969,14 +974,15 @@ impl SpannerDb { pub fn put_bso_sync(&self, bso: params::PutBso) -> Result { let collection_id = self.get_or_create_collection_id(&bso.collection)?; - let user_id: u64 = bso.user_id.legacy_id; - let touch = self.touch_collection(user_id as u32, collection_id)?; + let kid = bso.user_id.fxa_id.clone(); + let legacy = bso.user_id.legacy_id as i32; + let touch = self.touch_collection(&bso.user_id, collection_id)?; let timestamp = self.timestamp()?; let result = self - .sql("SELECT 1 as count FROM bso WHERE userid = @userid AND collection = @collectionid AND id = @bsoid")? + .sql("SELECT 1 as count FROM bso WHERE kid = @kid AND collection = @collectionid AND id = @bsoid")? .params(params! { - "userid" => user_id.to_string(), + "kid" => kid.clone(), "collectionid" => collection_id.to_string(), "bsoid" => bso.id.to_string(), }) @@ -985,7 +991,8 @@ impl SpannerDb { let exists = result.is_some(); let mut sqlparams = params! { - "userid" => user_id.to_string(), + "kid" => kid.clone(), + "userid" => legacy.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => bso.id.to_string(), }; @@ -1056,7 +1063,7 @@ impl SpannerDb { q = format!( "UPDATE bso SET {}{}", - q, " WHERE userid = @userid AND collection = @collectionid AND id = @bsoid" + q, " WHERE kid = @kid AND collection = @collectionid AND id = @bsoid" ); q @@ -1067,9 +1074,9 @@ impl SpannerDb { .unwrap_or_else(|| "NULL".to_owned()) != "NULL"; let sql = if use_sortindex { - "INSERT INTO bso (userid, collection, id, sortindex, payload, modified, ttl) VALUES (@userid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" + "INSERT INTO bso (userid, kid, collection, id, sortindex, payload, modified, ttl) VALUES (@userid, @kid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" } else { - "INSERT INTO bso (userid, collection, id, payload, modified, ttl) VALUES (@userid, @collectionid, @bsoid, @payload, @modified, @expiry)" + "INSERT INTO bso (userid, kid, collection, id, payload, modified, ttl) VALUES (@userid, @kid, @collectionid, @bsoid, @payload, @modified, @expiry)" }; if use_sortindex { @@ -1140,7 +1147,7 @@ impl SpannerDb { })?; result.success.push(id); } - self.touch_collection(input.user_id.legacy_id as u32, collection_id)?; + self.touch_collection(&input.user_id, collection_id)?; Ok(result) } @@ -1266,7 +1273,7 @@ impl Db for SpannerDb { let db = self.clone(); Box::new(self.thread_pool.spawn_handle(lazy(move || { future::result( - db.touch_collection(param.user_id.legacy_id as u32, param.collection_id) + db.touch_collection(¶m.user_id, param.collection_id) .map_err(Into::into), ) }))) diff --git a/src/server/test.rs b/src/server/test.rs index b711d59116..a7c6607526 100644 --- a/src/server/test.rs +++ b/src/server/test.rs @@ -267,7 +267,7 @@ fn delete_collection() { http::Method::DELETE, "/1.5/42/storage/bookmarks", None, - Some("0.00"), + None, // deleting a collection may return a tombstone rather than "0.00" ); test_endpoint_with_response( http::Method::DELETE, From adb463f072fa89a8f029eb81cbef78b2d5cf6743 Mon Sep 17 00:00:00 2001 From: jrconlin Date: Tue, 1 Oct 2019 17:24:08 -0700 Subject: [PATCH 4/9] f r's * Added ddl for spanner * include old index and new index entries * change to fxa_kid to reduce confusion * match tombstone behaviors between mysql & spanner Closes #170 --- spanner-2019-10-01.ddl | 37 +++++ src/db/spanner/models.rs | 302 ++++++++++++++++++++++++--------------- src/server/test.rs | 26 +++- src/web/auth.rs | 15 ++ src/web/extractors.rs | 9 +- 5 files changed, 267 insertions(+), 122 deletions(-) create mode 100644 spanner-2019-10-01.ddl diff --git a/spanner-2019-10-01.ddl b/spanner-2019-10-01.ddl new file mode 100644 index 0000000000..4b00c228c0 --- /dev/null +++ b/spanner-2019-10-01.ddl @@ -0,0 +1,37 @@ +CREATE TABLE batches ( + userid STRING(MAX) NOT NULL, + collection INT64 NOT NULL, + id TIMESTAMP NOT NULL, + fxa_kid STRING(MAX) NOT NULL, + bsos STRING(MAX) NOT NULL, + expiry TIMESTAMP NOT NULL, + timestamp TIMESTAMP, +) PRIMARY KEY(userid, fxa_kid, collection, id); + +CREATE TABLE collections ( + collectionid INT64 NOT NULL, + name STRING(MAX) NOT NULL, +) PRIMARY KEY(collectionid); + +CREATE TABLE user_collections ( + userid STRING(MAX) NOT NULL, + fxa_kid STRING(MAX) NOT NULL, + collection INT64 NOT NULL, + last_modified TIMESTAMP NOT NULL, +) PRIMARY KEY(userid, fxa_kid, collection); + +CREATE TABLE bso ( + userid STRING(MAX) NOT NULL, + fxa_kid STRING(MAX) NOT NULL, + collection INT64 NOT NULL, + id STRING(MAX) NOT NULL, + sortindex INT64, + modified TIMESTAMP NOT NULL, + payload STRING(MAX) NOT NULL, + ttl TIMESTAMP NOT NULL, +) PRIMARY KEY(userid, fxa_kid, collection, id), + INTERLEAVE IN PARENT user_collections ON DELETE CASCADE; + +CREATE INDEX BsoLastModified ON bso(userid, fxa_kid, collection, modified DESC, ttl), INTERLEAVE IN user_collections; + +CREATE INDEX BsoTtl ON bso(ttl) \ No newline at end of file diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index 43b809bf57..8113fdc75c 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -60,10 +60,10 @@ struct SpannerDbSession { /// CURRENT_TIMESTAMP() from Spanner, used for timestamping this session's /// operations timestamp: Option, - /// Cache of collection modified timestamps per (fxa_id, collection_id) - coll_modified_cache: HashMap<(String, i32), SyncTimestamp>, + /// Cache of collection modified timestamps per (fxa_kid, legacy_id, collection_id) + coll_modified_cache: HashMap<(String, i32, i32), SyncTimestamp>, /// Currently locked collections - coll_locks: HashMap<(String, i32), CollectionLock>, + coll_locks: HashMap<(String, i32, i32), CollectionLock>, #[cfg(feature = "google_grpc")] transaction: Option, #[cfg(not(feature = "google_grpc"))] @@ -193,7 +193,9 @@ impl SpannerDb { // Begin a transaction self.begin(false)?; - let user_id = params.user_id.fxa_id; + let fxa_kid = params.user_id.fxa_kid; + let legacy = params.user_id.legacy_id as i32; + let collection_id = self.get_collection_id(¶ms.collection) .or_else(|e| match e.kind() { @@ -209,16 +211,16 @@ impl SpannerDb { .session .borrow() .coll_locks - .get(&(user_id.clone(), collection_id)) + .get(&(fxa_kid.clone(), legacy, collection_id)) .is_some() { return Ok(()); } - self.session - .borrow_mut() - .coll_locks - .insert((user_id.clone(), collection_id), CollectionLock::Read); + self.session.borrow_mut().coll_locks.insert( + (fxa_kid.clone(), legacy, collection_id), + CollectionLock::Read, + ); Ok(()) } @@ -227,14 +229,15 @@ impl SpannerDb { // Begin a transaction self.begin(true)?; - let user_id = params.user_id.fxa_id; + let fxa_kid = params.user_id.fxa_kid; + let legacy = params.user_id.legacy_id as i32; let collection_id = self.get_or_create_collection_id(¶ms.collection)?; - if let Some(CollectionLock::Read) = self - .inner - .session - .borrow() - .coll_locks - .get(&(user_id.clone(), collection_id)) + if let Some(CollectionLock::Read) = + self.inner + .session + .borrow() + .coll_locks + .get(&(fxa_kid.clone(), legacy, collection_id)) { Err(DbError::internal("Can't escalate read-lock to write-lock"))? } @@ -243,11 +246,13 @@ impl SpannerDb { .sql( "SELECT CURRENT_TIMESTAMP(), last_modified FROM user_collections - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", )? .params(params! { - "kid" => user_id.clone(), + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -258,7 +263,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_modified_cache - .insert((user_id.clone(), collection_id), modified); + .insert((fxa_kid.clone(), legacy, collection_id), modified); SyncTimestamp::from_rfc3339(result[0].get_string_value())? } else { let result = self @@ -269,10 +274,10 @@ impl SpannerDb { }; self.set_timestamp(timestamp); - self.session - .borrow_mut() - .coll_locks - .insert((user_id.clone(), collection_id), CollectionLock::Write); + self.session.borrow_mut().coll_locks.insert( + (fxa_kid.clone(), legacy, collection_id), + CollectionLock::Write, + ); Ok(()) } @@ -490,15 +495,16 @@ impl SpannerDb { &self, params: params::GetCollectionTimestamp, ) -> Result { - let user_id = params.user_id.fxa_id; + let fxa_kid = params.user_id.fxa_kid; + let legacy = params.user_id.legacy_id as i32; dbg!("!!QQQ get_collection_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; - if let Some(modified) = self - .session - .borrow() - .coll_modified_cache - .get(&(user_id.clone(), collection_id)) + if let Some(modified) = + self.session + .borrow() + .coll_modified_cache + .get(&(fxa_kid.clone(), legacy, collection_id)) { return Ok(*modified); } @@ -507,11 +513,13 @@ impl SpannerDb { .sql( "SELECT last_modified FROM user_collections - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", )? .params(params! { - "kid" => user_id.clone(), + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -525,14 +533,19 @@ impl SpannerDb { &self, user_id: params::GetCollectionTimestamps, ) -> Result { - let user_id = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; let modifieds = self .sql( "SELECT collection, last_modified FROM user_collections - WHERE kid = @kid", + WHERE fxa_kid = @fxa_kid + AND userid = @legacy", )? - .params(params! {"kid" => user_id}) + .params(params! { + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string() + }) .execute(&self.conn)? .map(|row| { let collection_id = row[0] @@ -606,16 +619,21 @@ impl SpannerDb { &self, user_id: params::GetCollectionCounts, ) -> Result { - let user_id = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; + let counts = self .sql( "SELECT collection, COUNT(collection) FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND ttl > CURRENT_TIMESTAMP() GROUP BY collection", )? - .params(params! {"kid" => user_id}) + .params(params! { + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string()}) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -636,16 +654,21 @@ impl SpannerDb { &self, user_id: params::GetCollectionUsage, ) -> Result { - let user_id = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; + let usages = self .sql( "SELECT collection, SUM(LENGTH(payload)) FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND ttl > CURRENT_TIMESTAMP() GROUP BY collection", )? - .params(params! {"kid" => user_id}) + .params(params! { + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string()}) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -666,16 +689,21 @@ impl SpannerDb { &self, user_id: params::GetStorageTimestamp, ) -> Result { - let user_id = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; let ts0 = "0001-01-01T00:00:00Z"; let result = self .sql(&format!( "SELECT COALESCE(MAX(last_modified), TIMESTAMP '{}') FROM user_collections - WHERE kid = @kid", + WHERE fxa_kid = @fxa_kid + AND userid = @legacy", ts0 ))? - .params(params! {"kid" => user_id}) + .params(params! { + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string(), + }) .execute(&self.conn)? .one_or_none()?; if let Some(result) = result { @@ -696,16 +724,21 @@ impl SpannerDb { &self, user_id: params::GetStorageUsage, ) -> Result { - let user_id = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; let result = self .sql( "SELECT SUM(LENGTH(payload)) FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND ttl > CURRENT_TIMESTAMP() - GROUP BY kid", + GROUP BY fxa_kid", )? - .params(params! {"kid" => user_id}) + .params(params! { + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string() + }) .execute(&self.conn)? .one_or_none()?; if let Some(result) = result { @@ -719,18 +752,19 @@ impl SpannerDb { } } - fn erect_tombstone(&self, user_id: &HawkIdentifier) -> Result<()> { + fn erect_tombstone(&self, user_id: &HawkIdentifier) -> Result { // Delete the old tombstone (if it exists) - - let legacy = user_id.legacy_id as i32; - let kid = user_id.fxa_id.clone(); + let legacy = user_id.legacy_id; + let fxa_kid = user_id.fxa_kid.clone(); self.sql( "DELETE FROM user_collections - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collection", )? .params(params! { - "kid" => kid, + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string(), "collection" => TOMBSTONE.to_string(), }) .param_types(param_types! { @@ -739,12 +773,12 @@ impl SpannerDb { .execute(&self.conn)?; self.sql( - "INSERT INTO user_collections (userid, kid, collection, last_modified) - VALUES (@userid, @kid, @collection, @modified)", + "INSERT INTO user_collections (userid, fxa_kid, collection, last_modified) + VALUES (@userid, @fxa_kid, @collection, @modified)", )? .params(params! { "userid" => legacy.to_string(), - "kid" => user_id.fxa_id.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), "collection" => TOMBSTONE.to_string(), "modified" => self.timestamp()?.as_rfc3339()? }) @@ -753,23 +787,34 @@ impl SpannerDb { "collection" => SpannerType::Int64, }) .execute(&self.conn)?; - Ok(()) + // Return timestamp, because sometimes there's a delay between writing and + // reading the database. + Ok(self.timestamp()?) } pub fn delete_storage_sync(&self, user_id: params::DeleteStorage) -> Result<()> { - let kid = user_id.fxa_id; + let fxa_kid = user_id.fxa_kid; + let legacy = user_id.legacy_id; self.sql( "DELETE FROM user_collections - WHERE kid = @kid", + WHERE fxa_kid = @fxa_kid + AND userid = @legacy", )? - .params(params! {"kid" => kid.clone()}) + .params(params! { + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string() + }) .execute(&self.conn)?; self.sql( "DELETE FROM bso - WHERE kid = @kid", + WHERE fxa_kid = @fxa_kid + AND userid = @legacy", )? - .params(params! {"kid" => kid.clone()}) + .params(params! { + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string() + }) .execute(&self.conn)?; Ok(()) } @@ -785,31 +830,44 @@ impl SpannerDb { &self, params: params::DeleteCollection, ) -> Result { - let kid = params.user_id.fxa_id.clone(); + let fxa_kid = params.user_id.fxa_kid.clone(); + let legacy = params.user_id.legacy_id; let collection_id = self.get_collection_id(¶ms.collection)?; - self.sql( - "DELETE FROM bso - WHERE kid = @kid + let mut result = self + .sql( + "DELETE FROM bso + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", - )? - .params(params! { - "kid" => kid.clone(), - "collectionid" => collection_id.to_string(), - }) - .execute(&self.conn)?; + )? + .params(params! { + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string(), + "collectionid" => collection_id.to_string(), + }) + .execute(&self.conn)? + .one_or_none()? + .is_some(); - self.sql( - "DELETE FROM user_collections - WHERE kid = @kid + result = result + || self + .sql( + "DELETE FROM user_collections + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", - )? - .params(params! { - "kid" => kid.to_string(), - "collectionid" => collection_id.to_string(), - }) - .execute(&self.conn)?; - - self.erect_tombstone(¶ms.user_id)?; + )? + .params(params! { + "fxa_kid" => fxa_kid.to_string(), + "legacy" => legacy.to_string(), + "collectionid" => collection_id.to_string(), + }) + .execute(&self.conn)? + .one_or_none()? + .is_some(); + if result { + self.erect_tombstone(¶ms.user_id)?; + } self.get_storage_timestamp_sync(params.user_id) } @@ -832,11 +890,13 @@ impl SpannerDb { .sql( "SELECT 1 as count FROM user_collections - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", )? .params(params! { - "kid" => user_id.fxa_id.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), + "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -847,11 +907,13 @@ impl SpannerDb { self.sql( "UPDATE user_collections SET last_modified = @last_modified - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid", )? .params(params! { - "kid" => user_id.fxa_id.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), + "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "last_modified" => timestamp.as_rfc3339()?, }) @@ -862,11 +924,11 @@ impl SpannerDb { Ok(timestamp) } else { self.sql( - "INSERT INTO user_collections (kid, userid, collection, last_modified) - VALUES (@kid, @userid, @collectionid, @modified)", + "INSERT INTO user_collections (fxa_kid, userid, collection, last_modified) + VALUES (@fxa_kid, @userid, @collectionid, @modified)", )? .params(params! { - "kid" => user_id.fxa_id.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), "userid" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "modified" => timestamp.as_rfc3339()?, @@ -887,12 +949,14 @@ impl SpannerDb { let result = self .sql( "DELETE FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND id = @bsoid", )? .params(params! { - "kid" => user_id.fxa_id.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), + "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -909,13 +973,15 @@ impl SpannerDb { let collection_id = self.get_collection_id(¶ms.collection)?; let mut sqlparams = params! { - "kid" => user_id.fxa_id, + "fxa_kid" => user_id.fxa_kid, + "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), }; sqlparams.insert("ids".to_owned(), as_list_value(params.ids.into_iter())); self.sql( "DELETE FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND id IN UNNEST(@ids)", )? @@ -925,7 +991,8 @@ impl SpannerDb { } pub fn get_bsos_sync(&self, params: params::GetBsos) -> Result { - let user_id = params.user_id.fxa_id.clone(); + let fxa_kid = params.user_id.fxa_kid.clone(); + let legacy = params.user_id.legacy_id; let collection_id = self.get_collection_id(¶ms.collection)?; let BsoQueryParams { newer, @@ -939,12 +1006,14 @@ impl SpannerDb { let mut query = "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND ttl > CURRENT_TIMESTAMP()" .to_string(); let mut sqlparams = params! { - "kid" => user_id, + "fxa_kid" => fxa_kid, + "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), }; let mut sqltypes = HashMap::new(); @@ -1032,20 +1101,22 @@ impl SpannerDb { } pub fn get_bso_sync(&self, params: params::GetBso) -> Result> { - let user_id = params.user_id.fxa_id; + let fxa_kid = params.user_id.fxa_kid; let collection_id = self.get_collection_id(¶ms.collection)?; let result = self .sql( "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND id = @bsoid AND ttl > CURRENT_TIMESTAMP()", )? .params(params! { - "kid" => user_id, + "fxa_kid" => fxa_kid, + "legacy" => params.user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -1059,7 +1130,7 @@ impl SpannerDb { } pub fn get_bso_timestamp_sync(&self, params: params::GetBsoTimestamp) -> Result { - let kid = params.user_id.fxa_id; + let fxa_kid = params.user_id.fxa_kid; dbg!("!!QQQ get_bso_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; @@ -1068,12 +1139,14 @@ impl SpannerDb { "SELECT modified FROM bso WHERE collection = @collectionid - AND kid = @kid + AND userid = @legacy + AND fxa_kid = @fxa_kid AND id = @bsoid AND ttl > CURRENT_TIMESTAMP()", )? .params(params! { - "kid" => kid, + "fxa_kid" => fxa_kid, + "legacy" => params.user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -1088,8 +1161,8 @@ impl SpannerDb { pub fn put_bso_sync(&self, bso: params::PutBso) -> Result { let collection_id = self.get_or_create_collection_id(&bso.collection)?; - let kid = bso.user_id.fxa_id.clone(); - let legacy = bso.user_id.legacy_id as i32; + let fxa_kid = bso.user_id.fxa_kid.clone(); + let legacy = bso.user_id.legacy_id; let touch = self.touch_collection(&bso.user_id, collection_id)?; let timestamp = self.timestamp()?; @@ -1097,12 +1170,14 @@ impl SpannerDb { .sql( "SELECT 1 as count FROM bso - WHERE kid = @kid + WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND id = @bsoid", )? .params(params! { - "kid" => kid.clone(), + "fxa_kid" => fxa_kid.clone(), + "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => bso.id.to_string(), }) @@ -1111,7 +1186,7 @@ impl SpannerDb { let exists = result.is_some(); let mut sqlparams = params! { - "kid" => kid.clone(), + "fxa_kid" => fxa_kid.clone(), "userid" => legacy.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => bso.id.to_string(), @@ -1184,7 +1259,8 @@ impl SpannerDb { q = format!( "UPDATE bso SET {}{}", q, - " WHERE kid = @kid + " WHERE fxa_kid = @fxa_kid + AND userid = @legacy AND collection = @collectionid AND id = @bsoid" ); @@ -1197,11 +1273,11 @@ impl SpannerDb { .unwrap_or_else(|| "NULL".to_owned()) != "NULL"; let sql = if use_sortindex { - "INSERT INTO bso (userid, kid, collection, id, sortindex, payload, modified, ttl) - VALUES (@userid, @kid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" + "INSERT INTO bso (userid, fxa_kid, collection, id, sortindex, payload, modified, ttl) + VALUES (@userid, @fxa_kid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" } else { - "INSERT INTO bso (userid, kid, collection, id, payload, modified, ttl) - VALUES (@userid, @kid, @collectionid, @bsoid, @payload, @modified, @expiry)" + "INSERT INTO bso (userid, fxa_kid, collection, id, payload, modified, ttl) + VALUES (@userid, @fxa_kid, @collectionid, @bsoid, @payload, @modified, @expiry)" }; if use_sortindex { diff --git a/src/server/test.rs b/src/server/test.rs index a7c6607526..960fda05b3 100644 --- a/src/server/test.rs +++ b/src/server/test.rs @@ -109,6 +109,9 @@ fn create_hawk_header(method: &str, port: u16, path: &str) -> String { node: format!("http://{}:{}", host, port).to_string(), salt: "wibble".to_string(), user_id: 42, + fxa_uid: "xxx_test".to_owned(), + fxa_kid: "xxx_test".to_owned(), + device_id: "xxx_test".to_owned(), }; let payload = serde_json::to_string(&payload).unwrap(); let mut signature: Hmac = Hmac::new_varkey(&SECRETS.signing_secret).unwrap(); @@ -177,6 +180,7 @@ where panic!("test_endpoint_with_response: Block failed: {:?}", e); } }; + if !sresponse.response().status().is_success() { dbg!( "⚠️ Warning: Returned error", @@ -191,7 +195,7 @@ where panic!("test_endpoint_with_response: serde_json failed: {:?}", e); } }; - assertions(result); + assertions(result) } fn test_endpoint_with_body(method: http::Method, path: &str, body: serde_json::Value) -> Bytes { @@ -263,24 +267,34 @@ fn delete_all() { #[test] fn delete_collection() { let start = SyncTimestamp::default(); - test_endpoint( + test_endpoint_with_response( http::Method::DELETE, "/1.5/42/storage/bookmarks", - None, - None, // deleting a collection may return a tombstone rather than "0.00" + &move |result: DeleteBso| { + assert!( + result == SyncTimestamp::from_seconds(0.00), + format!("Bad Bookmarks {:?} != 0", result) + ); + }, ); test_endpoint_with_response( http::Method::DELETE, "/1.5/42/storage/bookmarks?ids=1,", &move |result: DeleteBso| { - assert!(result > start); + assert!( + result > start, + format!("Bad Bookmarks ids {:?} < {:?}", result, start) + ); }, ); test_endpoint_with_response( http::Method::DELETE, "/1.5/42/storage/bookmarks?ids=1,2,3", &move |result: DeleteBso| { - assert!(result > start); + assert!( + result > start, + format!("Bad Bookmarks ids, m {:?} < {:?}", result, start) + ); }, ); } diff --git a/src/web/auth.rs b/src/web/auth.rs index bc1c6e4a06..66ae8cc7f7 100644 --- a/src/web/auth.rs +++ b/src/web/auth.rs @@ -42,6 +42,15 @@ pub struct HawkPayload { /// User identifier. #[serde(rename = "uid")] pub user_id: u64, + + #[serde(default)] + pub fxa_uid: String, + + #[serde(default)] + pub fxa_kid: String, + + #[serde(default, rename = "hashed_device_id")] + pub device_id: String, } impl HawkPayload { @@ -133,6 +142,9 @@ impl HawkPayload { node: "friendly-node".to_string(), salt: "saltysalt".to_string(), user_id, + fxa_uid: "xxx_test".to_owned(), + fxa_kid: "xxx_test".to_owned(), + device_id: "xxx_test".to_owned(), } } } @@ -482,6 +494,9 @@ mod tests { node: "http://localhost:5000".to_string(), salt: "2b307b".to_string(), user_id: 1, + fxa_uid: "319b98f9961ff1dbdd07313cd6ba925a".to_owned(), + fxa_kid: "de697ad66d845b2873c9d7e13b8971af".to_owned(), + device_id: "2bcb92f4d4698c3d7b083a3c698a16ccd78bc2a8d20a96e4bb128ddceaf4e0b6".to_owned(), }, } } diff --git a/src/web/extractors.rs b/src/web/extractors.rs index c5372b65c9..5289e6cba1 100644 --- a/src/web/extractors.rs +++ b/src/web/extractors.rs @@ -820,7 +820,8 @@ pub struct HawkIdentifier { /// For MySQL database backends as the primary key pub legacy_id: u64, /// For NoSQL database backends that require randomly distributed primary keys - pub fxa_id: String, + pub fxa_uid: String, + pub fxa_kid: String, } impl HawkIdentifier { @@ -836,7 +837,8 @@ impl HawkIdentifier { // Create a "dummy" HawkID for use by DockerFlow commands Self { legacy_id: 0, - fxa_id: "cmd".to_owned(), + fxa_uid: "cmd".to_owned(), + fxa_kid: "cmd".to_owned(), } } @@ -906,7 +908,8 @@ impl HawkIdentifier { let user_id = HawkIdentifier { legacy_id: payload.user_id, - fxa_id: "".to_string(), + fxa_uid: "".to_string(), + fxa_kid: "".to_string(), }; Ok(user_id) } From 3635377e23278ce686f5010e5c30296b362f5a8c Mon Sep 17 00:00:00 2001 From: jrconlin Date: Wed, 2 Oct 2019 10:55:26 -0700 Subject: [PATCH 5/9] f rm dbg! --- src/web/auth.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/web/auth.rs b/src/web/auth.rs index 66ae8cc7f7..808376f3ea 100644 --- a/src/web/auth.rs +++ b/src/web/auth.rs @@ -125,7 +125,6 @@ impl HawkPayload { // Comment the following to disable auth verify_hmac(payload, &secrets.signing_secret, signature)?; - dbg!(std::str::from_utf8(payload).unwrap()); let payload: HawkPayload = serde_json::from_slice(payload)?; if expiry == 0 || (payload.expires.round() as u64) > expiry { From 46c3f98f4a33b6d25b2052fe364ae1dc96728c0c Mon Sep 17 00:00:00 2001 From: jrconlin Date: Wed, 2 Oct 2019 17:12:36 -0700 Subject: [PATCH 6/9] f r's --- src/db/spanner/models.rs | 354 ++++++++++++++++----------------------- src/web/extractors.rs | 4 +- 2 files changed, 148 insertions(+), 210 deletions(-) diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index 8113fdc75c..acdc0c20d1 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -60,10 +60,10 @@ struct SpannerDbSession { /// CURRENT_TIMESTAMP() from Spanner, used for timestamping this session's /// operations timestamp: Option, - /// Cache of collection modified timestamps per (fxa_kid, legacy_id, collection_id) - coll_modified_cache: HashMap<(String, i32, i32), SyncTimestamp>, + /// Cache of collection modified timestamps per (fxa_kid, fxa_uid, collection_id) + coll_modified_cache: HashMap<(String, String, i32), SyncTimestamp>, /// Currently locked collections - coll_locks: HashMap<(String, i32, i32), CollectionLock>, + coll_locks: HashMap<(String, String, i32), CollectionLock>, #[cfg(feature = "google_grpc")] transaction: Option, #[cfg(not(feature = "google_grpc"))] @@ -194,7 +194,7 @@ impl SpannerDb { self.begin(false)?; let fxa_kid = params.user_id.fxa_kid; - let legacy = params.user_id.legacy_id as i32; + let fxa_uid = params.user_id.fxa_uid; let collection_id = self.get_collection_id(¶ms.collection) @@ -211,14 +211,14 @@ impl SpannerDb { .session .borrow() .coll_locks - .get(&(fxa_kid.clone(), legacy, collection_id)) + .get(&(fxa_kid.clone(), fxa_uid.clone(), collection_id)) .is_some() { return Ok(()); } self.session.borrow_mut().coll_locks.insert( - (fxa_kid.clone(), legacy, collection_id), + (fxa_kid.clone(), fxa_uid.clone(), collection_id), CollectionLock::Read, ); @@ -230,15 +230,13 @@ impl SpannerDb { self.begin(true)?; let fxa_kid = params.user_id.fxa_kid; - let legacy = params.user_id.legacy_id as i32; + let fxa_uid = params.user_id.fxa_uid; let collection_id = self.get_or_create_collection_id(¶ms.collection)?; - if let Some(CollectionLock::Read) = - self.inner - .session - .borrow() - .coll_locks - .get(&(fxa_kid.clone(), legacy, collection_id)) - { + if let Some(CollectionLock::Read) = self.inner.session.borrow().coll_locks.get(&( + fxa_kid.clone(), + fxa_uid.clone(), + collection_id, + )) { Err(DbError::internal("Can't escalate read-lock to write-lock"))? } @@ -246,13 +244,13 @@ impl SpannerDb { .sql( "SELECT CURRENT_TIMESTAMP(), last_modified FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid", )? .params(params! { + "fxa_uid" => fxa_uid.clone(), "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -263,7 +261,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_modified_cache - .insert((fxa_kid.clone(), legacy, collection_id), modified); + .insert((fxa_kid.clone(), fxa_uid.clone(), collection_id), modified); SyncTimestamp::from_rfc3339(result[0].get_string_value())? } else { let result = self @@ -275,7 +273,7 @@ impl SpannerDb { self.set_timestamp(timestamp); self.session.borrow_mut().coll_locks.insert( - (fxa_kid.clone(), legacy, collection_id), + (fxa_kid.clone(), fxa_uid.clone(), collection_id), CollectionLock::Write, ); @@ -496,16 +494,15 @@ impl SpannerDb { params: params::GetCollectionTimestamp, ) -> Result { let fxa_kid = params.user_id.fxa_kid; - let legacy = params.user_id.legacy_id as i32; + let fxa_uid = params.user_id.fxa_uid; dbg!("!!QQQ get_collection_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; - if let Some(modified) = - self.session - .borrow() - .coll_modified_cache - .get(&(fxa_kid.clone(), legacy, collection_id)) - { + if let Some(modified) = self.session.borrow().coll_modified_cache.get(&( + fxa_kid.clone(), + fxa_uid.clone(), + collection_id, + )) { return Ok(*modified); } @@ -513,13 +510,13 @@ impl SpannerDb { .sql( "SELECT last_modified FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid", )? .params(params! { + "fxa_uid" => fxa_uid.to_string(), "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string(), "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -534,17 +531,17 @@ impl SpannerDb { user_id: params::GetCollectionTimestamps, ) -> Result { let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; + let fxa_uid = user_id.fxa_uid; let modifieds = self .sql( "SELECT collection, last_modified FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy", + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid", )? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string() + "fxa_uid" => fxa_uid, + "fxa_kid" => fxa_kid }) .execute(&self.conn)? .map(|row| { @@ -620,20 +617,21 @@ impl SpannerDb { user_id: params::GetCollectionCounts, ) -> Result { let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; + let fxa_uid = user_id.fxa_uid; let counts = self .sql( "SELECT collection, COUNT(collection) FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection", )? .params(params! { + "fxa_uid" => fxa_uid, "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string()}) + }) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -654,21 +652,19 @@ impl SpannerDb { &self, user_id: params::GetCollectionUsage, ) -> Result { - let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; - let usages = self .sql( "SELECT collection, SUM(LENGTH(payload)) FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND ttl > CURRENT_TIMESTAMP() GROUP BY collection", )? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string()}) + "fxa_uid" => user_id.fxa_uid, + "fxa_kid" => user_id.fxa_kid + }) .execute(&self.conn)? .map(|row| { let collection = row[0] @@ -689,20 +685,18 @@ impl SpannerDb { &self, user_id: params::GetStorageTimestamp, ) -> Result { - let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; let ts0 = "0001-01-01T00:00:00Z"; let result = self .sql(&format!( "SELECT COALESCE(MAX(last_modified), TIMESTAMP '{}') FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy", + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid", ts0 ))? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string(), + "fxa_uid" => user_id.fxa_uid, + "fxa_kid" => user_id.fxa_kid }) .execute(&self.conn)? .one_or_none()?; @@ -724,20 +718,18 @@ impl SpannerDb { &self, user_id: params::GetStorageUsage, ) -> Result { - let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; let result = self .sql( "SELECT SUM(LENGTH(payload)) FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND ttl > CURRENT_TIMESTAMP() GROUP BY fxa_kid", )? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string() + "fxa_uid" => user_id.fxa_uid, + "fxa_kid" => user_id.fxa_kid }) .execute(&self.conn)? .one_or_none()?; @@ -754,38 +746,32 @@ impl SpannerDb { fn erect_tombstone(&self, user_id: &HawkIdentifier) -> Result { // Delete the old tombstone (if it exists) - let legacy = user_id.legacy_id; - let fxa_kid = user_id.fxa_kid.clone(); + let params = params! { + "fxa_uid" => user_id.fxa_uid.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), + "collection" => TOMBSTONE.to_string(), + "modified" => self.timestamp()?.as_rfc3339()? + }; + let types = param_types! { + "modified" => SpannerType::Timestamp, + "collection" => SpannerType::Int64, + }; self.sql( "DELETE FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collection", )? - .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string(), - "collection" => TOMBSTONE.to_string(), - }) - .param_types(param_types! { - "collection" => SpannerType::Int64, - }) + .params(params.clone()) + .param_types(types.clone()) .execute(&self.conn)?; self.sql( "INSERT INTO user_collections (userid, fxa_kid, collection, last_modified) - VALUES (@userid, @fxa_kid, @collection, @modified)", + VALUES (@fxa_uid, @fxa_kid, @collection, @modified)", )? - .params(params! { - "userid" => legacy.to_string(), - "fxa_kid" => user_id.fxa_kid.clone(), - "collection" => TOMBSTONE.to_string(), - "modified" => self.timestamp()?.as_rfc3339()? - }) - .param_types(param_types! { - "modified" => SpannerType::Timestamp, - "collection" => SpannerType::Int64, - }) + .params(params.clone()) + .param_types(types.clone()) .execute(&self.conn)?; // Return timestamp, because sometimes there's a delay between writing and // reading the database. @@ -793,28 +779,24 @@ impl SpannerDb { } pub fn delete_storage_sync(&self, user_id: params::DeleteStorage) -> Result<()> { - let fxa_kid = user_id.fxa_kid; - let legacy = user_id.legacy_id; + let params = params! { + "fxa_uid" => user_id.fxa_uid.clone(), + "fxa_kid" => user_id.fxa_kid.clone() + }; self.sql( "DELETE FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy", + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid", )? - .params(params! { - "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string() - }) + .params(params.clone()) .execute(&self.conn)?; self.sql( "DELETE FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy", + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid", )? - .params(params! { - "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string() - }) + .params(params.clone()) .execute(&self.conn)?; Ok(()) } @@ -830,42 +812,23 @@ impl SpannerDb { &self, params: params::DeleteCollection, ) -> Result { - let fxa_kid = params.user_id.fxa_kid.clone(); - let legacy = params.user_id.legacy_id; - let collection_id = self.get_collection_id(¶ms.collection)?; - let mut result = self + let sqlparams = params! { + "fxa_uid" => params.user_id.fxa_uid.clone(), + "fxa_kid" => params.user_id.fxa_kid.clone(), + "collectionid" => self.get_collection_id(¶ms.collection)?.to_string(), + }; + if self .sql( - "DELETE FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy - AND collection = @collectionid", + "DELETE FROM user_collections + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid + AND collection = @collectionid", )? - .params(params! { - "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string(), - "collectionid" => collection_id.to_string(), - }) + .params(sqlparams.clone()) .execute(&self.conn)? - .one_or_none()? - .is_some(); - - result = result - || self - .sql( - "DELETE FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy - AND collection = @collectionid", - )? - .params(params! { - "fxa_kid" => fxa_kid.to_string(), - "legacy" => legacy.to_string(), - "collectionid" => collection_id.to_string(), - }) - .execute(&self.conn)? - .one_or_none()? - .is_some(); - if result { + .affected_rows()? + > 0 + { self.erect_tombstone(¶ms.user_id)?; } self.get_storage_timestamp_sync(params.user_id) @@ -886,19 +849,24 @@ impl SpannerDb { // buffered on the client side and only issued to Spanner in the final // transaction Commit. let timestamp = self.timestamp()?; + let sqlparams = params! { + "fxa_uid" => user_id.fxa_uid.clone(), + "fxa_kid" => user_id.fxa_kid.clone(), + "collectionid" => collection_id.to_string(), + "last_modified" => timestamp.as_rfc3339()?, + }; + let sql_types = param_types! { + "last_modified" => SpannerType::Timestamp, + }; let result = self .sql( "SELECT 1 as count FROM user_collections - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid", )? - .params(params! { - "fxa_kid" => user_id.fxa_kid.clone(), - "legacy" => user_id.legacy_id.to_string(), - "collectionid" => collection_id.to_string(), - }) + .params(sqlparams.clone()) .execute(&self.conn)? .one_or_none()?; let exists = result.is_some(); @@ -907,35 +875,21 @@ impl SpannerDb { self.sql( "UPDATE user_collections SET last_modified = @last_modified - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid", )? - .params(params! { - "fxa_kid" => user_id.fxa_kid.clone(), - "legacy" => user_id.legacy_id.to_string(), - "collectionid" => collection_id.to_string(), - "last_modified" => timestamp.as_rfc3339()?, - }) - .param_types(param_types! { - "last_modified" => SpannerType::Timestamp, - }) + .params(sqlparams.clone()) + .param_types(sql_types.clone()) .execute(&self.conn)?; Ok(timestamp) } else { self.sql( - "INSERT INTO user_collections (fxa_kid, userid, collection, last_modified) - VALUES (@fxa_kid, @userid, @collectionid, @modified)", + "INSERT INTO user_collections (userid, fxa_kid, collection, last_modified) + VALUES (@fxa_uid, @fxa_kid, @collectionid, @last_modified)", )? - .params(params! { - "fxa_kid" => user_id.fxa_kid.clone(), - "userid" => user_id.legacy_id.to_string(), - "collectionid" => collection_id.to_string(), - "modified" => timestamp.as_rfc3339()?, - }) - .param_types(param_types! { - "modified" => SpannerType::Timestamp, - }) + .params(sqlparams.clone()) + .param_types(sql_types.clone()) .execute(&self.conn)?; Ok(timestamp) } @@ -945,18 +899,17 @@ impl SpannerDb { let user_id = params.user_id.clone(); let collection_id = self.get_collection_id(¶ms.collection)?; let touch = self.touch_collection(¶ms.user_id, collection_id)?; - let result = self .sql( "DELETE FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND id = @bsoid", )? .params(params! { + "fxa_uid" => user_id.fxa_uid.clone(), "fxa_kid" => user_id.fxa_kid.clone(), - "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -973,15 +926,15 @@ impl SpannerDb { let collection_id = self.get_collection_id(¶ms.collection)?; let mut sqlparams = params! { + "fxa_uid" => user_id.fxa_uid.to_string(), "fxa_kid" => user_id.fxa_kid, - "legacy" => user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), }; sqlparams.insert("ids".to_owned(), as_list_value(params.ids.into_iter())); self.sql( "DELETE FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND id IN UNNEST(@ids)", )? @@ -991,9 +944,11 @@ impl SpannerDb { } pub fn get_bsos_sync(&self, params: params::GetBsos) -> Result { - let fxa_kid = params.user_id.fxa_kid.clone(); - let legacy = params.user_id.legacy_id; - let collection_id = self.get_collection_id(¶ms.collection)?; + let mut sqlparams = params! { + "fxa_uid" => params.user_id.fxa_uid.clone(), + "fxa_kid" => params.user_id.fxa_kid.clone(), + "collectionid" => self.get_collection_id(¶ms.collection)?.to_string(), + }; let BsoQueryParams { newer, older, @@ -1006,16 +961,11 @@ impl SpannerDb { let mut query = "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND ttl > CURRENT_TIMESTAMP()" .to_string(); - let mut sqlparams = params! { - "fxa_kid" => fxa_kid, - "legacy" => legacy.to_string(), - "collectionid" => collection_id.to_string(), - }; let mut sqltypes = HashMap::new(); if let Some(older) = older { @@ -1101,22 +1051,21 @@ impl SpannerDb { } pub fn get_bso_sync(&self, params: params::GetBso) -> Result> { - let fxa_kid = params.user_id.fxa_kid; let collection_id = self.get_collection_id(¶ms.collection)?; let result = self .sql( "SELECT id, modified, payload, COALESCE(sortindex, NULL), ttl FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND id = @bsoid AND ttl > CURRENT_TIMESTAMP()", )? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => params.user_id.legacy_id.to_string(), + "fxa_uid" => params.user_id.fxa_uid, + "fxa_kid" => params.user_id.fxa_kid, "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -1130,7 +1079,6 @@ impl SpannerDb { } pub fn get_bso_timestamp_sync(&self, params: params::GetBsoTimestamp) -> Result { - let fxa_kid = params.user_id.fxa_kid; dbg!("!!QQQ get_bso_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; @@ -1139,15 +1087,15 @@ impl SpannerDb { "SELECT modified FROM bso WHERE collection = @collectionid - AND userid = @legacy + AND userid = @fxa_uid AND fxa_kid = @fxa_kid AND id = @bsoid AND ttl > CURRENT_TIMESTAMP()", )? .params(params! { - "fxa_kid" => fxa_kid, - "legacy" => params.user_id.legacy_id.to_string(), "collectionid" => collection_id.to_string(), + "fxa_uid" => params.user_id.fxa_uid, + "fxa_kid" => params.user_id.fxa_kid, "bsoid" => params.id.to_string(), }) .execute(&self.conn)? @@ -1161,8 +1109,13 @@ impl SpannerDb { pub fn put_bso_sync(&self, bso: params::PutBso) -> Result { let collection_id = self.get_or_create_collection_id(&bso.collection)?; - let fxa_kid = bso.user_id.fxa_kid.clone(); - let legacy = bso.user_id.legacy_id; + let mut sqlparams = params! { + "fxa_uid" => bso.user_id.fxa_uid.clone(), + "fxa_kid" => bso.user_id.fxa_kid.clone(), + "collectionid" => collection_id.to_string(), + "bsoid" => bso.id.to_string(), + }; + let mut sqltypes = HashMap::new(); let touch = self.touch_collection(&bso.user_id, collection_id)?; let timestamp = self.timestamp()?; @@ -1170,29 +1123,16 @@ impl SpannerDb { .sql( "SELECT 1 as count FROM bso - WHERE fxa_kid = @fxa_kid - AND userid = @legacy + WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND id = @bsoid", )? - .params(params! { - "fxa_kid" => fxa_kid.clone(), - "legacy" => legacy.to_string(), - "collectionid" => collection_id.to_string(), - "bsoid" => bso.id.to_string(), - }) + .params(sqlparams.clone()) .execute(&self.conn)? .one_or_none()?; let exists = result.is_some(); - let mut sqlparams = params! { - "fxa_kid" => fxa_kid.clone(), - "userid" => legacy.to_string(), - "collectionid" => collection_id.to_string(), - "bsoid" => bso.id.to_string(), - }; - let mut sqltypes = HashMap::new(); - let sql = if exists { // NOTE: the "ttl" column is more aptly named "expiry": our mysql // schema names it this. the current spanner schema prefers "ttl" @@ -1256,16 +1196,14 @@ impl SpannerDb { return Ok(touch); } - q = format!( + format!( "UPDATE bso SET {}{}", q, - " WHERE fxa_kid = @fxa_kid - AND userid = @legacy + " WHERE userid = @fxa_uid + AND fxa_kid = @fxa_kid AND collection = @collectionid AND id = @bsoid" - ); - - q + ) } else { let use_sortindex = bso .sortindex @@ -1274,10 +1212,10 @@ impl SpannerDb { != "NULL"; let sql = if use_sortindex { "INSERT INTO bso (userid, fxa_kid, collection, id, sortindex, payload, modified, ttl) - VALUES (@userid, @fxa_kid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" + VALUES (@fxa_uid, @fxa_kid, @collectionid, @bsoid, @sortindex, @payload, @modified, @expiry)" } else { "INSERT INTO bso (userid, fxa_kid, collection, id, payload, modified, ttl) - VALUES (@userid, @fxa_kid, @collectionid, @bsoid, @payload, @modified, @expiry)" + VALUES (@fxa_uid, @fxa_kid, @collectionid, @bsoid, @payload, @modified, @expiry)" }; if use_sortindex { diff --git a/src/web/extractors.rs b/src/web/extractors.rs index 5289e6cba1..17faf05d59 100644 --- a/src/web/extractors.rs +++ b/src/web/extractors.rs @@ -908,8 +908,8 @@ impl HawkIdentifier { let user_id = HawkIdentifier { legacy_id: payload.user_id, - fxa_uid: "".to_string(), - fxa_kid: "".to_string(), + fxa_uid: payload.fxa_uid, + fxa_kid: payload.fxa_kid, }; Ok(user_id) } From 4a62b3efc9a08c81067cfb5e5e67c05b2757722a Mon Sep 17 00:00:00 2001 From: jrconlin Date: Thu, 3 Oct 2019 11:46:32 -0700 Subject: [PATCH 7/9] f fmt --- src/db/spanner/models.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index acdc0c20d1..77fd13e765 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -829,7 +829,7 @@ impl SpannerDb { .affected_rows()? > 0 { - self.erect_tombstone(¶ms.user_id)?; + return self.erect_tombstone(¶ms.user_id); } self.get_storage_timestamp_sync(params.user_id) } From d01d47915392b939feebd3f117cec0fe462f9295 Mon Sep 17 00:00:00 2001 From: jrconlin Date: Thu, 3 Oct 2019 12:50:01 -0700 Subject: [PATCH 8/9] f add pjenvey's opt --- src/db/spanner/models.rs | 84 ++++++++++++++++++++-------------------- src/web/extractors.rs | 2 +- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index 77fd13e765..f6c4f22a26 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -60,10 +60,10 @@ struct SpannerDbSession { /// CURRENT_TIMESTAMP() from Spanner, used for timestamping this session's /// operations timestamp: Option, - /// Cache of collection modified timestamps per (fxa_kid, fxa_uid, collection_id) - coll_modified_cache: HashMap<(String, String, i32), SyncTimestamp>, + /// Cache of collection modified timestamps per (HawkIdentifier, collection_id) + coll_modified_cache: HashMap<(HawkIdentifier, i32), SyncTimestamp>, /// Currently locked collections - coll_locks: HashMap<(String, String, i32), CollectionLock>, + coll_locks: HashMap<(HawkIdentifier, i32), CollectionLock>, #[cfg(feature = "google_grpc")] transaction: Option, #[cfg(not(feature = "google_grpc"))] @@ -193,9 +193,6 @@ impl SpannerDb { // Begin a transaction self.begin(false)?; - let fxa_kid = params.user_id.fxa_kid; - let fxa_uid = params.user_id.fxa_uid; - let collection_id = self.get_collection_id(¶ms.collection) .or_else(|e| match e.kind() { @@ -211,16 +208,16 @@ impl SpannerDb { .session .borrow() .coll_locks - .get(&(fxa_kid.clone(), fxa_uid.clone(), collection_id)) + .get(&(params.user_id.clone(), collection_id)) .is_some() { return Ok(()); } - self.session.borrow_mut().coll_locks.insert( - (fxa_kid.clone(), fxa_uid.clone(), collection_id), - CollectionLock::Read, - ); + self.session + .borrow_mut() + .coll_locks + .insert((params.user_id, collection_id), CollectionLock::Read); Ok(()) } @@ -229,14 +226,16 @@ impl SpannerDb { // Begin a transaction self.begin(true)?; - let fxa_kid = params.user_id.fxa_kid; - let fxa_uid = params.user_id.fxa_uid; + let fxa_uid = params.user_id.fxa_uid.clone(); + let fxa_kid = params.user_id.fxa_kid.clone(); let collection_id = self.get_or_create_collection_id(¶ms.collection)?; - if let Some(CollectionLock::Read) = self.inner.session.borrow().coll_locks.get(&( - fxa_kid.clone(), - fxa_uid.clone(), - collection_id, - )) { + if let Some(CollectionLock::Read) = self + .inner + .session + .borrow() + .coll_locks + .get(&(params.user_id.clone(), collection_id)) + { Err(DbError::internal("Can't escalate read-lock to write-lock"))? } @@ -249,8 +248,8 @@ impl SpannerDb { AND collection = @collectionid", )? .params(params! { - "fxa_uid" => fxa_uid.clone(), - "fxa_kid" => fxa_kid.clone(), + "fxa_uid" => fxa_uid, + "fxa_kid" => fxa_kid, "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -261,7 +260,7 @@ impl SpannerDb { self.session .borrow_mut() .coll_modified_cache - .insert((fxa_kid.clone(), fxa_uid.clone(), collection_id), modified); + .insert((params.user_id.clone(), collection_id), modified); SyncTimestamp::from_rfc3339(result[0].get_string_value())? } else { let result = self @@ -272,10 +271,10 @@ impl SpannerDb { }; self.set_timestamp(timestamp); - self.session.borrow_mut().coll_locks.insert( - (fxa_kid.clone(), fxa_uid.clone(), collection_id), - CollectionLock::Write, - ); + self.session + .borrow_mut() + .coll_locks + .insert((params.user_id, collection_id), CollectionLock::Write); Ok(()) } @@ -493,16 +492,17 @@ impl SpannerDb { &self, params: params::GetCollectionTimestamp, ) -> Result { - let fxa_kid = params.user_id.fxa_kid; - let fxa_uid = params.user_id.fxa_uid; + let fxa_uid = params.user_id.fxa_uid.clone(); + let fxa_kid = params.user_id.fxa_kid.clone(); dbg!("!!QQQ get_collection_timestamp_sync", ¶ms.collection); let collection_id = self.get_collection_id(¶ms.collection)?; - if let Some(modified) = self.session.borrow().coll_modified_cache.get(&( - fxa_kid.clone(), - fxa_uid.clone(), - collection_id, - )) { + if let Some(modified) = self + .session + .borrow() + .coll_modified_cache + .get(&(params.user_id, collection_id)) + { return Ok(*modified); } @@ -515,8 +515,8 @@ impl SpannerDb { AND collection = @collectionid", )? .params(params! { - "fxa_uid" => fxa_uid.to_string(), - "fxa_kid" => fxa_kid.clone(), + "fxa_uid" => fxa_uid, + "fxa_kid" => fxa_kid, "collectionid" => collection_id.to_string(), }) .execute(&self.conn)? @@ -530,8 +530,8 @@ impl SpannerDb { &self, user_id: params::GetCollectionTimestamps, ) -> Result { - let fxa_kid = user_id.fxa_kid; let fxa_uid = user_id.fxa_uid; + let fxa_kid = user_id.fxa_kid; let modifieds = self .sql( "SELECT collection, last_modified @@ -616,8 +616,8 @@ impl SpannerDb { &self, user_id: params::GetCollectionCounts, ) -> Result { - let fxa_kid = user_id.fxa_kid; let fxa_uid = user_id.fxa_uid; + let fxa_kid = user_id.fxa_kid; let counts = self .sql( @@ -780,8 +780,8 @@ impl SpannerDb { pub fn delete_storage_sync(&self, user_id: params::DeleteStorage) -> Result<()> { let params = params! { - "fxa_uid" => user_id.fxa_uid.clone(), - "fxa_kid" => user_id.fxa_kid.clone() + "fxa_uid" => user_id.fxa_uid.clone(), + "fxa_kid" => user_id.fxa_kid.clone() }; self.sql( "DELETE FROM user_collections @@ -829,7 +829,7 @@ impl SpannerDb { .affected_rows()? > 0 { - return self.erect_tombstone(¶ms.user_id); + self.erect_tombstone(¶ms.user_id)?; } self.get_storage_timestamp_sync(params.user_id) } @@ -908,8 +908,8 @@ impl SpannerDb { AND id = @bsoid", )? .params(params! { - "fxa_uid" => user_id.fxa_uid.clone(), - "fxa_kid" => user_id.fxa_kid.clone(), + "fxa_uid" => user_id.fxa_uid, + "fxa_kid" => user_id.fxa_kid, "collectionid" => collection_id.to_string(), "bsoid" => params.id.to_string(), }) @@ -926,7 +926,7 @@ impl SpannerDb { let collection_id = self.get_collection_id(¶ms.collection)?; let mut sqlparams = params! { - "fxa_uid" => user_id.fxa_uid.to_string(), + "fxa_uid" => user_id.fxa_uid, "fxa_kid" => user_id.fxa_kid, "collectionid" => collection_id.to_string(), }; diff --git a/src/web/extractors.rs b/src/web/extractors.rs index 17faf05d59..cd62650372 100644 --- a/src/web/extractors.rs +++ b/src/web/extractors.rs @@ -815,7 +815,7 @@ impl FromRequest for ConfigRequest { /// /// This token should be adapted as needed for the storage system to store data /// for the user. -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, PartialEq, Serialize)] pub struct HawkIdentifier { /// For MySQL database backends as the primary key pub legacy_id: u64, From c011ec83fef8f7c86204a25ccbf810d3009068da Mon Sep 17 00:00:00 2001 From: jrconlin Date: Thu, 3 Oct 2019 12:58:43 -0700 Subject: [PATCH 9/9] f return of the tombstone --- src/db/spanner/models.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/db/spanner/models.rs b/src/db/spanner/models.rs index f6c4f22a26..12a5b5cff8 100644 --- a/src/db/spanner/models.rs +++ b/src/db/spanner/models.rs @@ -829,7 +829,7 @@ impl SpannerDb { .affected_rows()? > 0 { - self.erect_tombstone(¶ms.user_id)?; + return self.erect_tombstone(¶ms.user_id); } self.get_storage_timestamp_sync(params.user_id) }