From f3f49785cdf4fd0c4c3bac994f130cd0dec287e5 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 15:53:19 -0500 Subject: [PATCH 1/7] Moved Rust code into shared workspace --- .gitignore | 3 + server/Cargo.lock => Cargo.lock | 978 ++++--- Cargo.toml | 7 + collector/Cargo.lock | 3460 ------------------------ collector/Cargo.toml | 4 +- mediator/Cargo.lock | 3460 ------------------------ mediator/Cargo.toml | 4 +- mediator/rustfmt.toml | 11 - notifications/Cargo.lock | 2521 ----------------- notifications/rustfmt.toml | 11 - collector/rustfmt.toml => rustfmt.toml | 0 server/Cargo.toml | 4 +- server/rustfmt.toml | 11 - 13 files changed, 630 insertions(+), 9844 deletions(-) rename server/Cargo.lock => Cargo.lock (82%) create mode 100644 Cargo.toml delete mode 100644 collector/Cargo.lock delete mode 100644 mediator/Cargo.lock delete mode 100644 mediator/rustfmt.toml delete mode 100644 notifications/Cargo.lock delete mode 100644 notifications/rustfmt.toml rename collector/rustfmt.toml => rustfmt.toml (100%) delete mode 100644 server/rustfmt.toml diff --git a/.gitignore b/.gitignore index dd0ee99..430b214 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +/target +**/*.rs.bk + # Vim Swap Files *.sw* diff --git a/server/Cargo.lock b/Cargo.lock similarity index 82% rename from server/Cargo.lock rename to Cargo.lock index 8002418..1664e76 100644 --- a/server/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,31 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be241f88f3b1e7e9a3fbe3b5a8a0f6915b5a1d7ee0d9a248d3376d01068cc60" +dependencies = [ + "actix-rt", + "actix_derive", + "bitflags", + "bytes 0.5.6", + "crossbeam-channel 0.4.4", + "derive_more", + "futures-channel", + "futures-util", + "log", + "once_cell", + "parking_lot", + "pin-project 0.4.29", + "smallvec", + "tokio", + "tokio-util", + "trust-dns-proto", + "trust-dns-resolver", +] + [[package]] name = "actix-codec" version = "0.3.0" @@ -13,7 +38,7 @@ dependencies = [ "futures-core", "futures-sink", "log", - "pin-project 0.4.28", + "pin-project 0.4.29", "tokio", "tokio-util", ] @@ -70,13 +95,13 @@ dependencies = [ "http", "httparse", "indexmap", - "itoa", + "itoa 0.4.8", "language-tags", "lazy_static 1.4.0", "log", "mime", "percent-encoding", - "pin-project 1.0.8", + "pin-project 1.0.10", "rand 0.7.3", "regex", "serde", @@ -93,8 +118,8 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" dependencies = [ - "quote 1.0.9", - "syn 1.0.78", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -152,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" dependencies = [ "futures-util", - "pin-project 0.4.28", + "pin-project 0.4.29", ] [[package]] @@ -214,15 +239,15 @@ dependencies = [ "futures-sink", "futures-util", "log", - "pin-project 0.4.28", + "pin-project 0.4.29", "slab", ] [[package]] name = "actix-web" -version = "3.3.2" +version = "3.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" +checksum = "b6534a126df581caf443ba2751cab42092c89b3f1d06a9d829b1e17edfe3e277" dependencies = [ "actix-codec", "actix-http", @@ -247,7 +272,7 @@ dependencies = [ "log", "mime", "openssl", - "pin-project 1.0.8", + "pin-project 1.0.10", "regex", "serde", "serde_json", @@ -258,15 +283,31 @@ dependencies = [ "url", ] +[[package]] +name = "actix-web-actors" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6edf3c2693e2a8c422800c87ee89a6a4eac7dd01109bc172a1093ce1f4f001" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "bytes 0.5.6", + "futures-channel", + "futures-core", + "pin-project 0.4.29", +] + [[package]] name = "actix-web-codegen" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -280,11 +321,22 @@ dependencies = [ "futures-util", ] +[[package]] +name = "actix_derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" +dependencies = [ + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", +] + [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "gimli", ] @@ -306,28 +358,28 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi 0.3.9", ] [[package]] name = "anyhow" -version = "1.0.44" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "async-trait" -version = "0.1.51" +version = "0.1.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -380,9 +432,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" dependencies = [ "addr2line", "cc", @@ -429,7 +481,7 @@ checksum = "f691e63585950d8c1c43644d11bab9073e40f5060dd2822734ae7c3dc69a3a80" dependencies = [ "base64 0.13.0", "blowfish", - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] @@ -484,7 +536,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ "block-padding 0.2.1", - "generic-array 0.14.4", + "generic-array 0.14.5", +] + +[[package]] +name = "block-buffer" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" +dependencies = [ + "generic-array 0.14.5", ] [[package]] @@ -535,9 +596,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.7.1" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byte-tools" @@ -574,9 +635,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.70" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "censor" @@ -605,12 +666,10 @@ version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" dependencies = [ - "js-sys", "libc", "num-integer", "num-traits", "time 0.1.44", - "wasm-bindgen", "winapi 0.3.9", ] @@ -620,14 +679,14 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", ] [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -660,15 +719,15 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" [[package]] name = "const_fn" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" +checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" [[package]] name = "convert_case" @@ -695,9 +754,9 @@ checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" dependencies = [ "core-foundation-sys", "libc", @@ -705,9 +764,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" @@ -720,21 +779,31 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.6", ] [[package]] @@ -745,17 +814,17 @@ checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-utils 0.8.6", ] [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils", + "crossbeam-utils 0.8.6", "lazy_static 1.4.0", "memoffset", "scopeguard", @@ -763,9 +832,20 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg 1.0.1", + "cfg-if 0.1.10", + "lazy_static 1.4.0", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" dependencies = [ "cfg-if 1.0.0", "lazy_static 1.4.0", @@ -773,23 +853,32 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", "rand_core 0.6.3", "subtle", "zeroize", ] +[[package]] +name = "crypto-common" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" +dependencies = [ + "generic-array 0.14.5", +] + [[package]] name = "crypto-mac" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", "subtle", ] @@ -801,15 +890,15 @@ checksum = "e35f15e1a0699dd988fed910dd78fdc6407f44654cd12589c91fa44ea67d9159" [[package]] name = "curv-kzen" -version = "0.8.2" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dec452bd369a0223f5fe65861d043daf9a270aecf6acc70841ed5b3058def19" +checksum = "ddc25c87ebf29b249e801de5eed820f0c9ba001054bf73008df884690a03e6eb" dependencies = [ "cryptoxide", "curve25519-dalek", "digest 0.9.0", "ff-zeroize", - "generic-array 0.14.4", + "generic-array 0.14.5", "hex", "hmac", "lazy_static 1.4.0", @@ -826,7 +915,7 @@ dependencies = [ "serde_bytes", "serde_derive", "sha2 0.8.2", - "sha2 0.9.8", + "sha2 0.9.9", "sha3", "thiserror", "typenum", @@ -848,9 +937,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.10.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c" dependencies = [ "darling_core", "darling_macro", @@ -858,74 +947,80 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.10.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.29", - "quote 1.0.9", - "strsim 0.9.3", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "strsim 0.10.0", + "syn 1.0.85", ] [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a" dependencies = [ "darling_core", - "quote 1.0.9", - "syn 1.0.78", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] name = "der" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" dependencies = [ "const-oid", ] [[package]] name = "derive_builder" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2658621297f2cf68762a6f7dc0bb7e1ff2cfd6583daef8ee0fed6f7ec468ec0" +checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30" dependencies = [ - "darling", - "derive_builder_core", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2791ea3e372c8495c0bc2033991d76b512cd799d07491fbd6890124db9458bef" +checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5" dependencies = [ "darling", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", +] + +[[package]] +name = "derive_builder_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73" +dependencies = [ + "derive_builder_core", + "syn 1.0.85", ] [[package]] name = "derive_more" -version = "0.99.16" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", - "proc-macro2 1.0.29", - "quote 1.0.9", - "rustc_version 0.3.3", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "rustc_version 0.4.0", + "syn 1.0.85", ] [[package]] @@ -969,9 +1064,9 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -989,7 +1084,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.4", + "generic-array 0.14.5", +] + +[[package]] +name = "digest" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" +dependencies = [ + "block-buffer 0.10.0", + "crypto-common", + "generic-array 0.14.5", ] [[package]] @@ -1030,7 +1136,7 @@ checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" dependencies = [ "crypto-bigint", "ff", - "generic-array 0.14.4", + "generic-array 0.14.5", "group", "pkcs8", "rand_core 0.6.3", @@ -1040,9 +1146,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.28" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ "cfg-if 1.0.0", ] @@ -1054,9 +1160,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" dependencies = [ "heck", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -1068,6 +1174,119 @@ dependencies = [ "backtrace", ] +[[package]] +name = "evoting-collector" +version = "0.1.0" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "actix-web-actors", + "actix-web-httpauth", + "anyhow", + "awc", + "base64 0.13.0", + "bigdecimal", + "chrono", + "curv-kzen", + "diesel", + "dotenv", + "futures", + "http", + "http-serde", + "itertools", + "jsonwebtoken", + "kzen-paillier", + "lazy_static 1.4.0", + "log", + "num", + "num-derive", + "num-traits", + "openssl", + "paste", + "rand 0.8.4", + "serde", + "serde_json", + "serde_repr", + "sha2 0.10.1", + "simple_logger", + "structopt", + "uuid", + "uuid-b64", + "validator", +] + +[[package]] +name = "evoting-mediator" +version = "0.1.0" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "actix-web-actors", + "actix-web-httpauth", + "anyhow", + "awc", + "base64 0.13.0", + "bigdecimal", + "chrono", + "curv-kzen", + "diesel", + "dotenv", + "futures", + "http", + "http-serde", + "itertools", + "jsonwebtoken", + "kzen-paillier", + "lazy_static 1.4.0", + "log", + "num", + "num-derive", + "num-traits", + "openssl", + "paste", + "rand 0.8.4", + "serde", + "serde_json", + "serde_repr", + "sha2 0.10.1", + "simple_logger", + "structopt", + "uuid", + "uuid-b64", + "validator", +] + +[[package]] +name = "evoting-notifications" +version = "0.1.0" +dependencies = [ + "actix", + "actix-codec", + "actix-http", + "actix-web", + "actix-web-actors", + "actix-web-httpauth", + "anyhow", + "awc", + "chrono", + "dotenv", + "futures", + "jsonwebtoken", + "log", + "openssl", + "serde", + "serde_json", + "serde_repr", + "simple_logger", + "structopt", + "uuid", + "uuid-b64", +] + [[package]] name = "evoting-server" version = "0.1.0" @@ -1123,9 +1342,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "synstructure", ] @@ -1137,14 +1356,23 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "fancy-regex" -version = "0.4.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36996e5f56f32ca51a937f325094fa450b32df871af1a89be331b7145b931bfc" +checksum = "9d6b8560a05112eb52f04b00e5d3790c0dd75d9d980eb8a122fb23b92a623ccf" dependencies = [ "bit-set", "regex", ] +[[package]] +name = "fastrand" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] + [[package]] name = "ff" version = "0.10.1" @@ -1176,9 +1404,9 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -1248,9 +1476,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" [[package]] name = "futures" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -1263,9 +1491,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", "futures-sink", @@ -1273,15 +1501,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", @@ -1290,42 +1518,39 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ - "autocfg 1.0.1", - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg 1.0.1", "futures-channel", "futures-core", "futures-io", @@ -1333,10 +1558,8 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.8", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] @@ -1360,9 +1583,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -1381,9 +1604,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" dependencies = [ "cfg-if 1.0.0", "libc", @@ -1392,9 +1615,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] name = "group" @@ -1483,13 +1706,13 @@ dependencies = [ [[package]] name = "http" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes 1.1.0", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] @@ -1502,6 +1725,16 @@ dependencies = [ "http", ] +[[package]] +name = "http-serde" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25698ac7002625796d5a7df8f0602400571da944c2edc1d5c268a6947dd4f692" +dependencies = [ + "http", + "serde", +] + [[package]] name = "httparse" version = "1.5.1" @@ -1529,8 +1762,8 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", - "pin-project 1.0.8", + "itoa 0.4.8", + "pin-project 1.0.10", "socket2", "tokio", "tower-service", @@ -1576,9 +1809,9 @@ checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg 1.0.1", "hashbrown", @@ -1586,18 +1819,18 @@ dependencies = [ [[package]] name = "inlinable_string" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" dependencies = [ "serde", ] [[package]] name = "instant" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", ] @@ -1640,9 +1873,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.9.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] @@ -1653,6 +1886,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "js-sys" version = "0.3.55" @@ -1694,9 +1933,9 @@ dependencies = [ [[package]] name = "kzen-paillier" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccce3a6f805aa7845961eed04c12dd2fab74004563794b270cfc063ff9dd8e6" +checksum = "2331394a15a3c06d7ddd931c083c96ab30ea20490899354f486891b9570f87b5" dependencies = [ "curv-kzen", "rayon", @@ -1723,9 +1962,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.103" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "linked-hash-map" @@ -1772,6 +2011,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" version = "2.4.1" @@ -1780,9 +2025,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg 1.0.1", ] @@ -1983,9 +2228,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -1993,18 +2238,18 @@ dependencies = [ [[package]] name = "object" -version = "0.26.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" [[package]] name = "opaque-debug" @@ -2020,9 +2265,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -2034,15 +2279,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.67" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg 1.0.1", "cc", @@ -2059,7 +2304,7 @@ checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" dependencies = [ "ecdsa", "elliptic-curve", - "sha2 0.9.8", + "sha2 0.9.9", ] [[package]] @@ -2104,9 +2349,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" [[package]] name = "pem" @@ -2125,53 +2370,44 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - [[package]] name = "pin-project" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" +checksum = "9615c18d31137579e9ff063499264ddc1278e7b1982757ebc111028c4d1dc909" dependencies = [ - "pin-project-internal 0.4.28", + "pin-project-internal 0.4.29", ] [[package]] name = "pin-project" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" dependencies = [ - "pin-project-internal 1.0.8", + "pin-project-internal 1.0.10", ] [[package]] name = "pin-project-internal" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" +checksum = "044964427019eed9d49d9d5bbce6047ef18f37100ea400912a9fa4a3523ab12a" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] name = "pin-project-internal" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -2182,9 +2418,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -2204,15 +2440,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.20" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "pq-sys" @@ -2230,9 +2466,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "version_check", ] @@ -2242,8 +2478,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "version_check", ] @@ -2253,12 +2489,6 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" version = "0.4.30" @@ -2270,9 +2500,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.29" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid 0.2.2", ] @@ -2300,11 +2530,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.9" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ - "proc-macro2 1.0.29", + "proc-macro2 1.0.36", ] [[package]] @@ -2435,7 +2665,7 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.3", + "getrandom 0.2.4", ] [[package]] @@ -2545,9 +2775,9 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" dependencies = [ - "crossbeam-channel", + "crossbeam-channel 0.5.2", "crossbeam-deque", - "crossbeam-utils", + "crossbeam-utils 0.8.6", "lazy_static 1.4.0", "num_cpus", ] @@ -2631,7 +2861,7 @@ dependencies = [ "mime_guess", "native-tls", "percent-encoding", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.8", "serde", "serde_json", "serde_urlencoded", @@ -2697,18 +2927,18 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.11.0", + "semver 1.0.4", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "safemem" @@ -2754,18 +2984,18 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" dependencies = [ "cc", ] [[package]] name = "security-framework" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "d09d3c15d814eda1d6a836f2f2b56a6abc1446c8a34351cb3180d3db92ffe4ce" dependencies = [ "bitflags", "core-foundation", @@ -2776,9 +3006,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "e90dd10c41c6bfc633da6e0c659bd25d31e0791e5974ac42970267d59eba87f7" dependencies = [ "core-foundation-sys", "libc", @@ -2790,17 +3020,14 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser 0.7.0", + "semver-parser", ] [[package]] name = "semver" -version = "0.11.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", -] +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "semver-parser" @@ -2808,20 +3035,11 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -2837,22 +3055,22 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] name = "serde_json" -version = "1.0.68" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" dependencies = [ - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -2863,19 +3081,19 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -2895,9 +3113,18 @@ dependencies = [ [[package]] name = "sha1" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" +dependencies = [ + "sha1_smol", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" @@ -2913,9 +3140,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", @@ -2924,6 +3151,17 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha2" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99c3bd8169c58782adad9290a9af5939994036b76187f7b4f0e6de91dbbfc0ec" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.1", +] + [[package]] name = "sha3" version = "0.9.1" @@ -2947,9 +3185,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" +checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" dependencies = [ "digest 0.9.0", "rand_core 0.6.3", @@ -2968,28 +3206,28 @@ dependencies = [ [[package]] name = "simple_logger" -version = "1.13.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" +checksum = "45b60258a35dc3cb8a16890b8fd6723349bfa458d7960e25e633f1b1c19d7b5e" dependencies = [ "atty", - "chrono", "colored", "log", + "time 0.3.5", "winapi 0.3.9", ] [[package]] name = "slab" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "socket2" @@ -3046,11 +3284,11 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "serde", "serde_derive", - "syn 1.0.78", + "syn 1.0.85", ] [[package]] @@ -3060,13 +3298,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "serde", "serde_derive", "serde_json", "sha1", - "syn 1.0.78", + "syn 1.0.85", ] [[package]] @@ -3083,15 +3321,15 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "strsim" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "structopt" -version = "0.3.23" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static 1.4.0", @@ -3100,15 +3338,15 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -3141,36 +3379,36 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.78" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "unicode-xid 0.2.2", ] [[package]] name = "synstructure" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "474aaa926faa1603c40b7885a9eaea29b444d1cb2850cb7c0e37bb1a4182f4fa" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "unicode-xid 0.2.2", ] [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if 1.0.0", + "fastrand", "libc", - "rand 0.8.4", "redox_syscall", "remove_dir_all", "winapi 0.3.9", @@ -3187,22 +3425,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.29" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", ] [[package]] @@ -3235,11 +3473,22 @@ dependencies = [ "libc", "standback", "stdweb", - "time-macros", + "time-macros 0.1.1", "version_check", "winapi 0.3.9", ] +[[package]] +name = "time" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" +dependencies = [ + "itoa 0.4.8", + "libc", + "time-macros 0.2.3", +] + [[package]] name = "time-macros" version = "0.1.1" @@ -3250,6 +3499,12 @@ dependencies = [ "time-macros-impl", ] +[[package]] +name = "time-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" + [[package]] name = "time-macros-impl" version = "0.1.2" @@ -3257,17 +3512,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "standback", - "syn 1.0.78", + "syn 1.0.85", ] [[package]] name = "tinyvec" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -3327,6 +3582,7 @@ checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" dependencies = [ "bytes 0.5.6", "futures-core", + "futures-io", "futures-sink", "log", "pin-project-lite 0.1.12", @@ -3341,13 +3597,13 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", "log", - "pin-project-lite 0.2.7", + "pin-project-lite 0.2.8", "tracing-core", ] @@ -3366,7 +3622,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.8", + "pin-project 1.0.10", "tracing", ] @@ -3417,15 +3673,9 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "ucd-trie" -version = "0.1.3" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicase" @@ -3438,9 +3688,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" @@ -3545,10 +3795,10 @@ dependencies = [ "if_chain", "lazy_static 1.4.0", "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", + "proc-macro2 1.0.36", + "quote 1.0.14", "regex", - "syn 1.0.78", + "syn 1.0.85", "validator_types", ] @@ -3558,8 +3808,8 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded9d97e1d42327632f5f3bae6403c04886e2de3036261ef42deebd931a6a291" dependencies = [ - "proc-macro2 1.0.29", - "syn 1.0.78", + "proc-macro2 1.0.36", + "syn 1.0.85", ] [[package]] @@ -3576,9 +3826,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" @@ -3623,9 +3873,9 @@ dependencies = [ "bumpalo", "lazy_static 1.4.0", "log", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "wasm-bindgen-shared", ] @@ -3647,7 +3897,7 @@ version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ - "quote 1.0.9", + "quote 1.0.14", "wasm-bindgen-macro-support", ] @@ -3657,9 +3907,9 @@ version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3750,30 +4000,30 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" +checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb" dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", "synstructure", ] [[package]] name = "zxcvbn" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f9db3a05b2ee81dcda4602487314ab654eca316f517be2e2e64175658f0dd0" +checksum = "7eb2873892ec52037005cc6c0852e4d15d6eee068651b6e2cdbd6df563112592" dependencies = [ "chrono", "derive_builder", diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..bac99b1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +members = [ + "server", + "mediator", + "collector", + "notifications", +] \ No newline at end of file diff --git a/collector/Cargo.lock b/collector/Cargo.lock deleted file mode 100644 index 32c0813..0000000 --- a/collector/Cargo.lock +++ /dev/null @@ -1,3460 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be241f88f3b1e7e9a3fbe3b5a8a0f6915b5a1d7ee0d9a248d3376d01068cc60" -dependencies = [ - "actix-rt", - "actix_derive", - "bitflags", - "bytes 0.5.6", - "crossbeam-channel 0.4.4", - "derive_more", - "futures-channel", - "futures-util", - "log", - "once_cell", - "parking_lot", - "pin-project 0.4.28", - "smallvec", - "tokio", - "tokio-util", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-codec" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" -dependencies = [ - "bitflags", - "bytes 0.5.6", - "futures-core", - "futures-sink", - "log", - "pin-project 0.4.28", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-connect" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more", - "either", - "futures-util", - "http", - "log", - "openssl", - "tokio-openssl", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-http" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee" -dependencies = [ - "actix-codec", - "actix-connect", - "actix-rt", - "actix-service", - "actix-threadpool", - "actix-tls", - "actix-utils", - "base64 0.13.0", - "bitflags", - "brotli2", - "bytes 0.5.6", - "cookie", - "copyless", - "derive_more", - "either", - "encoding_rs", - "flate2", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "h2", - "http", - "httparse", - "indexmap", - "itoa", - "language-tags", - "lazy_static 1.4.0", - "log", - "mime", - "percent-encoding", - "pin-project 1.0.8", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "sha-1", - "slab", - "time 0.2.27", -] - -[[package]] -name = "actix-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" -dependencies = [ - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-router" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c" -dependencies = [ - "bytestring", - "http", - "log", - "regex", - "serde", -] - -[[package]] -name = "actix-rt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" -dependencies = [ - "actix-macros", - "actix-threadpool", - "copyless", - "futures-channel", - "futures-util", - "smallvec", - "tokio", -] - -[[package]] -name = "actix-server" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "futures-channel", - "futures-util", - "log", - "mio", - "mio-uds", - "num_cpus", - "slab", - "socket2", -] - -[[package]] -name = "actix-service" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" -dependencies = [ - "futures-util", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-testing" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" -dependencies = [ - "actix-macros", - "actix-rt", - "actix-server", - "actix-service", - "log", - "socket2", -] - -[[package]] -name = "actix-threadpool" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" -dependencies = [ - "derive_more", - "futures-channel", - "lazy_static 1.4.0", - "log", - "num_cpus", - "parking_lot", - "threadpool", -] - -[[package]] -name = "actix-tls" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" -dependencies = [ - "actix-codec", - "actix-service", - "actix-utils", - "futures-util", - "openssl", - "tokio-openssl", -] - -[[package]] -name = "actix-utils" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "bitflags", - "bytes 0.5.6", - "either", - "futures-channel", - "futures-sink", - "futures-util", - "log", - "pin-project 0.4.28", - "slab", -] - -[[package]] -name = "actix-web" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-testing", - "actix-threadpool", - "actix-tls", - "actix-utils", - "actix-web-codegen", - "awc", - "bytes 0.5.6", - "derive_more", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "log", - "mime", - "openssl", - "pin-project 1.0.8", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "socket2", - "time 0.2.27", - "tinyvec", - "url", -] - -[[package]] -name = "actix-web-actors" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6edf3c2693e2a8c422800c87ee89a6a4eac7dd01109bc172a1093ce1f4f001" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "bytes 0.5.6", - "futures-channel", - "futures-core", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-web-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3b11a07a3df3f7970fd8bd38cc66998b5549f507c54cc64c6e843bc82d6358" -dependencies = [ - "actix-web", - "base64 0.13.0", - "futures-util", -] - -[[package]] -name = "actix_derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "addr2line" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "anyhow" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" - -[[package]] -name = "async-trait" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "awc" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" -dependencies = [ - "actix-codec", - "actix-http", - "actix-rt", - "actix-service", - "base64 0.13.0", - "bytes 0.5.6", - "cfg-if 1.0.0", - "derive_more", - "futures-core", - "log", - "mime", - "openssl", - "percent-encoding", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded", -] - -[[package]] -name = "backtrace" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - -[[package]] -name = "base64" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bigdecimal" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding 0.1.5", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array 0.14.4", -] - -[[package]] -name = "block-buffer" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", -] - -[[package]] -name = "bumpalo" -version = "3.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "bytestring" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" -dependencies = [ - "bytes 1.1.0", -] - -[[package]] -name = "cc" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time 0.1.44", - "winapi 0.3.9", -] - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static 1.4.0", - "winapi 0.3.9", -] - -[[package]] -name = "const-oid" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" - -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -dependencies = [ - "crossbeam-utils 0.7.2", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", - "lazy_static 1.4.0", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.0.1", - "cfg-if 0.1.10", - "lazy_static 1.4.0", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static 1.4.0", -] - -[[package]] -name = "crypto-bigint" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45" -dependencies = [ - "generic-array 0.14.4", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.4", - "subtle", -] - -[[package]] -name = "cryptoxide" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35f15e1a0699dd988fed910dd78fdc6407f44654cd12589c91fa44ea67d9159" - -[[package]] -name = "curv-kzen" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dec452bd369a0223f5fe65861d043daf9a270aecf6acc70841ed5b3058def19" -dependencies = [ - "cryptoxide", - "curve25519-dalek", - "digest 0.9.0", - "ff-zeroize", - "generic-array 0.14.4", - "hex", - "hmac", - "lazy_static 1.4.0", - "merkle-cbt", - "num-integer", - "num-traits", - "p256", - "pairing-plus", - "rand 0.6.5", - "rand 0.7.3", - "rust-gmp-kzen", - "secp256k1", - "serde", - "serde_bytes", - "serde_derive", - "sha2 0.8.2", - "sha2 0.9.8", - "sha3", - "thiserror", - "typenum", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "der" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derive_more" -version = "0.99.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" -dependencies = [ - "convert_case", - "proc-macro2 1.0.29", - "quote 1.0.9", - "rustc_version 0.3.3", - "syn 1.0.78", -] - -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "bigdecimal", - "bitflags", - "byteorder", - "chrono", - "diesel_derives", - "ipnetwork", - "libc", - "num-bigint", - "num-integer", - "num-traits", - "pq-sys", - "r2d2", - "serde_json", - "time 0.1.44", - "uuid", -] - -[[package]] -name = "diesel-derive-newtype" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e844e8e6f65dcf27aa0b97d4234f974d93dfbf56816033d71b5e0c7eb701709f" -dependencies = [ - "diesel", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.14.9", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "digest" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" -dependencies = [ - "block-buffer 0.10.0", - "crypto-common", - "generic-array 0.14.4", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "ecdsa" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" -dependencies = [ - "der", - "elliptic-curve", - "hmac", - "signature", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" -dependencies = [ - "crypto-bigint", - "ff", - "generic-array 0.14.4", - "group", - "pkcs8", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "encoding_rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "error-chain" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -dependencies = [ - "backtrace", -] - -[[package]] -name = "evoting-collector" -version = "0.1.0" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "actix-web-actors", - "actix-web-httpauth", - "anyhow", - "awc", - "base64 0.13.0", - "bigdecimal", - "chrono", - "curv-kzen", - "diesel", - "dotenv", - "futures", - "http", - "http-serde", - "itertools", - "jsonwebtoken", - "kzen-paillier", - "lazy_static 1.4.0", - "log", - "num", - "num-derive", - "num-traits", - "openssl", - "paste", - "rand 0.8.4", - "serde", - "serde_json", - "serde_repr", - "sha2 0.10.0", - "simple_logger", - "structopt", - "uuid", - "uuid-b64", - "validator", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "ff" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "ff-zeroize" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02169a2e8515aa316ce516eaaf6318a76617839fbf904073284bc2576b029ee" -dependencies = [ - "byteorder", - "ff_derive-zeroize", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "ff_derive-zeroize" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24d4059bc0d0a0bf26b740aa21af1f96a984f0ab7a21356d00b32475388b53a" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" - -[[package]] -name = "futures-executor" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" - -[[package]] -name = "futures-macro" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" -dependencies = [ - "autocfg 1.0.1", - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - -[[package]] -name = "futures-task" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" - -[[package]] -name = "futures-util" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" -dependencies = [ - "autocfg 1.0.1", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite 0.2.7", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" - -[[package]] -name = "group" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "h2" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", - "tracing-futures", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes 1.1.0", - "fnv", - "itoa", -] - -[[package]] -name = "http-serde" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25698ac7002625796d5a7df8f0602400571da944c2edc1d5c268a6947dd4f692" -dependencies = [ - "http", - "serde", -] - -[[package]] -name = "httparse" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "if_chain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg 1.0.1", - "hashbrown", -] - -[[package]] -name = "inlinable_string" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" -dependencies = [ - "serde", -] - -[[package]] -name = "instant" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2", - "widestring", - "winapi 0.3.9", - "winreg", -] - -[[package]] -name = "ipnetwork" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355" -dependencies = [ - "serde", -] - -[[package]] -name = "itertools" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" -dependencies = [ - "base64 0.12.3", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "kzen-paillier" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccce3a6f805aa7845961eed04c12dd2fab74004563794b270cfc063ff9dd8e6" -dependencies = [ - "curv-kzen", - "rayon", - "serde", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "merkle-cbt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f1ac8428ec02d6caa5a79c15e851d84d5dc7a00df0429a8aa860d104f0a81be" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg 1.0.1", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "num" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg 1.0.1", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg 1.0.1", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" -dependencies = [ - "autocfg 1.0.1", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-sys" -version = "0.9.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" -dependencies = [ - "autocfg 1.0.1", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "p256" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" -dependencies = [ - "ecdsa", - "elliptic-curve", - "sha2 0.9.8", -] - -[[package]] -name = "pairing-plus" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cda4f22e8e6720f3c254049960c8cc4f93cb82b5ade43bddd2622b5f39ea62" -dependencies = [ - "byteorder", - "digest 0.8.1", - "ff-zeroize", - "rand 0.4.6", - "rand_core 0.5.1", - "rand_xorshift 0.2.0", - "zeroize", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi 0.3.9", -] - -[[package]] -name = "paste" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" - -[[package]] -name = "pem" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" -dependencies = [ - "base64 0.13.0", - "once_cell", - "regex", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pin-project" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" -dependencies = [ - "pin-project-internal 0.4.28", -] - -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal 1.0.8", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pq-sys" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" -dependencies = [ - "vcpkg", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" -dependencies = [ - "unicode-xid 0.2.2", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2 1.0.29", -] - -[[package]] -name = "r2d2" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.7", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift 0.1.1", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_xorshift" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg 1.0.1", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel 0.5.1", - "crossbeam-deque", - "crossbeam-utils 0.8.5", - "lazy_static 1.4.0", - "num_cpus", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi 0.3.9", -] - -[[package]] -name = "rust-gmp-kzen" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e654bb304958a567aefa09e83cc313251388202c40bfc245fac19a0e2dd8d08" -dependencies = [ - "libc", - "num-traits", - "serde", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "safemem" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" - -[[package]] -name = "scheduled-thread-pool" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" -dependencies = [ - "parking_lot", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_json" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha2" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha2" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.10.1", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug 0.3.0", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" -dependencies = [ - "digest 0.9.0", - "rand_core 0.6.3", -] - -[[package]] -name = "simple_asn1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" -dependencies = [ - "chrono", - "num-bigint", - "num-traits", -] - -[[package]] -name = "simple_logger" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" -dependencies = [ - "atty", - "chrono", - "colored", - "log", - "winapi 0.3.9", -] - -[[package]] -name = "slab" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "smallvec" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der", -] - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" -dependencies = [ - "clap", - "lazy_static 1.4.0", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "unicode-xid 0.2.2", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "unicode-xid 0.2.2", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi 0.3.9", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "standback", - "syn 1.0.78", -] - -[[package]] -name = "tinyvec" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "iovec", - "lazy_static 1.4.0", - "libc", - "memchr", - "mio", - "mio-uds", - "pin-project-lite 0.1.12", - "signal-hook-registry", - "slab", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-openssl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" -dependencies = [ - "openssl", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -dependencies = [ - "bytes 0.5.6", - "futures-core", - "futures-io", - "futures-sink", - "log", - "pin-project-lite 0.1.12", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" -dependencies = [ - "cfg-if 1.0.0", - "log", - "pin-project-lite 0.2.7", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static 1.4.0", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.8", - "tracing", -] - -[[package]] -name = "trust-dns-proto" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "enum-as-inner", - "futures", - "idna", - "lazy_static 1.4.0", - "log", - "rand 0.7.3", - "smallvec", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb" -dependencies = [ - "cfg-if 0.1.10", - "futures", - "ipconfig", - "lazy_static 1.4.0", - "log", - "lru-cache", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "trust-dns-proto", -] - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -dependencies = [ - "cfg-if 0.1.10", - "rand 0.4.6", -] - -[[package]] -name = "uuid-b64" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b9cb172a0b1f4e0bf63b807d67ff9ff0d9fba2bcc5f30d3aacb7240e02fc1b" -dependencies = [ - "base64 0.8.0", - "diesel", - "diesel-derive-newtype", - "error-chain", - "inlinable_string", - "lazy_static 0.2.11", - "serde", - "uuid", -] - -[[package]] -name = "validator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0f08911ab0fee2c5009580f04615fa868898ee57de10692a45da0c3bcc3e5e" -dependencies = [ - "idna", - "lazy_static 1.4.0", - "regex", - "serde", - "serde_derive", - "serde_json", - "url", - "validator_derive", - "validator_types", -] - -[[package]] -name = "validator_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85135714dba11a1bd0b3eb1744169266f1a38977bf4e3ff5e2e1acb8c2b7eee" -dependencies = [ - "if_chain", - "lazy_static 1.4.0", - "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "regex", - "syn 1.0.78", - "validator_types", -] - -[[package]] -name = "validator_types" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded9d97e1d42327632f5f3bae6403c04886e2de3036261ef42deebd931a6a291" -dependencies = [ - "proc-macro2 1.0.29", - "syn 1.0.78", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static 1.4.0", - "log", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote 1.0.9", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "zeroize" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "synstructure", -] diff --git a/collector/Cargo.toml b/collector/Cargo.toml index e0224f6..95313a1 100644 --- a/collector/Cargo.toml +++ b/collector/Cargo.toml @@ -17,7 +17,7 @@ awc = "2.0.3" base64 = "0.13.0" bigdecimal = { version = "0.1.2", features = ["serde"] } chrono = "0.4.19" -curv-kzen = { package = "curv-kzen", version = "0.8.0" } +curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" futures = "0.3.17" @@ -25,7 +25,7 @@ http = "0.2.5" http-serde = "1.0.3" itertools = "0.10.1" jsonwebtoken = "7.2.0" -kzen-paillier = "0.4.1" +kzen-paillier = "0.4.2" lazy_static = "1.4.0" log = "0.4.14" num = "0.2.1" diff --git a/mediator/Cargo.lock b/mediator/Cargo.lock deleted file mode 100644 index d19e3c9..0000000 --- a/mediator/Cargo.lock +++ /dev/null @@ -1,3460 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be241f88f3b1e7e9a3fbe3b5a8a0f6915b5a1d7ee0d9a248d3376d01068cc60" -dependencies = [ - "actix-rt", - "actix_derive", - "bitflags", - "bytes 0.5.6", - "crossbeam-channel 0.4.4", - "derive_more", - "futures-channel", - "futures-util", - "log", - "once_cell", - "parking_lot", - "pin-project 0.4.28", - "smallvec", - "tokio", - "tokio-util", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-codec" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" -dependencies = [ - "bitflags", - "bytes 0.5.6", - "futures-core", - "futures-sink", - "log", - "pin-project 0.4.28", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-connect" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more", - "either", - "futures-util", - "http", - "log", - "openssl", - "tokio-openssl", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-http" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee" -dependencies = [ - "actix-codec", - "actix-connect", - "actix-rt", - "actix-service", - "actix-threadpool", - "actix-tls", - "actix-utils", - "base64 0.13.0", - "bitflags", - "brotli2", - "bytes 0.5.6", - "cookie", - "copyless", - "derive_more", - "either", - "encoding_rs", - "flate2", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "h2", - "http", - "httparse", - "indexmap", - "itoa", - "language-tags", - "lazy_static 1.4.0", - "log", - "mime", - "percent-encoding", - "pin-project 1.0.8", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "sha-1", - "slab", - "time 0.2.27", -] - -[[package]] -name = "actix-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" -dependencies = [ - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-router" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c" -dependencies = [ - "bytestring", - "http", - "log", - "regex", - "serde", -] - -[[package]] -name = "actix-rt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" -dependencies = [ - "actix-macros", - "actix-threadpool", - "copyless", - "futures-channel", - "futures-util", - "smallvec", - "tokio", -] - -[[package]] -name = "actix-server" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "futures-channel", - "futures-util", - "log", - "mio", - "mio-uds", - "num_cpus", - "slab", - "socket2", -] - -[[package]] -name = "actix-service" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" -dependencies = [ - "futures-util", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-testing" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" -dependencies = [ - "actix-macros", - "actix-rt", - "actix-server", - "actix-service", - "log", - "socket2", -] - -[[package]] -name = "actix-threadpool" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" -dependencies = [ - "derive_more", - "futures-channel", - "lazy_static 1.4.0", - "log", - "num_cpus", - "parking_lot", - "threadpool", -] - -[[package]] -name = "actix-tls" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" -dependencies = [ - "actix-codec", - "actix-service", - "actix-utils", - "futures-util", - "openssl", - "tokio-openssl", -] - -[[package]] -name = "actix-utils" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "bitflags", - "bytes 0.5.6", - "either", - "futures-channel", - "futures-sink", - "futures-util", - "log", - "pin-project 0.4.28", - "slab", -] - -[[package]] -name = "actix-web" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-testing", - "actix-threadpool", - "actix-tls", - "actix-utils", - "actix-web-codegen", - "awc", - "bytes 0.5.6", - "derive_more", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "log", - "mime", - "openssl", - "pin-project 1.0.8", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "socket2", - "time 0.2.27", - "tinyvec", - "url", -] - -[[package]] -name = "actix-web-actors" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6edf3c2693e2a8c422800c87ee89a6a4eac7dd01109bc172a1093ce1f4f001" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "bytes 0.5.6", - "futures-channel", - "futures-core", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-web-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3b11a07a3df3f7970fd8bd38cc66998b5549f507c54cc64c6e843bc82d6358" -dependencies = [ - "actix-web", - "base64 0.13.0", - "futures-util", -] - -[[package]] -name = "actix_derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "addr2line" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "anyhow" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" - -[[package]] -name = "async-trait" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "awc" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" -dependencies = [ - "actix-codec", - "actix-http", - "actix-rt", - "actix-service", - "base64 0.13.0", - "bytes 0.5.6", - "cfg-if 1.0.0", - "derive_more", - "futures-core", - "log", - "mime", - "openssl", - "percent-encoding", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded", -] - -[[package]] -name = "backtrace" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - -[[package]] -name = "base64" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bigdecimal" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1374191e2dd25f9ae02e3aa95041ed5d747fc77b3c102b49fe2dd9a8117a6244" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" -dependencies = [ - "block-padding 0.1.5", - "byte-tools", - "byteorder", - "generic-array 0.12.4", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array 0.14.4", -] - -[[package]] -name = "block-buffer" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "block-padding" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" -dependencies = [ - "byte-tools", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", -] - -[[package]] -name = "bumpalo" -version = "3.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" - -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "bytestring" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" -dependencies = [ - "bytes 1.1.0", -] - -[[package]] -name = "cc" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time 0.1.44", - "winapi 0.3.9", -] - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static 1.4.0", - "winapi 0.3.9", -] - -[[package]] -name = "const-oid" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdab415d6744056100f40250a66bc430c1a46f7a02e20bc11c94c79a0f0464df" - -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -dependencies = [ - "crossbeam-utils 0.7.2", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch", - "crossbeam-utils 0.8.5", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.5", - "lazy_static 1.4.0", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.0.1", - "cfg-if 0.1.10", - "lazy_static 1.4.0", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static 1.4.0", -] - -[[package]] -name = "crypto-bigint" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d12477e115c0d570c12a2dfd859f80b55b60ddb5075df210d3af06d133a69f45" -dependencies = [ - "generic-array 0.14.4", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d6b536309245c849479fba3da410962a43ed8e51c26b729208ec0ac2798d0" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array 0.14.4", - "subtle", -] - -[[package]] -name = "cryptoxide" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35f15e1a0699dd988fed910dd78fdc6407f44654cd12589c91fa44ea67d9159" - -[[package]] -name = "curv-kzen" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dec452bd369a0223f5fe65861d043daf9a270aecf6acc70841ed5b3058def19" -dependencies = [ - "cryptoxide", - "curve25519-dalek", - "digest 0.9.0", - "ff-zeroize", - "generic-array 0.14.4", - "hex", - "hmac", - "lazy_static 1.4.0", - "merkle-cbt", - "num-integer", - "num-traits", - "p256", - "pairing-plus", - "rand 0.6.5", - "rand 0.7.3", - "rust-gmp-kzen", - "secp256k1", - "serde", - "serde_bytes", - "serde_derive", - "sha2 0.8.2", - "sha2 0.9.8", - "sha3", - "thiserror", - "typenum", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "der" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" -dependencies = [ - "const-oid", -] - -[[package]] -name = "derive_more" -version = "0.99.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" -dependencies = [ - "convert_case", - "proc-macro2 1.0.29", - "quote 1.0.9", - "rustc_version 0.3.3", - "syn 1.0.78", -] - -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "bigdecimal", - "bitflags", - "byteorder", - "chrono", - "diesel_derives", - "ipnetwork", - "libc", - "num-bigint", - "num-integer", - "num-traits", - "pq-sys", - "r2d2", - "serde_json", - "time 0.1.44", - "uuid", -] - -[[package]] -name = "diesel-derive-newtype" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e844e8e6f65dcf27aa0b97d4234f974d93dfbf56816033d71b5e0c7eb701709f" -dependencies = [ - "diesel", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.14.9", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array 0.14.4", -] - -[[package]] -name = "digest" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b697d66081d42af4fba142d56918a3cb21dc8eb63372c6b85d14f44fb9c5979b" -dependencies = [ - "block-buffer 0.10.0", - "crypto-common", - "generic-array 0.14.4", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "ecdsa" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ee23aa5b4f68c7a092b5c3beb25f50c406adc75e2363634f242f28ab255372" -dependencies = [ - "der", - "elliptic-curve", - "hmac", - "signature", -] - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "elliptic-curve" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" -dependencies = [ - "crypto-bigint", - "ff", - "generic-array 0.14.4", - "group", - "pkcs8", - "rand_core 0.6.3", - "subtle", - "zeroize", -] - -[[package]] -name = "encoding_rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "error-chain" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -dependencies = [ - "backtrace", -] - -[[package]] -name = "evoting-mediator" -version = "0.1.0" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "actix-web-actors", - "actix-web-httpauth", - "anyhow", - "awc", - "base64 0.13.0", - "bigdecimal", - "chrono", - "curv-kzen", - "diesel", - "dotenv", - "futures", - "http", - "http-serde", - "itertools", - "jsonwebtoken", - "kzen-paillier", - "lazy_static 1.4.0", - "log", - "num", - "num-derive", - "num-traits", - "openssl", - "paste", - "rand 0.8.4", - "serde", - "serde_json", - "serde_repr", - "sha2 0.10.0", - "simple_logger", - "structopt", - "uuid", - "uuid-b64", - "validator", -] - -[[package]] -name = "fake-simd" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" - -[[package]] -name = "ff" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" -dependencies = [ - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "ff-zeroize" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02169a2e8515aa316ce516eaaf6318a76617839fbf904073284bc2576b029ee" -dependencies = [ - "byteorder", - "ff_derive-zeroize", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "ff_derive-zeroize" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24d4059bc0d0a0bf26b740aa21af1f96a984f0ab7a21356d00b32475388b53a" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" - -[[package]] -name = "futures-executor" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" - -[[package]] -name = "futures-macro" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" -dependencies = [ - "autocfg 1.0.1", - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - -[[package]] -name = "futures-task" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" - -[[package]] -name = "futures-util" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" -dependencies = [ - "autocfg 1.0.1", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite 0.2.7", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" - -[[package]] -name = "group" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" -dependencies = [ - "ff", - "rand_core 0.6.3", - "subtle", -] - -[[package]] -name = "h2" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", - "tracing-futures", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac", - "digest 0.9.0", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes 1.1.0", - "fnv", - "itoa", -] - -[[package]] -name = "http-serde" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25698ac7002625796d5a7df8f0602400571da944c2edc1d5c268a6947dd4f692" -dependencies = [ - "http", - "serde", -] - -[[package]] -name = "httparse" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "if_chain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg 1.0.1", - "hashbrown", -] - -[[package]] -name = "inlinable_string" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" -dependencies = [ - "serde", -] - -[[package]] -name = "instant" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2", - "widestring", - "winapi 0.3.9", - "winreg", -] - -[[package]] -name = "ipnetwork" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4088d739b183546b239688ddbc79891831df421773df95e236daf7867866d355" -dependencies = [ - "serde", -] - -[[package]] -name = "itertools" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" -dependencies = [ - "base64 0.12.3", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "kzen-paillier" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ccce3a6f805aa7845961eed04c12dd2fab74004563794b270cfc063ff9dd8e6" -dependencies = [ - "curv-kzen", - "rayon", - "serde", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "memoffset" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "merkle-cbt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f1ac8428ec02d6caa5a79c15e851d84d5dc7a00df0429a8aa860d104f0a81be" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg 1.0.1", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "num" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg 1.0.1", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-complex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg 1.0.1", - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" -dependencies = [ - "autocfg 1.0.1", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" -dependencies = [ - "autocfg 1.0.1", - "num-bigint", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg 1.0.1", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-sys" -version = "0.9.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" -dependencies = [ - "autocfg 1.0.1", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "p256" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" -dependencies = [ - "ecdsa", - "elliptic-curve", - "sha2 0.9.8", -] - -[[package]] -name = "pairing-plus" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cda4f22e8e6720f3c254049960c8cc4f93cb82b5ade43bddd2622b5f39ea62" -dependencies = [ - "byteorder", - "digest 0.8.1", - "ff-zeroize", - "rand 0.4.6", - "rand_core 0.5.1", - "rand_xorshift 0.2.0", - "zeroize", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi 0.3.9", -] - -[[package]] -name = "paste" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" - -[[package]] -name = "pem" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" -dependencies = [ - "base64 0.13.0", - "once_cell", - "regex", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pin-project" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" -dependencies = [ - "pin-project-internal 0.4.28", -] - -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal 1.0.8", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pq-sys" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" -dependencies = [ - "vcpkg", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" -dependencies = [ - "unicode-xid 0.2.2", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2 1.0.29", -] - -[[package]] -name = "r2d2" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.7", - "libc", - "rand_chacha 0.1.1", - "rand_core 0.4.2", - "rand_hc 0.1.0", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift 0.1.1", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", -] - -[[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.3", - "rand_hc 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.3", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom 0.2.3", -] - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.3", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.7", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_xorshift" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rayon" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" -dependencies = [ - "autocfg 1.0.1", - "crossbeam-deque", - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" -dependencies = [ - "crossbeam-channel 0.5.1", - "crossbeam-deque", - "crossbeam-utils 0.8.5", - "lazy_static 1.4.0", - "num_cpus", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi 0.3.9", -] - -[[package]] -name = "rust-gmp-kzen" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e654bb304958a567aefa09e83cc313251388202c40bfc245fac19a0e2dd8d08" -dependencies = [ - "libc", - "num-traits", - "serde", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "safemem" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" - -[[package]] -name = "scheduled-thread-pool" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7" -dependencies = [ - "parking_lot", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys", - "serde", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827cb7cce42533829c792fc51b82fbf18b125b45a702ef2c8be77fce65463a7b" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_json" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "sha2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" -dependencies = [ - "block-buffer 0.7.3", - "digest 0.8.1", - "fake-simd", - "opaque-debug 0.2.3", -] - -[[package]] -name = "sha2" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", -] - -[[package]] -name = "sha2" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.10.1", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug 0.3.0", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" -dependencies = [ - "digest 0.9.0", - "rand_core 0.6.3", -] - -[[package]] -name = "simple_asn1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" -dependencies = [ - "chrono", - "num-bigint", - "num-traits", -] - -[[package]] -name = "simple_logger" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" -dependencies = [ - "atty", - "chrono", - "colored", - "log", - "winapi 0.3.9", -] - -[[package]] -name = "slab" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "smallvec" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" -dependencies = [ - "der", -] - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" -dependencies = [ - "clap", - "lazy_static 1.4.0", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "unicode-xid 0.2.2", -] - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "unicode-xid 0.2.2", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi 0.3.9", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "standback", - "syn 1.0.78", -] - -[[package]] -name = "tinyvec" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "iovec", - "lazy_static 1.4.0", - "libc", - "memchr", - "mio", - "mio-uds", - "pin-project-lite 0.1.12", - "signal-hook-registry", - "slab", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-openssl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" -dependencies = [ - "openssl", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -dependencies = [ - "bytes 0.5.6", - "futures-core", - "futures-io", - "futures-sink", - "log", - "pin-project-lite 0.1.12", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" -dependencies = [ - "cfg-if 1.0.0", - "log", - "pin-project-lite 0.2.7", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static 1.4.0", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.8", - "tracing", -] - -[[package]] -name = "trust-dns-proto" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "enum-as-inner", - "futures", - "idna", - "lazy_static 1.4.0", - "log", - "rand 0.7.3", - "smallvec", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb" -dependencies = [ - "cfg-if 0.1.10", - "futures", - "ipconfig", - "lazy_static 1.4.0", - "log", - "lru-cache", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "trust-dns-proto", -] - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -dependencies = [ - "cfg-if 0.1.10", - "rand 0.4.6", -] - -[[package]] -name = "uuid-b64" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b9cb172a0b1f4e0bf63b807d67ff9ff0d9fba2bcc5f30d3aacb7240e02fc1b" -dependencies = [ - "base64 0.8.0", - "diesel", - "diesel-derive-newtype", - "error-chain", - "inlinable_string", - "lazy_static 0.2.11", - "serde", - "uuid", -] - -[[package]] -name = "validator" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0f08911ab0fee2c5009580f04615fa868898ee57de10692a45da0c3bcc3e5e" -dependencies = [ - "idna", - "lazy_static 1.4.0", - "regex", - "serde", - "serde_derive", - "serde_json", - "url", - "validator_derive", - "validator_types", -] - -[[package]] -name = "validator_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d85135714dba11a1bd0b3eb1744169266f1a38977bf4e3ff5e2e1acb8c2b7eee" -dependencies = [ - "if_chain", - "lazy_static 1.4.0", - "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "regex", - "syn 1.0.78", - "validator_types", -] - -[[package]] -name = "validator_types" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded9d97e1d42327632f5f3bae6403c04886e2de3036261ef42deebd931a6a291" -dependencies = [ - "proc-macro2 1.0.29", - "syn 1.0.78", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static 1.4.0", - "log", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote 1.0.9", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "zeroize" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "synstructure", -] diff --git a/mediator/Cargo.toml b/mediator/Cargo.toml index b57480e..f640d49 100644 --- a/mediator/Cargo.toml +++ b/mediator/Cargo.toml @@ -17,7 +17,7 @@ awc = "2.0.3" base64 = "0.13.0" bigdecimal = { version = "0.1.2", features = ["serde"] } chrono = "0.4.19" -curv-kzen = { package = "curv-kzen", version = "0.8.0" } +curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" futures = "0.3.17" @@ -25,7 +25,7 @@ http = "0.2.5" http-serde = "1.0.3" itertools = "0.10.1" jsonwebtoken = "7.2.0" -kzen-paillier = "0.4.1" +kzen-paillier = "0.4.2" lazy_static = "1.4.0" log = "0.4.14" num = "0.2.1" diff --git a/mediator/rustfmt.toml b/mediator/rustfmt.toml deleted file mode 100644 index d4a1802..0000000 --- a/mediator/rustfmt.toml +++ /dev/null @@ -1,11 +0,0 @@ -tab_spaces = 2 -max_width = 120 - -overflow_delimited_expr = true -reorder_impl_items = true -use_field_init_shorthand = true -match_block_trailing_comma = true - -imports_granularity = "Module" -group_imports = "StdExternalCrate" -imports_layout = "HorizontalVertical" \ No newline at end of file diff --git a/notifications/Cargo.lock b/notifications/Cargo.lock deleted file mode 100644 index 293f031..0000000 --- a/notifications/Cargo.lock +++ /dev/null @@ -1,2521 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "actix" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be241f88f3b1e7e9a3fbe3b5a8a0f6915b5a1d7ee0d9a248d3376d01068cc60" -dependencies = [ - "actix-rt", - "actix_derive", - "bitflags", - "bytes 0.5.6", - "crossbeam-channel", - "derive_more", - "futures-channel", - "futures-util", - "log", - "once_cell", - "parking_lot", - "pin-project 0.4.28", - "smallvec", - "tokio", - "tokio-util", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-codec" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" -dependencies = [ - "bitflags", - "bytes 0.5.6", - "futures-core", - "futures-sink", - "log", - "pin-project 0.4.28", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-connect" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "derive_more", - "either", - "futures-util", - "http", - "log", - "openssl", - "tokio-openssl", - "trust-dns-proto", - "trust-dns-resolver", -] - -[[package]] -name = "actix-http" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee" -dependencies = [ - "actix-codec", - "actix-connect", - "actix-rt", - "actix-service", - "actix-threadpool", - "actix-tls", - "actix-utils", - "base64 0.13.0", - "bitflags", - "brotli2", - "bytes 0.5.6", - "cookie", - "copyless", - "derive_more", - "either", - "encoding_rs", - "flate2", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "h2", - "http", - "httparse", - "indexmap", - "itoa", - "language-tags", - "lazy_static 1.4.0", - "log", - "mime", - "percent-encoding", - "pin-project 1.0.8", - "rand 0.7.3", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "sha-1", - "slab", - "time 0.2.27", -] - -[[package]] -name = "actix-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" -dependencies = [ - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-router" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c" -dependencies = [ - "bytestring", - "http", - "log", - "regex", - "serde", -] - -[[package]] -name = "actix-rt" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" -dependencies = [ - "actix-macros", - "actix-threadpool", - "copyless", - "futures-channel", - "futures-util", - "smallvec", - "tokio", -] - -[[package]] -name = "actix-server" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "futures-channel", - "futures-util", - "log", - "mio", - "mio-uds", - "num_cpus", - "slab", - "socket2", -] - -[[package]] -name = "actix-service" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" -dependencies = [ - "futures-util", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-testing" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" -dependencies = [ - "actix-macros", - "actix-rt", - "actix-server", - "actix-service", - "log", - "socket2", -] - -[[package]] -name = "actix-threadpool" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" -dependencies = [ - "derive_more", - "futures-channel", - "lazy_static 1.4.0", - "log", - "num_cpus", - "parking_lot", - "threadpool", -] - -[[package]] -name = "actix-tls" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" -dependencies = [ - "actix-codec", - "actix-service", - "actix-utils", - "futures-util", - "openssl", - "tokio-openssl", -] - -[[package]] -name = "actix-utils" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "bitflags", - "bytes 0.5.6", - "either", - "futures-channel", - "futures-sink", - "futures-util", - "log", - "pin-project 0.4.28", - "slab", -] - -[[package]] -name = "actix-web" -version = "3.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e641d4a172e7faa0862241a20ff4f1f5ab0ab7c279f00c2d4587b77483477b86" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-testing", - "actix-threadpool", - "actix-tls", - "actix-utils", - "actix-web-codegen", - "awc", - "bytes 0.5.6", - "derive_more", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "fxhash", - "log", - "mime", - "openssl", - "pin-project 1.0.8", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "socket2", - "time 0.2.27", - "tinyvec", - "url", -] - -[[package]] -name = "actix-web-actors" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6edf3c2693e2a8c422800c87ee89a6a4eac7dd01109bc172a1093ce1f4f001" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "bytes 0.5.6", - "futures-channel", - "futures-core", - "pin-project 0.4.28", -] - -[[package]] -name = "actix-web-codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3b11a07a3df3f7970fd8bd38cc66998b5549f507c54cc64c6e843bc82d6358" -dependencies = [ - "actix-web", - "base64 0.13.0", - "futures-util", -] - -[[package]] -name = "actix_derive" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b95aceadaf327f18f0df5962fedc1bde2f870566a0b9f65c89508a3b1f79334c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "addr2line" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "anyhow" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1" - -[[package]] -name = "async-trait" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "awc" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" -dependencies = [ - "actix-codec", - "actix-http", - "actix-rt", - "actix-service", - "base64 0.13.0", - "bytes 0.5.6", - "cfg-if 1.0.0", - "derive_more", - "futures-core", - "log", - "mime", - "openssl", - "percent-encoding", - "rand 0.7.3", - "serde", - "serde_json", - "serde_urlencoded", -] - -[[package]] -name = "backtrace" -version = "0.3.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - -[[package]] -name = "base64" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" -dependencies = [ - "byteorder", - "safemem", -] - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "base64" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", -] - -[[package]] -name = "bumpalo" -version = "3.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" - -[[package]] -name = "bytes" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" - -[[package]] -name = "bytestring" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" -dependencies = [ - "bytes 1.1.0", -] - -[[package]] -name = "cc" -version = "1.0.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time 0.1.44", - "winapi 0.3.9", -] - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "colored" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" -dependencies = [ - "atty", - "lazy_static 1.4.0", - "winapi 0.3.9", -] - -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - -[[package]] -name = "copyless" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" - -[[package]] -name = "cpufeatures" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" -dependencies = [ - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "lazy_static 1.4.0", -] - -[[package]] -name = "derive_more" -version = "0.99.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" -dependencies = [ - "convert_case", - "proc-macro2 1.0.29", - "quote 1.0.9", - "rustc_version 0.3.3", - "syn 1.0.78", -] - -[[package]] -name = "diesel" -version = "1.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28135ecf6b7d446b43e27e225622a038cc4e2930a1022f51cdb97ada19b8e4d" -dependencies = [ - "bitflags", - "byteorder", - "diesel_derives", - "pq-sys", - "uuid", -] - -[[package]] -name = "diesel-derive-newtype" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e844e8e6f65dcf27aa0b97d4234f974d93dfbf56816033d71b5e0c7eb701709f" -dependencies = [ - "diesel", - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.14.9", -] - -[[package]] -name = "diesel_derives" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encoding_rs" -version = "0.8.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "enum-as-inner" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" -dependencies = [ - "heck", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "error-chain" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -dependencies = [ - "backtrace", -] - -[[package]] -name = "evoting-notifications" -version = "0.1.0" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "actix-web-actors", - "actix-web-httpauth", - "anyhow", - "awc", - "chrono", - "dotenv", - "futures", - "jsonwebtoken", - "log", - "openssl", - "serde", - "serde_json", - "serde_repr", - "simple_logger", - "structopt", - "uuid", - "uuid-b64", -] - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if 1.0.0", - "crc32fast", - "libc", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" - -[[package]] -name = "futures-executor" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" - -[[package]] -name = "futures-macro" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" -dependencies = [ - "autocfg", - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - -[[package]] -name = "futures-task" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" - -[[package]] -name = "futures-util" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" -dependencies = [ - "autocfg", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite 0.2.7", - "pin-utils", - "proc-macro-hack", - "proc-macro-nested", - "slab", -] - -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" - -[[package]] -name = "h2" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", - "tracing-futures", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi 0.3.9", -] - -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes 1.1.0", - "fnv", - "itoa", -] - -[[package]] -name = "httparse" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - -[[package]] -name = "inlinable_string" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" -dependencies = [ - "serde", -] - -[[package]] -name = "instant" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipconfig" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" -dependencies = [ - "socket2", - "widestring", - "winapi 0.3.9", - "winreg", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonwebtoken" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" -dependencies = [ - "base64 0.12.3", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - -[[package]] -name = "language-tags" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" - -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" - -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "lock_api" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - -[[package]] -name = "mio-uds" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" -dependencies = [ - "iovec", - "libc", - "mio", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - -[[package]] -name = "net2" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "openssl" -version = "0.10.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-sys" -version = "0.9.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69df2d8dfc6ce3aaf44b40dec6f487d5a886516cf6879c49e98e0710f310a058" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" -dependencies = [ - "cfg-if 1.0.0", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi 0.3.9", -] - -[[package]] -name = "pem" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" -dependencies = [ - "base64 0.13.0", - "once_cell", - "regex", -] - -[[package]] -name = "percent-encoding" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" - -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - -[[package]] -name = "pin-project" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" -dependencies = [ - "pin-project-internal 0.4.28", -] - -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal 1.0.8", -] - -[[package]] -name = "pin-project-internal" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - -[[package]] -name = "pin-project-lite" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "pq-sys" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" -dependencies = [ - "vcpkg", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d" -dependencies = [ - "unicode-xid 0.2.2", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2 1.0.29", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi 0.3.9", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "safemem" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - -[[package]] -name = "serde" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.130" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_json" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer", - "cfg-if 1.0.0", - "cpufeatures", - "digest", - "opaque-debug", -] - -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - -[[package]] -name = "signal-hook-registry" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" -dependencies = [ - "libc", -] - -[[package]] -name = "simple_asn1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" -dependencies = [ - "chrono", - "num-bigint", - "num-traits", -] - -[[package]] -name = "simple_logger" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" -dependencies = [ - "atty", - "chrono", - "colored", - "log", - "winapi 0.3.9", -] - -[[package]] -name = "slab" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" - -[[package]] -name = "smallvec" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" - -[[package]] -name = "socket2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2 1.0.29", - "quote 1.0.9", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn 1.0.78", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf9d950ef167e25e0bdb073cf1d68e9ad2795ac826f2f3f59647817cf23c0bfa" -dependencies = [ - "clap", - "lazy_static 1.4.0", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134d838a2c9943ac3125cf6df165eda53493451b719f3255b2a26b85f772d0ba" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "syn" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - -[[package]] -name = "syn" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eac2e6c19f5c3abc0c229bea31ff0b9b091c7b14990e8924b92902a303a0c0" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "unicode-xid 0.2.2", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602eca064b2d83369e2b2f34b09c70b605402801927c65c11071ac911d299b88" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad553cc2c78e8de258400763a647e80e6d1b31ee237275d756f6836d204494c" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi 0.3.9", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2 1.0.29", - "quote 1.0.9", - "standback", - "syn 1.0.78", -] - -[[package]] -name = "tinyvec" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "0.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" -dependencies = [ - "bytes 0.5.6", - "fnv", - "futures-core", - "iovec", - "lazy_static 1.4.0", - "libc", - "memchr", - "mio", - "mio-uds", - "pin-project-lite 0.1.12", - "signal-hook-registry", - "slab", - "winapi 0.3.9", -] - -[[package]] -name = "tokio-openssl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594" -dependencies = [ - "openssl", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" -dependencies = [ - "bytes 0.5.6", - "futures-core", - "futures-io", - "futures-sink", - "log", - "pin-project-lite 0.1.12", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f96e095c0c82419687c20ddf5cb3eadb61f4e1405923c9dc8e53a1adacbda8" -dependencies = [ - "cfg-if 1.0.0", - "log", - "pin-project-lite 0.2.7", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static 1.4.0", -] - -[[package]] -name = "tracing-futures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" -dependencies = [ - "pin-project 1.0.8", - "tracing", -] - -[[package]] -name = "trust-dns-proto" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "enum-as-inner", - "futures", - "idna", - "lazy_static 1.4.0", - "log", - "rand 0.7.3", - "smallvec", - "thiserror", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.19.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb" -dependencies = [ - "cfg-if 0.1.10", - "futures", - "ipconfig", - "lazy_static 1.4.0", - "log", - "lru-cache", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "trust-dns-proto", -] - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - -[[package]] -name = "unicode-bidi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" -dependencies = [ - "cfg-if 0.1.10", - "rand 0.4.6", -] - -[[package]] -name = "uuid-b64" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b9cb172a0b1f4e0bf63b807d67ff9ff0d9fba2bcc5f30d3aacb7240e02fc1b" -dependencies = [ - "base64 0.8.0", - "diesel", - "diesel-derive-newtype", - "error-chain", - "inlinable_string", - "lazy_static 0.2.11", - "serde", - "uuid", -] - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static 1.4.0", - "log", - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote 1.0.9", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2 1.0.29", - "quote 1.0.9", - "syn 1.0.78", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/notifications/rustfmt.toml b/notifications/rustfmt.toml deleted file mode 100644 index d4a1802..0000000 --- a/notifications/rustfmt.toml +++ /dev/null @@ -1,11 +0,0 @@ -tab_spaces = 2 -max_width = 120 - -overflow_delimited_expr = true -reorder_impl_items = true -use_field_init_shorthand = true -match_block_trailing_comma = true - -imports_granularity = "Module" -group_imports = "StdExternalCrate" -imports_layout = "HorizontalVertical" \ No newline at end of file diff --git a/collector/rustfmt.toml b/rustfmt.toml similarity index 100% rename from collector/rustfmt.toml rename to rustfmt.toml diff --git a/server/Cargo.toml b/server/Cargo.toml index 9e3bfba..8f62b58 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -16,12 +16,12 @@ bcrypt = "0.10.1" bigdecimal = { version = "0.1.2", features = ["serde"] } censor = "0.2.0" chrono = "0.4.19" -curv-kzen = { package = "curv-kzen", version = "0.8.0" } +curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" futures = "0.3.17" jsonwebtoken = "7.2.0" -kzen-paillier = "0.4.1" +kzen-paillier = "0.4.2" lazy_static = "1.4.0" log = "0.4.14" num = "0.2.1" diff --git a/server/rustfmt.toml b/server/rustfmt.toml deleted file mode 100644 index d4a1802..0000000 --- a/server/rustfmt.toml +++ /dev/null @@ -1,11 +0,0 @@ -tab_spaces = 2 -max_width = 120 - -overflow_delimited_expr = true -reorder_impl_items = true -use_field_init_shorthand = true -match_block_trailing_comma = true - -imports_granularity = "Module" -group_imports = "StdExternalCrate" -imports_layout = "HorizontalVertical" \ No newline at end of file From 6add71d9e4b834dd1e619a2e7acaf9d0a947b255 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 15:58:22 -0500 Subject: [PATCH 2/7] Created new Rust library to store all shared code --- Cargo.lock | 4 ++++ Cargo.toml | 1 + README.md | 1 + shared/.gitignore | 11 +++++++++++ shared/Cargo.toml | 7 +++++++ shared/README.md | 3 +++ shared/src/lib.rs | 3 +++ 7 files changed, 30 insertions(+) create mode 100644 shared/.gitignore create mode 100644 shared/Cargo.toml create mode 100644 shared/README.md create mode 100644 shared/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1664e76..384a940 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1326,6 +1326,10 @@ dependencies = [ "zxcvbn", ] +[[package]] +name = "evoting-shared" +version = "0.1.0" + [[package]] name = "failure" version = "0.1.8" diff --git a/Cargo.toml b/Cargo.toml index bac99b1..f81f207 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ + "shared", "server", "mediator", "collector", diff --git a/README.md b/README.md index 814edda..79ce64e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ The code is laid out as a [monorepo](https://en.wikipedia.org/wiki/Monorepo) wit - [`/mediator`](/mediator) - Code for the collector mediator - [`/collector`](/collector) - Code for collector - [`/notifications`](/notifications) - Code for websocket notification server +- [`/shared`](/shared) - Shared code between the server, mediator, collector, and notifications - [`/frontend`](/frontend) - TypeScript code for single-page application See the `README.md` file in each subdirectory for directions on compiling and running the code. diff --git a/shared/.gitignore b/shared/.gitignore new file mode 100644 index 0000000..1bcabd7 --- /dev/null +++ b/shared/.gitignore @@ -0,0 +1,11 @@ +/target +**/*.rs.bk + +# Database login credentials +.env* + +# Files upload directory +/files + +# Schema file patch +src/schema.rs.orig diff --git a/shared/Cargo.toml b/shared/Cargo.toml new file mode 100644 index 0000000..508f9f2 --- /dev/null +++ b/shared/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "evoting-shared" +version = "0.1.0" +authors = ["Bryan McClain "] +edition = "2018" + +[dependencies] diff --git a/shared/README.md b/shared/README.md new file mode 100644 index 0000000..4f94a67 --- /dev/null +++ b/shared/README.md @@ -0,0 +1,3 @@ +# Electronic Voting Shared Library + +Code shared between the different Rust libraries diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..59207dc --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1,3 @@ +pub fn test() -> i32 { + 15 +} From b30b1fa62939faca3e9cf76bddecbbef3a49e6e1 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 19:44:57 -0500 Subject: [PATCH 3/7] Created shared library for code between the modules --- Cargo.lock | 24 + shared/Cargo.toml | 22 + shared/src/auth/audience.rs | 67 ++ shared/src/auth/constants.rs | 5 + shared/src/auth/jwt_secret.rs | 21 + shared/src/auth/jwt_token.rs | 188 ++++ shared/src/auth/mod.rs | 14 + shared/src/auth/permission.rs | 26 + shared/src/db/associations.rs | 916 ++++++++++++++++++ shared/src/db/db_connection.rs | 78 ++ shared/src/db/init.rs | 13 + shared/src/db/many_many_constructor.rs | 6 + shared/src/db/mod.rs | 19 + shared/src/db/sql_enum.rs | 54 ++ shared/src/db/subtypes.rs | 71 ++ shared/src/db/types.rs | 5 + shared/src/errors/client_request_error.rs | 73 ++ shared/src/errors/error_response.rs | 87 ++ shared/src/errors/generic_error.rs | 168 ++++ shared/src/errors/global_error_codes.rs | 46 + shared/src/errors/mod.rs | 12 + shared/src/lib.rs | 9 +- shared/src/protocol/count_ballot_votes.rs | 106 ++ shared/src/protocol/generator.rs | 48 + shared/src/protocol/location_anonymization.rs | 65 ++ shared/src/protocol/mod.rs | 12 + shared/src/protocol/shares_matrix.rs | 152 +++ shared/src/protocol/stpm.rs | 91 ++ shared/src/utils/convert_bigint.rs | 83 ++ shared/src/utils/is_offensive_string.rs | 26 + shared/src/utils/mod.rs | 13 + shared/src/utils/new_safe_uuid_v4.rs | 19 + shared/src/utils/password_complexity.rs | 45 + shared/src/utils/serialize_option_bigint.rs | 40 + 34 files changed, 2621 insertions(+), 3 deletions(-) create mode 100644 shared/src/auth/audience.rs create mode 100644 shared/src/auth/constants.rs create mode 100644 shared/src/auth/jwt_secret.rs create mode 100644 shared/src/auth/jwt_token.rs create mode 100644 shared/src/auth/mod.rs create mode 100644 shared/src/auth/permission.rs create mode 100644 shared/src/db/associations.rs create mode 100644 shared/src/db/db_connection.rs create mode 100644 shared/src/db/init.rs create mode 100644 shared/src/db/many_many_constructor.rs create mode 100644 shared/src/db/mod.rs create mode 100644 shared/src/db/sql_enum.rs create mode 100644 shared/src/db/subtypes.rs create mode 100644 shared/src/db/types.rs create mode 100644 shared/src/errors/client_request_error.rs create mode 100644 shared/src/errors/error_response.rs create mode 100644 shared/src/errors/generic_error.rs create mode 100644 shared/src/errors/global_error_codes.rs create mode 100644 shared/src/errors/mod.rs create mode 100644 shared/src/protocol/count_ballot_votes.rs create mode 100644 shared/src/protocol/generator.rs create mode 100644 shared/src/protocol/location_anonymization.rs create mode 100644 shared/src/protocol/mod.rs create mode 100644 shared/src/protocol/shares_matrix.rs create mode 100644 shared/src/protocol/stpm.rs create mode 100644 shared/src/utils/convert_bigint.rs create mode 100644 shared/src/utils/is_offensive_string.rs create mode 100644 shared/src/utils/mod.rs create mode 100644 shared/src/utils/new_safe_uuid_v4.rs create mode 100644 shared/src/utils/password_complexity.rs create mode 100644 shared/src/utils/serialize_option_bigint.rs diff --git a/Cargo.lock b/Cargo.lock index 384a940..97ed1a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1329,6 +1329,30 @@ dependencies = [ [[package]] name = "evoting-shared" version = "0.1.0" +dependencies = [ + "actix-http", + "actix-web", + "actix-web-httpauth", + "anyhow", + "awc", + "bigdecimal", + "censor", + "chrono", + "curv-kzen", + "diesel", + "futures", + "jsonwebtoken", + "kzen-paillier", + "lazy_static 1.4.0", + "log", + "num", + "paste", + "serde", + "serde_repr", + "uuid", + "uuid-b64", + "zxcvbn", +] [[package]] name = "failure" diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 508f9f2..1c4249f 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -5,3 +5,25 @@ authors = ["Bryan McClain "] edition = "2018" [dependencies] +actix-http = "2.2.1" +actix-web = { version = "3", features = ["openssl"] } +actix-web-httpauth = "0.5.1" +anyhow = "1.0.44" +awc = "2.0.3" +bigdecimal = { version = "0.1.2", features = ["serde"] } +censor = "0.2.0" +chrono = "0.4.19" +curv-kzen = { package = "curv-kzen", version = "0.9.0" } +diesel = { version = "1.4.8", features = ["postgres", "extras"] } +futures = "0.3.17" +jsonwebtoken = "7.2.0" +kzen-paillier = "0.4.2" +lazy_static = "1.4.0" +log = "0.4.14" +num = "0.2.1" +paste = "1.0.5" +serde = "1.0.130" +serde_repr = "0.1.7" +uuid = "0.6" +uuid-b64 = { version = "0.1.1", features = ["serde", "diesel-uuid"] } +zxcvbn = "2.1.1" diff --git a/shared/src/auth/audience.rs b/shared/src/auth/audience.rs new file mode 100644 index 0000000..11fd88c --- /dev/null +++ b/shared/src/auth/audience.rs @@ -0,0 +1,67 @@ +use serde::Deserialize; +use std::collections::HashSet; +use std::iter::FromIterator; + +/// Generic trait shared by all audience types +/// +/// An audience specifies which routes a JWT can access +pub trait Audience { + const TEXT: &'static str; + const ACCEPTS: &'static [&'static str]; + + /// Get the name to show for this audience type + fn get_name() -> String { + Self::TEXT.to_string() + } + + /// Get the list of all audiences accepted by this type + fn accepts() -> HashSet { + HashSet::from_iter(Self::ACCEPTS.iter().cloned().map(String::from)) + } +} + +/// Route is available to all token types +#[derive(Deserialize)] +pub struct All; + +impl Audience for All { + const TEXT: &'static str = "all"; + const ACCEPTS: &'static [&'static str] = &["all", "client-only", "server-only", "collector-only"]; +} + +/// Route can only be called by the frontend client +#[derive(Deserialize)] +pub struct ClientOnly; + +impl Audience for ClientOnly { + const TEXT: &'static str = "client-only"; + const ACCEPTS: &'static [&'static str] = &["all", "client-only"]; +} + +/// Route can only be called by the server +#[derive(Deserialize)] +pub struct ServerOnly; + +impl Audience for ServerOnly { + const TEXT: &'static str = "server-only"; + const ACCEPTS: &'static [&'static str] = &["all", "server-only"]; +} + +/// Route can only be called by a collector +#[derive(Deserialize)] +pub struct CollectorOnly; + +impl Audience for CollectorOnly { + const TEXT: &'static str = "collector-only"; + const ACCEPTS: &'static [&'static str] = &["all", "collector-only"]; +} + +/// Route can only be called by a mediator +#[derive(Deserialize)] +pub struct MediatorOnly; + +impl Audience for MediatorOnly { + const TEXT: &'static str = "mediator-only"; + const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; +} + diff --git a/shared/src/auth/constants.rs b/shared/src/auth/constants.rs new file mode 100644 index 0000000..27f7904 --- /dev/null +++ b/shared/src/auth/constants.rs @@ -0,0 +1,5 @@ +pub const JWT_ISSUER: &str = "evoting"; +pub const JWT_EXPIRATION_MIN: i64 = 10; + +pub const JWT_REFRESH_AUDIENCE: &str = "refresh"; +pub const JWT_REFRESH_EXPIRATION_MIN: i64 = 60; diff --git a/shared/src/auth/jwt_secret.rs b/shared/src/auth/jwt_secret.rs new file mode 100644 index 0000000..ebf8054 --- /dev/null +++ b/shared/src/auth/jwt_secret.rs @@ -0,0 +1,21 @@ +use jsonwebtoken::{DecodingKey, EncodingKey}; + +/// Simple wrapper struct to store the JWT secret +#[derive(Debug, Clone)] +pub struct JWTSecret { + secret: String, +} + +impl JWTSecret { + pub fn new(secret: impl Into) -> Self { + Self { secret: secret.into() } + } + + pub fn get_encoding_key(&self) -> EncodingKey { + EncodingKey::from_secret(self.secret.as_bytes()) + } + + pub fn get_decoding_key<'a>(&'a self) -> DecodingKey<'a> { + DecodingKey::from_secret(self.secret.as_bytes()) + } +} diff --git a/shared/src/auth/jwt_token.rs b/shared/src/auth/jwt_token.rs new file mode 100644 index 0000000..cf16c2e --- /dev/null +++ b/shared/src/auth/jwt_token.rs @@ -0,0 +1,188 @@ +use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; +use actix_web_httpauth::extractors::bearer::BearerAuth; +use chrono::{offset::Utc, Duration}; +use futures::executor::block_on; +use futures::future::{ready, Ready}; +use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::collections::HashSet; +use std::iter::FromIterator; +use std::marker::PhantomData; +use uuid_b64::UuidB64 as Uuid; + +use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; +use crate::errors::SharedError; + +// Type aliases for the different JWT tokens +pub type ClientToken = JWTToken; +pub type ServerToken = JWTToken; +pub type CollectorToken = JWTToken; +pub type MediatorToken = JWTToken; +pub type AnyToken = JWTToken; + +/// JSON Web Token used for user authentication +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct JWTToken { + // Reserved Claims + iss: String, // Issuer + sub: Uuid, // Subject (whom token refers to) + aud: String, // Audience (whom the token is intended for) + iat: i64, // Issued at (as UTC timestamp) + exp: i64, // Expiration time (as UTC timestamp) + + // Public and private claims + #[serde(flatten)] + user_data: T, + permissions: HashSet, + + #[serde(skip)] + _aud: PhantomData, +} + +/// Internal data used by the client JSON Web Token +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct JWTClientData { + email: String, + name: String, +} + +pub type JWTInternalData = (); + +/// Internal data used by the "Any" JSON Web Token +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct JWTAnyData { + email: Option, + name: Option, +} + +impl JWTToken +where + A: Audience, + T: Serialize + DeserializeOwned, +{ + /// Encode the JSON Web Token into a string + pub fn encode(&self, key: &EncodingKey) -> Result { + Ok(encode(&Header::default(), self, key)?) + } + + pub fn get_user_id(&self) -> Uuid { + self.sub + } + + /// Test if the user has permission to do something + pub fn has_permission(&self, p: Permission) -> bool { + self.permissions.contains(&p) + } +} + +impl JWTToken +where + A: Audience, +{ + /// Create a new JSON Web Token given the user, audience, and list of permissions + pub fn new(user_id: Uuid, name: impl ToString, email: impl ToString, permissions: &[Permission]) -> Self { + let now = Utc::now(); + let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); + + Self { + iss: JWT_ISSUER.to_string(), + sub: user_id, + aud: A::get_name(), + iat: now.timestamp(), + exp: expiration.timestamp(), + + user_data: JWTClientData { + email: email.to_string(), + name: name.to_string(), + }, + permissions: HashSet::from_iter(permissions.into_iter().cloned()), + + _aud: PhantomData, + } + } + + pub fn get_name(&self) -> &String { + &self.user_data.name + } + + pub fn get_email(&self) -> &String { + &self.user_data.email + } +} + +impl JWTToken +where + A: Audience, +{ + pub fn new(permissions: &[Permission]) -> Self { + use uuid::Uuid; + + let now = Utc::now(); + let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); + + Self { + iss: JWT_ISSUER.to_string(), + sub: Uuid::nil().into(), + aud: A::get_name(), + iat: now.timestamp(), + exp: expiration.timestamp(), + + user_data: (), + permissions: HashSet::from_iter(permissions.into_iter().cloned()), + + _aud: PhantomData, + } + } +} + +impl JWTToken +where + A: Audience, +{ + pub fn get_name(&self) -> Option<&String> { + self.user_data.name.as_ref() + } + + pub fn get_email(&self) -> Option<&String> { + self.user_data.email.as_ref() + } +} + +// +// Get the JSON Web Token from the request +// +impl FromRequest for JWTToken +where + A: Audience, + T: Serialize + DeserializeOwned, +{ + type Error = SharedError; + type Future = Ready>; + type Config = (); + + fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { + let result: Result = (|| { + // Extract the JWT from the header and the encryption key from the app data + let bearer_token = block_on(BearerAuth::from_request(req, pl))?; + let jwt_secret = req.app_data::>().expect("JWTSecret should be set"); + + // Validation parameters, + let validation = Validation { + validate_exp: true, + leeway: 15, + aud: Some(A::accepts()), + iss: Some(JWT_ISSUER.into()), + ..Default::default() + }; + + // Decode and validate the JWT + let token_data = decode::(bearer_token.token(), &jwt_secret.get_decoding_key(), &validation)?; + Ok(token_data.claims) + })(); + + ready(result) + } +} diff --git a/shared/src/auth/mod.rs b/shared/src/auth/mod.rs new file mode 100644 index 0000000..943edd5 --- /dev/null +++ b/shared/src/auth/mod.rs @@ -0,0 +1,14 @@ +// +// Structures and functions related to user authentication and authorization +// +pub mod audience; +mod constants; +mod jwt_secret; +mod jwt_token; +mod permission; + +pub use audience::Audience; +pub use constants::*; +pub use jwt_secret::JWTSecret; +pub use jwt_token::*; +pub use permission::{Permission, DEFAULT_PERMISSIONS}; diff --git a/shared/src/auth/permission.rs b/shared/src/auth/permission.rs new file mode 100644 index 0000000..924a459 --- /dev/null +++ b/shared/src/auth/permission.rs @@ -0,0 +1,26 @@ +use serde_repr::{Deserialize_repr, Serialize_repr}; +use std::fmt; + +pub static DEFAULT_PERMISSIONS: &[Permission] = &[ + Permission::CanLogin, + Permission::CreateElection, + Permission::Register, + Permission::Vote, +]; + +/// List of every permission +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)] +#[repr(u32)] +pub enum Permission { + CanLogin, + CreateElection, + Register, + Vote, + ManageCollector, +} + +impl fmt::Display for Permission { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} diff --git a/shared/src/db/associations.rs b/shared/src/db/associations.rs new file mode 100644 index 0000000..66a47fb --- /dev/null +++ b/shared/src/db/associations.rs @@ -0,0 +1,916 @@ +// ======================= +// Model Base +// ======================= +#[macro_export] +macro_rules! model_base( + () => { + model_base!(no update); + + // Save changes to database + pub fn update( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + self.save_changes::(conn.get()) + } + + // Insert as a new entry, or update the existing entry on conflict + // Uses the primary key to detect duplicate entries + pub fn insert_or_update( + &self, + conn: &crate::db::DbConnection + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + use diesel::insert_into; + + insert_into(::table()) + .values(self) + .on_conflict(::table().primary_key()) + .do_update() + .set(self) + .get_result::(conn.get()) + } + }; + + (order by $order:expr) => { + model_base!(); + paste::item! { + model_base!(@ order by crate::schema::$order); + } + }; + + (no update, order by $order:expr) => { + model_base!(no update); + paste::item! { + model_base!(@ order by crate::schema::$order); + } + }; + + (no update) => { + // Get all + pub fn all( + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + ::table() + .get_results::(conn.get()) + } + + // Count all users + pub fn count_all( + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + ::table() + .count().get_result::(conn.get()) + } + + // Find from ID + pub fn find( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + ::table() + .find(id) + .get_result::(conn.get()) + } + + // Find optional from ID + pub fn find_optional( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + ::table() + .find(id) + .get_result::(conn.get()) + .optional() + } + + // Create the new entry in the database + pub fn insert( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + use diesel::insert_into; + + insert_into(::table()) + .values(self) + .get_result::(conn.get()) + } + + // Insert only if the entry is not in the database + pub fn insert_ignore_conflicts( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::insert_into; + + insert_into(::table()) + .values(self) + .on_conflict_do_nothing() + .get_result::(conn.get()) + .optional() + } + + // Create multiple entries in the database + pub fn insert_list( + entries: &Vec, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::insert_into; + + insert_into(::table()) + .values(entries) + .get_results::(conn.get()) + } + + // Insert a list of values, but ignore duplicate values + pub fn insert_list_ignore_conflicts( + entries: &Vec, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::insert_into; + + insert_into(::table()) + .values(entries) + .on_conflict_do_nothing() + .get_results::(conn.get()) + } + + // Test if an item exists in the database + pub fn exists( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + Self::find_optional( + <&Self as diesel::associations::Identifiable>::id(&self), + conn, + ).map(|result| result.is_some()) + } + + // Test if an item exists by ID + pub fn exists_from_id( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + Self::find_optional(id, conn).map(|result| result.is_some()) + } + + // Reload from database + pub fn reload( + &mut self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<()> { + use diesel::prelude::*; + + let new_value = ::table() + .find( + <&Self as diesel::associations::Identifiable>::id(&self) + ) + .get_result::(conn.get())?; + + *self = new_value; + + Ok(()) + } + + // Reload from database + pub fn reload_new( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + ::table() + .find( + <&Self as diesel::associations::Identifiable>::id(&self) + ) + .get_result::(conn.get()) + } + + // Delete item in database + pub fn delete( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + use diesel::delete; + + delete( + ::table().find( + <&Self as diesel::associations::Identifiable>::id(&self) + ) + ) + .get_result::(conn.get()) + } + + // Delete item in database, but only if it already exists + pub fn delete_optional( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::delete; + + delete( + ::table().find( + <&Self as diesel::associations::Identifiable>::id(&self) + ) + ) + .get_result::(conn.get()) + .optional() + } + + // Delete item in database + pub fn delete_from_id( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + use diesel::delete; + + delete( + ::table().find(id) + ) + .get_result::(conn.get()) + } + + // Delete item in database, but only if it already exists + pub fn delete_from_id_optional( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::delete; + + delete( + ::table().find(id) + ) + .get_result::(conn.get()) + .optional() + } + }; + + (@ order by $order:expr) => { + + // Get all ordered by + pub fn all_ordered( + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + ::table().order_by($order) + .get_results::(conn.get()) + } + }; +); + +// ======================= +// Belongs To +// ======================= +#[macro_export] +macro_rules! belongs_to( + ($parent:ident) => { + paste::item! { + belongs_to!($parent, [<$parent:snake>]); + } + }; + + ($parent:ident, $func_base:ident) => { + belongs_to!(@ crate::models::$parent, $func_base); + }; + + (@ $parent:path, $func_base:ident) => { + // Get parent + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<$parent> { + use diesel::prelude::*; + + match >::foreign_key(&self) { + None => Err(diesel::result::Error::NotFound), + Some(id) => { + <$parent as diesel::associations::HasTable>::table() + .find(id) + .get_result::<$parent>(conn.get()) + } + } + } + } + + // Get parent optional + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + match >::foreign_key(&self) { + None => Ok(None), + Some(id) => { + <$parent as diesel::associations::HasTable>::table() + .find(id) + .get_result::<$parent>(conn.get()) + .optional() + } + } + } + } + }; +); + +// ======================= +// Has One +// ======================= +#[macro_export] +macro_rules! has_one( + // Pluralize + ($child:ident) => { + paste::item! { + has_one!($child, [<$child:snake>]); + } + }; + + ($child:ident, $func_base:ident) => { + has_one!(@ crate::models::$child, $func_base); + }; + + // Explicit function base + (@ $child:path, $func_base:ident) => { + + // Get child + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<$child> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ).get_result::<$child>(conn.get()) + } + } + + // Get child from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<$child> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id) + ).get_result::<$child>(conn.get()) + } + } + + // Delete child + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::delete; + use diesel::prelude::*; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ), + ) + .get_result::(conn.get()) + } + } + + // Delete child from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + use diesel::delete; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ), + ) + .get_result::(conn.get()) + } + } + }; +); + +// ======================= +// Has Zero or One +// ======================= +#[macro_export] +macro_rules! has_zero_or_one( + // Pluralize + ($child:ident) => { + paste::item! { + has_zero_or_one!($child, [<$child:snake>]); + } + }; + + ($child:ident, $func_base:ident) => { + has_zero_or_one!(@ crate::models::$child, $func_base); + }; + + // Explicit function base + (@ $child:path, $func_base:ident) => { + + // Get child + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ) + .get_result::<$child>(conn.get()) + .optional() + } + } + + // Get child from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id) + ) + .get_result::<$child>(conn.get()) + .optional() + } + } + + // Delete child + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::delete; + use diesel::prelude::*; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ), + ) + .get_result::<$child>(conn.get()) + .optional() + } + } + + // Delete child from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::delete; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ), + ) + .get_result::<$child>(conn.get()) + .optional() + } + } + }; +); + +// ======================= +// Has Many +// ======================= +#[macro_export] +macro_rules! has_many( + // Pluralize + ($child:ident) => { + paste::item! { + has_many!($child, [<$child:snake s>]); + } + }; + + ($child:ident, order by $order:expr) => { + paste::item! { + has_many!($child, order by $order, [<$child:snake s>]); + } + }; + + ($child:ident, $func_base:ident) => { + has_many!(@ crate::models::$child, $func_base); + }; + + ($child:ident, order by $order:expr, $func_base:ident) => { + has_many!(@ crate::models::$child, $func_base); + paste::item! { + has_many!(@ crate::models::$child, order by crate::schema::$order, $func_base); + } + }; + + // Explicit function base + (@ $child:path, $func_base:ident) => { + + // Get children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + $child::belonging_to(self).get_results::<$child>(conn.get()) + } + } + + // Get children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id) + ).get_results::<$child>(conn.get()) + } + } + + // Count children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + $child::belonging_to(self).count().get_result::(conn.get()) + } + } + + // Count children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id) + ).count().get_result::(conn.get()) + } + } + + // Delete all children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::delete; + use diesel::prelude::*; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ), + ) + .get_results::<$child>(conn.get()) + } + } + + // Delete all children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + use diesel::delete; + + delete( + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ), + ) + .get_results::<$child>(conn.get()) + } + } + }; + + // Has many ordered + (@ $child:path, order by $order:expr, $func_base:ident) => { + + // Get children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + $child::belonging_to(self).order_by($order).get_results::<$child>(conn.get()) + } + } + + // Get children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$child as diesel::associations::HasTable>::table().filter( + <$child as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id) + ) + .order_by($order) + .get_results::<$child>(conn.get()) + } + } + }; + + + // ======================= + // Has Many Through + // (Special case) + // ======================= + ($child:ident through $through:ident) => ( + paste::item! { + has_many!($child through $through, [<$child:snake s>]); + } + ); + + ($child:ident through $through:ident, order by $order:expr) => ( + paste::item! { + has_many!($child through $through, order by $order, [<$child:snake s>]); + } + ); + + ($child:ident through $through:ident, $func_base:ident) => { + has_many!(@ crate::models::$child => crate::models::$through, $func_base); + }; + + ($child:ident through $through:ident, order by $order:expr, $func_base:ident) => { + has_many!(@ crate::models::$child => crate::models::$through, $func_base); + paste::item! { + has_many!(@ crate::models::$child => crate::models::$through, order by crate::schema::$order, $func_base); + } + }; + + (@ $child:path => $through:path, $func_base:ident) => { + + // Get children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ) + .get_results::<($through, $child)>(conn.get()) + .map(|results| results.into_iter().map(|(_, second)| second).collect()) + } + } + + // Get children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ) + .get_results::<($through, $child)>(conn.get()) + .map(|results| results.into_iter().map(|(_, second)| second).collect()) + } + } + + // Count children + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ) + .count().get_result::(conn.get()) + } + } + + // Count children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ) + .count().get_result::(conn.get()) + } + } + + // Delete children from many-to-many the association + // Does NOT delete the actual values + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::delete; + use diesel::prelude::*; + + delete( + <$through as diesel::associations::HasTable>::table().filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ) + ).get_results::<$through>(conn.get()) + } + } + + // Delete children from many-to-many the association by the ID + // Does NOT delete the actual values + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::delete; + use diesel::prelude::*; + + delete( + <$through as diesel::associations::HasTable>::table().filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ) + ).get_results::<$through>(conn.get()) + } + } + + // Set children + paste::item! { + pub fn []<'a>( + &self, + list: impl std::iter::IntoIterator, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); + Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) + } + } + + // Set children Ids + paste::item! { + pub fn []<'a>( + &self, + ids_list: impl std::iter::IntoIterator>::ForeignKey>, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) + } + } + + // Set children from ID + paste::item! { + pub fn []<'a>( + id: <&Self as diesel::associations::Identifiable>::Id, + list: impl std::iter::IntoIterator, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); + Self::[](id, ids_list, conn) + } + } + + // Set all IDs from ID + paste::item! { + pub fn []<'a>( + id: <&Self as diesel::associations::Identifiable>::Id, + ids_list: impl std::iter::IntoIterator>::ForeignKey>, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + Self::[](id, conn)?; + + let new_entries: Vec<$through> = ids_list + .into_iter() + .map(|item| <$through as crate::db::ManyToManyConstructor>::new(id, item)) + .collect(); + + Ok($through::insert_list(&new_entries, conn)?) + } + } + }; + + (@ $child:path => $through:path, order by $order:expr, $func_base:ident) => { + // Get children ordered + paste::item! { + pub fn []( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(<&Self as diesel::associations::Identifiable>::id(&self)), + ) + .order_by($order) + .get_results::<($through, $child)>(conn.get()) + .map(|results| results.into_iter().map(|(_, second)| second).collect()) + } + } + + // Get ordered children from ID + paste::item! { + pub fn []( + id: <&Self as diesel::associations::Identifiable>::Id, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult> { + use diesel::prelude::*; + + <$through as diesel::associations::HasTable>::table() + .inner_join(<$child as diesel::associations::HasTable>::table()) + .filter( + <$through as diesel::associations::BelongsTo>::foreign_key_column() + .eq(id), + ) + .order_by($order) + .get_results::<($through, $child)>(conn.get()) + .map(|results| results.into_iter().map(|(_, second)| second).collect()) + } + } + }; +); diff --git a/shared/src/db/db_connection.rs b/shared/src/db/db_connection.rs new file mode 100644 index 0000000..33a79cf --- /dev/null +++ b/shared/src/db/db_connection.rs @@ -0,0 +1,78 @@ +use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; +use diesel::pg::PgConnection; +use diesel::r2d2::PoolError; +use futures::future::{ready, Ready}; +use std::ops::{Deref, DerefMut}; + +use crate::db::{PgPool, PgPooledConnection}; +use crate::errors::SharedError; + +pub enum DbConnection { + UnpooledConnection(PgConnection), + PooledConnection(PgPooledConnection), +} + +// +// Explicit extraction calls for when compiler can't implicitly convert +// +impl DbConnection { + pub fn new(conn: PgConnection) -> Self { + DbConnection::UnpooledConnection(conn) + } + pub fn new_pooled(conn: PgPooledConnection) -> Self { + DbConnection::PooledConnection(conn) + } + + pub fn get(&self) -> &PgConnection { + match self { + DbConnection::PooledConnection(pool) => &pool, + DbConnection::UnpooledConnection(conn) => &conn, + } + } + + pub fn get_mut(&mut self) -> &mut PgConnection { + match self { + DbConnection::PooledConnection(ref mut pool) => pool, + DbConnection::UnpooledConnection(ref mut conn) => conn, + } + } +} + +// +// Implicitly convert to the database connection type +// +impl Deref for DbConnection { + type Target = PgConnection; + fn deref(&self) -> &Self::Target { + self.get() + } +} + +impl DerefMut for DbConnection { + fn deref_mut(&mut self) -> &mut Self::Target { + self.get_mut() + } +} + +// +// Get the database connection from the request +// +impl FromRequest for DbConnection { + type Error = SharedError; + type Future = Ready>; + type Config = (); + + fn from_request(req: &HttpRequest, _pl: &mut Payload) -> Self::Future { + let res = get_connection_from_request(req); + ready(res.map_err(|e| e.into())) + } +} + +pub fn get_connection_from_request(req: &HttpRequest) -> Result { + let pool = req + .app_data::>() + .expect("PgPool app data should be set"); + + let conn = pool.get()?; + Ok(DbConnection::new_pooled(conn)) +} diff --git a/shared/src/db/init.rs b/shared/src/db/init.rs new file mode 100644 index 0000000..20a8849 --- /dev/null +++ b/shared/src/db/init.rs @@ -0,0 +1,13 @@ +use diesel::r2d2::{ConnectionManager, Pool}; +use diesel::{pg::PgConnection, Connection}; + +use crate::db::{DbConnection, PgPool}; + +pub fn open_new_connection_pool(database_url: &str) -> anyhow::Result { + let manager = ConnectionManager::::new(database_url); + Ok(Pool::builder().build(manager)?) +} + +pub fn open_new_connection(database_url: &str) -> anyhow::Result { + Ok(DbConnection::new(PgConnection::establish(&database_url)?)) +} diff --git a/shared/src/db/many_many_constructor.rs b/shared/src/db/many_many_constructor.rs new file mode 100644 index 0000000..b774e0c --- /dev/null +++ b/shared/src/db/many_many_constructor.rs @@ -0,0 +1,6 @@ +use diesel::associations::BelongsTo; + +/// Trait that must be implemented to construct a many-to-many relationship +pub trait ManyToManyConstructor: BelongsTo + BelongsTo { + fn new(left: &>::ForeignKey, right: &>::ForeignKey) -> Self; +} diff --git a/shared/src/db/mod.rs b/shared/src/db/mod.rs new file mode 100644 index 0000000..dfdb990 --- /dev/null +++ b/shared/src/db/mod.rs @@ -0,0 +1,19 @@ +// +// Database-specific objects and actions +// +mod db_connection; +mod init; +mod many_many_constructor; +mod types; + +#[macro_use] +mod sql_enum; +#[macro_use] +mod associations; +#[macro_use] +mod subtypes; + +pub use db_connection::{get_connection_from_request, DbConnection}; +pub use init::{open_new_connection, open_new_connection_pool}; +pub use many_many_constructor::ManyToManyConstructor; +pub use types::{PgPool, PgPooledConnection}; diff --git a/shared/src/db/sql_enum.rs b/shared/src/db/sql_enum.rs new file mode 100644 index 0000000..fe43487 --- /dev/null +++ b/shared/src/db/sql_enum.rs @@ -0,0 +1,54 @@ +#[macro_export] +macro_rules! sql_enum { + ($v:vis $name:ident $type:tt) => { + #[repr(i32)] + #[derive( + Debug, Copy, Clone, Eq, PartialEq, Hash, + serde_repr::Serialize_repr, serde_repr::Deserialize_repr, + FromSqlRow, FromPrimitive, AsExpression, + )] + #[sql_type = "Integer"] + $v enum $name $type + enum_internals!($name); + }; +} + +#[allow(unused)] +macro_rules! enum_internals { + ($($t:ty)*) => ($( + + // Required packages + use diesel::{ + backend::Backend, + deserialize::{self, FromSql}, + serialize::{self, Output, ToSql}, + sql_types::Integer, + }; + use std::io::Write; + + // Convert to SQL + impl ToSql for $t + where + DB: Backend, + i32: ToSql, + { + fn to_sql(&self, out: &mut Output) -> serialize::Result { + (*self as i32).to_sql(out) + } + } + + // Convert from SQL + impl FromSql for $t + where + DB: Backend, + i32: FromSql, + { + fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result { + let number = i32::from_sql(bytes)?; + num::FromPrimitive::from_i32(number).ok_or_else( + || format!("diesel::deserialize::FromSql for {} --- Invalid variant index {}", stringify!($t), number).into() + ) + } + } + )*) +} diff --git a/shared/src/db/subtypes.rs b/shared/src/db/subtypes.rs new file mode 100644 index 0000000..13d3724 --- /dev/null +++ b/shared/src/db/subtypes.rs @@ -0,0 +1,71 @@ +// ======================= +// Parent Type +// ======================= +#[macro_export] +macro_rules! parent_type( + ($discriminant:ty = $from_value:expr) => { + paste::item! { + parent_type!($discriminant = $from_value, [<$discriminant:snake>]); + } + }; + + ($discriminant:ty = $from_value:expr, $func_base:ident) => { + paste::item! { + pub fn [](&self) -> $discriminant { + self.$from_value + } + } + }; +); + +// ======================= +// Child Type +// ======================= +#[macro_export] +macro_rules! child_type( + ($parent:ty, $discriminant:ty = $value:expr) => { + paste::item! { + child_type!($parent, $discriminant = $value, [<$discriminant:snake>]); + } + }; + + ($parent:ty, $discriminant:ty = $from:expr, $func_base:ident) => { + paste::item! { + pub fn [](&self) -> $discriminant { + $from + } + } + + pub fn get_parent( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<$parent> { + use diesel::prelude::*; + + match >::foreign_key(&self) { + None => Err(diesel::result::Error::NotFound), + Some(id) => { + <$parent as diesel::associations::HasTable>::table() + .find(id) + .get_result::<$parent>(conn.get()) + } + } + } + + pub fn get_parent_optional( + &self, + conn: &crate::db::DbConnection, + ) -> diesel::prelude::QueryResult<$parent> { + use diesel::prelude::*; + + match >::foreign_key(&self) { + None => Err(diesel::result::Error::NotFound), + Some(id) => { + <$parent as diesel::associations::HasTable>::table() + .find(id) + .get_result::<$parent>(conn.get()) + } + } + } + }; +); diff --git a/shared/src/db/types.rs b/shared/src/db/types.rs new file mode 100644 index 0000000..5976a70 --- /dev/null +++ b/shared/src/db/types.rs @@ -0,0 +1,5 @@ +use diesel::pg::PgConnection; +use diesel::r2d2::{ConnectionManager, Pool, PooledConnection}; + +pub type PgPool = Pool>; +pub type PgPooledConnection = PooledConnection>; diff --git a/shared/src/errors/client_request_error.rs b/shared/src/errors/client_request_error.rs new file mode 100644 index 0000000..5c62f49 --- /dev/null +++ b/shared/src/errors/client_request_error.rs @@ -0,0 +1,73 @@ +use actix_http::{encoding::Decoder, Payload, PayloadStream}; +use awc::error::{JsonPayloadError, SendRequestError}; +use awc::http::StatusCode; +use awc::ClientResponse; +use serde::de::DeserializeOwned; +use std::future::Future; + +use crate::errors::ErrorResponse; + +/// Enum with all of the things that can go wrong when making a client request +#[derive(Debug)] +pub enum ClientRequestError { + SendError(SendRequestError), + ResponseError(ErrorResponse), + JSONError(JsonPayloadError), + UnknownError(StatusCode), +} + +impl ClientRequestError { + /// Handle the response from a client and parse the JSON body + /// + /// Returns an error if any of these steps fail + pub async fn handle( + input: impl Future>>, SendRequestError>>, + ) -> Result { + match input.await { + Err(e) => Err(Self::SendError(e)), + Ok(mut response) => { + // Try to deserialize the data if the request is ok + let status = response.status(); + if response.status() == StatusCode::OK { + return response.json::().await.map_err(|e| Self::JSONError(e)); + } + + // Otherwise, possibly parse an error response + // If the server didn't return an error response, then just return the status code + let error_response = response + .json::() + .await + .map_err(|_| Self::UnknownError(status))?; + + Err(Self::ResponseError(error_response)) + } + } + } + + /// Handle the response from a client, but don't parse the JSON body + /// + /// Returns an error if any of these steps fail + pub async fn handle_empty( + input: impl Future>>, SendRequestError>>, + ) -> Result<(), Self> { + match input.await { + Err(e) => Err(Self::SendError(e)), + Ok(mut response) => { + // Make sure the request is okay + let status = response.status(); + if response.status() == StatusCode::OK { + return Ok(()); + } + + // Otherwise, possibly parse an error response + // If the server didn't return an error response, then just return the status code + let error_response = response + .json::() + .await + .map_err(|_| Self::UnknownError(status))?; + + Err(Self::ResponseError(error_response)) + } + } + } +} diff --git a/shared/src/errors/error_response.rs b/shared/src/errors/error_response.rs new file mode 100644 index 0000000..64935ab --- /dev/null +++ b/shared/src/errors/error_response.rs @@ -0,0 +1,87 @@ +use actix_web::{http::StatusCode, HttpResponse, ResponseError}; +use serde::de::Error; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use std::fmt; + +use crate::errors::GlobalErrorCode; + +/// JSON response returned to the frontend on an error +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ErrorResponse { + #[serde( + serialize_with = "serialize_status_code", + deserialize_with = "deserialize_status_code" + )] + status_code: StatusCode, + description: String, + error_code: GlobalErrorCode, + + // Don't serialize on production system + #[cfg_attr(not(debug_assertions), serde(skip_serializing))] + #[serde(skip_serializing_if = "Option::is_none")] + developer_notes: Option, +} + +fn serialize_status_code(code: &StatusCode, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_u16(code.as_u16()) +} + +fn deserialize_status_code<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let integer: u16 = Deserialize::deserialize(deserializer)?; + StatusCode::from_u16(integer).map_err(D::Error::custom) +} + +impl ErrorResponse { + pub fn new( + status_code: StatusCode, + description: String, + error_code: GlobalErrorCode, + developer_notes: String, + ) -> Self { + ErrorResponse { + status_code, + description, + error_code, + developer_notes: Some(developer_notes), + } + } + + pub fn get_status_code(&self) -> StatusCode { + self.status_code + } + + pub fn get_description(&self) -> &String { + &self.description + } + + pub fn get_error_code(&self) -> &GlobalErrorCode { + &self.error_code + } + + pub fn get_developer_notes(&self) -> Option<&String> { + self.developer_notes.as_ref() + } +} + +impl fmt::Display for ErrorResponse { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "(#{:?}): {}", self.error_code, self.description)?; + if let Some(ref notes) = self.developer_notes { + write!(f, "\nDeveloper Notes: {}", notes)?; + } + Ok(()) + } +} + +impl ResponseError for ErrorResponse { + fn error_response(&self) -> HttpResponse { + HttpResponse::build(self.status_code).json(&self) + } +} diff --git a/shared/src/errors/generic_error.rs b/shared/src/errors/generic_error.rs new file mode 100644 index 0000000..aba1621 --- /dev/null +++ b/shared/src/errors/generic_error.rs @@ -0,0 +1,168 @@ +use actix_web::error::{JsonPayloadError, PathError, QueryPayloadError, UrlencodedError}; +use actix_web::{http::StatusCode, HttpResponse, ResponseError}; +use actix_web_httpauth::extractors::AuthenticationError; +use actix_web_httpauth::headers::www_authenticate::bearer::Bearer; +use diesel::r2d2::PoolError; +use jsonwebtoken::errors::Error as JWTError; +use std::{error, fmt}; + +use crate::errors::{ErrorResponse, GlobalErrorCode}; + +/// Internal errors that can occur within the shared library +#[derive(Debug)] +pub enum SharedError { + DatabaseConnectionError(diesel::ConnectionError), + DatabasePoolError(PoolError), + DatabaseError(diesel::result::Error), + JSONPayloadError(JsonPayloadError), + FormPayloadError(UrlencodedError), + URLPathError(PathError), + QueryStringError(QueryPayloadError), + JWTError(JWTError), + JWTExtractorError(AuthenticationError), +} + +impl SharedError { + pub fn get_error_response(&self) -> ErrorResponse { + match self { + SharedError::DatabaseConnectionError(error) => ErrorResponse::new( + StatusCode::INTERNAL_SERVER_ERROR, + "Database Connection Error".into(), + GlobalErrorCode::DatabaseConnectionError, + format!("{}", error), + ), + + SharedError::DatabasePoolError(error) => ErrorResponse::new( + StatusCode::INTERNAL_SERVER_ERROR, + "Database Connection Error".into(), + GlobalErrorCode::DatabaseConnectionError, + format!("{}", error), + ), + + SharedError::DatabaseError(error) => ErrorResponse::new( + StatusCode::INTERNAL_SERVER_ERROR, + "Database Query Error".into(), + GlobalErrorCode::DatabaseQueryError, + format!("{}", error), + ), + + SharedError::JSONPayloadError(error) => ErrorResponse::new( + StatusCode::BAD_REQUEST, + "Invalid JSON Object".into(), + GlobalErrorCode::JSONPayloadError, + format!("{}", error), + ), + + SharedError::FormPayloadError(error) => ErrorResponse::new( + StatusCode::BAD_REQUEST, + "Invalid Form Data".into(), + GlobalErrorCode::FormPayloadError, + format!("{}", error), + ), + + SharedError::URLPathError(error) => ErrorResponse::new( + StatusCode::BAD_REQUEST, + "Invalid URL Path".into(), + GlobalErrorCode::URLPathError, + format!("{}", error), + ), + + SharedError::QueryStringError(error) => ErrorResponse::new( + StatusCode::BAD_REQUEST, + "Invalid Query String".into(), + GlobalErrorCode::QueryStringError, + format!("{}", error), + ), + + SharedError::JWTError(error) => ErrorResponse::new( + StatusCode::UNAUTHORIZED, + "Invalid JWT Token".into(), + GlobalErrorCode::InvalidJWTToken, + format!("{}", error), + ), + + SharedError::JWTExtractorError(error) => ErrorResponse::new( + StatusCode::UNAUTHORIZED, + "Invalid JWT Token".into(), + GlobalErrorCode::InvalidJWTToken, + format!("{}", error), + ), + } + } +} + +// +// Various Error Traits +// +impl fmt::Display for SharedError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:?}", self) + } +} + +impl ResponseError for SharedError { + fn error_response(&self) -> HttpResponse { + let error = self.get_error_response(); + log::error!("{:?}", error); + error.error_response() + } +} + +impl error::Error for SharedError {} + +// +// Implicit conversion functions +// +impl From for SharedError { + fn from(error: diesel::ConnectionError) -> Self { + SharedError::DatabaseConnectionError(error) + } +} + +impl From for SharedError { + fn from(error: PoolError) -> Self { + SharedError::DatabasePoolError(error) + } +} + +impl From for SharedError { + fn from(error: diesel::result::Error) -> Self { + SharedError::DatabaseError(error) + } +} + +impl From for SharedError { + fn from(error: JsonPayloadError) -> Self { + SharedError::JSONPayloadError(error) + } +} + +impl From for SharedError { + fn from(error: UrlencodedError) -> Self { + SharedError::FormPayloadError(error) + } +} + +impl From for SharedError { + fn from(error: PathError) -> Self { + SharedError::URLPathError(error) + } +} + +impl From for SharedError { + fn from(error: QueryPayloadError) -> Self { + SharedError::QueryStringError(error) + } +} + +impl From for SharedError { + fn from(error: JWTError) -> Self { + SharedError::JWTError(error) + } +} + +impl From> for SharedError { + fn from(error: AuthenticationError) -> Self { + SharedError::JWTExtractorError(error) + } +} diff --git a/shared/src/errors/global_error_codes.rs b/shared/src/errors/global_error_codes.rs new file mode 100644 index 0000000..e839ed6 --- /dev/null +++ b/shared/src/errors/global_error_codes.rs @@ -0,0 +1,46 @@ +use serde_repr::{Deserialize_repr, Serialize_repr}; + +/// Error codes that are exposed on the frontend +#[derive(Serialize_repr, Deserialize_repr, Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u32)] +pub enum GlobalErrorCode { + UnknownError = 0, + DatabaseConnectionError, + DatabaseQueryError, + MissingAppData, + JSONPayloadError, + FormPayloadError, + URLPathError, + QueryStringError, + StructValidationError, + InvalidEmailPassword, + InvalidJWTToken, + UserEmailExists, + PasswordComplexityError, + RecaptchaError, + ForbiddenResourceAction, + NoSuchResource, + ElectionNotOwnedByUser, + ElectionNotDraft, + WrongElectionStatus, + AccessCodeNotFound, + NotRegistered, + AlreadyRegistered, + RegistrationClosed, + NotEnoughRegistered, + ElectionNotInitialized, + MediatorURLNotSet, + RegisterElectionError, + VerificationError, + AlreadyVoted, + VerifyVoteError, + VoteInvalid, + NotOpenForVoting, + NotEnoughVotes, + CancelationSharesError, + ElectionNotStarted, + NoNotifyPermission, + NoSubscribePermission, + NotificationError, + InvalidCollectorURI, +} diff --git a/shared/src/errors/mod.rs b/shared/src/errors/mod.rs new file mode 100644 index 0000000..7555903 --- /dev/null +++ b/shared/src/errors/mod.rs @@ -0,0 +1,12 @@ +// +// All code related to error handling for the API server +// +mod client_request_error; +mod error_response; +mod generic_error; +mod global_error_codes; + +pub use client_request_error::ClientRequestError; +pub use error_response::ErrorResponse; +pub(crate) use generic_error::SharedError; +pub use global_error_codes::GlobalErrorCode; diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 59207dc..e2d5516 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,3 +1,6 @@ -pub fn test() -> i32 { - 15 -} +pub mod auth; +#[macro_use] +pub mod db; +pub mod errors; +pub mod protocol; +pub mod utils; diff --git a/shared/src/protocol/count_ballot_votes.rs b/shared/src/protocol/count_ballot_votes.rs new file mode 100644 index 0000000..a2b2147 --- /dev/null +++ b/shared/src/protocol/count_ballot_votes.rs @@ -0,0 +1,106 @@ +use curv_kzen::arithmetic::traits::Converter; +use curv_kzen::BigInt; +use std::iter; + +/// +/// Test the validity of the voting vector, then count the number of votes +/// +/// On error, this returns None +/// On success, it returns the number of votes for each candidate +/// +pub fn count_ballot_votes( + forward_ballot: &BigInt, + reverse_ballot: &BigInt, + num_candidates: i64, + num_voters: i64, + no_vote_count: usize, +) -> Option> { + let total_bits = (num_candidates * num_voters) as usize; + let forward_bits = get_bits(forward_ballot, total_bits); + let reverse_bits = get_bits(reverse_ballot, total_bits); + + // Step 1: Make sure the forward and reverse bits match + for (f, r) in forward_bits.iter().zip(reverse_bits.iter().rev()) { + if *f != *r { + return None; + } + } + + // Step 2: Make sure each chunk has, at most, only one candidate selected + let chunks = get_chunks(&forward_bits, num_candidates as usize); + let (voted, no_vote) = match verify_chunks(&chunks) { + Some((voted, no_vote)) => (voted, no_vote), + None => return None, + }; + + // Step 3: Make sure the number of voted bits matches the users who voted + if voted + no_vote != (num_voters as usize) || no_vote != no_vote_count { + return None; + } + + // All checks passed! + Some(count_votes(&chunks, num_candidates as usize)) +} + +/// Convert the integer voting vector into a vector of bits +fn get_bits(input: &BigInt, total_bits: usize) -> Vec { + let reverse_bits: Vec = input + .to_str_radix(2) + .chars() + .rev() + .filter(|c| c.is_numeric()) + .map(|x| x == '1') + .chain(iter::repeat(false)) + .take(total_bits) + .collect(); + + reverse_bits.into_iter().rev().collect() +} + +/// Convert the vector of bits into chunks for each candidate +fn get_chunks(input: &[bool], num_candidates: usize) -> Vec> { + input + .chunks(num_candidates) + .map(|c| c.into_iter().cloned().collect()) + .collect() +} + +/// Make sure each chunk only has, at most, one candidate +/// Returns Some((voted, didn't vote)) on success, or None on failure +fn verify_chunks(input: &Vec>) -> Option<(usize, usize)> { + let mut voted = 0; + let mut no_vote = 0; + + for chunk in input { + let num_votes = chunk.into_iter().filter(|c| **c).count(); + match num_votes { + 0 => no_vote += 1, + 1 => voted += 1, + _ => return None, + } + } + + Some((voted, no_vote)) +} + +/// Total up the votes for each candidate +/// +/// This function assumes that the chunk input has already been validated by verify_chunks +fn count_votes(input: &Vec>, num_candidates: usize) -> Vec { + let mut votes = vec![0; num_candidates]; + + for chunk in input { + // Searches for the first candidate bit set in the chunk + if let Some(candidate) = chunk + .into_iter() + .rev() + .enumerate() + .filter_map(|(i, c)| (*c).then(|| i)) + .next() + { + votes[candidate] += 1; + } + } + + votes +} diff --git a/shared/src/protocol/generator.rs b/shared/src/protocol/generator.rs new file mode 100644 index 0000000..34c788d --- /dev/null +++ b/shared/src/protocol/generator.rs @@ -0,0 +1,48 @@ +use curv_kzen::arithmetic::{Modulo, One}; +use curv_kzen::BigInt; +use kzen_paillier::keygen::PrimeSampable; + +/// Returns a (generator, prime) pair for Z*p with at least n bits +/// +/// We generate a safe prime p = 2*q + 1, where q is also prime. +/// +/// To find the primitive root, we use Euler's totient function Φ(p) = p - 1. +/// Start by factorizing Φ(p). Since p-1 = 2*q, our factors are always 2 and q. +/// +/// Then, for all potential g in 2 ..= Φ(p) and all factors f of Φ(p), we confirm: +/// +/// g^(Φ(p)/f) != 1 (mod p) +/// +/// If this is true for every factor of Φ(p), then g is indeed a primitive root. +/// +/// Since p is prime, this is GUARANTEED to return a valid primitive root. +pub fn generator_prime_pair(num_bits: usize) -> (BigInt, BigInt) { + // Pick a random large prime + let p = BigInt::sample_safe_prime(num_bits); + + // To find primitive root, we consider the Euler's totient Φ(p) + // Since p is prime, Φ(p) = (p-1) + let totient = &p - 1; + + // Since p is a safe prime, we know p = 2*q + 1 + // So the prime factors of Φ(p) = p-1 = 2*q are always [2, q] + let factors = vec![BigInt::from(2), &totient / 2]; + + // There ALWAYS exists a primitive root somewhere 2 ..= Φ(p) + let mut g = BigInt::from(1); + 'next_generator: while &g <= &totient { + g = &g + 1; + + for factor in &factors { + // Check if g^(Φ(p) / factor) != 1 (mod p) + if BigInt::mod_pow(&g, &(&totient / factor), &p).is_one() { + continue 'next_generator; + } + } + + // We found one! + break; + } + + (g, p) +} diff --git a/shared/src/protocol/location_anonymization.rs b/shared/src/protocol/location_anonymization.rs new file mode 100644 index 0000000..b1e46a2 --- /dev/null +++ b/shared/src/protocol/location_anonymization.rs @@ -0,0 +1,65 @@ +use curv_kzen::arithmetic::{Modulo, Samplable}; +use kzen_paillier::*; + +/// First step of the location anonymization scheme +/// C1 computes e_x1 = E(x1) and sends it to C2 +/// +/// location = Secret location (0 <= location <= n - 1) +/// n = Public key for Paillier cryptosystem +/// +/// Returns e_x1 +pub fn step_1(location: &BigInt, n: &BigInt) -> BigInt { + // Compute E(x1) + let ek = EncryptionKey::from(n); + let e_x1: RawCiphertext = Paillier::encrypt(&ek, location.into()); + e_x1.0.into_owned() +} + +/// ith step of the location anonymization scheme: (Collectors C2 to C{n-1}) +/// Ci picks random ri with 0 <= ri < n +/// Ci computes e_xi = (e_x1 * ... * e_x{i-1}) * (E(ri)^(-1)) (mod n^2) and sends it to C{i+1} +/// +/// e_xi_1 = (e_x1 * ... * e_x{i-1}) +/// n = Public key for paillier cryptosystem +/// +/// Returns (ri, e_xi) +pub fn step_ith(e_xi_1: &BigInt, n: &BigInt) -> (BigInt, BigInt) { + // Pick random ri with 0 <= ri < n + let ri = BigInt::sample_below(n); + + // Compute E(r2) + let ek = EncryptionKey::from(n); + let e_ri: RawCiphertext = Paillier::encrypt(&ek, ri.clone().into()); + + // Compute (e_xi_1) * (E(ri)^(-1)) (mod n^2) + // Every encrypted r value should be invertible, so we should never panic when finding inverse + let e_xi = BigInt::mod_mul( + &e_xi_1, + &BigInt::mod_inv(&e_ri.0, &ek.nn).expect("Error: No Inverse"), + &ek.nn, + ); + + (ri, e_xi) +} + +/// Last step of the location anonymization scheme: +/// C1 decrypts D(e_x{n-1}), resulting in r1 +/// +/// The parties now have values: r1 + r2 + ... + rn (mod n) = x1 (mod n^2) +/// +/// e_xn_1 = (e_x1 * ... * e_x{n-1}) +/// p, q = Private key for Paillier cryptosystem +/// +/// Returns r1 +pub fn step_last(e_xn_1: &BigInt, p: &BigInt, q: &BigInt) -> BigInt { + let e_xn_1 = RawCiphertext::from(e_xn_1); + + // Compute r1 = D(e_x2) + let dk = DecryptionKey { + p: p.clone(), + q: q.clone(), + }; + let r1: RawPlaintext = Paillier::decrypt(&dk, e_xn_1); + + r1.0.into_owned() +} diff --git a/shared/src/protocol/mod.rs b/shared/src/protocol/mod.rs new file mode 100644 index 0000000..835c670 --- /dev/null +++ b/shared/src/protocol/mod.rs @@ -0,0 +1,12 @@ +// +// Functions and structures related to the math behind the e-voting protocol +// +mod count_ballot_votes; +mod generator; +pub mod location_anonymization; +mod shares_matrix; +pub mod stpm; + +pub use count_ballot_votes::count_ballot_votes; +pub use generator::generator_prime_pair; +pub use shares_matrix::SharesMatrix; diff --git a/shared/src/protocol/shares_matrix.rs b/shared/src/protocol/shares_matrix.rs new file mode 100644 index 0000000..044c4b0 --- /dev/null +++ b/shared/src/protocol/shares_matrix.rs @@ -0,0 +1,152 @@ +use curv_kzen::arithmetic::{Converter, Samplable}; +use curv_kzen::BigInt; +use std::fmt; +use std::ops::{Index, IndexMut}; + +/// Matrix used by the collectors for (n,n) Secret Sharing +pub struct SharesMatrix { + num_voters: usize, + modulus: BigInt, + matrix: Vec, +} + +impl SharesMatrix { + pub fn new(collector: usize, num_collectors: usize, num_voters: usize, modulus: BigInt) -> Self { + let mut matrix = SharesMatrix { + num_voters, + modulus, + matrix: vec![BigInt::from(0); num_voters * num_voters], + }; + + // Fill in the matrix quadrants + matrix.fill_collector(collector, num_collectors); + matrix + } + + pub fn get_num_voters(&self) -> usize { + self.num_voters + } + + pub fn get_modulus(&self) -> &BigInt { + &self.modulus + } + + /// Get the sum of shares for a given voter to use for the ballot. + /// For our protocol, this is the sum of the column. + /// + /// Returns nothing if the voter is outside the range of the number of voters. + pub fn get_ballot_shares(&self, voter: usize) -> Option { + if voter >= self.num_voters { + return None; + } + + let mut sum = BigInt::from(0); + for row in 0..self.num_voters { + sum += &self[(row, voter)]; + } + + Some(sum % &self.modulus) + } + + /// Get the sum of shares for a given voter to use for voter verification. + /// For our protocol, this is the sum of the row. + /// + /// Returns nothing if the voter is outside the range of the number of voters. + pub fn get_verification_shares(&self, voter: usize) -> Option { + if voter >= self.num_voters { + return None; + } + + let mut sum = BigInt::from(0); + for col in 0..self.num_voters { + sum += &self[(voter, col)]; + } + + Some(sum % &self.modulus) + } + + // Fill the quadrants associated with each collector + // + // [ 1 ][ 2 ][ 3 ] ... [ n ] + // [ n ][ 1 ][ 2 ] ... [n-1] + // [n-1][ n ][ 1 ] ... [n-2] + // | | | \ | + // [ 2 ][ 3 ][ 4 ] ... [ 1 ] + // + // Areas outside are filled with 0's so the sum is unchaged + fn fill_collector(&mut self, collector: usize, num_collectors: usize) { + // Fill the diagonal "cells", wrapping around + // Each cell is approx. (num_voters / num_collectors)^2 entries in size + // For a special case, the last row and column may be different + for cell_index in 0..num_collectors { + let row_cell_index = cell_index; + let col_cell_index = (collector + cell_index) % num_collectors; + + // Top left of the cell + let row_start = (row_cell_index * self.num_voters) / num_collectors; + let col_start = (col_cell_index * self.num_voters) / num_collectors; + + // Last row may be a different size to fill remaining rows + let row_end = if row_cell_index == (num_collectors - 1) { + self.num_voters + } else { + ((row_cell_index + 1) * self.num_voters) / num_collectors + }; + + // Last column may be a different size to fill remaining columns + let col_end = if col_cell_index == (num_collectors - 1) { + self.num_voters + } else { + ((col_cell_index + 1) * self.num_voters) / num_collectors + }; + + // Fill in all rows and columns in the individual cell + for row in row_start..row_end { + for col in col_start..col_end { + // Don't fill the main diagonal + if row != col { + self[(row, col)] = BigInt::sample_below(&self.modulus); + } + } + } + } + } +} + +impl Index<(usize, usize)> for SharesMatrix { + type Output = BigInt; + + fn index(&self, (row, col): (usize, usize)) -> &Self::Output { + &self.matrix[row * self.num_voters + col] + } +} + +impl IndexMut<(usize, usize)> for SharesMatrix { + fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output { + &mut self.matrix[row * self.num_voters + col] + } +} + +impl fmt::Display for SharesMatrix { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let num_digits = self.matrix.iter().max().map(|x| x.to_str_radix(10).len()).unwrap_or(0); + + writeln!( + f, + "SharesMatrix {{ num_voters: {}, modulus: {}, matrix: ", + self.num_voters, self.modulus + )?; + + for row in 0..self.num_voters { + write!(f, " |")?; + for col in 0..self.num_voters { + if col > 0 { + write!(f, ", ")?; + } + write!(f, "{:>width$}", self[(row, col)].to_string(), width = num_digits)?; + } + writeln!(f, "|")?; + } + writeln!(f, "}}") + } +} diff --git a/shared/src/protocol/stpm.rs b/shared/src/protocol/stpm.rs new file mode 100644 index 0000000..3504a3a --- /dev/null +++ b/shared/src/protocol/stpm.rs @@ -0,0 +1,91 @@ +use curv_kzen::arithmetic::{Modulo, Samplable}; +use kzen_paillier::*; + +/// First step of the STPM: +/// C1 computes e_x1 = E(x1) and sends it to C2 +/// +/// x1 = First number being multiplied +/// n = Public key for Paillier cryptosystem +/// +/// Returns e_x1 +pub fn step_1(x1: &BigInt, n: &BigInt) -> BigInt { + // Compute E(x1) + let ek = EncryptionKey::from(n); + let e_x1: RawCiphertext = Paillier::encrypt(&ek, x1.into()); + e_x1.0.into_owned() +} + +/// Second step of the STPM: +/// C2 picks random r2 with 0 <= r2 < n +/// C2 computes e_x2 = ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) and sends it to C1 +/// +/// e_x1 = E(x1) +/// x2 = Second number being multiplied +/// n = Public key for paillier cryptosystem +/// +/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus +/// This means that r1 (or r2) may be negative +/// +/// Returns (r2, e_x2) +pub fn step_2(e_x1: &BigInt, x2: &BigInt, n: &BigInt, normalize: bool) -> (BigInt, BigInt) { + // Pick random r2 with 0 <= r2 < n + let mut r2 = BigInt::sample_below(n); + + // Compute E(r2) + let ek = EncryptionKey::from(n); + let e_r2: RawCiphertext = Paillier::encrypt(&ek, r2.clone().into()); + + // Compute ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) + // Every encrypted r value should be invertible, so we should never panic when finding inverse + let e_x2 = BigInt::mod_mul( + &BigInt::mod_pow(e_x1, &x2, &ek.nn), + &BigInt::mod_inv(&e_r2.0, &ek.nn).expect("Error: No Inverse"), + &ek.nn, + ); + + // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus + // + // So, if 2*r2 > n, then r2 = r2 - n + // -This will be a negative number + if normalize && (&(2 * &r2) >= &n) { + r2 = &r2 - n; + } + + (r2, e_x2) +} + +/// Last step of the STPM: +/// C1 decrypts D(e_x2), resulting in r1 +/// +/// The two parties now have values: r1 + r2 (mod n) = x1 * x2 (mod n^2) +/// If the "normalize" flag was set to true, then r1 + r2 = x1 * x2 with NO modulus +/// +/// e_x2 = (E(x1)^x2) * (E(r2)^(-1)) (mod n^2) -- From previous step +/// p, q = Private key for Paillier cryptosystem +/// +/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus +/// This means that r1 (or r2) may be negative +/// +/// Returns r1 +pub fn step_3(e_x2: &BigInt, p: &BigInt, q: &BigInt, normalize: bool) -> BigInt { + let e_x2 = RawCiphertext::from(e_x2); + + // Compute r1 = D(e_x2) + let dk = DecryptionKey { + p: p.clone(), + q: q.clone(), + }; + let r1: RawPlaintext = Paillier::decrypt(&dk, e_x2); + + // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus + // + // So, if 2*r1 > n, then r1 = r1 - n + // -This will be a negative number + let n = p * q; + let mut r1 = r1.0.into_owned(); + if normalize && (&(2 * &r1) >= &n) { + r1 = &r1 - &n; + } + + r1 +} diff --git a/shared/src/utils/convert_bigint.rs b/shared/src/utils/convert_bigint.rs new file mode 100644 index 0000000..547469c --- /dev/null +++ b/shared/src/utils/convert_bigint.rs @@ -0,0 +1,83 @@ +use bigdecimal::BigDecimal; +use curv_kzen::arithmetic::{BigInt, Converter, NumberTests}; +use num::bigint::{BigInt as NumBigInt, Sign}; + +/// +/// Trait used to simplify converting between BigInt and BigDecimal +/// +pub trait ConvertBigInt { + fn to_bigint(&self) -> BigInt; + fn to_bigdecimal(&self) -> BigDecimal; + + fn from_bigint(bigint: BigInt) -> Self; + fn from_bigdecimal(bigdecimal: BigDecimal) -> Self; +} + +impl ConvertBigInt for BigInt { + fn to_bigint(&self) -> BigInt { + self.clone() + } + + fn to_bigdecimal(&self) -> BigDecimal { + BigDecimal::new(NumBigInt::from_bytes_be(get_sign(self), &self.to_bytes()), 0) + } + + fn from_bigint(bigint: BigInt) -> Self { + bigint + } + + fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { + let (bigint, _exponent) = bigdecimal.as_bigint_and_exponent(); + let (sign, bytes) = bigint.to_bytes_be(); + + // Parse from bytes and handle the negative sign + let result = BigInt::from_bytes(&bytes); + if sign == Sign::Minus { + -result + } else { + result + } + } +} + +impl ConvertBigInt for BigDecimal { + fn to_bigint(&self) -> BigInt { + let (bigint, _exponent) = self.as_bigint_and_exponent(); + let (sign, bytes) = bigint.to_bytes_be(); + + // Parse from bytes and handle the negative sign + let result = BigInt::from_bytes(&bytes); + if sign == Sign::Minus { + -result + } else { + result + } + } + + fn to_bigdecimal(&self) -> BigDecimal { + self.clone() + } + + fn from_bigint(bigint: BigInt) -> Self { + BigDecimal::new(NumBigInt::from_bytes_be(get_sign(&bigint), &bigint.to_bytes()), 0) + } + + fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { + bigdecimal + } +} + +/// +/// Figure out the sign of the input BigInt +/// +fn get_sign(input: &BigInt) -> Sign { + if BigInt::is_zero(input) { + return Sign::NoSign; + } + + if BigInt::is_negative(input) { + Sign::Minus + } else { + Sign::Plus + } +} diff --git a/shared/src/utils/is_offensive_string.rs b/shared/src/utils/is_offensive_string.rs new file mode 100644 index 0000000..42b669d --- /dev/null +++ b/shared/src/utils/is_offensive_string.rs @@ -0,0 +1,26 @@ +use censor::Censor; +use lazy_static::lazy_static; + +// Additional words to censor +const EXTRA_WORDS: &[&str] = &[ + "anal", "anus", "arse", "ball", "barf", "bastard", "biatch", "bloody", "blow", "bollock", "bollok", "boner", + "booger", "bugger", "bum", "butt", "clitoris", "cock", "coon", "crap", "crib", "cunt", "dildo", "dyke", "fag", + "fart", "feck", "fellate", "fellatio", "felching", "fudge", "flange", "homo", "jerk", "jizz", "knob", "labia", + "lmao", "lmfao", "muff", "nigga", "omg", "pee", "piss", "poo", "poop", "prick", "pube", "puke", "queer", "scrotum", + "slut", "smegma", "spunk", "tit", "tosser", "turd", "twat", "wank", "wtf", +]; + +lazy_static! { + static ref CUSTOM_CENSOR: Censor = Censor::Custom(EXTRA_WORDS.iter().map(|s| String::from(*s)).collect()); +} + +// +// Censor the string that it contains no offensive or vulgar words +// Returns true if the string fails the test +// +pub fn is_offensive_string(string: &str) -> bool { + Censor::Standard.check(string) + || Censor::Sex.check(string) + || Censor::Zealous.check(string) + || CUSTOM_CENSOR.check(string) +} diff --git a/shared/src/utils/mod.rs b/shared/src/utils/mod.rs new file mode 100644 index 0000000..df59e69 --- /dev/null +++ b/shared/src/utils/mod.rs @@ -0,0 +1,13 @@ +// +// General-purpose functions and objects +// +mod convert_bigint; +mod is_offensive_string; +mod new_safe_uuid_v4; +mod password_complexity; +pub mod serialize_option_bigint; + +pub use convert_bigint::ConvertBigInt; +pub use is_offensive_string::is_offensive_string; +pub use new_safe_uuid_v4::new_safe_uuid_v4; +pub use password_complexity::validate_password_complexity; diff --git a/shared/src/utils/new_safe_uuid_v4.rs b/shared/src/utils/new_safe_uuid_v4.rs new file mode 100644 index 0000000..5765f0d --- /dev/null +++ b/shared/src/utils/new_safe_uuid_v4.rs @@ -0,0 +1,19 @@ +use uuid_b64::UuidB64 as Uuid; + +use super::is_offensive_string; + +// +// Censor the base-64 UUID V4 text so that it contains no offensive or vulgar words +// The probability of such words appearing is very small, but we still want to be extra safe +// From experimental tests, only 1.6% to 1.7% of generated UUIDs even remotely fail the censorship check +// +pub fn new_safe_uuid_v4() -> Uuid { + loop { + let uuid = Uuid::new(); + if is_offensive_string(&uuid.to_istring()) { + continue; + } + + return uuid; + } +} diff --git a/shared/src/utils/password_complexity.rs b/shared/src/utils/password_complexity.rs new file mode 100644 index 0000000..f3c0149 --- /dev/null +++ b/shared/src/utils/password_complexity.rs @@ -0,0 +1,45 @@ +use zxcvbn::{zxcvbn, Entropy, ZxcvbnError}; + +/// Response from the password complexity check +#[derive(Debug, Clone)] +pub enum PasswordComplexityResponse { + PasswordOkay, + NotEnoughEntropy(Entropy), + ZxcvbnError(ZxcvbnError), +} + +// 0 - Too guessable: risky password. (guesses < 10^3) +// 1 - Very guessable: protection from throttled online attacks. (guesses < 10^6) +// 2 - Somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8) +// 3 - Safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10) +// 4 - Very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10) +const MINIMUM_PASSWORD_COMPLEXITY: u8 = 3; + +const SITE_SPECIFIC_PASSWORD_DICTIONARY: &[&str] = &["evoting", "voting", "voter"]; + +/// Use the zxcvbn library to verify the password complexity +/// +/// # Returns +/// Nested results for error handling +pub fn validate_password_complexity(password: &str, name: &str, email: &str) -> PasswordComplexityResponse { + let mut user_inputs: Vec<&str> = vec![name, email]; + user_inputs.extend_from_slice(SITE_SPECIFIC_PASSWORD_DICTIONARY); + + match zxcvbn(password, user_inputs.as_slice()) { + Ok(entropy) if entropy.score() >= MINIMUM_PASSWORD_COMPLEXITY => PasswordComplexityResponse::PasswordOkay, + Ok(entropy) => entropy.into(), + Err(e) => e.into(), + } +} + +impl From for PasswordComplexityResponse { + fn from(entropy: Entropy) -> Self { + Self::NotEnoughEntropy(entropy) + } +} + +impl From for PasswordComplexityResponse { + fn from(error: ZxcvbnError) -> Self { + Self::ZxcvbnError(error) + } +} diff --git a/shared/src/utils/serialize_option_bigint.rs b/shared/src/utils/serialize_option_bigint.rs new file mode 100644 index 0000000..d59403d --- /dev/null +++ b/shared/src/utils/serialize_option_bigint.rs @@ -0,0 +1,40 @@ +use curv_kzen::arithmetic::traits::Converter; +use curv_kzen::BigInt; +use serde::{de, ser}; +use std::fmt; + +pub fn serialize(x: &Option, serializer: S) -> Result { + match x { + Some(x) => serializer.serialize_str(&x.to_str_radix(10)), + None => serializer.serialize_none(), + } +} + +pub fn deserialize<'de, D: de::Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + struct OptionBigIntVisitor; + + impl<'de> de::Visitor<'de> for OptionBigIntVisitor { + type Value = Option; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("option of bigint") + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(None) + } + + #[inline] + fn visit_none(self) -> Result, E> { + Ok(None) + } + + #[inline] + fn visit_some>(self, deserializer: D) -> Result { + kzen_paillier::serialize::bigint::deserialize(deserializer).map(Some) + } + } + + deserializer.deserialize_option(OptionBigIntVisitor) +} From a18ee77954aadfac1011b4f35aba4a2266173564 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 21:35:35 -0500 Subject: [PATCH 4/7] Programs now use the shared library --- Cargo.lock | 8 + collector/Cargo.toml | 1 + collector/src/auth/constants.rs | 2 - collector/src/auth/jwt_token.rs | 223 ----- collector/src/auth/mod.rs | 14 - collector/src/auth/permission.rs | 26 - collector/src/db/associations.rs | 916 ------------------ collector/src/db/db_connection.rs | 77 -- collector/src/db/init.rs | 24 - collector/src/db/many_many_constructor.rs | 6 - collector/src/db/mod.rs | 19 - collector/src/db/sql_enum.rs | 54 -- collector/src/db/subtypes.rs | 71 -- collector/src/db/types.rs | 5 - collector/src/errors/client_request_error.rs | 73 -- collector/src/errors/error_response.rs | 71 -- collector/src/errors/global_error_codes.rs | 46 - collector/src/errors/mod.rs | 9 +- collector/src/errors/named_resource_type.rs | 12 +- collector/src/handlers/auth/get_me.rs | 2 +- .../create_and_initialize_election.rs | 2 +- .../election/get_cancelation_shares.rs | 2 +- .../election/get_election_parameters.rs | 2 +- .../election/get_question_parameters.rs | 2 +- .../verification_websocket_actor.rs | 12 +- .../verification/verify_ballot_websocket.rs | 2 +- collector/src/jwt/has_permission.rs | 71 ++ collector/src/jwt/mod.rs | 7 + collector/src/lib.rs | 19 +- collector/src/main.rs | 10 +- .../src/protocol/location_anonymization.rs | 65 -- collector/src/protocol/mod.rs | 8 - collector/src/protocol/shares_matrix.rs | 152 --- collector/src/protocol/stpm.rs | 91 -- collector/src/schema.rs | 7 +- collector/src/utils/convert_bigint.rs | 83 -- collector/src/utils/mod.rs | 7 - .../src/utils/serialize_option_bigint.rs | 40 - mediator/Cargo.toml | 1 + mediator/src/auth/audience.rs | 66 -- mediator/src/auth/constants.rs | 2 - mediator/src/auth/jwt_secret.rs | 21 - mediator/src/auth/jwt_token.rs | 245 ----- mediator/src/auth/mod.rs | 14 - mediator/src/auth/permission.rs | 26 - mediator/src/db/associations.rs | 916 ------------------ mediator/src/db/db_connection.rs | 77 -- mediator/src/db/init.rs | 24 - mediator/src/db/many_many_constructor.rs | 6 - mediator/src/db/mod.rs | 19 - mediator/src/db/sql_enum.rs | 54 -- mediator/src/db/subtypes.rs | 71 -- mediator/src/db/types.rs | 5 - mediator/src/errors/client_request_error.rs | 73 -- mediator/src/errors/error_response.rs | 71 -- mediator/src/errors/global_error_codes.rs | 46 - mediator/src/errors/mod.rs | 9 +- mediator/src/errors/named_resource_type.rs | 4 +- mediator/src/errors/websocket_error.rs | 96 -- mediator/src/handlers/auth/get_me.rs | 2 +- .../src/handlers/collector/all_collectors.rs | 2 +- .../collector/create_or_update_collector.rs | 2 +- .../src/handlers/collector/get_collector.rs | 2 +- .../handlers/collector/update_collector.rs | 2 +- .../create_and_initialize_election.rs | 2 +- .../election/get_cancelation_shares.rs | 2 +- .../election/get_election_collectors.rs | 2 +- .../handlers/verification/mediator_actor.rs | 10 +- .../handlers/verification/verify_ballot.rs | 2 +- mediator/src/jwt/has_permission.rs | 93 ++ mediator/src/jwt/mod.rs | 7 + mediator/src/lib.rs | 19 +- mediator/src/main.rs | 12 +- mediator/src/notifications/send.rs | 2 +- .../src/protocol/location_anonymization.rs | 65 -- mediator/src/protocol/mod.rs | 5 - mediator/src/protocol/stpm.rs | 91 -- mediator/src/schema.rs | 8 +- mediator/src/utils/convert_bigint.rs | 83 -- mediator/src/utils/mod.rs | 8 - mediator/src/utils/serialize_option_bigint.rs | 40 - notifications/Cargo.toml | 1 + notifications/src/auth/audience.rs | 67 -- notifications/src/auth/constants.rs | 2 - notifications/src/auth/jwt_secret.rs | 21 - notifications/src/auth/jwt_token.rs | 185 ---- notifications/src/auth/mod.rs | 16 - notifications/src/auth/permission.rs | 25 - notifications/src/errors/error_response.rs | 71 -- .../src/errors/global_error_codes.rs | 46 - notifications/src/errors/mod.rs | 7 +- notifications/src/errors/websocket_error.rs | 96 -- .../src/handlers/notifications/notify.rs | 2 +- .../src/handlers/notifications/subscribe.rs | 2 +- notifications/src/jwt/has_permission.rs | 33 + notifications/src/jwt/mod.rs | 9 + .../src/{auth => jwt}/websocket_token.rs | 2 +- notifications/src/lib.rs | 2 +- notifications/src/main.rs | 4 +- .../src/notifications/websocket_actor.rs | 10 +- server/Cargo.toml | 1 + server/src/auth/audience.rs | 67 -- server/src/auth/constants.rs | 5 - server/src/auth/jwt_secret.rs | 21 - server/src/auth/jwt_token.rs | 253 ----- server/src/auth/mod.rs | 12 - server/src/auth/permission.rs | 26 - server/src/db/associations.rs | 916 ------------------ server/src/db/db_connection.rs | 77 -- server/src/db/init.rs | 24 - server/src/db/many_many_constructor.rs | 6 - server/src/db/mod.rs | 19 - server/src/db/sql_enum.rs | 54 -- server/src/db/subtypes.rs | 71 -- server/src/db/types.rs | 5 - server/src/errors/client_request_error.rs | 73 -- server/src/errors/error_response.rs | 71 -- server/src/errors/global_error_codes.rs | 46 - server/src/errors/mod.rs | 7 +- server/src/errors/service_error.rs | 5 +- .../src/handlers/account/register_account.rs | 3 +- server/src/handlers/account/update_account.rs | 2 +- .../src/handlers/account/update_password.rs | 3 +- server/src/handlers/auth/get_me.rs | 2 +- server/src/handlers/auth/login.rs | 3 +- server/src/handlers/auth/refresh.rs | 3 +- server/src/handlers/election/all_elections.rs | 2 +- .../src/handlers/election/create_election.rs | 2 +- .../src/handlers/election/delete_election.rs | 2 +- server/src/handlers/election/get_election.rs | 2 +- .../election/get_election_by_access_code.rs | 2 +- .../election/get_election_parameters.rs | 2 +- .../handlers/election/get_election_results.rs | 2 +- .../src/handlers/election/update_election.rs | 2 +- .../registration/open_registration.rs | 2 +- .../registration/register_for_election.rs | 2 +- .../registration/unregister_from_election.rs | 4 +- server/src/handlers/voting/close_voting.rs | 2 +- .../src/handlers/voting/initialize_voting.rs | 2 +- server/src/handlers/voting/vote.rs | 2 +- server/src/jwt/has_permission.rs | 91 ++ server/src/jwt/mod.rs | 13 + server/src/{auth => jwt}/refresh_token.rs | 2 +- server/src/lib.rs | 18 +- server/src/main.rs | 12 +- server/src/notifications/send.rs | 2 +- server/src/protocol/count_ballot_votes.rs | 106 -- server/src/protocol/generator.rs | 48 - server/src/protocol/mod.rs | 8 - server/src/schema.rs | 9 +- server/src/utils/convert_bigint.rs | 83 -- server/src/utils/is_offensive_string.rs | 26 - server/src/utils/mod.rs | 11 - server/src/utils/new_safe_uuid_v4.rs | 19 - server/src/utils/serialize_option_bigint.rs | 40 - server/src/views/auth.rs | 4 +- shared/Cargo.toml | 4 + shared/src/auth/audience.rs | 67 -- shared/src/auth/constants.rs | 5 - shared/src/auth/jwt_secret.rs | 21 - shared/src/auth/mod.rs | 8 - shared/src/db/sql_enum.rs | 1 + shared/src/errors/client_request_error.rs | 4 +- shared/src/errors/mod.rs | 6 +- .../{generic_error.rs => shared_error.rs} | 0 .../src/errors/websocket_error.rs | 2 +- .../src/auth => shared/src/jwt}/audience.rs | 1 - .../src/auth => shared/src/jwt}/jwt_secret.rs | 0 shared/src/{auth => jwt}/jwt_token.rs | 22 +- shared/src/jwt/mod.rs | 15 + shared/src/lib.rs | 1 + shared/src/utils/mod.rs | 3 +- shared/src/utils/password_complexity.rs | 45 - .../src/utils/serialize_option_uri.rs | 0 174 files changed, 530 insertions(+), 7121 deletions(-) delete mode 100644 collector/src/auth/constants.rs delete mode 100644 collector/src/auth/jwt_token.rs delete mode 100644 collector/src/auth/mod.rs delete mode 100644 collector/src/auth/permission.rs delete mode 100644 collector/src/db/associations.rs delete mode 100644 collector/src/db/db_connection.rs delete mode 100644 collector/src/db/init.rs delete mode 100644 collector/src/db/many_many_constructor.rs delete mode 100644 collector/src/db/mod.rs delete mode 100644 collector/src/db/sql_enum.rs delete mode 100644 collector/src/db/subtypes.rs delete mode 100644 collector/src/db/types.rs delete mode 100644 collector/src/errors/client_request_error.rs delete mode 100644 collector/src/errors/error_response.rs delete mode 100644 collector/src/errors/global_error_codes.rs create mode 100644 collector/src/jwt/has_permission.rs create mode 100644 collector/src/jwt/mod.rs delete mode 100644 collector/src/protocol/location_anonymization.rs delete mode 100644 collector/src/protocol/mod.rs delete mode 100644 collector/src/protocol/shares_matrix.rs delete mode 100644 collector/src/protocol/stpm.rs delete mode 100644 collector/src/utils/convert_bigint.rs delete mode 100644 collector/src/utils/mod.rs delete mode 100644 collector/src/utils/serialize_option_bigint.rs delete mode 100644 mediator/src/auth/audience.rs delete mode 100644 mediator/src/auth/constants.rs delete mode 100644 mediator/src/auth/jwt_secret.rs delete mode 100644 mediator/src/auth/jwt_token.rs delete mode 100644 mediator/src/auth/mod.rs delete mode 100644 mediator/src/auth/permission.rs delete mode 100644 mediator/src/db/associations.rs delete mode 100644 mediator/src/db/db_connection.rs delete mode 100644 mediator/src/db/init.rs delete mode 100644 mediator/src/db/many_many_constructor.rs delete mode 100644 mediator/src/db/mod.rs delete mode 100644 mediator/src/db/sql_enum.rs delete mode 100644 mediator/src/db/subtypes.rs delete mode 100644 mediator/src/db/types.rs delete mode 100644 mediator/src/errors/client_request_error.rs delete mode 100644 mediator/src/errors/error_response.rs delete mode 100644 mediator/src/errors/global_error_codes.rs delete mode 100644 mediator/src/errors/websocket_error.rs create mode 100644 mediator/src/jwt/has_permission.rs create mode 100644 mediator/src/jwt/mod.rs delete mode 100644 mediator/src/protocol/location_anonymization.rs delete mode 100644 mediator/src/protocol/mod.rs delete mode 100644 mediator/src/protocol/stpm.rs delete mode 100644 mediator/src/utils/convert_bigint.rs delete mode 100644 mediator/src/utils/mod.rs delete mode 100644 mediator/src/utils/serialize_option_bigint.rs delete mode 100644 notifications/src/auth/audience.rs delete mode 100644 notifications/src/auth/constants.rs delete mode 100644 notifications/src/auth/jwt_secret.rs delete mode 100644 notifications/src/auth/jwt_token.rs delete mode 100644 notifications/src/auth/mod.rs delete mode 100644 notifications/src/auth/permission.rs delete mode 100644 notifications/src/errors/error_response.rs delete mode 100644 notifications/src/errors/global_error_codes.rs delete mode 100644 notifications/src/errors/websocket_error.rs create mode 100644 notifications/src/jwt/has_permission.rs create mode 100644 notifications/src/jwt/mod.rs rename notifications/src/{auth => jwt}/websocket_token.rs (96%) delete mode 100644 server/src/auth/audience.rs delete mode 100644 server/src/auth/constants.rs delete mode 100644 server/src/auth/jwt_secret.rs delete mode 100644 server/src/auth/jwt_token.rs delete mode 100644 server/src/auth/permission.rs delete mode 100644 server/src/db/associations.rs delete mode 100644 server/src/db/db_connection.rs delete mode 100644 server/src/db/init.rs delete mode 100644 server/src/db/many_many_constructor.rs delete mode 100644 server/src/db/mod.rs delete mode 100644 server/src/db/sql_enum.rs delete mode 100644 server/src/db/subtypes.rs delete mode 100644 server/src/db/types.rs delete mode 100644 server/src/errors/client_request_error.rs delete mode 100644 server/src/errors/error_response.rs delete mode 100644 server/src/errors/global_error_codes.rs create mode 100644 server/src/jwt/has_permission.rs create mode 100644 server/src/jwt/mod.rs rename server/src/{auth => jwt}/refresh_token.rs (97%) delete mode 100644 server/src/protocol/count_ballot_votes.rs delete mode 100644 server/src/protocol/generator.rs delete mode 100644 server/src/protocol/mod.rs delete mode 100644 server/src/utils/convert_bigint.rs delete mode 100644 server/src/utils/is_offensive_string.rs delete mode 100644 server/src/utils/mod.rs delete mode 100644 server/src/utils/new_safe_uuid_v4.rs delete mode 100644 server/src/utils/serialize_option_bigint.rs delete mode 100644 shared/src/auth/audience.rs delete mode 100644 shared/src/auth/constants.rs delete mode 100644 shared/src/auth/jwt_secret.rs rename shared/src/errors/{generic_error.rs => shared_error.rs} (100%) rename {collector => shared}/src/errors/websocket_error.rs (99%) rename {collector/src/auth => shared/src/jwt}/audience.rs (99%) rename {collector/src/auth => shared/src/jwt}/jwt_secret.rs (100%) rename shared/src/{auth => jwt}/jwt_token.rs (95%) create mode 100644 shared/src/jwt/mod.rs delete mode 100644 shared/src/utils/password_complexity.rs rename {mediator => shared}/src/utils/serialize_option_uri.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 97ed1a4..0737b5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1192,6 +1192,7 @@ dependencies = [ "curv-kzen", "diesel", "dotenv", + "evoting-shared", "futures", "http", "http-serde", @@ -1235,6 +1236,7 @@ dependencies = [ "curv-kzen", "diesel", "dotenv", + "evoting-shared", "futures", "http", "http-serde", @@ -1274,6 +1276,7 @@ dependencies = [ "awc", "chrono", "dotenv", + "evoting-shared", "futures", "jsonwebtoken", "log", @@ -1304,6 +1307,7 @@ dependencies = [ "curv-kzen", "diesel", "dotenv", + "evoting-shared", "futures", "jsonwebtoken", "kzen-paillier", @@ -1330,6 +1334,7 @@ dependencies = [ name = "evoting-shared" version = "0.1.0" dependencies = [ + "actix-codec", "actix-http", "actix-web", "actix-web-httpauth", @@ -1341,6 +1346,8 @@ dependencies = [ "curv-kzen", "diesel", "futures", + "http", + "http-serde", "jsonwebtoken", "kzen-paillier", "lazy_static 1.4.0", @@ -1348,6 +1355,7 @@ dependencies = [ "num", "paste", "serde", + "serde_json", "serde_repr", "uuid", "uuid-b64", diff --git a/collector/Cargo.toml b/collector/Cargo.toml index 95313a1..2faf7a4 100644 --- a/collector/Cargo.toml +++ b/collector/Cargo.toml @@ -20,6 +20,7 @@ chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" +evoting-shared = { path = "../shared" } futures = "0.3.17" http = "0.2.5" http-serde = "1.0.3" diff --git a/collector/src/auth/constants.rs b/collector/src/auth/constants.rs deleted file mode 100644 index 82facef..0000000 --- a/collector/src/auth/constants.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub const JWT_ISSUER: &str = "evoting"; -pub const JWT_EXPIRATION_MIN: i64 = 10; diff --git a/collector/src/auth/jwt_token.rs b/collector/src/auth/jwt_token.rs deleted file mode 100644 index 49867b4..0000000 --- a/collector/src/auth/jwt_token.rs +++ /dev/null @@ -1,223 +0,0 @@ -use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use chrono::{offset::Utc, Duration}; -use futures::executor::block_on; -use futures::future::{ready, Ready}; -use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::collections::HashSet; -use std::iter::FromIterator; -use std::marker::PhantomData; -use uuid_b64::UuidB64 as Uuid; - -use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; -use crate::errors::{ResourceAction, ResourceType, ServiceError}; - -// Type aliases for the different JWT tokens -pub type ClientToken = JWTToken; -pub type ServerToken = JWTToken; -pub type CollectorToken = JWTToken; -pub type MediatorToken = JWTToken; -pub type AnyToken = JWTToken; - -/// JSON Web Token used for user authentication -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTToken { - // Reserved Claims - iss: String, // Issuer - sub: Uuid, // Subject (whom token refers to) - aud: String, // Audience (whom the token is intended for) - iat: i64, // Issued at (as UTC timestamp) - exp: i64, // Expiration time (as UTC timestamp) - - // Public and private claims - #[serde(flatten)] - user_data: T, - permissions: HashSet, - - #[serde(skip)] - _aud: PhantomData, -} - -/// Internal data used by the client JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTClientData { - email: String, - name: String, -} - -pub type JWTInternalData = (); - -/// Internal data used by the "Any" JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTAnyData { - email: Option, - name: Option, -} - -impl JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - /// Encode the JSON Web Token into a string - pub fn encode(&self, key: &EncodingKey) -> Result { - Ok(encode(&Header::default(), self, key)?) - } - - pub fn get_user_id(&self) -> Uuid { - self.sub - } - - /// Test if the user has permission to do something - pub fn has_permission(&self, p: Permission) -> bool { - self.permissions.contains(&p) - } - - // - // Methods to test user permissions - // - pub fn test_can_manage_account(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::User, - ResourceAction::Update, - )) - } - } - pub fn test_can_view_elections(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::ReadPrivate, - )) - } - } - - pub fn test_can_create_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Create, - )) - } - } - - pub fn test_can_register_for_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Register, - )) - } - } - - pub fn test_can_vote(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Register, - )) - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> &String { - &self.user_data.name - } - - pub fn get_email(&self) -> &String { - &self.user_data.email - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn new(permissions: &[Permission]) -> Self { - use uuid::Uuid; - - let now = Utc::now(); - let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); - - Self { - iss: JWT_ISSUER.to_string(), - sub: Uuid::nil().into(), - aud: A::get_name(), - iat: now.timestamp(), - exp: expiration.timestamp(), - - user_data: (), - permissions: HashSet::from_iter(permissions.into_iter().cloned()), - - _aud: PhantomData, - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> Option<&String> { - self.user_data.name.as_ref() - } - - pub fn get_email(&self) -> Option<&String> { - self.user_data.email.as_ref() - } -} - -// -// Get the JSON Web Token from the request -// -impl FromRequest for JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - type Error = ServiceError; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { - let result: Result = (|| { - // Extract the JWT from the header and the encryption key from the app data - let bearer_token = block_on(BearerAuth::from_request(req, pl))?; - let jwt_secret = req.app_data::>().expect("JWTSecret should be set"); - - // Validation parameters, - let validation = Validation { - validate_exp: true, - leeway: 15, - aud: Some(A::accepts()), - iss: Some(JWT_ISSUER.into()), - ..Default::default() - }; - - // Decode and validate the JWT - let token_data = decode::(bearer_token.token(), &jwt_secret.get_decoding_key(), &validation)?; - Ok(token_data.claims) - })(); - - ready(result) - } -} diff --git a/collector/src/auth/mod.rs b/collector/src/auth/mod.rs deleted file mode 100644 index 943edd5..0000000 --- a/collector/src/auth/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -// -// Structures and functions related to user authentication and authorization -// -pub mod audience; -mod constants; -mod jwt_secret; -mod jwt_token; -mod permission; - -pub use audience::Audience; -pub use constants::*; -pub use jwt_secret::JWTSecret; -pub use jwt_token::*; -pub use permission::{Permission, DEFAULT_PERMISSIONS}; diff --git a/collector/src/auth/permission.rs b/collector/src/auth/permission.rs deleted file mode 100644 index 924a459..0000000 --- a/collector/src/auth/permission.rs +++ /dev/null @@ -1,26 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; -use std::fmt; - -pub static DEFAULT_PERMISSIONS: &[Permission] = &[ - Permission::CanLogin, - Permission::CreateElection, - Permission::Register, - Permission::Vote, -]; - -/// List of every permission -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)] -#[repr(u32)] -pub enum Permission { - CanLogin, - CreateElection, - Register, - Vote, - ManageCollector, -} - -impl fmt::Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} diff --git a/collector/src/db/associations.rs b/collector/src/db/associations.rs deleted file mode 100644 index 66a47fb..0000000 --- a/collector/src/db/associations.rs +++ /dev/null @@ -1,916 +0,0 @@ -// ======================= -// Model Base -// ======================= -#[macro_export] -macro_rules! model_base( - () => { - model_base!(no update); - - // Save changes to database - pub fn update( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - self.save_changes::(conn.get()) - } - - // Insert as a new entry, or update the existing entry on conflict - // Uses the primary key to detect duplicate entries - pub fn insert_or_update( - &self, - conn: &crate::db::DbConnection - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict(::table().primary_key()) - .do_update() - .set(self) - .get_result::(conn.get()) - } - }; - - (order by $order:expr) => { - model_base!(); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update, order by $order:expr) => { - model_base!(no update); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update) => { - // Get all - pub fn all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .get_results::(conn.get()) - } - - // Count all users - pub fn count_all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .count().get_result::(conn.get()) - } - - // Find from ID - pub fn find( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - } - - // Find optional from ID - pub fn find_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - .optional() - } - - // Create the new entry in the database - pub fn insert( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .get_result::(conn.get()) - } - - // Insert only if the entry is not in the database - pub fn insert_ignore_conflicts( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict_do_nothing() - .get_result::(conn.get()) - .optional() - } - - // Create multiple entries in the database - pub fn insert_list( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .get_results::(conn.get()) - } - - // Insert a list of values, but ignore duplicate values - pub fn insert_list_ignore_conflicts( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .on_conflict_do_nothing() - .get_results::(conn.get()) - } - - // Test if an item exists in the database - pub fn exists( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional( - <&Self as diesel::associations::Identifiable>::id(&self), - conn, - ).map(|result| result.is_some()) - } - - // Test if an item exists by ID - pub fn exists_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional(id, conn).map(|result| result.is_some()) - } - - // Reload from database - pub fn reload( - &mut self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<()> { - use diesel::prelude::*; - - let new_value = ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get())?; - - *self = new_value; - - Ok(()) - } - - // Reload from database - pub fn reload_new( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get()) - } - - // Delete item in database - pub fn delete( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - .optional() - } - - // Delete item in database - pub fn delete_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_from_id_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - .optional() - } - }; - - (@ order by $order:expr) => { - - // Get all ordered by - pub fn all_ordered( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table().order_by($order) - .get_results::(conn.get()) - } - }; -); - -// ======================= -// Belongs To -// ======================= -#[macro_export] -macro_rules! belongs_to( - ($parent:ident) => { - paste::item! { - belongs_to!($parent, [<$parent:snake>]); - } - }; - - ($parent:ident, $func_base:ident) => { - belongs_to!(@ crate::models::$parent, $func_base); - }; - - (@ $parent:path, $func_base:ident) => { - // Get parent - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - } - - // Get parent optional - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Ok(None), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - .optional() - } - } - } - } - }; -); - -// ======================= -// Has One -// ======================= -#[macro_export] -macro_rules! has_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ).get_result::<$child>(conn.get()) - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_result::<$child>(conn.get()) - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::(conn.get()) - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::(conn.get()) - } - } - }; -); - -// ======================= -// Has Zero or One -// ======================= -#[macro_export] -macro_rules! has_zero_or_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_zero_or_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_zero_or_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - }; -); - -// ======================= -// Has Many -// ======================= -#[macro_export] -macro_rules! has_many( - // Pluralize - ($child:ident) => { - paste::item! { - has_many!($child, [<$child:snake s>]); - } - }; - - ($child:ident, order by $order:expr) => { - paste::item! { - has_many!($child, order by $order, [<$child:snake s>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - }; - - ($child:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - paste::item! { - has_many!(@ crate::models::$child, order by crate::schema::$order, $func_base); - } - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_results::<$child>(conn.get()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - $child::belonging_to(self).count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).count().get_result::(conn.get()) - } - } - - // Delete all children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_results::<$child>(conn.get()) - } - } - - // Delete all children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_results::<$child>(conn.get()) - } - } - }; - - // Has many ordered - (@ $child:path, order by $order:expr, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).order_by($order).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .order_by($order) - .get_results::<$child>(conn.get()) - } - } - }; - - - // ======================= - // Has Many Through - // (Special case) - // ======================= - ($child:ident through $through:ident) => ( - paste::item! { - has_many!($child through $through, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, order by $order:expr) => ( - paste::item! { - has_many!($child through $through, order by $order, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - }; - - ($child:ident through $through:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - paste::item! { - has_many!(@ crate::models::$child => crate::models::$through, order by crate::schema::$order, $func_base); - } - }; - - (@ $child:path => $through:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .count().get_result::(conn.get()) - } - } - - // Delete children from many-to-many the association - // Does NOT delete the actual values - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Delete children from many-to-many the association by the ID - // Does NOT delete the actual values - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Set children - paste::item! { - pub fn []<'a>( - &self, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children Ids - paste::item! { - pub fn []<'a>( - &self, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](id, ids_list, conn) - } - } - - // Set all IDs from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](id, conn)?; - - let new_entries: Vec<$through> = ids_list - .into_iter() - .map(|item| <$through as crate::db::ManyToManyConstructor>::new(id, item)) - .collect(); - - Ok($through::insert_list(&new_entries, conn)?) - } - } - }; - - (@ $child:path => $through:path, order by $order:expr, $func_base:ident) => { - // Get children ordered - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get ordered children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - }; -); diff --git a/collector/src/db/db_connection.rs b/collector/src/db/db_connection.rs deleted file mode 100644 index 26bbc4f..0000000 --- a/collector/src/db/db_connection.rs +++ /dev/null @@ -1,77 +0,0 @@ -use actix_web::{dev::Payload, web, Error, FromRequest, HttpRequest}; -use diesel::pg::PgConnection; -use futures::future::{ready, Ready}; -use std::ops::{Deref, DerefMut}; - -use crate::db::{PgPool, PgPooledConnection}; -use crate::errors::ServiceError; - -pub enum DbConnection { - UnpooledConnection(PgConnection), - PooledConnection(PgPooledConnection), -} - -// -// Explicit extraction calls for when compiler can't implicitly convert -// -impl DbConnection { - pub fn new(conn: PgConnection) -> Self { - DbConnection::UnpooledConnection(conn) - } - pub fn new_pooled(conn: PgPooledConnection) -> Self { - DbConnection::PooledConnection(conn) - } - - pub fn get(&self) -> &PgConnection { - match self { - DbConnection::PooledConnection(pool) => &pool, - DbConnection::UnpooledConnection(conn) => &conn, - } - } - - pub fn get_mut(&mut self) -> &mut PgConnection { - match self { - DbConnection::PooledConnection(ref mut pool) => pool, - DbConnection::UnpooledConnection(ref mut conn) => conn, - } - } -} - -// -// Implicitly convert to the database connection type -// -impl Deref for DbConnection { - type Target = PgConnection; - fn deref(&self) -> &Self::Target { - self.get() - } -} - -impl DerefMut for DbConnection { - fn deref_mut(&mut self) -> &mut Self::Target { - self.get_mut() - } -} - -// -// Get the database connection from the request -// -impl FromRequest for DbConnection { - type Error = Error; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, _pl: &mut Payload) -> Self::Future { - let res = get_connection_from_request(req); - ready(res.map_err(|e| e.into())) - } -} - -pub fn get_connection_from_request(req: &HttpRequest) -> Result { - let pool = req - .app_data::>() - .ok_or(ServiceError::MissingAppData("PgPool".into()))?; - - let conn = pool.get()?; - Ok(DbConnection::new_pooled(conn)) -} diff --git a/collector/src/db/init.rs b/collector/src/db/init.rs deleted file mode 100644 index 51a67d6..0000000 --- a/collector/src/db/init.rs +++ /dev/null @@ -1,24 +0,0 @@ -use diesel::r2d2::{ConnectionManager, Pool, PoolError}; -use diesel::{pg::PgConnection, Connection}; - -use crate::config; -use crate::db::{DbConnection, PgPool}; - -pub fn establish_new_connection_pool() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(init_pool(&database_url)?) -} - -fn init_pool(database_url: &str) -> Result { - let manager = ConnectionManager::::new(database_url); - Pool::builder().build(manager) -} - -pub fn open_new_connection() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(DbConnection::new(PgConnection::establish(&database_url)?)) -} diff --git a/collector/src/db/many_many_constructor.rs b/collector/src/db/many_many_constructor.rs deleted file mode 100644 index b774e0c..0000000 --- a/collector/src/db/many_many_constructor.rs +++ /dev/null @@ -1,6 +0,0 @@ -use diesel::associations::BelongsTo; - -/// Trait that must be implemented to construct a many-to-many relationship -pub trait ManyToManyConstructor: BelongsTo + BelongsTo { - fn new(left: &>::ForeignKey, right: &>::ForeignKey) -> Self; -} diff --git a/collector/src/db/mod.rs b/collector/src/db/mod.rs deleted file mode 100644 index 4f1818a..0000000 --- a/collector/src/db/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -// Database-specific objects and actions -// -mod db_connection; -mod init; -mod many_many_constructor; -mod types; - -#[macro_use] -mod sql_enum; -#[macro_use] -mod associations; -#[macro_use] -mod subtypes; - -pub use db_connection::{get_connection_from_request, DbConnection}; -pub use init::{establish_new_connection_pool, open_new_connection}; -pub use many_many_constructor::ManyToManyConstructor; -pub use types::{PgPool, PgPooledConnection}; diff --git a/collector/src/db/sql_enum.rs b/collector/src/db/sql_enum.rs deleted file mode 100644 index fe43487..0000000 --- a/collector/src/db/sql_enum.rs +++ /dev/null @@ -1,54 +0,0 @@ -#[macro_export] -macro_rules! sql_enum { - ($v:vis $name:ident $type:tt) => { - #[repr(i32)] - #[derive( - Debug, Copy, Clone, Eq, PartialEq, Hash, - serde_repr::Serialize_repr, serde_repr::Deserialize_repr, - FromSqlRow, FromPrimitive, AsExpression, - )] - #[sql_type = "Integer"] - $v enum $name $type - enum_internals!($name); - }; -} - -#[allow(unused)] -macro_rules! enum_internals { - ($($t:ty)*) => ($( - - // Required packages - use diesel::{ - backend::Backend, - deserialize::{self, FromSql}, - serialize::{self, Output, ToSql}, - sql_types::Integer, - }; - use std::io::Write; - - // Convert to SQL - impl ToSql for $t - where - DB: Backend, - i32: ToSql, - { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - (*self as i32).to_sql(out) - } - } - - // Convert from SQL - impl FromSql for $t - where - DB: Backend, - i32: FromSql, - { - fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result { - let number = i32::from_sql(bytes)?; - num::FromPrimitive::from_i32(number).ok_or_else( - || format!("diesel::deserialize::FromSql for {} --- Invalid variant index {}", stringify!($t), number).into() - ) - } - } - )*) -} diff --git a/collector/src/db/subtypes.rs b/collector/src/db/subtypes.rs deleted file mode 100644 index 13d3724..0000000 --- a/collector/src/db/subtypes.rs +++ /dev/null @@ -1,71 +0,0 @@ -// ======================= -// Parent Type -// ======================= -#[macro_export] -macro_rules! parent_type( - ($discriminant:ty = $from_value:expr) => { - paste::item! { - parent_type!($discriminant = $from_value, [<$discriminant:snake>]); - } - }; - - ($discriminant:ty = $from_value:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - self.$from_value - } - } - }; -); - -// ======================= -// Child Type -// ======================= -#[macro_export] -macro_rules! child_type( - ($parent:ty, $discriminant:ty = $value:expr) => { - paste::item! { - child_type!($parent, $discriminant = $value, [<$discriminant:snake>]); - } - }; - - ($parent:ty, $discriminant:ty = $from:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - $from - } - } - - pub fn get_parent( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - - pub fn get_parent_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - }; -); diff --git a/collector/src/db/types.rs b/collector/src/db/types.rs deleted file mode 100644 index 5976a70..0000000 --- a/collector/src/db/types.rs +++ /dev/null @@ -1,5 +0,0 @@ -use diesel::pg::PgConnection; -use diesel::r2d2::{ConnectionManager, Pool, PooledConnection}; - -pub type PgPool = Pool>; -pub type PgPooledConnection = PooledConnection>; diff --git a/collector/src/errors/client_request_error.rs b/collector/src/errors/client_request_error.rs deleted file mode 100644 index 5c62f49..0000000 --- a/collector/src/errors/client_request_error.rs +++ /dev/null @@ -1,73 +0,0 @@ -use actix_http::{encoding::Decoder, Payload, PayloadStream}; -use awc::error::{JsonPayloadError, SendRequestError}; -use awc::http::StatusCode; -use awc::ClientResponse; -use serde::de::DeserializeOwned; -use std::future::Future; - -use crate::errors::ErrorResponse; - -/// Enum with all of the things that can go wrong when making a client request -#[derive(Debug)] -pub enum ClientRequestError { - SendError(SendRequestError), - ResponseError(ErrorResponse), - JSONError(JsonPayloadError), - UnknownError(StatusCode), -} - -impl ClientRequestError { - /// Handle the response from a client and parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle( - input: impl Future>>, SendRequestError>>, - ) -> Result { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Try to deserialize the data if the request is ok - let status = response.status(); - if response.status() == StatusCode::OK { - return response.json::().await.map_err(|e| Self::JSONError(e)); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } - - /// Handle the response from a client, but don't parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle_empty( - input: impl Future>>, SendRequestError>>, - ) -> Result<(), Self> { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Make sure the request is okay - let status = response.status(); - if response.status() == StatusCode::OK { - return Ok(()); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } -} diff --git a/collector/src/errors/error_response.rs b/collector/src/errors/error_response.rs deleted file mode 100644 index 25c48dc..0000000 --- a/collector/src/errors/error_response.rs +++ /dev/null @@ -1,71 +0,0 @@ -use actix_web::{http::StatusCode, HttpResponse, ResponseError}; -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt; - -use crate::errors::GlobalErrorCode; - -/// JSON response returned to the frontend on an error -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ErrorResponse { - #[serde( - serialize_with = "serialize_status_code", - deserialize_with = "deserialize_status_code" - )] - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - - // Don't serialize on production system - #[cfg_attr(not(debug_assertions), serde(skip_serializing))] - #[serde(skip_serializing_if = "Option::is_none")] - developer_notes: Option, -} - -fn serialize_status_code(code: &StatusCode, serializer: S) -> Result -where - S: Serializer, -{ - serializer.serialize_u16(code.as_u16()) -} - -fn deserialize_status_code<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let integer: u16 = Deserialize::deserialize(deserializer)?; - StatusCode::from_u16(integer).map_err(D::Error::custom) -} - -impl ErrorResponse { - pub fn new( - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - developer_notes: String, - ) -> Self { - ErrorResponse { - status_code, - description, - error_code, - developer_notes: Some(developer_notes), - } - } -} - -impl fmt::Display for ErrorResponse { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(#{:?}): {}", self.error_code, self.description)?; - if let Some(ref notes) = self.developer_notes { - write!(f, "\nDeveloper Notes: {}", notes)?; - } - Ok(()) - } -} - -impl ResponseError for ErrorResponse { - fn error_response(&self) -> HttpResponse { - HttpResponse::build(self.status_code).json(&self) - } -} diff --git a/collector/src/errors/global_error_codes.rs b/collector/src/errors/global_error_codes.rs deleted file mode 100644 index 56f6e2c..0000000 --- a/collector/src/errors/global_error_codes.rs +++ /dev/null @@ -1,46 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; - -/// Error codes that are exposed on the frontend -#[derive(Serialize_repr, Deserialize_repr, Debug)] -#[repr(u32)] -pub enum GlobalErrorCode { - UnknownError = 0, - DatabaseConnectionError, - DatabaseQueryError, - MissingAppData, - JSONPayloadError, - FormPayloadError, - URLPathError, - QueryStringError, - StructValidationError, - InvalidEmailPassword, - InvalidJWTToken, - UserEmailExists, - PasswordComplexityError, - RecaptchaError, - ForbiddenResourceAction, - NoSuchResource, - ElectionNotOwnedByUser, - ElectionNotDraft, - WrongElectionStatus, - AccessCodeNotFound, - NotRegistered, - AlreadyRegistered, - RegistrationClosed, - NotEnoughRegistered, - ElectionNotInitialized, - MediatorURLNotSet, - RegisterElectionError, - VerificationError, - AlreadyVoted, - VerifyVoteError, - VoteInvalid, - NotOpenForVoting, - NotEnoughVotes, - CancelationSharesError, - ElectionNotStarted, - NoNotifyPermission, - NoSubscribePermission, - NotificationError, - InvalidCollectorURI, -} diff --git a/collector/src/errors/mod.rs b/collector/src/errors/mod.rs index af80390..eb56f16 100644 --- a/collector/src/errors/mod.rs +++ b/collector/src/errors/mod.rs @@ -1,20 +1,13 @@ // // All code related to error handling for the API server // -mod client_request_error; -mod error_response; -mod global_error_codes; mod named_resource_type; mod resource_action; mod resource_type; mod service_error; -mod websocket_error; -pub use client_request_error::ClientRequestError; -pub use error_response::ErrorResponse; -pub use global_error_codes::GlobalErrorCode; +pub use evoting_shared::errors::*; // Re-export pub use named_resource_type::NamedResourceType; pub use resource_action::ResourceAction; pub use resource_type::ResourceType; pub use service_error::ServiceError; -pub use websocket_error::WebsocketError; diff --git a/collector/src/errors/named_resource_type.rs b/collector/src/errors/named_resource_type.rs index 2ed30af..dfbfa37 100644 --- a/collector/src/errors/named_resource_type.rs +++ b/collector/src/errors/named_resource_type.rs @@ -50,11 +50,15 @@ impl NamedResourceType { impl fmt::Display for NamedResourceType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - NamedResourceType::User { id } => write!(f, "{} (ID: {})", self.get_name(), id), - NamedResourceType::Election { id } => write!(f, "{} (ID: {})", self.get_name(), id), + NamedResourceType::User { id } => { + write!(f, "{} (ID: {})", self.get_name(), id) + }, + NamedResourceType::Election { id } => { + write!(f, "{} (ID: {})", self.get_name(), id) + }, NamedResourceType::Question { id, election_id } => { write!(f, "{} (ID: {}, Election ID: {})", self.get_name(), id, election_id) - } + }, NamedResourceType::EncryptedLocation { user_id, election_id } => { write!( f, @@ -63,7 +67,7 @@ impl fmt::Display for NamedResourceType { user_id, election_id ) - } + }, } } } diff --git a/collector/src/handlers/auth/get_me.rs b/collector/src/handlers/auth/get_me.rs index 8323943..a2c8240 100644 --- a/collector/src/handlers/auth/get_me.rs +++ b/collector/src/handlers/auth/get_me.rs @@ -1,6 +1,6 @@ use actix_web::HttpResponse; -use crate::auth::AnyToken; +use crate::jwt::AnyToken; use crate::views::auth::UserDetails; pub async fn get_me(token: AnyToken) -> HttpResponse { diff --git a/collector/src/handlers/election/create_and_initialize_election.rs b/collector/src/handlers/election/create_and_initialize_election.rs index 98d8d49..7952c51 100644 --- a/collector/src/handlers/election/create_and_initialize_election.rs +++ b/collector/src/handlers/election/create_and_initialize_election.rs @@ -7,9 +7,9 @@ use serde::{Deserialize, Serialize}; use uuid_b64::UuidB64 as Uuid; use validator::{Validate, ValidationError}; -use crate::auth::MediatorToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{HasPermission, MediatorToken}; use crate::models::{Election, EncryptedLocation, Question, Registration}; use crate::protocol::{location_anonymization as loc_anon, SharesMatrix}; use crate::utils::ConvertBigInt; diff --git a/collector/src/handlers/election/get_cancelation_shares.rs b/collector/src/handlers/election/get_cancelation_shares.rs index 24569ce..92d237f 100644 --- a/collector/src/handlers/election/get_cancelation_shares.rs +++ b/collector/src/handlers/election/get_cancelation_shares.rs @@ -4,9 +4,9 @@ use serde::Deserialize; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::MediatorToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{HasPermission, MediatorToken}; use crate::models::Election; use crate::utils::ConvertBigInt; use crate::views::election::CancelationShares; diff --git a/collector/src/handlers/election/get_election_parameters.rs b/collector/src/handlers/election/get_election_parameters.rs index c880c1c..b369b4a 100644 --- a/collector/src/handlers/election/get_election_parameters.rs +++ b/collector/src/handlers/election/get_election_parameters.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Election; use crate::utils::ConvertBigInt; use crate::views::election::ElectionParameters; diff --git a/collector/src/handlers/election/get_question_parameters.rs b/collector/src/handlers/election/get_question_parameters.rs index 3f0fe09..0026376 100644 --- a/collector/src/handlers/election/get_question_parameters.rs +++ b/collector/src/handlers/election/get_question_parameters.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Election; use crate::utils::ConvertBigInt; use crate::views::election::QuestionParameters; diff --git a/collector/src/handlers/verification/verification_websocket_actor.rs b/collector/src/handlers/verification/verification_websocket_actor.rs index c4c68e1..407495e 100644 --- a/collector/src/handlers/verification/verification_websocket_actor.rs +++ b/collector/src/handlers/verification/verification_websocket_actor.rs @@ -281,7 +281,7 @@ impl StreamHandler> for VerificationWebso log::info!("Received close message, closing... ({:#?})", reason); ctx.close(reason); return ctx.stop(); - } + }, // Parse JSON message ws::Message::Text(text) => match serde_json::from_str::(&text) { @@ -301,22 +301,22 @@ impl StreamHandler> for VerificationWebso if self.verify_signature(&data, ctx) { self_addr.do_send(data); } - } + }, WebsocketMessage::SP1_STMP_Response(data) => { if self.verify_signature(&data, ctx) { self_addr.do_send(data); } - } + }, WebsocketMessage::SP1_Product_Response(data) => { if self.verify_signature(&data, ctx) { self_addr.do_send(data); } - } + }, WebsocketMessage::SP2_Shares_Response(data) => { if self.verify_signature(&data, ctx) { self_addr.do_send(data); } - } + }, } } @@ -431,7 +431,7 @@ impl Handler> for VerificationWebsocketAc ), ctx, ) - } + }, }; // ============================================ diff --git a/collector/src/handlers/verification/verify_ballot_websocket.rs b/collector/src/handlers/verification/verify_ballot_websocket.rs index c7020e1..2d19604 100644 --- a/collector/src/handlers/verification/verify_ballot_websocket.rs +++ b/collector/src/handlers/verification/verify_ballot_websocket.rs @@ -3,9 +3,9 @@ use actix_web_actors::ws; use uuid_b64::UuidB64 as Uuid; use super::verification_websocket_actor::VerificationWebsocketActor; -use crate::auth::MediatorToken; use crate::db::DbConnection; use crate::errors::{ServiceError, WebsocketError}; +use crate::jwt::{HasPermission, MediatorToken}; use crate::models::{Election, Question}; pub async fn verify_ballot_websocket( diff --git a/collector/src/jwt/has_permission.rs b/collector/src/jwt/has_permission.rs new file mode 100644 index 0000000..c3e25e2 --- /dev/null +++ b/collector/src/jwt/has_permission.rs @@ -0,0 +1,71 @@ +use crate::errors::{ResourceAction, ResourceType, ServiceError}; +use crate::jwt::{Audience, JWTToken, Permission}; + +/// Helper trait that exposes methods for checking specific permissions +pub trait HasPermission { + /// Test if the user has permission to do something + fn has_permission(&self, p: Permission) -> bool; + + // =================================== + // Methods to test user permissions + // =================================== + fn test_can_manage_account(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::User, + ResourceAction::Update, + )) + } + } + fn test_can_view_elections(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::ReadPrivate, + )) + } + } + + fn test_can_create_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Create, + )) + } + } + + fn test_can_register_for_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Register, + )) + } + } + + fn test_can_vote(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Register, + )) + } + } +} + +impl HasPermission for JWTToken { + fn has_permission(&self, p: Permission) -> bool { + self.test_has_permission(p) + } +} diff --git a/collector/src/jwt/mod.rs b/collector/src/jwt/mod.rs new file mode 100644 index 0000000..3e9f742 --- /dev/null +++ b/collector/src/jwt/mod.rs @@ -0,0 +1,7 @@ +// +// Structures and functions related to JSON web tokens +// +mod has_permission; + +pub use evoting_shared::jwt::*; // Re-export +pub use has_permission::HasPermission; diff --git a/collector/src/lib.rs b/collector/src/lib.rs index 7c6be17..b61bbf5 100644 --- a/collector/src/lib.rs +++ b/collector/src/lib.rs @@ -4,16 +4,25 @@ extern crate diesel; #[allow(unused)] #[macro_use] extern crate num_derive; +#[macro_use] +extern crate evoting_shared; // All internal code modules -pub mod auth; pub mod config; -#[macro_use] -pub mod db; pub mod errors; pub mod handlers; +pub mod jwt; pub mod models; -pub mod protocol; pub mod schema; -pub mod utils; pub mod views; + +// Re-export modules from the shared library +pub mod db { + pub use evoting_shared::db::*; +} +pub mod protocol { + pub use evoting_shared::protocol::*; +} +pub mod utils { + pub use evoting_shared::utils::*; +} diff --git a/collector/src/main.rs b/collector/src/main.rs index 4d83737..da06f85 100644 --- a/collector/src/main.rs +++ b/collector/src/main.rs @@ -9,11 +9,11 @@ use std::str::FromStr; use structopt::StructOpt; use uuid_b64::UuidB64 as Uuid; -use evoting_collector::auth::{CollectorToken, JWTSecret, Permission}; use evoting_collector::config::{self, EnvPrefix}; use evoting_collector::db; use evoting_collector::errors::{ClientRequestError, ServiceError}; use evoting_collector::handlers; +use evoting_collector::jwt::{CollectorToken, JWTSecret, Permission}; #[actix_web::main] async fn main() -> anyhow::Result<()> { @@ -32,8 +32,12 @@ async fn main() -> anyhow::Result<()> { // Let the mediator know about this collector register_collector_with_mediator().await?; - // Database connection pool and web server - let connection_pool = db::establish_new_connection_pool()?; + // Database connection pool + let database_url = + config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; + let connection_pool = db::open_new_connection_pool(&database_url)?; + + // Build the web server let mut server = HttpServer::new(move || { App::new() // Connect to database diff --git a/collector/src/protocol/location_anonymization.rs b/collector/src/protocol/location_anonymization.rs deleted file mode 100644 index b1e46a2..0000000 --- a/collector/src/protocol/location_anonymization.rs +++ /dev/null @@ -1,65 +0,0 @@ -use curv_kzen::arithmetic::{Modulo, Samplable}; -use kzen_paillier::*; - -/// First step of the location anonymization scheme -/// C1 computes e_x1 = E(x1) and sends it to C2 -/// -/// location = Secret location (0 <= location <= n - 1) -/// n = Public key for Paillier cryptosystem -/// -/// Returns e_x1 -pub fn step_1(location: &BigInt, n: &BigInt) -> BigInt { - // Compute E(x1) - let ek = EncryptionKey::from(n); - let e_x1: RawCiphertext = Paillier::encrypt(&ek, location.into()); - e_x1.0.into_owned() -} - -/// ith step of the location anonymization scheme: (Collectors C2 to C{n-1}) -/// Ci picks random ri with 0 <= ri < n -/// Ci computes e_xi = (e_x1 * ... * e_x{i-1}) * (E(ri)^(-1)) (mod n^2) and sends it to C{i+1} -/// -/// e_xi_1 = (e_x1 * ... * e_x{i-1}) -/// n = Public key for paillier cryptosystem -/// -/// Returns (ri, e_xi) -pub fn step_ith(e_xi_1: &BigInt, n: &BigInt) -> (BigInt, BigInt) { - // Pick random ri with 0 <= ri < n - let ri = BigInt::sample_below(n); - - // Compute E(r2) - let ek = EncryptionKey::from(n); - let e_ri: RawCiphertext = Paillier::encrypt(&ek, ri.clone().into()); - - // Compute (e_xi_1) * (E(ri)^(-1)) (mod n^2) - // Every encrypted r value should be invertible, so we should never panic when finding inverse - let e_xi = BigInt::mod_mul( - &e_xi_1, - &BigInt::mod_inv(&e_ri.0, &ek.nn).expect("Error: No Inverse"), - &ek.nn, - ); - - (ri, e_xi) -} - -/// Last step of the location anonymization scheme: -/// C1 decrypts D(e_x{n-1}), resulting in r1 -/// -/// The parties now have values: r1 + r2 + ... + rn (mod n) = x1 (mod n^2) -/// -/// e_xn_1 = (e_x1 * ... * e_x{n-1}) -/// p, q = Private key for Paillier cryptosystem -/// -/// Returns r1 -pub fn step_last(e_xn_1: &BigInt, p: &BigInt, q: &BigInt) -> BigInt { - let e_xn_1 = RawCiphertext::from(e_xn_1); - - // Compute r1 = D(e_x2) - let dk = DecryptionKey { - p: p.clone(), - q: q.clone(), - }; - let r1: RawPlaintext = Paillier::decrypt(&dk, e_xn_1); - - r1.0.into_owned() -} diff --git a/collector/src/protocol/mod.rs b/collector/src/protocol/mod.rs deleted file mode 100644 index 21ee61b..0000000 --- a/collector/src/protocol/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Functions and structures related to the math behind the e-voting protocol -// -pub mod location_anonymization; -mod shares_matrix; -pub mod stpm; - -pub use shares_matrix::SharesMatrix; diff --git a/collector/src/protocol/shares_matrix.rs b/collector/src/protocol/shares_matrix.rs deleted file mode 100644 index 044c4b0..0000000 --- a/collector/src/protocol/shares_matrix.rs +++ /dev/null @@ -1,152 +0,0 @@ -use curv_kzen::arithmetic::{Converter, Samplable}; -use curv_kzen::BigInt; -use std::fmt; -use std::ops::{Index, IndexMut}; - -/// Matrix used by the collectors for (n,n) Secret Sharing -pub struct SharesMatrix { - num_voters: usize, - modulus: BigInt, - matrix: Vec, -} - -impl SharesMatrix { - pub fn new(collector: usize, num_collectors: usize, num_voters: usize, modulus: BigInt) -> Self { - let mut matrix = SharesMatrix { - num_voters, - modulus, - matrix: vec![BigInt::from(0); num_voters * num_voters], - }; - - // Fill in the matrix quadrants - matrix.fill_collector(collector, num_collectors); - matrix - } - - pub fn get_num_voters(&self) -> usize { - self.num_voters - } - - pub fn get_modulus(&self) -> &BigInt { - &self.modulus - } - - /// Get the sum of shares for a given voter to use for the ballot. - /// For our protocol, this is the sum of the column. - /// - /// Returns nothing if the voter is outside the range of the number of voters. - pub fn get_ballot_shares(&self, voter: usize) -> Option { - if voter >= self.num_voters { - return None; - } - - let mut sum = BigInt::from(0); - for row in 0..self.num_voters { - sum += &self[(row, voter)]; - } - - Some(sum % &self.modulus) - } - - /// Get the sum of shares for a given voter to use for voter verification. - /// For our protocol, this is the sum of the row. - /// - /// Returns nothing if the voter is outside the range of the number of voters. - pub fn get_verification_shares(&self, voter: usize) -> Option { - if voter >= self.num_voters { - return None; - } - - let mut sum = BigInt::from(0); - for col in 0..self.num_voters { - sum += &self[(voter, col)]; - } - - Some(sum % &self.modulus) - } - - // Fill the quadrants associated with each collector - // - // [ 1 ][ 2 ][ 3 ] ... [ n ] - // [ n ][ 1 ][ 2 ] ... [n-1] - // [n-1][ n ][ 1 ] ... [n-2] - // | | | \ | - // [ 2 ][ 3 ][ 4 ] ... [ 1 ] - // - // Areas outside are filled with 0's so the sum is unchaged - fn fill_collector(&mut self, collector: usize, num_collectors: usize) { - // Fill the diagonal "cells", wrapping around - // Each cell is approx. (num_voters / num_collectors)^2 entries in size - // For a special case, the last row and column may be different - for cell_index in 0..num_collectors { - let row_cell_index = cell_index; - let col_cell_index = (collector + cell_index) % num_collectors; - - // Top left of the cell - let row_start = (row_cell_index * self.num_voters) / num_collectors; - let col_start = (col_cell_index * self.num_voters) / num_collectors; - - // Last row may be a different size to fill remaining rows - let row_end = if row_cell_index == (num_collectors - 1) { - self.num_voters - } else { - ((row_cell_index + 1) * self.num_voters) / num_collectors - }; - - // Last column may be a different size to fill remaining columns - let col_end = if col_cell_index == (num_collectors - 1) { - self.num_voters - } else { - ((col_cell_index + 1) * self.num_voters) / num_collectors - }; - - // Fill in all rows and columns in the individual cell - for row in row_start..row_end { - for col in col_start..col_end { - // Don't fill the main diagonal - if row != col { - self[(row, col)] = BigInt::sample_below(&self.modulus); - } - } - } - } - } -} - -impl Index<(usize, usize)> for SharesMatrix { - type Output = BigInt; - - fn index(&self, (row, col): (usize, usize)) -> &Self::Output { - &self.matrix[row * self.num_voters + col] - } -} - -impl IndexMut<(usize, usize)> for SharesMatrix { - fn index_mut(&mut self, (row, col): (usize, usize)) -> &mut Self::Output { - &mut self.matrix[row * self.num_voters + col] - } -} - -impl fmt::Display for SharesMatrix { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let num_digits = self.matrix.iter().max().map(|x| x.to_str_radix(10).len()).unwrap_or(0); - - writeln!( - f, - "SharesMatrix {{ num_voters: {}, modulus: {}, matrix: ", - self.num_voters, self.modulus - )?; - - for row in 0..self.num_voters { - write!(f, " |")?; - for col in 0..self.num_voters { - if col > 0 { - write!(f, ", ")?; - } - write!(f, "{:>width$}", self[(row, col)].to_string(), width = num_digits)?; - } - writeln!(f, "|")?; - } - writeln!(f, "}}") - } -} diff --git a/collector/src/protocol/stpm.rs b/collector/src/protocol/stpm.rs deleted file mode 100644 index 3504a3a..0000000 --- a/collector/src/protocol/stpm.rs +++ /dev/null @@ -1,91 +0,0 @@ -use curv_kzen::arithmetic::{Modulo, Samplable}; -use kzen_paillier::*; - -/// First step of the STPM: -/// C1 computes e_x1 = E(x1) and sends it to C2 -/// -/// x1 = First number being multiplied -/// n = Public key for Paillier cryptosystem -/// -/// Returns e_x1 -pub fn step_1(x1: &BigInt, n: &BigInt) -> BigInt { - // Compute E(x1) - let ek = EncryptionKey::from(n); - let e_x1: RawCiphertext = Paillier::encrypt(&ek, x1.into()); - e_x1.0.into_owned() -} - -/// Second step of the STPM: -/// C2 picks random r2 with 0 <= r2 < n -/// C2 computes e_x2 = ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) and sends it to C1 -/// -/// e_x1 = E(x1) -/// x2 = Second number being multiplied -/// n = Public key for paillier cryptosystem -/// -/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus -/// This means that r1 (or r2) may be negative -/// -/// Returns (r2, e_x2) -pub fn step_2(e_x1: &BigInt, x2: &BigInt, n: &BigInt, normalize: bool) -> (BigInt, BigInt) { - // Pick random r2 with 0 <= r2 < n - let mut r2 = BigInt::sample_below(n); - - // Compute E(r2) - let ek = EncryptionKey::from(n); - let e_r2: RawCiphertext = Paillier::encrypt(&ek, r2.clone().into()); - - // Compute ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) - // Every encrypted r value should be invertible, so we should never panic when finding inverse - let e_x2 = BigInt::mod_mul( - &BigInt::mod_pow(e_x1, &x2, &ek.nn), - &BigInt::mod_inv(&e_r2.0, &ek.nn).expect("Error: No Inverse"), - &ek.nn, - ); - - // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus - // - // So, if 2*r2 > n, then r2 = r2 - n - // -This will be a negative number - if normalize && (&(2 * &r2) >= &n) { - r2 = &r2 - n; - } - - (r2, e_x2) -} - -/// Last step of the STPM: -/// C1 decrypts D(e_x2), resulting in r1 -/// -/// The two parties now have values: r1 + r2 (mod n) = x1 * x2 (mod n^2) -/// If the "normalize" flag was set to true, then r1 + r2 = x1 * x2 with NO modulus -/// -/// e_x2 = (E(x1)^x2) * (E(r2)^(-1)) (mod n^2) -- From previous step -/// p, q = Private key for Paillier cryptosystem -/// -/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus -/// This means that r1 (or r2) may be negative -/// -/// Returns r1 -pub fn step_3(e_x2: &BigInt, p: &BigInt, q: &BigInt, normalize: bool) -> BigInt { - let e_x2 = RawCiphertext::from(e_x2); - - // Compute r1 = D(e_x2) - let dk = DecryptionKey { - p: p.clone(), - q: q.clone(), - }; - let r1: RawPlaintext = Paillier::decrypt(&dk, e_x2); - - // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus - // - // So, if 2*r1 > n, then r1 = r1 - n - // -This will be a negative number - let n = p * q; - let mut r1 = r1.0.into_owned(); - if normalize && (&(2 * &r1) >= &n) { - r1 = &r1 - &n; - } - - r1 -} diff --git a/collector/src/schema.rs b/collector/src/schema.rs index 417e2a5..f4bd3a1 100644 --- a/collector/src/schema.rs +++ b/collector/src/schema.rs @@ -41,9 +41,4 @@ joinable!(questions -> elections (election_id)); joinable!(registrations -> elections (election_id)); joinable!(registrations -> questions (question_id)); -allow_tables_to_appear_in_same_query!( - elections, - encrypted_locations, - questions, - registrations, -); +allow_tables_to_appear_in_same_query!(elections, encrypted_locations, questions, registrations,); diff --git a/collector/src/utils/convert_bigint.rs b/collector/src/utils/convert_bigint.rs deleted file mode 100644 index 547469c..0000000 --- a/collector/src/utils/convert_bigint.rs +++ /dev/null @@ -1,83 +0,0 @@ -use bigdecimal::BigDecimal; -use curv_kzen::arithmetic::{BigInt, Converter, NumberTests}; -use num::bigint::{BigInt as NumBigInt, Sign}; - -/// -/// Trait used to simplify converting between BigInt and BigDecimal -/// -pub trait ConvertBigInt { - fn to_bigint(&self) -> BigInt; - fn to_bigdecimal(&self) -> BigDecimal; - - fn from_bigint(bigint: BigInt) -> Self; - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self; -} - -impl ConvertBigInt for BigInt { - fn to_bigint(&self) -> BigInt { - self.clone() - } - - fn to_bigdecimal(&self) -> BigDecimal { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(self), &self.to_bytes()), 0) - } - - fn from_bigint(bigint: BigInt) -> Self { - bigint - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - let (bigint, _exponent) = bigdecimal.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } -} - -impl ConvertBigInt for BigDecimal { - fn to_bigint(&self) -> BigInt { - let (bigint, _exponent) = self.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } - - fn to_bigdecimal(&self) -> BigDecimal { - self.clone() - } - - fn from_bigint(bigint: BigInt) -> Self { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(&bigint), &bigint.to_bytes()), 0) - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - bigdecimal - } -} - -/// -/// Figure out the sign of the input BigInt -/// -fn get_sign(input: &BigInt) -> Sign { - if BigInt::is_zero(input) { - return Sign::NoSign; - } - - if BigInt::is_negative(input) { - Sign::Minus - } else { - Sign::Plus - } -} diff --git a/collector/src/utils/mod.rs b/collector/src/utils/mod.rs deleted file mode 100644 index a4adee7..0000000 --- a/collector/src/utils/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -// -// General-purpose functions and objects -// -mod convert_bigint; -pub mod serialize_option_bigint; - -pub use convert_bigint::ConvertBigInt; diff --git a/collector/src/utils/serialize_option_bigint.rs b/collector/src/utils/serialize_option_bigint.rs deleted file mode 100644 index d59403d..0000000 --- a/collector/src/utils/serialize_option_bigint.rs +++ /dev/null @@ -1,40 +0,0 @@ -use curv_kzen::arithmetic::traits::Converter; -use curv_kzen::BigInt; -use serde::{de, ser}; -use std::fmt; - -pub fn serialize(x: &Option, serializer: S) -> Result { - match x { - Some(x) => serializer.serialize_str(&x.to_str_radix(10)), - None => serializer.serialize_none(), - } -} - -pub fn deserialize<'de, D: de::Deserializer<'de>>(deserializer: D) -> Result, D::Error> { - struct OptionBigIntVisitor; - - impl<'de> de::Visitor<'de> for OptionBigIntVisitor { - type Value = Option; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("option of bigint") - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(None) - } - - #[inline] - fn visit_none(self) -> Result, E> { - Ok(None) - } - - #[inline] - fn visit_some>(self, deserializer: D) -> Result { - kzen_paillier::serialize::bigint::deserialize(deserializer).map(Some) - } - } - - deserializer.deserialize_option(OptionBigIntVisitor) -} diff --git a/mediator/Cargo.toml b/mediator/Cargo.toml index f640d49..1815d6d 100644 --- a/mediator/Cargo.toml +++ b/mediator/Cargo.toml @@ -20,6 +20,7 @@ chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" +evoting-shared = { path = "../shared" } futures = "0.3.17" http = "0.2.5" http-serde = "1.0.3" diff --git a/mediator/src/auth/audience.rs b/mediator/src/auth/audience.rs deleted file mode 100644 index 024470b..0000000 --- a/mediator/src/auth/audience.rs +++ /dev/null @@ -1,66 +0,0 @@ -use serde::Deserialize; -use std::collections::HashSet; -use std::iter::FromIterator; - -/// Generic trait shared by all audience types -/// -/// An audience specifies which routes a JWT can access -pub trait Audience { - const TEXT: &'static str; - const ACCEPTS: &'static [&'static str]; - - /// Get the name to show for this audience type - fn get_name() -> String { - Self::TEXT.to_string() - } - - /// Get the list of all audiences accepted by this type - fn accepts() -> HashSet { - HashSet::from_iter(Self::ACCEPTS.iter().cloned().map(String::from)) - } -} - -/// Route is available to all token types -#[derive(Deserialize)] -pub struct All; - -impl Audience for All { - const TEXT: &'static str = "all"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only", "server-only", "collector-only", "mediator-only"]; -} - -/// Route can only be called by the frontend client -#[derive(Deserialize)] -pub struct ClientOnly; - -impl Audience for ClientOnly { - const TEXT: &'static str = "client-only"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only"]; -} - -/// Route can only be called by the server -#[derive(Deserialize)] -pub struct ServerOnly; - -impl Audience for ServerOnly { - const TEXT: &'static str = "server-only"; - const ACCEPTS: &'static [&'static str] = &["all", "server-only"]; -} - -/// Route can only be called by a collector -#[derive(Deserialize)] -pub struct CollectorOnly; - -impl Audience for CollectorOnly { - const TEXT: &'static str = "collector-only"; - const ACCEPTS: &'static [&'static str] = &["all", "collector-only"]; -} - -/// Route can only be called by a mediator -#[derive(Deserialize)] -pub struct MediatorOnly; - -impl Audience for MediatorOnly { - const TEXT: &'static str = "mediator-only"; - const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; -} diff --git a/mediator/src/auth/constants.rs b/mediator/src/auth/constants.rs deleted file mode 100644 index 82facef..0000000 --- a/mediator/src/auth/constants.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub const JWT_ISSUER: &str = "evoting"; -pub const JWT_EXPIRATION_MIN: i64 = 10; diff --git a/mediator/src/auth/jwt_secret.rs b/mediator/src/auth/jwt_secret.rs deleted file mode 100644 index ebf8054..0000000 --- a/mediator/src/auth/jwt_secret.rs +++ /dev/null @@ -1,21 +0,0 @@ -use jsonwebtoken::{DecodingKey, EncodingKey}; - -/// Simple wrapper struct to store the JWT secret -#[derive(Debug, Clone)] -pub struct JWTSecret { - secret: String, -} - -impl JWTSecret { - pub fn new(secret: impl Into) -> Self { - Self { secret: secret.into() } - } - - pub fn get_encoding_key(&self) -> EncodingKey { - EncodingKey::from_secret(self.secret.as_bytes()) - } - - pub fn get_decoding_key<'a>(&'a self) -> DecodingKey<'a> { - DecodingKey::from_secret(self.secret.as_bytes()) - } -} diff --git a/mediator/src/auth/jwt_token.rs b/mediator/src/auth/jwt_token.rs deleted file mode 100644 index e5e801f..0000000 --- a/mediator/src/auth/jwt_token.rs +++ /dev/null @@ -1,245 +0,0 @@ -use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use chrono::{offset::Utc, Duration}; -use futures::executor::block_on; -use futures::future::{ready, Ready}; -use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::collections::HashSet; -use std::iter::FromIterator; -use std::marker::PhantomData; -use uuid_b64::UuidB64 as Uuid; - -use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; -use crate::errors::{ResourceAction, ResourceType, ServiceError}; - -// Type aliases for the different JWT tokens -pub type ClientToken = JWTToken; -pub type ServerToken = JWTToken; -pub type CollectorToken = JWTToken; -pub type MediatorToken = JWTToken; -pub type AnyToken = JWTToken; - -/// JSON Web Token used for user authentication -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTToken { - // Reserved Claims - iss: String, // Issuer - sub: Uuid, // Subject (whom token refers to) - aud: String, // Audience (whom the token is intended for) - iat: i64, // Issued at (as UTC timestamp) - exp: i64, // Expiration time (as UTC timestamp) - - // Public and private claims - #[serde(flatten)] - user_data: T, - permissions: HashSet, - - #[serde(skip)] - _aud: PhantomData, -} - -/// Internal data used by the client JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTClientData { - email: String, - name: String, -} - -pub type JWTInternalData = (); - -/// Internal data used by the "Any" JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTAnyData { - email: Option, - name: Option, -} - -impl JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - /// Encode the JSON Web Token into a string - pub fn encode(&self, key: &EncodingKey) -> Result { - Ok(encode(&Header::default(), self, key)?) - } - - pub fn get_user_id(&self) -> Uuid { - self.sub - } - - /// Test if the user has permission to do something - pub fn has_permission(&self, p: Permission) -> bool { - self.permissions.contains(&p) - } - - // - // Methods to test user permissions - // - pub fn test_can_manage_account(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::User, - ResourceAction::Update, - )) - } - } - pub fn test_can_view_elections(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::ReadPrivate, - )) - } - } - - pub fn test_can_create_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Create, - )) - } - } - - pub fn test_can_register_for_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Register, - )) - } - } - - pub fn test_can_vote(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Register, - )) - } - } - - pub fn test_can_view_collectors(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Collector, - ResourceAction::ReadPrivate, - )) - } - } - - pub fn test_can_register_collector(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::ManageCollector) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Collector, - ResourceAction::Create, - )) - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> &String { - &self.user_data.name - } - - pub fn get_email(&self) -> &String { - &self.user_data.email - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn new(permissions: &[Permission]) -> Self { - use uuid::Uuid; - - let now = Utc::now(); - let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); - - Self { - iss: JWT_ISSUER.to_string(), - sub: Uuid::nil().into(), - aud: A::get_name(), - iat: now.timestamp(), - exp: expiration.timestamp(), - - user_data: (), - permissions: HashSet::from_iter(permissions.into_iter().cloned()), - - _aud: PhantomData, - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> Option<&String> { - self.user_data.name.as_ref() - } - - pub fn get_email(&self) -> Option<&String> { - self.user_data.email.as_ref() - } -} - -// -// Get the JSON Web Token from the request -// -impl FromRequest for JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - type Error = ServiceError; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { - let result: Result = (|| { - // Extract the JWT from the header and the encryption key from the app data - let bearer_token = block_on(BearerAuth::from_request(req, pl))?; - let jwt_secret = req.app_data::>().expect("JWTSecret should be set"); - - // Validation parameters, - let validation = Validation { - validate_exp: true, - leeway: 15, - aud: Some(A::accepts()), - iss: Some(JWT_ISSUER.into()), - ..Default::default() - }; - - // Decode and validate the JWT - let token_data = decode::(bearer_token.token(), &jwt_secret.get_decoding_key(), &validation)?; - Ok(token_data.claims) - })(); - - ready(result) - } -} diff --git a/mediator/src/auth/mod.rs b/mediator/src/auth/mod.rs deleted file mode 100644 index 943edd5..0000000 --- a/mediator/src/auth/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -// -// Structures and functions related to user authentication and authorization -// -pub mod audience; -mod constants; -mod jwt_secret; -mod jwt_token; -mod permission; - -pub use audience::Audience; -pub use constants::*; -pub use jwt_secret::JWTSecret; -pub use jwt_token::*; -pub use permission::{Permission, DEFAULT_PERMISSIONS}; diff --git a/mediator/src/auth/permission.rs b/mediator/src/auth/permission.rs deleted file mode 100644 index 924a459..0000000 --- a/mediator/src/auth/permission.rs +++ /dev/null @@ -1,26 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; -use std::fmt; - -pub static DEFAULT_PERMISSIONS: &[Permission] = &[ - Permission::CanLogin, - Permission::CreateElection, - Permission::Register, - Permission::Vote, -]; - -/// List of every permission -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)] -#[repr(u32)] -pub enum Permission { - CanLogin, - CreateElection, - Register, - Vote, - ManageCollector, -} - -impl fmt::Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} diff --git a/mediator/src/db/associations.rs b/mediator/src/db/associations.rs deleted file mode 100644 index 66a47fb..0000000 --- a/mediator/src/db/associations.rs +++ /dev/null @@ -1,916 +0,0 @@ -// ======================= -// Model Base -// ======================= -#[macro_export] -macro_rules! model_base( - () => { - model_base!(no update); - - // Save changes to database - pub fn update( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - self.save_changes::(conn.get()) - } - - // Insert as a new entry, or update the existing entry on conflict - // Uses the primary key to detect duplicate entries - pub fn insert_or_update( - &self, - conn: &crate::db::DbConnection - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict(::table().primary_key()) - .do_update() - .set(self) - .get_result::(conn.get()) - } - }; - - (order by $order:expr) => { - model_base!(); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update, order by $order:expr) => { - model_base!(no update); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update) => { - // Get all - pub fn all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .get_results::(conn.get()) - } - - // Count all users - pub fn count_all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .count().get_result::(conn.get()) - } - - // Find from ID - pub fn find( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - } - - // Find optional from ID - pub fn find_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - .optional() - } - - // Create the new entry in the database - pub fn insert( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .get_result::(conn.get()) - } - - // Insert only if the entry is not in the database - pub fn insert_ignore_conflicts( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict_do_nothing() - .get_result::(conn.get()) - .optional() - } - - // Create multiple entries in the database - pub fn insert_list( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .get_results::(conn.get()) - } - - // Insert a list of values, but ignore duplicate values - pub fn insert_list_ignore_conflicts( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .on_conflict_do_nothing() - .get_results::(conn.get()) - } - - // Test if an item exists in the database - pub fn exists( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional( - <&Self as diesel::associations::Identifiable>::id(&self), - conn, - ).map(|result| result.is_some()) - } - - // Test if an item exists by ID - pub fn exists_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional(id, conn).map(|result| result.is_some()) - } - - // Reload from database - pub fn reload( - &mut self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<()> { - use diesel::prelude::*; - - let new_value = ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get())?; - - *self = new_value; - - Ok(()) - } - - // Reload from database - pub fn reload_new( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get()) - } - - // Delete item in database - pub fn delete( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - .optional() - } - - // Delete item in database - pub fn delete_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_from_id_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - .optional() - } - }; - - (@ order by $order:expr) => { - - // Get all ordered by - pub fn all_ordered( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table().order_by($order) - .get_results::(conn.get()) - } - }; -); - -// ======================= -// Belongs To -// ======================= -#[macro_export] -macro_rules! belongs_to( - ($parent:ident) => { - paste::item! { - belongs_to!($parent, [<$parent:snake>]); - } - }; - - ($parent:ident, $func_base:ident) => { - belongs_to!(@ crate::models::$parent, $func_base); - }; - - (@ $parent:path, $func_base:ident) => { - // Get parent - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - } - - // Get parent optional - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Ok(None), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - .optional() - } - } - } - } - }; -); - -// ======================= -// Has One -// ======================= -#[macro_export] -macro_rules! has_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ).get_result::<$child>(conn.get()) - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_result::<$child>(conn.get()) - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::(conn.get()) - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::(conn.get()) - } - } - }; -); - -// ======================= -// Has Zero or One -// ======================= -#[macro_export] -macro_rules! has_zero_or_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_zero_or_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_zero_or_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - }; -); - -// ======================= -// Has Many -// ======================= -#[macro_export] -macro_rules! has_many( - // Pluralize - ($child:ident) => { - paste::item! { - has_many!($child, [<$child:snake s>]); - } - }; - - ($child:ident, order by $order:expr) => { - paste::item! { - has_many!($child, order by $order, [<$child:snake s>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - }; - - ($child:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - paste::item! { - has_many!(@ crate::models::$child, order by crate::schema::$order, $func_base); - } - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_results::<$child>(conn.get()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - $child::belonging_to(self).count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).count().get_result::(conn.get()) - } - } - - // Delete all children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_results::<$child>(conn.get()) - } - } - - // Delete all children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_results::<$child>(conn.get()) - } - } - }; - - // Has many ordered - (@ $child:path, order by $order:expr, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).order_by($order).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .order_by($order) - .get_results::<$child>(conn.get()) - } - } - }; - - - // ======================= - // Has Many Through - // (Special case) - // ======================= - ($child:ident through $through:ident) => ( - paste::item! { - has_many!($child through $through, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, order by $order:expr) => ( - paste::item! { - has_many!($child through $through, order by $order, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - }; - - ($child:ident through $through:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - paste::item! { - has_many!(@ crate::models::$child => crate::models::$through, order by crate::schema::$order, $func_base); - } - }; - - (@ $child:path => $through:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .count().get_result::(conn.get()) - } - } - - // Delete children from many-to-many the association - // Does NOT delete the actual values - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Delete children from many-to-many the association by the ID - // Does NOT delete the actual values - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Set children - paste::item! { - pub fn []<'a>( - &self, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children Ids - paste::item! { - pub fn []<'a>( - &self, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](id, ids_list, conn) - } - } - - // Set all IDs from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](id, conn)?; - - let new_entries: Vec<$through> = ids_list - .into_iter() - .map(|item| <$through as crate::db::ManyToManyConstructor>::new(id, item)) - .collect(); - - Ok($through::insert_list(&new_entries, conn)?) - } - } - }; - - (@ $child:path => $through:path, order by $order:expr, $func_base:ident) => { - // Get children ordered - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get ordered children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - }; -); diff --git a/mediator/src/db/db_connection.rs b/mediator/src/db/db_connection.rs deleted file mode 100644 index 26bbc4f..0000000 --- a/mediator/src/db/db_connection.rs +++ /dev/null @@ -1,77 +0,0 @@ -use actix_web::{dev::Payload, web, Error, FromRequest, HttpRequest}; -use diesel::pg::PgConnection; -use futures::future::{ready, Ready}; -use std::ops::{Deref, DerefMut}; - -use crate::db::{PgPool, PgPooledConnection}; -use crate::errors::ServiceError; - -pub enum DbConnection { - UnpooledConnection(PgConnection), - PooledConnection(PgPooledConnection), -} - -// -// Explicit extraction calls for when compiler can't implicitly convert -// -impl DbConnection { - pub fn new(conn: PgConnection) -> Self { - DbConnection::UnpooledConnection(conn) - } - pub fn new_pooled(conn: PgPooledConnection) -> Self { - DbConnection::PooledConnection(conn) - } - - pub fn get(&self) -> &PgConnection { - match self { - DbConnection::PooledConnection(pool) => &pool, - DbConnection::UnpooledConnection(conn) => &conn, - } - } - - pub fn get_mut(&mut self) -> &mut PgConnection { - match self { - DbConnection::PooledConnection(ref mut pool) => pool, - DbConnection::UnpooledConnection(ref mut conn) => conn, - } - } -} - -// -// Implicitly convert to the database connection type -// -impl Deref for DbConnection { - type Target = PgConnection; - fn deref(&self) -> &Self::Target { - self.get() - } -} - -impl DerefMut for DbConnection { - fn deref_mut(&mut self) -> &mut Self::Target { - self.get_mut() - } -} - -// -// Get the database connection from the request -// -impl FromRequest for DbConnection { - type Error = Error; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, _pl: &mut Payload) -> Self::Future { - let res = get_connection_from_request(req); - ready(res.map_err(|e| e.into())) - } -} - -pub fn get_connection_from_request(req: &HttpRequest) -> Result { - let pool = req - .app_data::>() - .ok_or(ServiceError::MissingAppData("PgPool".into()))?; - - let conn = pool.get()?; - Ok(DbConnection::new_pooled(conn)) -} diff --git a/mediator/src/db/init.rs b/mediator/src/db/init.rs deleted file mode 100644 index 51a67d6..0000000 --- a/mediator/src/db/init.rs +++ /dev/null @@ -1,24 +0,0 @@ -use diesel::r2d2::{ConnectionManager, Pool, PoolError}; -use diesel::{pg::PgConnection, Connection}; - -use crate::config; -use crate::db::{DbConnection, PgPool}; - -pub fn establish_new_connection_pool() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(init_pool(&database_url)?) -} - -fn init_pool(database_url: &str) -> Result { - let manager = ConnectionManager::::new(database_url); - Pool::builder().build(manager) -} - -pub fn open_new_connection() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(DbConnection::new(PgConnection::establish(&database_url)?)) -} diff --git a/mediator/src/db/many_many_constructor.rs b/mediator/src/db/many_many_constructor.rs deleted file mode 100644 index b774e0c..0000000 --- a/mediator/src/db/many_many_constructor.rs +++ /dev/null @@ -1,6 +0,0 @@ -use diesel::associations::BelongsTo; - -/// Trait that must be implemented to construct a many-to-many relationship -pub trait ManyToManyConstructor: BelongsTo + BelongsTo { - fn new(left: &>::ForeignKey, right: &>::ForeignKey) -> Self; -} diff --git a/mediator/src/db/mod.rs b/mediator/src/db/mod.rs deleted file mode 100644 index 4f1818a..0000000 --- a/mediator/src/db/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -// Database-specific objects and actions -// -mod db_connection; -mod init; -mod many_many_constructor; -mod types; - -#[macro_use] -mod sql_enum; -#[macro_use] -mod associations; -#[macro_use] -mod subtypes; - -pub use db_connection::{get_connection_from_request, DbConnection}; -pub use init::{establish_new_connection_pool, open_new_connection}; -pub use many_many_constructor::ManyToManyConstructor; -pub use types::{PgPool, PgPooledConnection}; diff --git a/mediator/src/db/sql_enum.rs b/mediator/src/db/sql_enum.rs deleted file mode 100644 index fe43487..0000000 --- a/mediator/src/db/sql_enum.rs +++ /dev/null @@ -1,54 +0,0 @@ -#[macro_export] -macro_rules! sql_enum { - ($v:vis $name:ident $type:tt) => { - #[repr(i32)] - #[derive( - Debug, Copy, Clone, Eq, PartialEq, Hash, - serde_repr::Serialize_repr, serde_repr::Deserialize_repr, - FromSqlRow, FromPrimitive, AsExpression, - )] - #[sql_type = "Integer"] - $v enum $name $type - enum_internals!($name); - }; -} - -#[allow(unused)] -macro_rules! enum_internals { - ($($t:ty)*) => ($( - - // Required packages - use diesel::{ - backend::Backend, - deserialize::{self, FromSql}, - serialize::{self, Output, ToSql}, - sql_types::Integer, - }; - use std::io::Write; - - // Convert to SQL - impl ToSql for $t - where - DB: Backend, - i32: ToSql, - { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - (*self as i32).to_sql(out) - } - } - - // Convert from SQL - impl FromSql for $t - where - DB: Backend, - i32: FromSql, - { - fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result { - let number = i32::from_sql(bytes)?; - num::FromPrimitive::from_i32(number).ok_or_else( - || format!("diesel::deserialize::FromSql for {} --- Invalid variant index {}", stringify!($t), number).into() - ) - } - } - )*) -} diff --git a/mediator/src/db/subtypes.rs b/mediator/src/db/subtypes.rs deleted file mode 100644 index 13d3724..0000000 --- a/mediator/src/db/subtypes.rs +++ /dev/null @@ -1,71 +0,0 @@ -// ======================= -// Parent Type -// ======================= -#[macro_export] -macro_rules! parent_type( - ($discriminant:ty = $from_value:expr) => { - paste::item! { - parent_type!($discriminant = $from_value, [<$discriminant:snake>]); - } - }; - - ($discriminant:ty = $from_value:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - self.$from_value - } - } - }; -); - -// ======================= -// Child Type -// ======================= -#[macro_export] -macro_rules! child_type( - ($parent:ty, $discriminant:ty = $value:expr) => { - paste::item! { - child_type!($parent, $discriminant = $value, [<$discriminant:snake>]); - } - }; - - ($parent:ty, $discriminant:ty = $from:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - $from - } - } - - pub fn get_parent( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - - pub fn get_parent_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - }; -); diff --git a/mediator/src/db/types.rs b/mediator/src/db/types.rs deleted file mode 100644 index 5976a70..0000000 --- a/mediator/src/db/types.rs +++ /dev/null @@ -1,5 +0,0 @@ -use diesel::pg::PgConnection; -use diesel::r2d2::{ConnectionManager, Pool, PooledConnection}; - -pub type PgPool = Pool>; -pub type PgPooledConnection = PooledConnection>; diff --git a/mediator/src/errors/client_request_error.rs b/mediator/src/errors/client_request_error.rs deleted file mode 100644 index 5c62f49..0000000 --- a/mediator/src/errors/client_request_error.rs +++ /dev/null @@ -1,73 +0,0 @@ -use actix_http::{encoding::Decoder, Payload, PayloadStream}; -use awc::error::{JsonPayloadError, SendRequestError}; -use awc::http::StatusCode; -use awc::ClientResponse; -use serde::de::DeserializeOwned; -use std::future::Future; - -use crate::errors::ErrorResponse; - -/// Enum with all of the things that can go wrong when making a client request -#[derive(Debug)] -pub enum ClientRequestError { - SendError(SendRequestError), - ResponseError(ErrorResponse), - JSONError(JsonPayloadError), - UnknownError(StatusCode), -} - -impl ClientRequestError { - /// Handle the response from a client and parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle( - input: impl Future>>, SendRequestError>>, - ) -> Result { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Try to deserialize the data if the request is ok - let status = response.status(); - if response.status() == StatusCode::OK { - return response.json::().await.map_err(|e| Self::JSONError(e)); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } - - /// Handle the response from a client, but don't parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle_empty( - input: impl Future>>, SendRequestError>>, - ) -> Result<(), Self> { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Make sure the request is okay - let status = response.status(); - if response.status() == StatusCode::OK { - return Ok(()); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } -} diff --git a/mediator/src/errors/error_response.rs b/mediator/src/errors/error_response.rs deleted file mode 100644 index 25c48dc..0000000 --- a/mediator/src/errors/error_response.rs +++ /dev/null @@ -1,71 +0,0 @@ -use actix_web::{http::StatusCode, HttpResponse, ResponseError}; -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt; - -use crate::errors::GlobalErrorCode; - -/// JSON response returned to the frontend on an error -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ErrorResponse { - #[serde( - serialize_with = "serialize_status_code", - deserialize_with = "deserialize_status_code" - )] - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - - // Don't serialize on production system - #[cfg_attr(not(debug_assertions), serde(skip_serializing))] - #[serde(skip_serializing_if = "Option::is_none")] - developer_notes: Option, -} - -fn serialize_status_code(code: &StatusCode, serializer: S) -> Result -where - S: Serializer, -{ - serializer.serialize_u16(code.as_u16()) -} - -fn deserialize_status_code<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let integer: u16 = Deserialize::deserialize(deserializer)?; - StatusCode::from_u16(integer).map_err(D::Error::custom) -} - -impl ErrorResponse { - pub fn new( - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - developer_notes: String, - ) -> Self { - ErrorResponse { - status_code, - description, - error_code, - developer_notes: Some(developer_notes), - } - } -} - -impl fmt::Display for ErrorResponse { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(#{:?}): {}", self.error_code, self.description)?; - if let Some(ref notes) = self.developer_notes { - write!(f, "\nDeveloper Notes: {}", notes)?; - } - Ok(()) - } -} - -impl ResponseError for ErrorResponse { - fn error_response(&self) -> HttpResponse { - HttpResponse::build(self.status_code).json(&self) - } -} diff --git a/mediator/src/errors/global_error_codes.rs b/mediator/src/errors/global_error_codes.rs deleted file mode 100644 index 56f6e2c..0000000 --- a/mediator/src/errors/global_error_codes.rs +++ /dev/null @@ -1,46 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; - -/// Error codes that are exposed on the frontend -#[derive(Serialize_repr, Deserialize_repr, Debug)] -#[repr(u32)] -pub enum GlobalErrorCode { - UnknownError = 0, - DatabaseConnectionError, - DatabaseQueryError, - MissingAppData, - JSONPayloadError, - FormPayloadError, - URLPathError, - QueryStringError, - StructValidationError, - InvalidEmailPassword, - InvalidJWTToken, - UserEmailExists, - PasswordComplexityError, - RecaptchaError, - ForbiddenResourceAction, - NoSuchResource, - ElectionNotOwnedByUser, - ElectionNotDraft, - WrongElectionStatus, - AccessCodeNotFound, - NotRegistered, - AlreadyRegistered, - RegistrationClosed, - NotEnoughRegistered, - ElectionNotInitialized, - MediatorURLNotSet, - RegisterElectionError, - VerificationError, - AlreadyVoted, - VerifyVoteError, - VoteInvalid, - NotOpenForVoting, - NotEnoughVotes, - CancelationSharesError, - ElectionNotStarted, - NoNotifyPermission, - NoSubscribePermission, - NotificationError, - InvalidCollectorURI, -} diff --git a/mediator/src/errors/mod.rs b/mediator/src/errors/mod.rs index af80390..eb56f16 100644 --- a/mediator/src/errors/mod.rs +++ b/mediator/src/errors/mod.rs @@ -1,20 +1,13 @@ // // All code related to error handling for the API server // -mod client_request_error; -mod error_response; -mod global_error_codes; mod named_resource_type; mod resource_action; mod resource_type; mod service_error; -mod websocket_error; -pub use client_request_error::ClientRequestError; -pub use error_response::ErrorResponse; -pub use global_error_codes::GlobalErrorCode; +pub use evoting_shared::errors::*; // Re-export pub use named_resource_type::NamedResourceType; pub use resource_action::ResourceAction; pub use resource_type::ResourceType; pub use service_error::ServiceError; -pub use websocket_error::WebsocketError; diff --git a/mediator/src/errors/named_resource_type.rs b/mediator/src/errors/named_resource_type.rs index ee62e73..a8ef078 100644 --- a/mediator/src/errors/named_resource_type.rs +++ b/mediator/src/errors/named_resource_type.rs @@ -61,7 +61,7 @@ impl fmt::Display for NamedResourceType { NamedResourceType::Election { id } => write!(f, "{} (ID: {})", self.get_name(), id), NamedResourceType::Question { id, election_id } => { write!(f, "{} (ID: {}, Election ID: {})", self.get_name(), id, election_id) - } + }, NamedResourceType::Registration { user_id, election_id } => { write!( f, @@ -70,7 +70,7 @@ impl fmt::Display for NamedResourceType { user_id, election_id ) - } + }, } } } diff --git a/mediator/src/errors/websocket_error.rs b/mediator/src/errors/websocket_error.rs deleted file mode 100644 index 3b7b9c3..0000000 --- a/mediator/src/errors/websocket_error.rs +++ /dev/null @@ -1,96 +0,0 @@ -use actix_codec::Framed; -use awc::error::{WsClientError, WsProtocolError}; -use awc::http::StatusCode; -use awc::ws::{CloseCode, Codec, Frame, Message, WebsocketsRequest}; -use awc::BoxedSocket; -use futures::{sink::SinkExt, stream::StreamExt}; -use serde::{de::DeserializeOwned, Serialize}; - -use crate::errors::ErrorResponse; - -/// Handles any errors related to websockets -#[derive(Debug)] -pub enum WebsocketError { - RequestError(actix_web::Error), - ClientError(WsClientError), - ProtocolError(WsProtocolError), - JSONError(serde_json::Error), - UnexpectedFrame(Frame), - WebsocketClosed, - ResponseError(ErrorResponse), - UnknownError(StatusCode), -} - -impl WebsocketError { - /// Attempts to connect to the websocket - /// Returns the stream on success or an error - pub async fn connect(input: WebsocketsRequest) -> Result, Self> { - let (mut response, stream) = match input.connect().await { - Err(e) => return Err(Self::ClientError(e)), - Ok(resp) => resp, - }; - - // Try to deserialize the data if the request is ok - let status = response.status(); - if response.status() == StatusCode::SWITCHING_PROTOCOLS { - return Ok(stream); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - - /// Serialize and send JSON data through the steam - pub async fn send_json(stream: &mut Framed, data: &T) -> Result<(), Self> { - let json_string = serde_json::to_string(data).map_err(|e| Self::JSONError(e))?; - stream - .send(Message::Text(json_string)) - .await - .map_err(|e| Self::ProtocolError(e)) - } - - /// Attempts to read the next websocket packet as a JSON data structure. - /// Returns the data on success or closes the connection on error - pub async fn read_json(stream: &mut Framed) -> Result { - // Read the next frame, closing the connection on any errors - let frame = match stream.next().await { - None => return Err(Self::WebsocketClosed), - Some(Err(e)) => { - stream - .send(Message::Close(Some((CloseCode::Error, format!("{}", e)).into()))) - .await - .map_err(|e| Self::ProtocolError(e))?; - - return Err(Self::ProtocolError(e)); - } - Some(Ok(resp)) => resp, - }; - - // Make sure the frame is text - let text = match frame { - Frame::Text(text) => text, - other => return Err(Self::UnexpectedFrame(other)), - }; - - // Parse the JSON - serde_json::from_slice::(text.as_ref()).map_err(|e| Self::JSONError(e)) - } -} - -impl From for WebsocketError { - fn from(error: actix_web::Error) -> Self { - WebsocketError::RequestError(error) - } -} - -impl From for WebsocketError { - fn from(error: WsClientError) -> Self { - WebsocketError::ClientError(error) - } -} diff --git a/mediator/src/handlers/auth/get_me.rs b/mediator/src/handlers/auth/get_me.rs index 8323943..a2c8240 100644 --- a/mediator/src/handlers/auth/get_me.rs +++ b/mediator/src/handlers/auth/get_me.rs @@ -1,6 +1,6 @@ use actix_web::HttpResponse; -use crate::auth::AnyToken; +use crate::jwt::AnyToken; use crate::views::auth::UserDetails; pub async fn get_me(token: AnyToken) -> HttpResponse { diff --git a/mediator/src/handlers/collector/all_collectors.rs b/mediator/src/handlers/collector/all_collectors.rs index 5697104..394ca78 100644 --- a/mediator/src/handlers/collector/all_collectors.rs +++ b/mediator/src/handlers/collector/all_collectors.rs @@ -1,8 +1,8 @@ use actix_web::HttpResponse; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Collector; use crate::views::collector::PublicCollectorList; diff --git a/mediator/src/handlers/collector/create_or_update_collector.rs b/mediator/src/handlers/collector/create_or_update_collector.rs index 90aa7cb..6ee37fe 100644 --- a/mediator/src/handlers/collector/create_or_update_collector.rs +++ b/mediator/src/handlers/collector/create_or_update_collector.rs @@ -4,9 +4,9 @@ use serde::Deserialize; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::{CollectorToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{CollectorToken, HasPermission, JWTSecret}; use crate::models::Collector; use crate::notifications::notify_collector_created_or_updated; diff --git a/mediator/src/handlers/collector/get_collector.rs b/mediator/src/handlers/collector/get_collector.rs index d754555..3f02e72 100644 --- a/mediator/src/handlers/collector/get_collector.rs +++ b/mediator/src/handlers/collector/get_collector.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Collector; use crate::views::collector::PublicCollector; diff --git a/mediator/src/handlers/collector/update_collector.rs b/mediator/src/handlers/collector/update_collector.rs index 59df723..1e2496a 100644 --- a/mediator/src/handlers/collector/update_collector.rs +++ b/mediator/src/handlers/collector/update_collector.rs @@ -4,9 +4,9 @@ use serde::Deserialize; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::CollectorToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{CollectorToken, HasPermission}; use crate::models::Collector; #[derive(Deserialize, Validate)] diff --git a/mediator/src/handlers/election/create_and_initialize_election.rs b/mediator/src/handlers/election/create_and_initialize_election.rs index c1c360a..fc5b679 100644 --- a/mediator/src/handlers/election/create_and_initialize_election.rs +++ b/mediator/src/handlers/election/create_and_initialize_election.rs @@ -8,9 +8,9 @@ use serde::{Deserialize, Serialize}; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::{JWTSecret, MediatorToken, ServerToken, DEFAULT_PERMISSIONS}; use crate::db::DbConnection; use crate::errors::{ClientRequestError, ServiceError}; +use crate::jwt::{HasPermission, JWTSecret, MediatorToken, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Collector, Election, ElectionCollector, Question, Registration}; use crate::protocol::location_anonymization as loc_anon; use crate::views::election::InitializeElectionResult; diff --git a/mediator/src/handlers/election/get_cancelation_shares.rs b/mediator/src/handlers/election/get_cancelation_shares.rs index 0a2f2d5..e292edf 100644 --- a/mediator/src/handlers/election/get_cancelation_shares.rs +++ b/mediator/src/handlers/election/get_cancelation_shares.rs @@ -7,9 +7,9 @@ use serde::{Deserialize, Serialize}; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::{JWTSecret, MediatorToken, ServerToken, DEFAULT_PERMISSIONS}; use crate::db::DbConnection; use crate::errors::{ClientRequestError, ServiceError}; +use crate::jwt::{HasPermission, JWTSecret, MediatorToken, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Collector, Election}; use crate::utils::ConvertBigInt; use crate::views::election::CancelationShares; diff --git a/mediator/src/handlers/election/get_election_collectors.rs b/mediator/src/handlers/election/get_election_collectors.rs index 1b87e16..07b0fe6 100644 --- a/mediator/src/handlers/election/get_election_collectors.rs +++ b/mediator/src/handlers/election/get_election_collectors.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::{NamedResourceType, ServiceError}; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Election; use crate::views::collector::PublicCollectorList; diff --git a/mediator/src/handlers/verification/mediator_actor.rs b/mediator/src/handlers/verification/mediator_actor.rs index 7d88fc8..9b44313 100644 --- a/mediator/src/handlers/verification/mediator_actor.rs +++ b/mediator/src/handlers/verification/mediator_actor.rs @@ -308,7 +308,7 @@ impl StreamHandler<(usize, Result)> for MediatorActo log::info!("Received close message, closing all websockets ... ({:#?})", reason); (0..self.num_collectors).for_each(|index| self.close(index, reason.clone())); return ctx.stop(); - } + }, // Parse JSON message ws::Frame::Text(text) => match serde_json::from_slice::(text.as_ref()) { @@ -335,22 +335,22 @@ impl StreamHandler<(usize, Result)> for MediatorActo if self.verify_origin(&data, collector_index, ctx) && self.verify_signature(&data, ctx) { self_addr.do_send(data); } - } + }, WebsocketMessage::SP2_Result_Response(data) => { if self.verify_origin(&data, collector_index, ctx) && self.verify_signature(&data, ctx) { self_addr.do_send(data) } - } + }, WebsocketMessage::UnicastMessage(data) => { if self.verify_origin(&data, collector_index, ctx) { self_addr.do_send(data) } - } + }, WebsocketMessage::BroadcastMessage(data) => { if self.verify_origin(&data, collector_index, ctx) { self_addr.do_send(data) } - } + }, } } diff --git a/mediator/src/handlers/verification/verify_ballot.rs b/mediator/src/handlers/verification/verify_ballot.rs index b8bee27..2bac05d 100644 --- a/mediator/src/handlers/verification/verify_ballot.rs +++ b/mediator/src/handlers/verification/verify_ballot.rs @@ -7,9 +7,9 @@ use validator::Validate; use super::mediator_actor::MediatorActor; use super::types::VerifyBallotData; -use crate::auth::{AnyToken, JWTSecret, MediatorToken, DEFAULT_PERMISSIONS}; use crate::db::DbConnection; use crate::errors::{NamedResourceType, ServiceError, WebsocketError}; +use crate::jwt::{AnyToken, HasPermission, JWTSecret, MediatorToken, DEFAULT_PERMISSIONS}; use crate::models::{Election, Question}; use crate::views::verification::VerificationResult; diff --git a/mediator/src/jwt/has_permission.rs b/mediator/src/jwt/has_permission.rs new file mode 100644 index 0000000..58c4389 --- /dev/null +++ b/mediator/src/jwt/has_permission.rs @@ -0,0 +1,93 @@ +use crate::errors::{ResourceAction, ResourceType, ServiceError}; +use crate::jwt::{Audience, JWTToken, Permission}; + +/// Helper trait that exposes methods for checking specific permissions +pub trait HasPermission { + /// Test if the user has permission to do something + fn has_permission(&self, p: Permission) -> bool; + + // =================================== + // Methods to test user permissions + // =================================== + fn test_can_manage_account(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::User, + ResourceAction::Update, + )) + } + } + fn test_can_view_elections(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::ReadPrivate, + )) + } + } + + fn test_can_create_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Create, + )) + } + } + + fn test_can_register_for_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Register, + )) + } + } + + fn test_can_vote(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Register, + )) + } + } + + fn test_can_view_collectors(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Collector, + ResourceAction::ReadPrivate, + )) + } + } + + fn test_can_register_collector(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::ManageCollector) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Collector, + ResourceAction::Create, + )) + } + } +} + +impl HasPermission for JWTToken { + fn has_permission(&self, p: Permission) -> bool { + self.test_has_permission(p) + } +} diff --git a/mediator/src/jwt/mod.rs b/mediator/src/jwt/mod.rs new file mode 100644 index 0000000..3e9f742 --- /dev/null +++ b/mediator/src/jwt/mod.rs @@ -0,0 +1,7 @@ +// +// Structures and functions related to JSON web tokens +// +mod has_permission; + +pub use evoting_shared::jwt::*; // Re-export +pub use has_permission::HasPermission; diff --git a/mediator/src/lib.rs b/mediator/src/lib.rs index 79550d7..b1703cb 100644 --- a/mediator/src/lib.rs +++ b/mediator/src/lib.rs @@ -4,17 +4,26 @@ extern crate diesel; #[allow(unused)] #[macro_use] extern crate num_derive; +#[macro_use] +extern crate evoting_shared; // All internal code modules -pub mod auth; pub mod config; -#[macro_use] -pub mod db; pub mod errors; pub mod handlers; +pub mod jwt; pub mod models; pub mod notifications; -pub mod protocol; pub mod schema; -pub mod utils; pub mod views; + +// Re-export modules from the shared library +pub mod db { + pub use evoting_shared::db::*; +} +pub mod protocol { + pub use evoting_shared::protocol::*; +} +pub mod utils { + pub use evoting_shared::utils::*; +} diff --git a/mediator/src/main.rs b/mediator/src/main.rs index 9334389..8c6680a 100644 --- a/mediator/src/main.rs +++ b/mediator/src/main.rs @@ -4,11 +4,11 @@ use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; use simple_logger::SimpleLogger; use structopt::StructOpt; -use evoting_mediator::auth; use evoting_mediator::config; use evoting_mediator::db; use evoting_mediator::errors::ServiceError; use evoting_mediator::handlers; +use evoting_mediator::jwt; #[actix_web::main] async fn main() -> anyhow::Result<()> { @@ -26,14 +26,18 @@ async fn main() -> anyhow::Result<()> { log::set_max_level(LevelFilter::Info); } - // Database connection pool and web server - let connection_pool = db::establish_new_connection_pool()?; + // Database connection pool + let database_url = + config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; + let connection_pool = db::open_new_connection_pool(&database_url)?; + + // Build the web server let mut server = HttpServer::new(move || { App::new() // Connect to database .data(connection_pool.clone()) // Encryption secret for JSON Web Token - .data(auth::JWTSecret::new(config::get_jwt_secret())) + .data(jwt::JWTSecret::new(config::get_jwt_secret())) // Enable logger .wrap(middleware::Logger::default()) // Configure error handlers diff --git a/mediator/src/notifications/send.rs b/mediator/src/notifications/send.rs index c973fa7..4de09b0 100644 --- a/mediator/src/notifications/send.rs +++ b/mediator/src/notifications/send.rs @@ -1,8 +1,8 @@ use actix_web::client::Client; -use crate::auth::{JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::config; use crate::errors::ClientRequestError; +use crate::jwt::{JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::Collector; use crate::notifications::{mediator_types, AllMediatorMessages}; diff --git a/mediator/src/protocol/location_anonymization.rs b/mediator/src/protocol/location_anonymization.rs deleted file mode 100644 index b1e46a2..0000000 --- a/mediator/src/protocol/location_anonymization.rs +++ /dev/null @@ -1,65 +0,0 @@ -use curv_kzen::arithmetic::{Modulo, Samplable}; -use kzen_paillier::*; - -/// First step of the location anonymization scheme -/// C1 computes e_x1 = E(x1) and sends it to C2 -/// -/// location = Secret location (0 <= location <= n - 1) -/// n = Public key for Paillier cryptosystem -/// -/// Returns e_x1 -pub fn step_1(location: &BigInt, n: &BigInt) -> BigInt { - // Compute E(x1) - let ek = EncryptionKey::from(n); - let e_x1: RawCiphertext = Paillier::encrypt(&ek, location.into()); - e_x1.0.into_owned() -} - -/// ith step of the location anonymization scheme: (Collectors C2 to C{n-1}) -/// Ci picks random ri with 0 <= ri < n -/// Ci computes e_xi = (e_x1 * ... * e_x{i-1}) * (E(ri)^(-1)) (mod n^2) and sends it to C{i+1} -/// -/// e_xi_1 = (e_x1 * ... * e_x{i-1}) -/// n = Public key for paillier cryptosystem -/// -/// Returns (ri, e_xi) -pub fn step_ith(e_xi_1: &BigInt, n: &BigInt) -> (BigInt, BigInt) { - // Pick random ri with 0 <= ri < n - let ri = BigInt::sample_below(n); - - // Compute E(r2) - let ek = EncryptionKey::from(n); - let e_ri: RawCiphertext = Paillier::encrypt(&ek, ri.clone().into()); - - // Compute (e_xi_1) * (E(ri)^(-1)) (mod n^2) - // Every encrypted r value should be invertible, so we should never panic when finding inverse - let e_xi = BigInt::mod_mul( - &e_xi_1, - &BigInt::mod_inv(&e_ri.0, &ek.nn).expect("Error: No Inverse"), - &ek.nn, - ); - - (ri, e_xi) -} - -/// Last step of the location anonymization scheme: -/// C1 decrypts D(e_x{n-1}), resulting in r1 -/// -/// The parties now have values: r1 + r2 + ... + rn (mod n) = x1 (mod n^2) -/// -/// e_xn_1 = (e_x1 * ... * e_x{n-1}) -/// p, q = Private key for Paillier cryptosystem -/// -/// Returns r1 -pub fn step_last(e_xn_1: &BigInt, p: &BigInt, q: &BigInt) -> BigInt { - let e_xn_1 = RawCiphertext::from(e_xn_1); - - // Compute r1 = D(e_x2) - let dk = DecryptionKey { - p: p.clone(), - q: q.clone(), - }; - let r1: RawPlaintext = Paillier::decrypt(&dk, e_xn_1); - - r1.0.into_owned() -} diff --git a/mediator/src/protocol/mod.rs b/mediator/src/protocol/mod.rs deleted file mode 100644 index 02dab4c..0000000 --- a/mediator/src/protocol/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -// -// Functions and structures related to the math behind the e-voting protocol -// -pub mod location_anonymization; -pub mod stpm; diff --git a/mediator/src/protocol/stpm.rs b/mediator/src/protocol/stpm.rs deleted file mode 100644 index 3504a3a..0000000 --- a/mediator/src/protocol/stpm.rs +++ /dev/null @@ -1,91 +0,0 @@ -use curv_kzen::arithmetic::{Modulo, Samplable}; -use kzen_paillier::*; - -/// First step of the STPM: -/// C1 computes e_x1 = E(x1) and sends it to C2 -/// -/// x1 = First number being multiplied -/// n = Public key for Paillier cryptosystem -/// -/// Returns e_x1 -pub fn step_1(x1: &BigInt, n: &BigInt) -> BigInt { - // Compute E(x1) - let ek = EncryptionKey::from(n); - let e_x1: RawCiphertext = Paillier::encrypt(&ek, x1.into()); - e_x1.0.into_owned() -} - -/// Second step of the STPM: -/// C2 picks random r2 with 0 <= r2 < n -/// C2 computes e_x2 = ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) and sends it to C1 -/// -/// e_x1 = E(x1) -/// x2 = Second number being multiplied -/// n = Public key for paillier cryptosystem -/// -/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus -/// This means that r1 (or r2) may be negative -/// -/// Returns (r2, e_x2) -pub fn step_2(e_x1: &BigInt, x2: &BigInt, n: &BigInt, normalize: bool) -> (BigInt, BigInt) { - // Pick random r2 with 0 <= r2 < n - let mut r2 = BigInt::sample_below(n); - - // Compute E(r2) - let ek = EncryptionKey::from(n); - let e_r2: RawCiphertext = Paillier::encrypt(&ek, r2.clone().into()); - - // Compute ((e_x1)^x2) * (E(r2)^(-1)) (mod n^2) - // Every encrypted r value should be invertible, so we should never panic when finding inverse - let e_x2 = BigInt::mod_mul( - &BigInt::mod_pow(e_x1, &x2, &ek.nn), - &BigInt::mod_inv(&e_r2.0, &ek.nn).expect("Error: No Inverse"), - &ek.nn, - ); - - // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus - // - // So, if 2*r2 > n, then r2 = r2 - n - // -This will be a negative number - if normalize && (&(2 * &r2) >= &n) { - r2 = &r2 - n; - } - - (r2, e_x2) -} - -/// Last step of the STPM: -/// C1 decrypts D(e_x2), resulting in r1 -/// -/// The two parties now have values: r1 + r2 (mod n) = x1 * x2 (mod n^2) -/// If the "normalize" flag was set to true, then r1 + r2 = x1 * x2 with NO modulus -/// -/// e_x2 = (E(x1)^x2) * (E(r2)^(-1)) (mod n^2) -- From previous step -/// p, q = Private key for Paillier cryptosystem -/// -/// normalize = If true, then finds r1 + r2 = x1 * x2 with NO modulus -/// This means that r1 (or r2) may be negative -/// -/// Returns r1 -pub fn step_3(e_x2: &BigInt, p: &BigInt, q: &BigInt, normalize: bool) -> BigInt { - let e_x2 = RawCiphertext::from(e_x2); - - // Compute r1 = D(e_x2) - let dk = DecryptionKey { - p: p.clone(), - q: q.clone(), - }; - let r1: RawPlaintext = Paillier::decrypt(&dk, e_x2); - - // If the "normalize" flag is set, then r1 + r2 = x1 * x2 with NO modulus - // - // So, if 2*r1 > n, then r1 = r1 - n - // -This will be a negative number - let n = p * q; - let mut r1 = r1.0.into_owned(); - if normalize && (&(2 * &r1) >= &n) { - r1 = &r1 - &n; - } - - r1 -} diff --git a/mediator/src/schema.rs b/mediator/src/schema.rs index f07f477..ace515a 100644 --- a/mediator/src/schema.rs +++ b/mediator/src/schema.rs @@ -43,10 +43,4 @@ joinable!(election_collectors -> elections (election_id)); joinable!(questions -> elections (election_id)); joinable!(registrations -> elections (election_id)); -allow_tables_to_appear_in_same_query!( - collectors, - election_collectors, - elections, - questions, - registrations, -); +allow_tables_to_appear_in_same_query!(collectors, election_collectors, elections, questions, registrations,); diff --git a/mediator/src/utils/convert_bigint.rs b/mediator/src/utils/convert_bigint.rs deleted file mode 100644 index 547469c..0000000 --- a/mediator/src/utils/convert_bigint.rs +++ /dev/null @@ -1,83 +0,0 @@ -use bigdecimal::BigDecimal; -use curv_kzen::arithmetic::{BigInt, Converter, NumberTests}; -use num::bigint::{BigInt as NumBigInt, Sign}; - -/// -/// Trait used to simplify converting between BigInt and BigDecimal -/// -pub trait ConvertBigInt { - fn to_bigint(&self) -> BigInt; - fn to_bigdecimal(&self) -> BigDecimal; - - fn from_bigint(bigint: BigInt) -> Self; - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self; -} - -impl ConvertBigInt for BigInt { - fn to_bigint(&self) -> BigInt { - self.clone() - } - - fn to_bigdecimal(&self) -> BigDecimal { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(self), &self.to_bytes()), 0) - } - - fn from_bigint(bigint: BigInt) -> Self { - bigint - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - let (bigint, _exponent) = bigdecimal.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } -} - -impl ConvertBigInt for BigDecimal { - fn to_bigint(&self) -> BigInt { - let (bigint, _exponent) = self.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } - - fn to_bigdecimal(&self) -> BigDecimal { - self.clone() - } - - fn from_bigint(bigint: BigInt) -> Self { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(&bigint), &bigint.to_bytes()), 0) - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - bigdecimal - } -} - -/// -/// Figure out the sign of the input BigInt -/// -fn get_sign(input: &BigInt) -> Sign { - if BigInt::is_zero(input) { - return Sign::NoSign; - } - - if BigInt::is_negative(input) { - Sign::Minus - } else { - Sign::Plus - } -} diff --git a/mediator/src/utils/mod.rs b/mediator/src/utils/mod.rs deleted file mode 100644 index b319ea1..0000000 --- a/mediator/src/utils/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// -// General-purpose functions and objects -// -mod convert_bigint; -pub mod serialize_option_bigint; -pub mod serialize_option_uri; - -pub use convert_bigint::ConvertBigInt; diff --git a/mediator/src/utils/serialize_option_bigint.rs b/mediator/src/utils/serialize_option_bigint.rs deleted file mode 100644 index d59403d..0000000 --- a/mediator/src/utils/serialize_option_bigint.rs +++ /dev/null @@ -1,40 +0,0 @@ -use curv_kzen::arithmetic::traits::Converter; -use curv_kzen::BigInt; -use serde::{de, ser}; -use std::fmt; - -pub fn serialize(x: &Option, serializer: S) -> Result { - match x { - Some(x) => serializer.serialize_str(&x.to_str_radix(10)), - None => serializer.serialize_none(), - } -} - -pub fn deserialize<'de, D: de::Deserializer<'de>>(deserializer: D) -> Result, D::Error> { - struct OptionBigIntVisitor; - - impl<'de> de::Visitor<'de> for OptionBigIntVisitor { - type Value = Option; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("option of bigint") - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(None) - } - - #[inline] - fn visit_none(self) -> Result, E> { - Ok(None) - } - - #[inline] - fn visit_some>(self, deserializer: D) -> Result { - kzen_paillier::serialize::bigint::deserialize(deserializer).map(Some) - } - } - - deserializer.deserialize_option(OptionBigIntVisitor) -} diff --git a/notifications/Cargo.toml b/notifications/Cargo.toml index e7f5a16..c5c0b9b 100644 --- a/notifications/Cargo.toml +++ b/notifications/Cargo.toml @@ -16,6 +16,7 @@ anyhow = "1.0.44" awc = "2.0.3" chrono = "0.4.19" dotenv = "0.15.0" +evoting-shared = { path = "../shared" } futures = "0.3.17" jsonwebtoken = "7.2.0" log = "0.4.14" diff --git a/notifications/src/auth/audience.rs b/notifications/src/auth/audience.rs deleted file mode 100644 index 11fd88c..0000000 --- a/notifications/src/auth/audience.rs +++ /dev/null @@ -1,67 +0,0 @@ -use serde::Deserialize; -use std::collections::HashSet; -use std::iter::FromIterator; - -/// Generic trait shared by all audience types -/// -/// An audience specifies which routes a JWT can access -pub trait Audience { - const TEXT: &'static str; - const ACCEPTS: &'static [&'static str]; - - /// Get the name to show for this audience type - fn get_name() -> String { - Self::TEXT.to_string() - } - - /// Get the list of all audiences accepted by this type - fn accepts() -> HashSet { - HashSet::from_iter(Self::ACCEPTS.iter().cloned().map(String::from)) - } -} - -/// Route is available to all token types -#[derive(Deserialize)] -pub struct All; - -impl Audience for All { - const TEXT: &'static str = "all"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only", "server-only", "collector-only"]; -} - -/// Route can only be called by the frontend client -#[derive(Deserialize)] -pub struct ClientOnly; - -impl Audience for ClientOnly { - const TEXT: &'static str = "client-only"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only"]; -} - -/// Route can only be called by the server -#[derive(Deserialize)] -pub struct ServerOnly; - -impl Audience for ServerOnly { - const TEXT: &'static str = "server-only"; - const ACCEPTS: &'static [&'static str] = &["all", "server-only"]; -} - -/// Route can only be called by a collector -#[derive(Deserialize)] -pub struct CollectorOnly; - -impl Audience for CollectorOnly { - const TEXT: &'static str = "collector-only"; - const ACCEPTS: &'static [&'static str] = &["all", "collector-only"]; -} - -/// Route can only be called by a mediator -#[derive(Deserialize)] -pub struct MediatorOnly; - -impl Audience for MediatorOnly { - const TEXT: &'static str = "mediator-only"; - const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; -} - diff --git a/notifications/src/auth/constants.rs b/notifications/src/auth/constants.rs deleted file mode 100644 index 82facef..0000000 --- a/notifications/src/auth/constants.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub const JWT_ISSUER: &str = "evoting"; -pub const JWT_EXPIRATION_MIN: i64 = 10; diff --git a/notifications/src/auth/jwt_secret.rs b/notifications/src/auth/jwt_secret.rs deleted file mode 100644 index ebf8054..0000000 --- a/notifications/src/auth/jwt_secret.rs +++ /dev/null @@ -1,21 +0,0 @@ -use jsonwebtoken::{DecodingKey, EncodingKey}; - -/// Simple wrapper struct to store the JWT secret -#[derive(Debug, Clone)] -pub struct JWTSecret { - secret: String, -} - -impl JWTSecret { - pub fn new(secret: impl Into) -> Self { - Self { secret: secret.into() } - } - - pub fn get_encoding_key(&self) -> EncodingKey { - EncodingKey::from_secret(self.secret.as_bytes()) - } - - pub fn get_decoding_key<'a>(&'a self) -> DecodingKey<'a> { - DecodingKey::from_secret(self.secret.as_bytes()) - } -} diff --git a/notifications/src/auth/jwt_token.rs b/notifications/src/auth/jwt_token.rs deleted file mode 100644 index 6dde643..0000000 --- a/notifications/src/auth/jwt_token.rs +++ /dev/null @@ -1,185 +0,0 @@ -use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use chrono::{offset::Utc, Duration}; -use futures::executor::block_on; -use futures::future::{ready, Ready}; -use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::collections::HashSet; -use std::iter::FromIterator; -use std::marker::PhantomData; -use uuid_b64::UuidB64 as Uuid; - -use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; -use crate::errors::ServiceError; - -// Type aliases for the different JWT tokens -pub type ClientToken = JWTToken; -pub type ServerToken = JWTToken; -pub type CollectorToken = JWTToken; -pub type MediatorToken = JWTToken; -pub type AnyToken = JWTToken; - -/// JSON Web Token used for user authentication -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTToken { - // Reserved Claims - iss: String, // Issuer - sub: Uuid, // Subject (whom token refers to) - aud: String, // Audience (whom the token is intended for) - iat: i64, // Issued at (as UTC timestamp) - exp: i64, // Expiration time (as UTC timestamp) - - // Public and private claims - #[serde(flatten)] - user_data: T, - permissions: HashSet, - - #[serde(skip)] - _aud: PhantomData, -} - -/// Internal data used by the client JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTClientData { - email: String, - name: String, -} - -pub type JWTInternalData = (); - -/// Internal data used by the "Any" JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTAnyData { - email: Option, - name: Option, -} - -impl JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - /// Encode the JSON Web Token into a string - pub fn encode(&self, key: &EncodingKey) -> Result { - Ok(encode(&Header::default(), self, key)?) - } - - pub fn get_user_id(&self) -> Uuid { - self.sub - } - - /// Test if the user has permission to do something - pub fn has_permission(&self, p: Permission) -> bool { - self.permissions.contains(&p) - } - - // - // Methods to test user permissions - // - pub fn test_can_send_notification(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::NoNotifyPermission) - } - } - - pub fn test_can_subscribe_to_notifications(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::NoSubscribePermission) - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> &String { - &self.user_data.name - } - - pub fn get_email(&self) -> &String { - &self.user_data.email - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn new(permissions: &[Permission]) -> Self { - use uuid::Uuid; - - let now = Utc::now(); - let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); - - Self { - iss: JWT_ISSUER.to_string(), - sub: Uuid::nil().into(), - aud: A::get_name(), - iat: now.timestamp(), - exp: expiration.timestamp(), - - user_data: (), - permissions: HashSet::from_iter(permissions.into_iter().cloned()), - - _aud: PhantomData, - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> Option<&String> { - self.user_data.name.as_ref() - } - - pub fn get_email(&self) -> Option<&String> { - self.user_data.email.as_ref() - } -} - -// -// Get the JSON Web Token from the request -// -impl FromRequest for JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - type Error = ServiceError; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { - let result: Result = (|| { - // Extract the JWT from the header and the encryption key from the app data - let bearer_token = block_on(BearerAuth::from_request(req, pl))?; - let jwt_secret = req.app_data::>().expect("JWTSecret should be set"); - - // Validation parameters, - let validation = Validation { - validate_exp: true, - leeway: 15, - aud: Some(A::accepts()), - iss: Some(JWT_ISSUER.into()), - ..Default::default() - }; - - // Decode and validate the JWT - let token_data = decode::(bearer_token.token(), &jwt_secret.get_decoding_key(), &validation)?; - Ok(token_data.claims) - })(); - - ready(result) - } -} diff --git a/notifications/src/auth/mod.rs b/notifications/src/auth/mod.rs deleted file mode 100644 index 76f8cdf..0000000 --- a/notifications/src/auth/mod.rs +++ /dev/null @@ -1,16 +0,0 @@ -// -// Structures and functions related to user authentication and authorization -// -pub mod audience; -mod constants; -mod jwt_secret; -mod jwt_token; -mod permission; -mod websocket_token; - -pub use audience::Audience; -pub use constants::*; -pub use jwt_secret::JWTSecret; -pub use jwt_token::*; -pub use permission::{Permission, DEFAULT_PERMISSIONS}; -pub use websocket_token::{JWTWebsocketToken, WebsocketToken}; diff --git a/notifications/src/auth/permission.rs b/notifications/src/auth/permission.rs deleted file mode 100644 index 97af5b1..0000000 --- a/notifications/src/auth/permission.rs +++ /dev/null @@ -1,25 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; -use std::fmt; - -pub static DEFAULT_PERMISSIONS: &[Permission] = &[ - Permission::CanLogin, - Permission::CreateElection, - Permission::Register, - Permission::Vote, -]; - -/// List of every permission -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)] -#[repr(u32)] -pub enum Permission { - CanLogin, - CreateElection, - Register, - Vote, -} - -impl fmt::Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} diff --git a/notifications/src/errors/error_response.rs b/notifications/src/errors/error_response.rs deleted file mode 100644 index 25c48dc..0000000 --- a/notifications/src/errors/error_response.rs +++ /dev/null @@ -1,71 +0,0 @@ -use actix_web::{http::StatusCode, HttpResponse, ResponseError}; -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt; - -use crate::errors::GlobalErrorCode; - -/// JSON response returned to the frontend on an error -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ErrorResponse { - #[serde( - serialize_with = "serialize_status_code", - deserialize_with = "deserialize_status_code" - )] - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - - // Don't serialize on production system - #[cfg_attr(not(debug_assertions), serde(skip_serializing))] - #[serde(skip_serializing_if = "Option::is_none")] - developer_notes: Option, -} - -fn serialize_status_code(code: &StatusCode, serializer: S) -> Result -where - S: Serializer, -{ - serializer.serialize_u16(code.as_u16()) -} - -fn deserialize_status_code<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let integer: u16 = Deserialize::deserialize(deserializer)?; - StatusCode::from_u16(integer).map_err(D::Error::custom) -} - -impl ErrorResponse { - pub fn new( - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - developer_notes: String, - ) -> Self { - ErrorResponse { - status_code, - description, - error_code, - developer_notes: Some(developer_notes), - } - } -} - -impl fmt::Display for ErrorResponse { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(#{:?}): {}", self.error_code, self.description)?; - if let Some(ref notes) = self.developer_notes { - write!(f, "\nDeveloper Notes: {}", notes)?; - } - Ok(()) - } -} - -impl ResponseError for ErrorResponse { - fn error_response(&self) -> HttpResponse { - HttpResponse::build(self.status_code).json(&self) - } -} diff --git a/notifications/src/errors/global_error_codes.rs b/notifications/src/errors/global_error_codes.rs deleted file mode 100644 index 56f6e2c..0000000 --- a/notifications/src/errors/global_error_codes.rs +++ /dev/null @@ -1,46 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; - -/// Error codes that are exposed on the frontend -#[derive(Serialize_repr, Deserialize_repr, Debug)] -#[repr(u32)] -pub enum GlobalErrorCode { - UnknownError = 0, - DatabaseConnectionError, - DatabaseQueryError, - MissingAppData, - JSONPayloadError, - FormPayloadError, - URLPathError, - QueryStringError, - StructValidationError, - InvalidEmailPassword, - InvalidJWTToken, - UserEmailExists, - PasswordComplexityError, - RecaptchaError, - ForbiddenResourceAction, - NoSuchResource, - ElectionNotOwnedByUser, - ElectionNotDraft, - WrongElectionStatus, - AccessCodeNotFound, - NotRegistered, - AlreadyRegistered, - RegistrationClosed, - NotEnoughRegistered, - ElectionNotInitialized, - MediatorURLNotSet, - RegisterElectionError, - VerificationError, - AlreadyVoted, - VerifyVoteError, - VoteInvalid, - NotOpenForVoting, - NotEnoughVotes, - CancelationSharesError, - ElectionNotStarted, - NoNotifyPermission, - NoSubscribePermission, - NotificationError, - InvalidCollectorURI, -} diff --git a/notifications/src/errors/mod.rs b/notifications/src/errors/mod.rs index bb3566d..3516767 100644 --- a/notifications/src/errors/mod.rs +++ b/notifications/src/errors/mod.rs @@ -1,12 +1,7 @@ // // All code related to error handling for the API server // -mod error_response; -mod global_error_codes; mod service_error; -mod websocket_error; -pub use error_response::ErrorResponse; -pub use global_error_codes::GlobalErrorCode; +pub use evoting_shared::errors::*; // Re-export pub use service_error::ServiceError; -pub use websocket_error::WebsocketError; diff --git a/notifications/src/errors/websocket_error.rs b/notifications/src/errors/websocket_error.rs deleted file mode 100644 index 3b7b9c3..0000000 --- a/notifications/src/errors/websocket_error.rs +++ /dev/null @@ -1,96 +0,0 @@ -use actix_codec::Framed; -use awc::error::{WsClientError, WsProtocolError}; -use awc::http::StatusCode; -use awc::ws::{CloseCode, Codec, Frame, Message, WebsocketsRequest}; -use awc::BoxedSocket; -use futures::{sink::SinkExt, stream::StreamExt}; -use serde::{de::DeserializeOwned, Serialize}; - -use crate::errors::ErrorResponse; - -/// Handles any errors related to websockets -#[derive(Debug)] -pub enum WebsocketError { - RequestError(actix_web::Error), - ClientError(WsClientError), - ProtocolError(WsProtocolError), - JSONError(serde_json::Error), - UnexpectedFrame(Frame), - WebsocketClosed, - ResponseError(ErrorResponse), - UnknownError(StatusCode), -} - -impl WebsocketError { - /// Attempts to connect to the websocket - /// Returns the stream on success or an error - pub async fn connect(input: WebsocketsRequest) -> Result, Self> { - let (mut response, stream) = match input.connect().await { - Err(e) => return Err(Self::ClientError(e)), - Ok(resp) => resp, - }; - - // Try to deserialize the data if the request is ok - let status = response.status(); - if response.status() == StatusCode::SWITCHING_PROTOCOLS { - return Ok(stream); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - - /// Serialize and send JSON data through the steam - pub async fn send_json(stream: &mut Framed, data: &T) -> Result<(), Self> { - let json_string = serde_json::to_string(data).map_err(|e| Self::JSONError(e))?; - stream - .send(Message::Text(json_string)) - .await - .map_err(|e| Self::ProtocolError(e)) - } - - /// Attempts to read the next websocket packet as a JSON data structure. - /// Returns the data on success or closes the connection on error - pub async fn read_json(stream: &mut Framed) -> Result { - // Read the next frame, closing the connection on any errors - let frame = match stream.next().await { - None => return Err(Self::WebsocketClosed), - Some(Err(e)) => { - stream - .send(Message::Close(Some((CloseCode::Error, format!("{}", e)).into()))) - .await - .map_err(|e| Self::ProtocolError(e))?; - - return Err(Self::ProtocolError(e)); - } - Some(Ok(resp)) => resp, - }; - - // Make sure the frame is text - let text = match frame { - Frame::Text(text) => text, - other => return Err(Self::UnexpectedFrame(other)), - }; - - // Parse the JSON - serde_json::from_slice::(text.as_ref()).map_err(|e| Self::JSONError(e)) - } -} - -impl From for WebsocketError { - fn from(error: actix_web::Error) -> Self { - WebsocketError::RequestError(error) - } -} - -impl From for WebsocketError { - fn from(error: WsClientError) -> Self { - WebsocketError::ClientError(error) - } -} diff --git a/notifications/src/handlers/notifications/notify.rs b/notifications/src/handlers/notifications/notify.rs index de5ce94..2aac49e 100644 --- a/notifications/src/handlers/notifications/notify.rs +++ b/notifications/src/handlers/notifications/notify.rs @@ -1,8 +1,8 @@ use actix::Addr; use actix_web::{web, HttpResponse}; -use crate::auth::ServerToken; use crate::errors::ServiceError; +use crate::jwt::{HasPermission, ServerToken}; use crate::notifications::{AllServerMessages, ElectionEvent, GlobalEvent, SubscriptionActor}; pub async fn notify( diff --git a/notifications/src/handlers/notifications/subscribe.rs b/notifications/src/handlers/notifications/subscribe.rs index 52bdb6f..18387d1 100644 --- a/notifications/src/handlers/notifications/subscribe.rs +++ b/notifications/src/handlers/notifications/subscribe.rs @@ -2,8 +2,8 @@ use actix::Addr; use actix_web::{web, HttpRequest, HttpResponse}; use actix_web_actors::ws; -use crate::auth::WebsocketToken; use crate::errors::{ServiceError, WebsocketError}; +use crate::jwt::{HasPermission, WebsocketToken}; use crate::notifications::{SubscriptionActor, WebsocketActor, WS_PROTOCOL}; pub async fn subscribe( diff --git a/notifications/src/jwt/has_permission.rs b/notifications/src/jwt/has_permission.rs new file mode 100644 index 0000000..8b324ce --- /dev/null +++ b/notifications/src/jwt/has_permission.rs @@ -0,0 +1,33 @@ +use crate::errors::ServiceError; +use crate::jwt::{Audience, JWTToken, Permission}; + +/// Helper trait that exposes methods for checking specific permissions +pub trait HasPermission { + /// Test if the user has permission to do something + fn has_permission(&self, p: Permission) -> bool; + + // =================================== + // Methods to test user permissions + // =================================== + fn test_can_send_notification(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::NoNotifyPermission) + } + } + + fn test_can_subscribe_to_notifications(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::NoSubscribePermission) + } + } +} + +impl HasPermission for JWTToken { + fn has_permission(&self, p: Permission) -> bool { + self.test_has_permission(p) + } +} diff --git a/notifications/src/jwt/mod.rs b/notifications/src/jwt/mod.rs new file mode 100644 index 0000000..721e4f7 --- /dev/null +++ b/notifications/src/jwt/mod.rs @@ -0,0 +1,9 @@ +// +// Structures and functions related to JSON web tokens +// +mod has_permission; +mod websocket_token; + +pub use evoting_shared::jwt::*; // Re-export +pub use has_permission::HasPermission; +pub use websocket_token::{JWTWebsocketToken, WebsocketToken}; diff --git a/notifications/src/auth/websocket_token.rs b/notifications/src/jwt/websocket_token.rs similarity index 96% rename from notifications/src/auth/websocket_token.rs rename to notifications/src/jwt/websocket_token.rs index 45fb737..77979b6 100644 --- a/notifications/src/auth/websocket_token.rs +++ b/notifications/src/jwt/websocket_token.rs @@ -4,8 +4,8 @@ use jsonwebtoken::{decode, Validation}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; -use crate::auth::{audience, Audience, JWTClientData, JWTSecret, JWTToken, JWT_ISSUER}; use crate::errors::ServiceError; +use crate::jwt::{audience, Audience, JWTClientData, JWTSecret, JWTToken, JWT_ISSUER}; use crate::notifications::WS_PROTOCOL; /// Type aliases for the different JWT websocket tokens diff --git a/notifications/src/lib.rs b/notifications/src/lib.rs index 6804e82..753d7bd 100644 --- a/notifications/src/lib.rs +++ b/notifications/src/lib.rs @@ -1,6 +1,6 @@ // All internal code modules -pub mod auth; pub mod config; pub mod errors; pub mod handlers; +pub mod jwt; pub mod notifications; diff --git a/notifications/src/main.rs b/notifications/src/main.rs index d38da06..bc09f14 100644 --- a/notifications/src/main.rs +++ b/notifications/src/main.rs @@ -5,10 +5,10 @@ use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; use simple_logger::SimpleLogger; use structopt::StructOpt; -use evoting_notifications::auth; use evoting_notifications::config; use evoting_notifications::errors::ServiceError; use evoting_notifications::handlers; +use evoting_notifications::jwt; use evoting_notifications::notifications::SubscriptionActor; #[actix_web::main] @@ -36,7 +36,7 @@ async fn main() -> anyhow::Result<()> { // Actor to manage subscriptions .data(subscription_addr.clone()) // Encryption secret for JSON Web Token - .data(auth::JWTSecret::new(config::get_jwt_secret())) + .data(jwt::JWTSecret::new(config::get_jwt_secret())) // Enable logger .wrap(middleware::Logger::default()) // Configure error handlers diff --git a/notifications/src/notifications/websocket_actor.rs b/notifications/src/notifications/websocket_actor.rs index 74edc6e..fc506b8 100644 --- a/notifications/src/notifications/websocket_actor.rs +++ b/notifications/src/notifications/websocket_actor.rs @@ -106,7 +106,7 @@ impl StreamHandler> for WebsocketActor { log::info!("Received close message, closing... ({:#?})", reason); ctx.close(reason); return ctx.stop(); - } + }, // Parse JSON message ws::Message::Text(text) => match serde_json::from_str::(&text) { @@ -115,7 +115,7 @@ impl StreamHandler> for WebsocketActor { message: "Invalid JSON data".into(), developer_notes: Some(format!("{}", e)), }) - } + }, Ok(json) => json, }, @@ -125,13 +125,13 @@ impl StreamHandler> for WebsocketActor { message: "Unsupported Frame: Binary Data".into(), developer_notes: None, }) - } + }, ws::Message::Continuation(_) => { return self_addr.do_send(NonFatalError { message: "Unsupported Frame: Continuation".into(), developer_notes: None, }) - } + }, }; // Send actor message to handle the data @@ -276,7 +276,7 @@ impl Handler for WebsocketActor { None => ctx.text(notify.get_json()), Some(user_id) if user_id == self.user_id => ctx.text(notify.get_json()), - Some(_) => { /* User Id's don't match */ } + Some(_) => { /* User Id's don't match */ }, } } } diff --git a/server/Cargo.toml b/server/Cargo.toml index 8f62b58..6ad4c68 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -19,6 +19,7 @@ chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } dotenv = "0.15.0" +evoting-shared = { path = "../shared" } futures = "0.3.17" jsonwebtoken = "7.2.0" kzen-paillier = "0.4.2" diff --git a/server/src/auth/audience.rs b/server/src/auth/audience.rs deleted file mode 100644 index 11fd88c..0000000 --- a/server/src/auth/audience.rs +++ /dev/null @@ -1,67 +0,0 @@ -use serde::Deserialize; -use std::collections::HashSet; -use std::iter::FromIterator; - -/// Generic trait shared by all audience types -/// -/// An audience specifies which routes a JWT can access -pub trait Audience { - const TEXT: &'static str; - const ACCEPTS: &'static [&'static str]; - - /// Get the name to show for this audience type - fn get_name() -> String { - Self::TEXT.to_string() - } - - /// Get the list of all audiences accepted by this type - fn accepts() -> HashSet { - HashSet::from_iter(Self::ACCEPTS.iter().cloned().map(String::from)) - } -} - -/// Route is available to all token types -#[derive(Deserialize)] -pub struct All; - -impl Audience for All { - const TEXT: &'static str = "all"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only", "server-only", "collector-only"]; -} - -/// Route can only be called by the frontend client -#[derive(Deserialize)] -pub struct ClientOnly; - -impl Audience for ClientOnly { - const TEXT: &'static str = "client-only"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only"]; -} - -/// Route can only be called by the server -#[derive(Deserialize)] -pub struct ServerOnly; - -impl Audience for ServerOnly { - const TEXT: &'static str = "server-only"; - const ACCEPTS: &'static [&'static str] = &["all", "server-only"]; -} - -/// Route can only be called by a collector -#[derive(Deserialize)] -pub struct CollectorOnly; - -impl Audience for CollectorOnly { - const TEXT: &'static str = "collector-only"; - const ACCEPTS: &'static [&'static str] = &["all", "collector-only"]; -} - -/// Route can only be called by a mediator -#[derive(Deserialize)] -pub struct MediatorOnly; - -impl Audience for MediatorOnly { - const TEXT: &'static str = "mediator-only"; - const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; -} - diff --git a/server/src/auth/constants.rs b/server/src/auth/constants.rs deleted file mode 100644 index 27f7904..0000000 --- a/server/src/auth/constants.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub const JWT_ISSUER: &str = "evoting"; -pub const JWT_EXPIRATION_MIN: i64 = 10; - -pub const JWT_REFRESH_AUDIENCE: &str = "refresh"; -pub const JWT_REFRESH_EXPIRATION_MIN: i64 = 60; diff --git a/server/src/auth/jwt_secret.rs b/server/src/auth/jwt_secret.rs deleted file mode 100644 index ebf8054..0000000 --- a/server/src/auth/jwt_secret.rs +++ /dev/null @@ -1,21 +0,0 @@ -use jsonwebtoken::{DecodingKey, EncodingKey}; - -/// Simple wrapper struct to store the JWT secret -#[derive(Debug, Clone)] -pub struct JWTSecret { - secret: String, -} - -impl JWTSecret { - pub fn new(secret: impl Into) -> Self { - Self { secret: secret.into() } - } - - pub fn get_encoding_key(&self) -> EncodingKey { - EncodingKey::from_secret(self.secret.as_bytes()) - } - - pub fn get_decoding_key<'a>(&'a self) -> DecodingKey<'a> { - DecodingKey::from_secret(self.secret.as_bytes()) - } -} diff --git a/server/src/auth/jwt_token.rs b/server/src/auth/jwt_token.rs deleted file mode 100644 index 14a8bde..0000000 --- a/server/src/auth/jwt_token.rs +++ /dev/null @@ -1,253 +0,0 @@ -use actix_web::{dev::Payload, web, FromRequest, HttpRequest}; -use actix_web_httpauth::extractors::bearer::BearerAuth; -use chrono::{offset::Utc, Duration}; -use futures::executor::block_on; -use futures::future::{ready, Ready}; -use jsonwebtoken::{decode, encode, EncodingKey, Header, Validation}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use std::collections::HashSet; -use std::iter::FromIterator; -use std::marker::PhantomData; -use uuid_b64::UuidB64 as Uuid; - -use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; -use crate::db::DbConnection; -use crate::errors::{ResourceAction, ResourceType, ServiceError}; -use crate::models::User; - -// Type aliases for the different JWT tokens -pub type ClientToken = JWTToken; -pub type ServerToken = JWTToken; -pub type CollectorToken = JWTToken; -pub type MediatorToken = JWTToken; -pub type AnyToken = JWTToken; - -/// JSON Web Token used for user authentication -#[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTToken { - // Reserved Claims - iss: String, // Issuer - sub: Uuid, // Subject (whom token refers to) - aud: String, // Audience (whom the token is intended for) - iat: i64, // Issued at (as UTC timestamp) - exp: i64, // Expiration time (as UTC timestamp) - - // Public and private claims - #[serde(flatten)] - user_data: T, - permissions: HashSet, - - #[serde(skip)] - _aud: PhantomData, -} - -/// Internal data used by the client JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTClientData { - email: String, - name: String, -} - -pub type JWTInternalData = (); - -/// Internal data used by the "Any" JSON Web Token -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct JWTAnyData { - email: Option, - name: Option, -} - -impl JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - /// Encode the JSON Web Token into a string - pub fn encode(&self, key: &EncodingKey) -> Result { - Ok(encode(&Header::default(), self, key)?) - } - - pub fn get_user_id(&self) -> Uuid { - self.sub - } - - /// Make sure the user ID is acutally in the database - pub fn validate_user_id(&self, conn: &DbConnection) -> Result { - User::find_optional(&self.sub, conn)?.ok_or_else(|| ServiceError::JWTNoSuchUser { user_id: self.sub }) - } - - /// Test if the user has permission to do something - pub fn has_permission(&self, p: Permission) -> bool { - self.permissions.contains(&p) - } - - // - // Methods to test user permissions - // - pub fn test_can_manage_account(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::User, - ResourceAction::Update, - )) - } - } - - pub fn test_can_view_elections(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::ReadPrivate, - )) - } - } - - pub fn test_can_create_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Create, - )) - } - } - - pub fn test_can_register_for_election(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Register, - )) - } - } - - pub fn test_can_vote(&self) -> Result<(), ServiceError> { - if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { - Ok(()) - } else { - Err(ServiceError::ForbiddenResourceAction( - ResourceType::Election, - ResourceAction::Vote, - )) - } - } -} - -impl JWTToken -where - A: Audience, -{ - /// Create a new JSON Web Token given the user, audience, and list of permissions - pub fn new(user: User, permissions: &[Permission]) -> Self { - let now = Utc::now(); - let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); - - Self { - iss: JWT_ISSUER.to_string(), - sub: user.id, - aud: A::get_name(), - iat: now.timestamp(), - exp: expiration.timestamp(), - - user_data: JWTClientData { - email: user.email, - name: user.name, - }, - permissions: HashSet::from_iter(permissions.into_iter().cloned()), - - _aud: PhantomData, - } - } - - pub fn get_name(&self) -> &String { - &self.user_data.name - } - - pub fn get_email(&self) -> &String { - &self.user_data.email - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn new(permissions: &[Permission]) -> Self { - use uuid::Uuid; - - let now = Utc::now(); - let expiration = now + Duration::minutes(JWT_EXPIRATION_MIN); - - Self { - iss: JWT_ISSUER.to_string(), - sub: Uuid::nil().into(), - aud: A::get_name(), - iat: now.timestamp(), - exp: expiration.timestamp(), - - user_data: (), - permissions: HashSet::from_iter(permissions.into_iter().cloned()), - - _aud: PhantomData, - } - } -} - -impl JWTToken -where - A: Audience, -{ - pub fn get_name(&self) -> Option<&String> { - self.user_data.name.as_ref() - } - - pub fn get_email(&self) -> Option<&String> { - self.user_data.email.as_ref() - } -} - -// -// Get the JSON Web Token from the request -// -impl FromRequest for JWTToken -where - A: Audience, - T: Serialize + DeserializeOwned, -{ - type Error = ServiceError; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future { - let result: Result = (|| { - // Extract the JWT from the header and the encryption key from the app data - let bearer_token = block_on(BearerAuth::from_request(req, pl))?; - let jwt_secret = req.app_data::>().expect("JWTSecret should be set"); - - // Validation parameters, - let validation = Validation { - validate_exp: true, - leeway: 15, - aud: Some(A::accepts()), - iss: Some(JWT_ISSUER.into()), - ..Default::default() - }; - - // Decode and validate the JWT - let token_data = decode::(bearer_token.token(), &jwt_secret.get_decoding_key(), &validation)?; - Ok(token_data.claims) - })(); - - ready(result) - } -} diff --git a/server/src/auth/mod.rs b/server/src/auth/mod.rs index 56fbeee..bb8bec4 100644 --- a/server/src/auth/mod.rs +++ b/server/src/auth/mod.rs @@ -1,20 +1,8 @@ // // Structures and functions related to user authentication and authorization // -pub mod audience; mod captcha; -mod constants; -mod jwt_secret; -mod jwt_token; mod password_complexity; -mod permission; -mod refresh_token; -pub use audience::Audience; pub use captcha::verify_recaptcha; -pub use constants::*; -pub use jwt_secret::JWTSecret; -pub use jwt_token::*; pub use password_complexity::validate_password_complexity; -pub use permission::{Permission, DEFAULT_PERMISSIONS}; -pub use refresh_token::RefreshToken; diff --git a/server/src/auth/permission.rs b/server/src/auth/permission.rs deleted file mode 100644 index 924a459..0000000 --- a/server/src/auth/permission.rs +++ /dev/null @@ -1,26 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; -use std::fmt; - -pub static DEFAULT_PERMISSIONS: &[Permission] = &[ - Permission::CanLogin, - Permission::CreateElection, - Permission::Register, - Permission::Vote, -]; - -/// List of every permission -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr)] -#[repr(u32)] -pub enum Permission { - CanLogin, - CreateElection, - Register, - Vote, - ManageCollector, -} - -impl fmt::Display for Permission { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} diff --git a/server/src/db/associations.rs b/server/src/db/associations.rs deleted file mode 100644 index 66a47fb..0000000 --- a/server/src/db/associations.rs +++ /dev/null @@ -1,916 +0,0 @@ -// ======================= -// Model Base -// ======================= -#[macro_export] -macro_rules! model_base( - () => { - model_base!(no update); - - // Save changes to database - pub fn update( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - self.save_changes::(conn.get()) - } - - // Insert as a new entry, or update the existing entry on conflict - // Uses the primary key to detect duplicate entries - pub fn insert_or_update( - &self, - conn: &crate::db::DbConnection - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict(::table().primary_key()) - .do_update() - .set(self) - .get_result::(conn.get()) - } - }; - - (order by $order:expr) => { - model_base!(); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update, order by $order:expr) => { - model_base!(no update); - paste::item! { - model_base!(@ order by crate::schema::$order); - } - }; - - (no update) => { - // Get all - pub fn all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .get_results::(conn.get()) - } - - // Count all users - pub fn count_all( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .count().get_result::(conn.get()) - } - - // Find from ID - pub fn find( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - } - - // Find optional from ID - pub fn find_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table() - .find(id) - .get_result::(conn.get()) - .optional() - } - - // Create the new entry in the database - pub fn insert( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .get_result::(conn.get()) - } - - // Insert only if the entry is not in the database - pub fn insert_ignore_conflicts( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(self) - .on_conflict_do_nothing() - .get_result::(conn.get()) - .optional() - } - - // Create multiple entries in the database - pub fn insert_list( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .get_results::(conn.get()) - } - - // Insert a list of values, but ignore duplicate values - pub fn insert_list_ignore_conflicts( - entries: &Vec, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::insert_into; - - insert_into(::table()) - .values(entries) - .on_conflict_do_nothing() - .get_results::(conn.get()) - } - - // Test if an item exists in the database - pub fn exists( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional( - <&Self as diesel::associations::Identifiable>::id(&self), - conn, - ).map(|result| result.is_some()) - } - - // Test if an item exists by ID - pub fn exists_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - Self::find_optional(id, conn).map(|result| result.is_some()) - } - - // Reload from database - pub fn reload( - &mut self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<()> { - use diesel::prelude::*; - - let new_value = ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get())?; - - *self = new_value; - - Ok(()) - } - - // Reload from database - pub fn reload_new( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - ::table() - .find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - .get_result::(conn.get()) - } - - // Delete item in database - pub fn delete( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find( - <&Self as diesel::associations::Identifiable>::id(&self) - ) - ) - .get_result::(conn.get()) - .optional() - } - - // Delete item in database - pub fn delete_from_id( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - } - - // Delete item in database, but only if it already exists - pub fn delete_from_id_optional( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - ::table().find(id) - ) - .get_result::(conn.get()) - .optional() - } - }; - - (@ order by $order:expr) => { - - // Get all ordered by - pub fn all_ordered( - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - ::table().order_by($order) - .get_results::(conn.get()) - } - }; -); - -// ======================= -// Belongs To -// ======================= -#[macro_export] -macro_rules! belongs_to( - ($parent:ident) => { - paste::item! { - belongs_to!($parent, [<$parent:snake>]); - } - }; - - ($parent:ident, $func_base:ident) => { - belongs_to!(@ crate::models::$parent, $func_base); - }; - - (@ $parent:path, $func_base:ident) => { - // Get parent - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - } - - // Get parent optional - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Ok(None), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - .optional() - } - } - } - } - }; -); - -// ======================= -// Has One -// ======================= -#[macro_export] -macro_rules! has_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ).get_result::<$child>(conn.get()) - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$child> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_result::<$child>(conn.get()) - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::(conn.get()) - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::(conn.get()) - } - } - }; -); - -// ======================= -// Has Zero or One -// ======================= -#[macro_export] -macro_rules! has_zero_or_one( - // Pluralize - ($child:ident) => { - paste::item! { - has_zero_or_one!($child, [<$child:snake>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_zero_or_one!(@ crate::models::$child, $func_base); - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Get child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - - // Delete child from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_result::<$child>(conn.get()) - .optional() - } - } - }; -); - -// ======================= -// Has Many -// ======================= -#[macro_export] -macro_rules! has_many( - // Pluralize - ($child:ident) => { - paste::item! { - has_many!($child, [<$child:snake s>]); - } - }; - - ($child:ident, order by $order:expr) => { - paste::item! { - has_many!($child, order by $order, [<$child:snake s>]); - } - }; - - ($child:ident, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - }; - - ($child:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child, $func_base); - paste::item! { - has_many!(@ crate::models::$child, order by crate::schema::$order, $func_base); - } - }; - - // Explicit function base - (@ $child:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).get_results::<$child>(conn.get()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - $child::belonging_to(self).count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ).count().get_result::(conn.get()) - } - } - - // Delete all children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ), - ) - .get_results::<$child>(conn.get()) - } - } - - // Delete all children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - use diesel::delete; - - delete( - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ), - ) - .get_results::<$child>(conn.get()) - } - } - }; - - // Has many ordered - (@ $child:path, order by $order:expr, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - $child::belonging_to(self).order_by($order).get_results::<$child>(conn.get()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$child as diesel::associations::HasTable>::table().filter( - <$child as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id) - ) - .order_by($order) - .get_results::<$child>(conn.get()) - } - } - }; - - - // ======================= - // Has Many Through - // (Special case) - // ======================= - ($child:ident through $through:ident) => ( - paste::item! { - has_many!($child through $through, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, order by $order:expr) => ( - paste::item! { - has_many!($child through $through, order by $order, [<$child:snake s>]); - } - ); - - ($child:ident through $through:ident, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - }; - - ($child:ident through $through:ident, order by $order:expr, $func_base:ident) => { - has_many!(@ crate::models::$child => crate::models::$through, $func_base); - paste::item! { - has_many!(@ crate::models::$child => crate::models::$through, order by crate::schema::$order, $func_base); - } - }; - - (@ $child:path => $through:path, $func_base:ident) => { - - // Get children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Count children - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .count().get_result::(conn.get()) - } - } - - // Count children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .count().get_result::(conn.get()) - } - } - - // Delete children from many-to-many the association - // Does NOT delete the actual values - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Delete children from many-to-many the association by the ID - // Does NOT delete the actual values - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::delete; - use diesel::prelude::*; - - delete( - <$through as diesel::associations::HasTable>::table().filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - ).get_results::<$through>(conn.get()) - } - } - - // Set children - paste::item! { - pub fn []<'a>( - &self, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children Ids - paste::item! { - pub fn []<'a>( - &self, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](<&Self as diesel::associations::Identifiable>::id(&self), ids_list, conn) - } - } - - // Set children from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - list: impl std::iter::IntoIterator, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - let ids_list = list.into_iter().map(|item| <&$child as diesel::associations::Identifiable>::id(&item)); - Self::[](id, ids_list, conn) - } - } - - // Set all IDs from ID - paste::item! { - pub fn []<'a>( - id: <&Self as diesel::associations::Identifiable>::Id, - ids_list: impl std::iter::IntoIterator>::ForeignKey>, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - Self::[](id, conn)?; - - let new_entries: Vec<$through> = ids_list - .into_iter() - .map(|item| <$through as crate::db::ManyToManyConstructor>::new(id, item)) - .collect(); - - Ok($through::insert_list(&new_entries, conn)?) - } - } - }; - - (@ $child:path => $through:path, order by $order:expr, $func_base:ident) => { - // Get children ordered - paste::item! { - pub fn []( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(<&Self as diesel::associations::Identifiable>::id(&self)), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - - // Get ordered children from ID - paste::item! { - pub fn []( - id: <&Self as diesel::associations::Identifiable>::Id, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult> { - use diesel::prelude::*; - - <$through as diesel::associations::HasTable>::table() - .inner_join(<$child as diesel::associations::HasTable>::table()) - .filter( - <$through as diesel::associations::BelongsTo>::foreign_key_column() - .eq(id), - ) - .order_by($order) - .get_results::<($through, $child)>(conn.get()) - .map(|results| results.into_iter().map(|(_, second)| second).collect()) - } - } - }; -); diff --git a/server/src/db/db_connection.rs b/server/src/db/db_connection.rs deleted file mode 100644 index 26bbc4f..0000000 --- a/server/src/db/db_connection.rs +++ /dev/null @@ -1,77 +0,0 @@ -use actix_web::{dev::Payload, web, Error, FromRequest, HttpRequest}; -use diesel::pg::PgConnection; -use futures::future::{ready, Ready}; -use std::ops::{Deref, DerefMut}; - -use crate::db::{PgPool, PgPooledConnection}; -use crate::errors::ServiceError; - -pub enum DbConnection { - UnpooledConnection(PgConnection), - PooledConnection(PgPooledConnection), -} - -// -// Explicit extraction calls for when compiler can't implicitly convert -// -impl DbConnection { - pub fn new(conn: PgConnection) -> Self { - DbConnection::UnpooledConnection(conn) - } - pub fn new_pooled(conn: PgPooledConnection) -> Self { - DbConnection::PooledConnection(conn) - } - - pub fn get(&self) -> &PgConnection { - match self { - DbConnection::PooledConnection(pool) => &pool, - DbConnection::UnpooledConnection(conn) => &conn, - } - } - - pub fn get_mut(&mut self) -> &mut PgConnection { - match self { - DbConnection::PooledConnection(ref mut pool) => pool, - DbConnection::UnpooledConnection(ref mut conn) => conn, - } - } -} - -// -// Implicitly convert to the database connection type -// -impl Deref for DbConnection { - type Target = PgConnection; - fn deref(&self) -> &Self::Target { - self.get() - } -} - -impl DerefMut for DbConnection { - fn deref_mut(&mut self) -> &mut Self::Target { - self.get_mut() - } -} - -// -// Get the database connection from the request -// -impl FromRequest for DbConnection { - type Error = Error; - type Future = Ready>; - type Config = (); - - fn from_request(req: &HttpRequest, _pl: &mut Payload) -> Self::Future { - let res = get_connection_from_request(req); - ready(res.map_err(|e| e.into())) - } -} - -pub fn get_connection_from_request(req: &HttpRequest) -> Result { - let pool = req - .app_data::>() - .ok_or(ServiceError::MissingAppData("PgPool".into()))?; - - let conn = pool.get()?; - Ok(DbConnection::new_pooled(conn)) -} diff --git a/server/src/db/init.rs b/server/src/db/init.rs deleted file mode 100644 index 51a67d6..0000000 --- a/server/src/db/init.rs +++ /dev/null @@ -1,24 +0,0 @@ -use diesel::r2d2::{ConnectionManager, Pool, PoolError}; -use diesel::{pg::PgConnection, Connection}; - -use crate::config; -use crate::db::{DbConnection, PgPool}; - -pub fn establish_new_connection_pool() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(init_pool(&database_url)?) -} - -fn init_pool(database_url: &str) -> Result { - let manager = ConnectionManager::::new(database_url); - Pool::builder().build(manager) -} - -pub fn open_new_connection() -> anyhow::Result { - let database_url = - config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; - - Ok(DbConnection::new(PgConnection::establish(&database_url)?)) -} diff --git a/server/src/db/many_many_constructor.rs b/server/src/db/many_many_constructor.rs deleted file mode 100644 index b774e0c..0000000 --- a/server/src/db/many_many_constructor.rs +++ /dev/null @@ -1,6 +0,0 @@ -use diesel::associations::BelongsTo; - -/// Trait that must be implemented to construct a many-to-many relationship -pub trait ManyToManyConstructor: BelongsTo + BelongsTo { - fn new(left: &>::ForeignKey, right: &>::ForeignKey) -> Self; -} diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs deleted file mode 100644 index 4f1818a..0000000 --- a/server/src/db/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -// Database-specific objects and actions -// -mod db_connection; -mod init; -mod many_many_constructor; -mod types; - -#[macro_use] -mod sql_enum; -#[macro_use] -mod associations; -#[macro_use] -mod subtypes; - -pub use db_connection::{get_connection_from_request, DbConnection}; -pub use init::{establish_new_connection_pool, open_new_connection}; -pub use many_many_constructor::ManyToManyConstructor; -pub use types::{PgPool, PgPooledConnection}; diff --git a/server/src/db/sql_enum.rs b/server/src/db/sql_enum.rs deleted file mode 100644 index fe43487..0000000 --- a/server/src/db/sql_enum.rs +++ /dev/null @@ -1,54 +0,0 @@ -#[macro_export] -macro_rules! sql_enum { - ($v:vis $name:ident $type:tt) => { - #[repr(i32)] - #[derive( - Debug, Copy, Clone, Eq, PartialEq, Hash, - serde_repr::Serialize_repr, serde_repr::Deserialize_repr, - FromSqlRow, FromPrimitive, AsExpression, - )] - #[sql_type = "Integer"] - $v enum $name $type - enum_internals!($name); - }; -} - -#[allow(unused)] -macro_rules! enum_internals { - ($($t:ty)*) => ($( - - // Required packages - use diesel::{ - backend::Backend, - deserialize::{self, FromSql}, - serialize::{self, Output, ToSql}, - sql_types::Integer, - }; - use std::io::Write; - - // Convert to SQL - impl ToSql for $t - where - DB: Backend, - i32: ToSql, - { - fn to_sql(&self, out: &mut Output) -> serialize::Result { - (*self as i32).to_sql(out) - } - } - - // Convert from SQL - impl FromSql for $t - where - DB: Backend, - i32: FromSql, - { - fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result { - let number = i32::from_sql(bytes)?; - num::FromPrimitive::from_i32(number).ok_or_else( - || format!("diesel::deserialize::FromSql for {} --- Invalid variant index {}", stringify!($t), number).into() - ) - } - } - )*) -} diff --git a/server/src/db/subtypes.rs b/server/src/db/subtypes.rs deleted file mode 100644 index 13d3724..0000000 --- a/server/src/db/subtypes.rs +++ /dev/null @@ -1,71 +0,0 @@ -// ======================= -// Parent Type -// ======================= -#[macro_export] -macro_rules! parent_type( - ($discriminant:ty = $from_value:expr) => { - paste::item! { - parent_type!($discriminant = $from_value, [<$discriminant:snake>]); - } - }; - - ($discriminant:ty = $from_value:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - self.$from_value - } - } - }; -); - -// ======================= -// Child Type -// ======================= -#[macro_export] -macro_rules! child_type( - ($parent:ty, $discriminant:ty = $value:expr) => { - paste::item! { - child_type!($parent, $discriminant = $value, [<$discriminant:snake>]); - } - }; - - ($parent:ty, $discriminant:ty = $from:expr, $func_base:ident) => { - paste::item! { - pub fn [](&self) -> $discriminant { - $from - } - } - - pub fn get_parent( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - - pub fn get_parent_optional( - &self, - conn: &crate::db::DbConnection, - ) -> diesel::prelude::QueryResult<$parent> { - use diesel::prelude::*; - - match >::foreign_key(&self) { - None => Err(diesel::result::Error::NotFound), - Some(id) => { - <$parent as diesel::associations::HasTable>::table() - .find(id) - .get_result::<$parent>(conn.get()) - } - } - } - }; -); diff --git a/server/src/db/types.rs b/server/src/db/types.rs deleted file mode 100644 index 5976a70..0000000 --- a/server/src/db/types.rs +++ /dev/null @@ -1,5 +0,0 @@ -use diesel::pg::PgConnection; -use diesel::r2d2::{ConnectionManager, Pool, PooledConnection}; - -pub type PgPool = Pool>; -pub type PgPooledConnection = PooledConnection>; diff --git a/server/src/errors/client_request_error.rs b/server/src/errors/client_request_error.rs deleted file mode 100644 index 5c62f49..0000000 --- a/server/src/errors/client_request_error.rs +++ /dev/null @@ -1,73 +0,0 @@ -use actix_http::{encoding::Decoder, Payload, PayloadStream}; -use awc::error::{JsonPayloadError, SendRequestError}; -use awc::http::StatusCode; -use awc::ClientResponse; -use serde::de::DeserializeOwned; -use std::future::Future; - -use crate::errors::ErrorResponse; - -/// Enum with all of the things that can go wrong when making a client request -#[derive(Debug)] -pub enum ClientRequestError { - SendError(SendRequestError), - ResponseError(ErrorResponse), - JSONError(JsonPayloadError), - UnknownError(StatusCode), -} - -impl ClientRequestError { - /// Handle the response from a client and parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle( - input: impl Future>>, SendRequestError>>, - ) -> Result { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Try to deserialize the data if the request is ok - let status = response.status(); - if response.status() == StatusCode::OK { - return response.json::().await.map_err(|e| Self::JSONError(e)); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } - - /// Handle the response from a client, but don't parse the JSON body - /// - /// Returns an error if any of these steps fail - pub async fn handle_empty( - input: impl Future>>, SendRequestError>>, - ) -> Result<(), Self> { - match input.await { - Err(e) => Err(Self::SendError(e)), - Ok(mut response) => { - // Make sure the request is okay - let status = response.status(); - if response.status() == StatusCode::OK { - return Ok(()); - } - - // Otherwise, possibly parse an error response - // If the server didn't return an error response, then just return the status code - let error_response = response - .json::() - .await - .map_err(|_| Self::UnknownError(status))?; - - Err(Self::ResponseError(error_response)) - } - } - } -} diff --git a/server/src/errors/error_response.rs b/server/src/errors/error_response.rs deleted file mode 100644 index 25c48dc..0000000 --- a/server/src/errors/error_response.rs +++ /dev/null @@ -1,71 +0,0 @@ -use actix_web::{http::StatusCode, HttpResponse, ResponseError}; -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt; - -use crate::errors::GlobalErrorCode; - -/// JSON response returned to the frontend on an error -#[derive(Serialize, Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct ErrorResponse { - #[serde( - serialize_with = "serialize_status_code", - deserialize_with = "deserialize_status_code" - )] - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - - // Don't serialize on production system - #[cfg_attr(not(debug_assertions), serde(skip_serializing))] - #[serde(skip_serializing_if = "Option::is_none")] - developer_notes: Option, -} - -fn serialize_status_code(code: &StatusCode, serializer: S) -> Result -where - S: Serializer, -{ - serializer.serialize_u16(code.as_u16()) -} - -fn deserialize_status_code<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let integer: u16 = Deserialize::deserialize(deserializer)?; - StatusCode::from_u16(integer).map_err(D::Error::custom) -} - -impl ErrorResponse { - pub fn new( - status_code: StatusCode, - description: String, - error_code: GlobalErrorCode, - developer_notes: String, - ) -> Self { - ErrorResponse { - status_code, - description, - error_code, - developer_notes: Some(developer_notes), - } - } -} - -impl fmt::Display for ErrorResponse { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "(#{:?}): {}", self.error_code, self.description)?; - if let Some(ref notes) = self.developer_notes { - write!(f, "\nDeveloper Notes: {}", notes)?; - } - Ok(()) - } -} - -impl ResponseError for ErrorResponse { - fn error_response(&self) -> HttpResponse { - HttpResponse::build(self.status_code).json(&self) - } -} diff --git a/server/src/errors/global_error_codes.rs b/server/src/errors/global_error_codes.rs deleted file mode 100644 index 56f6e2c..0000000 --- a/server/src/errors/global_error_codes.rs +++ /dev/null @@ -1,46 +0,0 @@ -use serde_repr::{Deserialize_repr, Serialize_repr}; - -/// Error codes that are exposed on the frontend -#[derive(Serialize_repr, Deserialize_repr, Debug)] -#[repr(u32)] -pub enum GlobalErrorCode { - UnknownError = 0, - DatabaseConnectionError, - DatabaseQueryError, - MissingAppData, - JSONPayloadError, - FormPayloadError, - URLPathError, - QueryStringError, - StructValidationError, - InvalidEmailPassword, - InvalidJWTToken, - UserEmailExists, - PasswordComplexityError, - RecaptchaError, - ForbiddenResourceAction, - NoSuchResource, - ElectionNotOwnedByUser, - ElectionNotDraft, - WrongElectionStatus, - AccessCodeNotFound, - NotRegistered, - AlreadyRegistered, - RegistrationClosed, - NotEnoughRegistered, - ElectionNotInitialized, - MediatorURLNotSet, - RegisterElectionError, - VerificationError, - AlreadyVoted, - VerifyVoteError, - VoteInvalid, - NotOpenForVoting, - NotEnoughVotes, - CancelationSharesError, - ElectionNotStarted, - NoNotifyPermission, - NoSubscribePermission, - NotificationError, - InvalidCollectorURI, -} diff --git a/server/src/errors/mod.rs b/server/src/errors/mod.rs index 029d77b..eb56f16 100644 --- a/server/src/errors/mod.rs +++ b/server/src/errors/mod.rs @@ -1,17 +1,12 @@ // // All code related to error handling for the API server // -mod client_request_error; -mod error_response; -mod global_error_codes; mod named_resource_type; mod resource_action; mod resource_type; mod service_error; -pub use client_request_error::ClientRequestError; -pub use error_response::ErrorResponse; -pub use global_error_codes::GlobalErrorCode; +pub use evoting_shared::errors::*; // Re-export pub use named_resource_type::NamedResourceType; pub use resource_action::ResourceAction; pub use resource_type::ResourceType; diff --git a/server/src/errors/service_error.rs b/server/src/errors/service_error.rs index 66eb388..3325a87 100644 --- a/server/src/errors/service_error.rs +++ b/server/src/errors/service_error.rs @@ -9,10 +9,9 @@ use std::{error, fmt}; use uuid_b64::UuidB64 as Uuid; use validator::ValidationErrors; -use crate::errors::{ - ClientRequestError, ErrorResponse, GlobalErrorCode, NamedResourceType, ResourceAction, ResourceType, -}; +use crate::errors::{NamedResourceType, ResourceAction, ResourceType}; use crate::models::ElectionStatus; +use evoting_shared::errors::{ClientRequestError, ErrorResponse, GlobalErrorCode}; /// Enumeration of all possible errors that can occur #[derive(Debug)] diff --git a/server/src/handlers/account/register_account.rs b/server/src/handlers/account/register_account.rs index 28a4fa7..776650f 100644 --- a/server/src/handlers/account/register_account.rs +++ b/server/src/handlers/account/register_account.rs @@ -2,9 +2,10 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; use validator::Validate; -use crate::auth::{validate_password_complexity, verify_recaptcha, JWTSecret}; +use crate::auth::{validate_password_complexity, verify_recaptcha}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::JWTSecret; use crate::models::User; use crate::views::auth::LoginResult; diff --git a/server/src/handlers/account/update_account.rs b/server/src/handlers/account/update_account.rs index 3c42602..f60ba3e 100644 --- a/server/src/handlers/account/update_account.rs +++ b/server/src/handlers/account/update_account.rs @@ -2,9 +2,9 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; use validator::Validate; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::notifications::notify_name_changed; use crate::views::auth::LoginResult; diff --git a/server/src/handlers/account/update_password.rs b/server/src/handlers/account/update_password.rs index fc40e81..a822dc5 100644 --- a/server/src/handlers/account/update_password.rs +++ b/server/src/handlers/account/update_password.rs @@ -2,9 +2,10 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; use validator::Validate; -use crate::auth::{validate_password_complexity, ClientToken}; +use crate::auth::validate_password_complexity; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; #[derive(Debug, Deserialize, Validate)] #[serde(rename_all = "camelCase")] diff --git a/server/src/handlers/auth/get_me.rs b/server/src/handlers/auth/get_me.rs index 8323943..a2c8240 100644 --- a/server/src/handlers/auth/get_me.rs +++ b/server/src/handlers/auth/get_me.rs @@ -1,6 +1,6 @@ use actix_web::HttpResponse; -use crate::auth::AnyToken; +use crate::jwt::AnyToken; use crate::views::auth::UserDetails; pub async fn get_me(token: AnyToken) -> HttpResponse { diff --git a/server/src/handlers/auth/login.rs b/server/src/handlers/auth/login.rs index 704045d..d705287 100644 --- a/server/src/handlers/auth/login.rs +++ b/server/src/handlers/auth/login.rs @@ -2,9 +2,10 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; use validator::Validate; -use crate::auth::{verify_recaptcha, JWTSecret}; +use crate::auth::verify_recaptcha; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::JWTSecret; use crate::models::User; use crate::views::auth::LoginResult; diff --git a/server/src/handlers/auth/refresh.rs b/server/src/handlers/auth/refresh.rs index bd5a7d8..0ef637f 100644 --- a/server/src/handlers/auth/refresh.rs +++ b/server/src/handlers/auth/refresh.rs @@ -1,8 +1,9 @@ use actix_web::{web, HttpResponse}; -use crate::auth::{JWTSecret, RefreshToken}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::JWTSecret; +use crate::jwt::RefreshToken; use crate::models::User; use crate::views::auth::LoginResult; diff --git a/server/src/handlers/election/all_elections.rs b/server/src/handlers/election/all_elections.rs index 044d906..03f9805 100644 --- a/server/src/handlers/election/all_elections.rs +++ b/server/src/handlers/election/all_elections.rs @@ -2,9 +2,9 @@ use actix_web::HttpResponse; use diesel::prelude::*; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::{Election, ElectionStatus}; use crate::views::election::{AllElectionsResult, PublicElectionList, UserDetails}; diff --git a/server/src/handlers/election/create_election.rs b/server/src/handlers/election/create_election.rs index ee25770..a7b93ed 100644 --- a/server/src/handlers/election/create_election.rs +++ b/server/src/handlers/election/create_election.rs @@ -4,9 +4,9 @@ use serde::{Deserialize, Serialize}; use validator::Validate; use super::helpers::validate_candidates; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Candidate, Election, Question}; use crate::notifications::notify_election_created; use crate::views::election::NewElectionResult; diff --git a/server/src/handlers/election/delete_election.rs b/server/src/handlers/election/delete_election.rs index 36535c3..026a1a6 100644 --- a/server/src/handlers/election/delete_election.rs +++ b/server/src/handlers/election/delete_election.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::{ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Election, ElectionStatus}; use crate::notifications::notify_election_deleted; diff --git a/server/src/handlers/election/get_election.rs b/server/src/handlers/election/get_election.rs index 7d8c356..89c88ec 100644 --- a/server/src/handlers/election/get_election.rs +++ b/server/src/handlers/election/get_election.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::{NamedResourceType, ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::{Election, ElectionStatus}; use crate::views::election::{PublicElectionDetails, PublicElectionQuestion, RegisteredUserDetails, UserDetails}; diff --git a/server/src/handlers/election/get_election_by_access_code.rs b/server/src/handlers/election/get_election_by_access_code.rs index 2c99ac6..0966c1b 100644 --- a/server/src/handlers/election/get_election_by_access_code.rs +++ b/server/src/handlers/election/get_election_by_access_code.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use serde::Deserialize; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::{Election, ElectionStatus, ACCESS_CODE_LENGTH}; use crate::views::election::GetElectionByAccessCode; diff --git a/server/src/handlers/election/get_election_parameters.rs b/server/src/handlers/election/get_election_parameters.rs index 35c25f5..ff7149a 100644 --- a/server/src/handlers/election/get_election_parameters.rs +++ b/server/src/handlers/election/get_election_parameters.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::{NamedResourceType, ServiceError}; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::Election; use crate::utils::ConvertBigInt; use crate::views::election::{ElectionParameters, QuestionParameters}; diff --git a/server/src/handlers/election/get_election_results.rs b/server/src/handlers/election/get_election_results.rs index 5c01a7b..cf6dc27 100644 --- a/server/src/handlers/election/get_election_results.rs +++ b/server/src/handlers/election/get_election_results.rs @@ -2,9 +2,9 @@ use actix_web::{web, HttpResponse}; use std::collections::HashMap; use uuid_b64::UuidB64 as Uuid; -use crate::auth::ClientToken; use crate::db::DbConnection; use crate::errors::{NamedResourceType, ServiceError}; +use crate::jwt::{ClientToken, HasPermission}; use crate::models::{Election, ElectionStatus}; use crate::protocol::count_ballot_votes; use crate::utils::ConvertBigInt; diff --git a/server/src/handlers/election/update_election.rs b/server/src/handlers/election/update_election.rs index eddbf1f..e65963d 100644 --- a/server/src/handlers/election/update_election.rs +++ b/server/src/handlers/election/update_election.rs @@ -5,9 +5,9 @@ use uuid_b64::UuidB64 as Uuid; use validator::Validate; use super::helpers::validate_candidates; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::{ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Candidate, Election, ElectionStatus, Question}; use crate::notifications::notify_election_updated; diff --git a/server/src/handlers/registration/open_registration.rs b/server/src/handlers/registration/open_registration.rs index 6656182..dbbbfbe 100644 --- a/server/src/handlers/registration/open_registration.rs +++ b/server/src/handlers/registration/open_registration.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::{ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Election, ElectionStatus}; use crate::notifications::{notify_election_published, notify_registration_opened}; use crate::views::election::PublishElectionResult; diff --git a/server/src/handlers/registration/register_for_election.rs b/server/src/handlers/registration/register_for_election.rs index b98c636..1365d84 100644 --- a/server/src/handlers/registration/register_for_election.rs +++ b/server/src/handlers/registration/register_for_election.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Election, ElectionStatus, Registration}; use crate::notifications::notify_user_registered; diff --git a/server/src/handlers/registration/unregister_from_election.rs b/server/src/handlers/registration/unregister_from_election.rs index 6fc221f..100a33e 100644 --- a/server/src/handlers/registration/unregister_from_election.rs +++ b/server/src/handlers/registration/unregister_from_election.rs @@ -1,9 +1,9 @@ use actix_web::{web, HttpResponse}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret}; use crate::db::DbConnection; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, HasPermission, JWTSecret}; use crate::models::{Election, ElectionStatus}; use crate::notifications::notify_user_unregistered; @@ -35,7 +35,7 @@ pub async fn unregister_from_election( user_id, election_id: election.id, }); - } + }, }; // Delete the registration from the database diff --git a/server/src/handlers/voting/close_voting.rs b/server/src/handlers/voting/close_voting.rs index 607e965..4bee863 100644 --- a/server/src/handlers/voting/close_voting.rs +++ b/server/src/handlers/voting/close_voting.rs @@ -7,10 +7,10 @@ use jsonwebtoken::EncodingKey; use serde::{Deserialize, Serialize}; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::config; use crate::db::DbConnection; use crate::errors::{ClientRequestError, ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Election, ElectionStatus, Question}; use crate::notifications::{notify_results_published, notify_voting_closed}; use crate::utils::ConvertBigInt; diff --git a/server/src/handlers/voting/initialize_voting.rs b/server/src/handlers/voting/initialize_voting.rs index ef7cfe0..7518f55 100644 --- a/server/src/handlers/voting/initialize_voting.rs +++ b/server/src/handlers/voting/initialize_voting.rs @@ -7,10 +7,10 @@ use std::cmp::max; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::{ClientToken, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::config; use crate::db::DbConnection; use crate::errors::{ClientRequestError, ResourceAction, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Election, ElectionStatus, Registration}; use crate::notifications::{notify_registration_closed, notify_voting_opened}; use crate::protocol::generator_prime_pair; diff --git a/server/src/handlers/voting/vote.rs b/server/src/handlers/voting/vote.rs index 2471dba..a8781cc 100644 --- a/server/src/handlers/voting/vote.rs +++ b/server/src/handlers/voting/vote.rs @@ -5,10 +5,10 @@ use serde::{Deserialize, Serialize}; use uuid_b64::UuidB64 as Uuid; use validator::Validate; -use crate::auth::{ClientToken, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::config; use crate::db::DbConnection; use crate::errors::{ClientRequestError, ServiceError}; +use crate::jwt::{ClientToken, HasPermission, JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Commitment, Election, ElectionStatus}; use crate::notifications::notify_vote_received; use crate::utils::ConvertBigInt; diff --git a/server/src/jwt/has_permission.rs b/server/src/jwt/has_permission.rs new file mode 100644 index 0000000..403dac7 --- /dev/null +++ b/server/src/jwt/has_permission.rs @@ -0,0 +1,91 @@ +use uuid_b64::UuidB64 as Uuid; + +use crate::db::DbConnection; +use crate::errors::{ResourceAction, ResourceType, ServiceError}; +use crate::jwt::{Audience, JWTToken, Permission}; +use crate::models::User; + +/// Helper trait that exposes methods for checking specific permissions +pub trait HasPermission { + /// Get the user ID associated with the JWT token + fn get_user_uuid(&self) -> Uuid; + + /// Test if the user has permission to do something + fn has_permission(&self, p: Permission) -> bool; + + // ================================================== + // Make sure the user ID is acutally in the database + // ================================================== + fn validate_user_id(&self, conn: &DbConnection) -> Result { + let user_id = self.get_user_uuid(); + User::find_optional(&user_id, conn)?.ok_or_else(|| ServiceError::JWTNoSuchUser { user_id }) + } + + // =================================== + // Methods to test user permissions + // =================================== + fn test_can_manage_account(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::User, + ResourceAction::Update, + )) + } + } + + fn test_can_view_elections(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::ReadPrivate, + )) + } + } + + fn test_can_create_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::CreateElection) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Create, + )) + } + } + + fn test_can_register_for_election(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Register) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Register, + )) + } + } + + fn test_can_vote(&self) -> Result<(), ServiceError> { + if self.has_permission(Permission::CanLogin) && self.has_permission(Permission::Vote) { + Ok(()) + } else { + Err(ServiceError::ForbiddenResourceAction( + ResourceType::Election, + ResourceAction::Vote, + )) + } + } +} + +impl HasPermission for JWTToken { + fn get_user_uuid(&self) -> Uuid { + self.get_user_id() + } + + fn has_permission(&self, p: Permission) -> bool { + self.test_has_permission(p) + } +} diff --git a/server/src/jwt/mod.rs b/server/src/jwt/mod.rs new file mode 100644 index 0000000..e7b72c2 --- /dev/null +++ b/server/src/jwt/mod.rs @@ -0,0 +1,13 @@ +// +// Structures and functions related to JSON web tokens +// +mod has_permission; +mod refresh_token; + +pub use evoting_shared::jwt::*; // Re-export +pub use has_permission::HasPermission; +pub use refresh_token::RefreshToken; + +// Other JWT constants +pub const JWT_REFRESH_AUDIENCE: &str = "refresh"; +pub const JWT_REFRESH_EXPIRATION_MIN: i64 = 60; diff --git a/server/src/auth/refresh_token.rs b/server/src/jwt/refresh_token.rs similarity index 97% rename from server/src/auth/refresh_token.rs rename to server/src/jwt/refresh_token.rs index ffb5a0b..0f9ad42 100644 --- a/server/src/auth/refresh_token.rs +++ b/server/src/jwt/refresh_token.rs @@ -9,9 +9,9 @@ use std::collections::HashSet; use std::iter::FromIterator; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{Permission, JWT_ISSUER, JWT_REFRESH_AUDIENCE, JWT_REFRESH_EXPIRATION_MIN}; use crate::db::get_connection_from_request; use crate::errors::ServiceError; +use crate::jwt::{Permission, JWT_ISSUER, JWT_REFRESH_AUDIENCE, JWT_REFRESH_EXPIRATION_MIN}; use crate::models::User; /// Special JWT token that is designed to refresh an existing token diff --git a/server/src/lib.rs b/server/src/lib.rs index cd04356..8d2049b 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -3,17 +3,27 @@ extern crate diesel; #[macro_use] extern crate num_derive; +#[macro_use] +extern crate evoting_shared; // All internal code modules pub mod auth; pub mod config; -#[macro_use] -pub mod db; pub mod errors; pub mod handlers; +pub mod jwt; pub mod models; pub mod notifications; -pub mod protocol; pub mod schema; -pub mod utils; pub mod views; + +// Re-export modules from the shared library +pub mod db { + pub use evoting_shared::db::*; +} +pub mod protocol { + pub use evoting_shared::protocol::*; +} +pub mod utils { + pub use evoting_shared::utils::*; +} diff --git a/server/src/main.rs b/server/src/main.rs index 07a1a78..24351e5 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -4,11 +4,11 @@ use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod}; use simple_logger::SimpleLogger; use structopt::StructOpt; -use evoting_server::auth; use evoting_server::config; use evoting_server::db; use evoting_server::errors::ServiceError; use evoting_server::handlers; +use evoting_server::jwt; #[actix_web::main] async fn main() -> anyhow::Result<()> { @@ -24,14 +24,18 @@ async fn main() -> anyhow::Result<()> { log::set_max_level(LevelFilter::Info); } - // Database connection pool and web server - let connection_pool = db::establish_new_connection_pool()?; + // Database connection pool + let database_url = + config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; + let connection_pool = db::open_new_connection_pool(&database_url)?; + + // Build the web server let mut server = HttpServer::new(move || { App::new() // Connect to database .data(connection_pool.clone()) // Encryption secret for JSON Web Token - .data(auth::JWTSecret::new(config::get_jwt_secret())) + .data(jwt::JWTSecret::new(config::get_jwt_secret())) // Enable logger .wrap(middleware::Logger::default()) // Configure error handlers diff --git a/server/src/notifications/send.rs b/server/src/notifications/send.rs index d652dea..89b931a 100644 --- a/server/src/notifications/send.rs +++ b/server/src/notifications/send.rs @@ -1,10 +1,10 @@ use actix_web::client::Client; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::config; use crate::db::DbConnection; use crate::errors::ClientRequestError; +use crate::jwt::{JWTSecret, ServerToken, DEFAULT_PERMISSIONS}; use crate::models::{Commitment, Election, Question, User}; use crate::notifications::{server_types, AllServerMessages}; use crate::utils::ConvertBigInt; diff --git a/server/src/protocol/count_ballot_votes.rs b/server/src/protocol/count_ballot_votes.rs deleted file mode 100644 index a2b2147..0000000 --- a/server/src/protocol/count_ballot_votes.rs +++ /dev/null @@ -1,106 +0,0 @@ -use curv_kzen::arithmetic::traits::Converter; -use curv_kzen::BigInt; -use std::iter; - -/// -/// Test the validity of the voting vector, then count the number of votes -/// -/// On error, this returns None -/// On success, it returns the number of votes for each candidate -/// -pub fn count_ballot_votes( - forward_ballot: &BigInt, - reverse_ballot: &BigInt, - num_candidates: i64, - num_voters: i64, - no_vote_count: usize, -) -> Option> { - let total_bits = (num_candidates * num_voters) as usize; - let forward_bits = get_bits(forward_ballot, total_bits); - let reverse_bits = get_bits(reverse_ballot, total_bits); - - // Step 1: Make sure the forward and reverse bits match - for (f, r) in forward_bits.iter().zip(reverse_bits.iter().rev()) { - if *f != *r { - return None; - } - } - - // Step 2: Make sure each chunk has, at most, only one candidate selected - let chunks = get_chunks(&forward_bits, num_candidates as usize); - let (voted, no_vote) = match verify_chunks(&chunks) { - Some((voted, no_vote)) => (voted, no_vote), - None => return None, - }; - - // Step 3: Make sure the number of voted bits matches the users who voted - if voted + no_vote != (num_voters as usize) || no_vote != no_vote_count { - return None; - } - - // All checks passed! - Some(count_votes(&chunks, num_candidates as usize)) -} - -/// Convert the integer voting vector into a vector of bits -fn get_bits(input: &BigInt, total_bits: usize) -> Vec { - let reverse_bits: Vec = input - .to_str_radix(2) - .chars() - .rev() - .filter(|c| c.is_numeric()) - .map(|x| x == '1') - .chain(iter::repeat(false)) - .take(total_bits) - .collect(); - - reverse_bits.into_iter().rev().collect() -} - -/// Convert the vector of bits into chunks for each candidate -fn get_chunks(input: &[bool], num_candidates: usize) -> Vec> { - input - .chunks(num_candidates) - .map(|c| c.into_iter().cloned().collect()) - .collect() -} - -/// Make sure each chunk only has, at most, one candidate -/// Returns Some((voted, didn't vote)) on success, or None on failure -fn verify_chunks(input: &Vec>) -> Option<(usize, usize)> { - let mut voted = 0; - let mut no_vote = 0; - - for chunk in input { - let num_votes = chunk.into_iter().filter(|c| **c).count(); - match num_votes { - 0 => no_vote += 1, - 1 => voted += 1, - _ => return None, - } - } - - Some((voted, no_vote)) -} - -/// Total up the votes for each candidate -/// -/// This function assumes that the chunk input has already been validated by verify_chunks -fn count_votes(input: &Vec>, num_candidates: usize) -> Vec { - let mut votes = vec![0; num_candidates]; - - for chunk in input { - // Searches for the first candidate bit set in the chunk - if let Some(candidate) = chunk - .into_iter() - .rev() - .enumerate() - .filter_map(|(i, c)| (*c).then(|| i)) - .next() - { - votes[candidate] += 1; - } - } - - votes -} diff --git a/server/src/protocol/generator.rs b/server/src/protocol/generator.rs deleted file mode 100644 index 34c788d..0000000 --- a/server/src/protocol/generator.rs +++ /dev/null @@ -1,48 +0,0 @@ -use curv_kzen::arithmetic::{Modulo, One}; -use curv_kzen::BigInt; -use kzen_paillier::keygen::PrimeSampable; - -/// Returns a (generator, prime) pair for Z*p with at least n bits -/// -/// We generate a safe prime p = 2*q + 1, where q is also prime. -/// -/// To find the primitive root, we use Euler's totient function Φ(p) = p - 1. -/// Start by factorizing Φ(p). Since p-1 = 2*q, our factors are always 2 and q. -/// -/// Then, for all potential g in 2 ..= Φ(p) and all factors f of Φ(p), we confirm: -/// -/// g^(Φ(p)/f) != 1 (mod p) -/// -/// If this is true for every factor of Φ(p), then g is indeed a primitive root. -/// -/// Since p is prime, this is GUARANTEED to return a valid primitive root. -pub fn generator_prime_pair(num_bits: usize) -> (BigInt, BigInt) { - // Pick a random large prime - let p = BigInt::sample_safe_prime(num_bits); - - // To find primitive root, we consider the Euler's totient Φ(p) - // Since p is prime, Φ(p) = (p-1) - let totient = &p - 1; - - // Since p is a safe prime, we know p = 2*q + 1 - // So the prime factors of Φ(p) = p-1 = 2*q are always [2, q] - let factors = vec![BigInt::from(2), &totient / 2]; - - // There ALWAYS exists a primitive root somewhere 2 ..= Φ(p) - let mut g = BigInt::from(1); - 'next_generator: while &g <= &totient { - g = &g + 1; - - for factor in &factors { - // Check if g^(Φ(p) / factor) != 1 (mod p) - if BigInt::mod_pow(&g, &(&totient / factor), &p).is_one() { - continue 'next_generator; - } - } - - // We found one! - break; - } - - (g, p) -} diff --git a/server/src/protocol/mod.rs b/server/src/protocol/mod.rs deleted file mode 100644 index d09c68f..0000000 --- a/server/src/protocol/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Functions and structures related to the math behind the e-voting protocol -// -mod count_ballot_votes; -mod generator; - -pub use count_ballot_votes::count_ballot_votes; -pub use generator::generator_prime_pair; diff --git a/server/src/schema.rs b/server/src/schema.rs index 65e84fc..e3ae4dc 100644 --- a/server/src/schema.rs +++ b/server/src/schema.rs @@ -73,11 +73,4 @@ joinable!(questions -> elections (election_id)); joinable!(registrations -> elections (election_id)); joinable!(registrations -> users (user_id)); -allow_tables_to_appear_in_same_query!( - candidates, - commitments, - elections, - questions, - registrations, - users, -); +allow_tables_to_appear_in_same_query!(candidates, commitments, elections, questions, registrations, users,); diff --git a/server/src/utils/convert_bigint.rs b/server/src/utils/convert_bigint.rs deleted file mode 100644 index 547469c..0000000 --- a/server/src/utils/convert_bigint.rs +++ /dev/null @@ -1,83 +0,0 @@ -use bigdecimal::BigDecimal; -use curv_kzen::arithmetic::{BigInt, Converter, NumberTests}; -use num::bigint::{BigInt as NumBigInt, Sign}; - -/// -/// Trait used to simplify converting between BigInt and BigDecimal -/// -pub trait ConvertBigInt { - fn to_bigint(&self) -> BigInt; - fn to_bigdecimal(&self) -> BigDecimal; - - fn from_bigint(bigint: BigInt) -> Self; - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self; -} - -impl ConvertBigInt for BigInt { - fn to_bigint(&self) -> BigInt { - self.clone() - } - - fn to_bigdecimal(&self) -> BigDecimal { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(self), &self.to_bytes()), 0) - } - - fn from_bigint(bigint: BigInt) -> Self { - bigint - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - let (bigint, _exponent) = bigdecimal.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } -} - -impl ConvertBigInt for BigDecimal { - fn to_bigint(&self) -> BigInt { - let (bigint, _exponent) = self.as_bigint_and_exponent(); - let (sign, bytes) = bigint.to_bytes_be(); - - // Parse from bytes and handle the negative sign - let result = BigInt::from_bytes(&bytes); - if sign == Sign::Minus { - -result - } else { - result - } - } - - fn to_bigdecimal(&self) -> BigDecimal { - self.clone() - } - - fn from_bigint(bigint: BigInt) -> Self { - BigDecimal::new(NumBigInt::from_bytes_be(get_sign(&bigint), &bigint.to_bytes()), 0) - } - - fn from_bigdecimal(bigdecimal: BigDecimal) -> Self { - bigdecimal - } -} - -/// -/// Figure out the sign of the input BigInt -/// -fn get_sign(input: &BigInt) -> Sign { - if BigInt::is_zero(input) { - return Sign::NoSign; - } - - if BigInt::is_negative(input) { - Sign::Minus - } else { - Sign::Plus - } -} diff --git a/server/src/utils/is_offensive_string.rs b/server/src/utils/is_offensive_string.rs deleted file mode 100644 index 42b669d..0000000 --- a/server/src/utils/is_offensive_string.rs +++ /dev/null @@ -1,26 +0,0 @@ -use censor::Censor; -use lazy_static::lazy_static; - -// Additional words to censor -const EXTRA_WORDS: &[&str] = &[ - "anal", "anus", "arse", "ball", "barf", "bastard", "biatch", "bloody", "blow", "bollock", "bollok", "boner", - "booger", "bugger", "bum", "butt", "clitoris", "cock", "coon", "crap", "crib", "cunt", "dildo", "dyke", "fag", - "fart", "feck", "fellate", "fellatio", "felching", "fudge", "flange", "homo", "jerk", "jizz", "knob", "labia", - "lmao", "lmfao", "muff", "nigga", "omg", "pee", "piss", "poo", "poop", "prick", "pube", "puke", "queer", "scrotum", - "slut", "smegma", "spunk", "tit", "tosser", "turd", "twat", "wank", "wtf", -]; - -lazy_static! { - static ref CUSTOM_CENSOR: Censor = Censor::Custom(EXTRA_WORDS.iter().map(|s| String::from(*s)).collect()); -} - -// -// Censor the string that it contains no offensive or vulgar words -// Returns true if the string fails the test -// -pub fn is_offensive_string(string: &str) -> bool { - Censor::Standard.check(string) - || Censor::Sex.check(string) - || Censor::Zealous.check(string) - || CUSTOM_CENSOR.check(string) -} diff --git a/server/src/utils/mod.rs b/server/src/utils/mod.rs deleted file mode 100644 index 00330f3..0000000 --- a/server/src/utils/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -// -// General-purpose functions and objects -// -mod convert_bigint; -mod is_offensive_string; -mod new_safe_uuid_v4; -pub mod serialize_option_bigint; - -pub use convert_bigint::ConvertBigInt; -pub use is_offensive_string::is_offensive_string; -pub use new_safe_uuid_v4::new_safe_uuid_v4; diff --git a/server/src/utils/new_safe_uuid_v4.rs b/server/src/utils/new_safe_uuid_v4.rs deleted file mode 100644 index 5765f0d..0000000 --- a/server/src/utils/new_safe_uuid_v4.rs +++ /dev/null @@ -1,19 +0,0 @@ -use uuid_b64::UuidB64 as Uuid; - -use super::is_offensive_string; - -// -// Censor the base-64 UUID V4 text so that it contains no offensive or vulgar words -// The probability of such words appearing is very small, but we still want to be extra safe -// From experimental tests, only 1.6% to 1.7% of generated UUIDs even remotely fail the censorship check -// -pub fn new_safe_uuid_v4() -> Uuid { - loop { - let uuid = Uuid::new(); - if is_offensive_string(&uuid.to_istring()) { - continue; - } - - return uuid; - } -} diff --git a/server/src/utils/serialize_option_bigint.rs b/server/src/utils/serialize_option_bigint.rs deleted file mode 100644 index d59403d..0000000 --- a/server/src/utils/serialize_option_bigint.rs +++ /dev/null @@ -1,40 +0,0 @@ -use curv_kzen::arithmetic::traits::Converter; -use curv_kzen::BigInt; -use serde::{de, ser}; -use std::fmt; - -pub fn serialize(x: &Option, serializer: S) -> Result { - match x { - Some(x) => serializer.serialize_str(&x.to_str_radix(10)), - None => serializer.serialize_none(), - } -} - -pub fn deserialize<'de, D: de::Deserializer<'de>>(deserializer: D) -> Result, D::Error> { - struct OptionBigIntVisitor; - - impl<'de> de::Visitor<'de> for OptionBigIntVisitor { - type Value = Option; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("option of bigint") - } - - #[inline] - fn visit_unit(self) -> Result { - Ok(None) - } - - #[inline] - fn visit_none(self) -> Result, E> { - Ok(None) - } - - #[inline] - fn visit_some>(self, deserializer: D) -> Result { - kzen_paillier::serialize::bigint::deserialize(deserializer).map(Some) - } - } - - deserializer.deserialize_option(OptionBigIntVisitor) -} diff --git a/server/src/views/auth.rs b/server/src/views/auth.rs index cfdc511..5f10ab3 100644 --- a/server/src/views/auth.rs +++ b/server/src/views/auth.rs @@ -1,8 +1,8 @@ use serde::Serialize; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{ClientToken, JWTSecret, RefreshToken, DEFAULT_PERMISSIONS}; use crate::errors::ServiceError; +use crate::jwt::{ClientToken, JWTSecret, RefreshToken, DEFAULT_PERMISSIONS}; use crate::models::User; #[derive(Serialize)] @@ -38,7 +38,7 @@ impl LoginResult { let refresh_encoding_key = user.get_refresh_encoding_key(); // Generate the JWT tokens - let client_token = ClientToken::new(user.clone(), DEFAULT_PERMISSIONS); + let client_token = ClientToken::new(user.id, &user.name, &user.email, DEFAULT_PERMISSIONS); let refresh_token = RefreshToken::new(user, DEFAULT_PERMISSIONS); // Encode the tokens diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 1c4249f..6ecea28 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -5,6 +5,7 @@ authors = ["Bryan McClain "] edition = "2018" [dependencies] +actix-codec = "0.3.0" actix-http = "2.2.1" actix-web = { version = "3", features = ["openssl"] } actix-web-httpauth = "0.5.1" @@ -16,6 +17,8 @@ chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } futures = "0.3.17" +http = "0.2.5" +http-serde = "1.0.3" jsonwebtoken = "7.2.0" kzen-paillier = "0.4.2" lazy_static = "1.4.0" @@ -23,6 +26,7 @@ log = "0.4.14" num = "0.2.1" paste = "1.0.5" serde = "1.0.130" +serde_json = "1.0.68" serde_repr = "0.1.7" uuid = "0.6" uuid-b64 = { version = "0.1.1", features = ["serde", "diesel-uuid"] } diff --git a/shared/src/auth/audience.rs b/shared/src/auth/audience.rs deleted file mode 100644 index 11fd88c..0000000 --- a/shared/src/auth/audience.rs +++ /dev/null @@ -1,67 +0,0 @@ -use serde::Deserialize; -use std::collections::HashSet; -use std::iter::FromIterator; - -/// Generic trait shared by all audience types -/// -/// An audience specifies which routes a JWT can access -pub trait Audience { - const TEXT: &'static str; - const ACCEPTS: &'static [&'static str]; - - /// Get the name to show for this audience type - fn get_name() -> String { - Self::TEXT.to_string() - } - - /// Get the list of all audiences accepted by this type - fn accepts() -> HashSet { - HashSet::from_iter(Self::ACCEPTS.iter().cloned().map(String::from)) - } -} - -/// Route is available to all token types -#[derive(Deserialize)] -pub struct All; - -impl Audience for All { - const TEXT: &'static str = "all"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only", "server-only", "collector-only"]; -} - -/// Route can only be called by the frontend client -#[derive(Deserialize)] -pub struct ClientOnly; - -impl Audience for ClientOnly { - const TEXT: &'static str = "client-only"; - const ACCEPTS: &'static [&'static str] = &["all", "client-only"]; -} - -/// Route can only be called by the server -#[derive(Deserialize)] -pub struct ServerOnly; - -impl Audience for ServerOnly { - const TEXT: &'static str = "server-only"; - const ACCEPTS: &'static [&'static str] = &["all", "server-only"]; -} - -/// Route can only be called by a collector -#[derive(Deserialize)] -pub struct CollectorOnly; - -impl Audience for CollectorOnly { - const TEXT: &'static str = "collector-only"; - const ACCEPTS: &'static [&'static str] = &["all", "collector-only"]; -} - -/// Route can only be called by a mediator -#[derive(Deserialize)] -pub struct MediatorOnly; - -impl Audience for MediatorOnly { - const TEXT: &'static str = "mediator-only"; - const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; -} - diff --git a/shared/src/auth/constants.rs b/shared/src/auth/constants.rs deleted file mode 100644 index 27f7904..0000000 --- a/shared/src/auth/constants.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub const JWT_ISSUER: &str = "evoting"; -pub const JWT_EXPIRATION_MIN: i64 = 10; - -pub const JWT_REFRESH_AUDIENCE: &str = "refresh"; -pub const JWT_REFRESH_EXPIRATION_MIN: i64 = 60; diff --git a/shared/src/auth/jwt_secret.rs b/shared/src/auth/jwt_secret.rs deleted file mode 100644 index ebf8054..0000000 --- a/shared/src/auth/jwt_secret.rs +++ /dev/null @@ -1,21 +0,0 @@ -use jsonwebtoken::{DecodingKey, EncodingKey}; - -/// Simple wrapper struct to store the JWT secret -#[derive(Debug, Clone)] -pub struct JWTSecret { - secret: String, -} - -impl JWTSecret { - pub fn new(secret: impl Into) -> Self { - Self { secret: secret.into() } - } - - pub fn get_encoding_key(&self) -> EncodingKey { - EncodingKey::from_secret(self.secret.as_bytes()) - } - - pub fn get_decoding_key<'a>(&'a self) -> DecodingKey<'a> { - DecodingKey::from_secret(self.secret.as_bytes()) - } -} diff --git a/shared/src/auth/mod.rs b/shared/src/auth/mod.rs index 943edd5..bc0357d 100644 --- a/shared/src/auth/mod.rs +++ b/shared/src/auth/mod.rs @@ -1,14 +1,6 @@ // // Structures and functions related to user authentication and authorization // -pub mod audience; -mod constants; -mod jwt_secret; -mod jwt_token; mod permission; -pub use audience::Audience; -pub use constants::*; -pub use jwt_secret::JWTSecret; -pub use jwt_token::*; pub use permission::{Permission, DEFAULT_PERMISSIONS}; diff --git a/shared/src/db/sql_enum.rs b/shared/src/db/sql_enum.rs index fe43487..b347383 100644 --- a/shared/src/db/sql_enum.rs +++ b/shared/src/db/sql_enum.rs @@ -14,6 +14,7 @@ macro_rules! sql_enum { } #[allow(unused)] +#[macro_export] macro_rules! enum_internals { ($($t:ty)*) => ($( diff --git a/shared/src/errors/client_request_error.rs b/shared/src/errors/client_request_error.rs index 5c62f49..95424e8 100644 --- a/shared/src/errors/client_request_error.rs +++ b/shared/src/errors/client_request_error.rs @@ -40,7 +40,7 @@ impl ClientRequestError { .map_err(|_| Self::UnknownError(status))?; Err(Self::ResponseError(error_response)) - } + }, } } @@ -67,7 +67,7 @@ impl ClientRequestError { .map_err(|_| Self::UnknownError(status))?; Err(Self::ResponseError(error_response)) - } + }, } } } diff --git a/shared/src/errors/mod.rs b/shared/src/errors/mod.rs index 7555903..f40464d 100644 --- a/shared/src/errors/mod.rs +++ b/shared/src/errors/mod.rs @@ -3,10 +3,12 @@ // mod client_request_error; mod error_response; -mod generic_error; mod global_error_codes; +mod shared_error; +mod websocket_error; pub use client_request_error::ClientRequestError; pub use error_response::ErrorResponse; -pub(crate) use generic_error::SharedError; pub use global_error_codes::GlobalErrorCode; +pub(crate) use shared_error::SharedError; +pub use websocket_error::WebsocketError; diff --git a/shared/src/errors/generic_error.rs b/shared/src/errors/shared_error.rs similarity index 100% rename from shared/src/errors/generic_error.rs rename to shared/src/errors/shared_error.rs diff --git a/collector/src/errors/websocket_error.rs b/shared/src/errors/websocket_error.rs similarity index 99% rename from collector/src/errors/websocket_error.rs rename to shared/src/errors/websocket_error.rs index 3b7b9c3..a5d5822 100644 --- a/collector/src/errors/websocket_error.rs +++ b/shared/src/errors/websocket_error.rs @@ -68,7 +68,7 @@ impl WebsocketError { .map_err(|e| Self::ProtocolError(e))?; return Err(Self::ProtocolError(e)); - } + }, Some(Ok(resp)) => resp, }; diff --git a/collector/src/auth/audience.rs b/shared/src/jwt/audience.rs similarity index 99% rename from collector/src/auth/audience.rs rename to shared/src/jwt/audience.rs index 11fd88c..3d7bda1 100644 --- a/collector/src/auth/audience.rs +++ b/shared/src/jwt/audience.rs @@ -64,4 +64,3 @@ impl Audience for MediatorOnly { const TEXT: &'static str = "mediator-only"; const ACCEPTS: &'static [&'static str] = &["all", "mediator-only"]; } - diff --git a/collector/src/auth/jwt_secret.rs b/shared/src/jwt/jwt_secret.rs similarity index 100% rename from collector/src/auth/jwt_secret.rs rename to shared/src/jwt/jwt_secret.rs diff --git a/shared/src/auth/jwt_token.rs b/shared/src/jwt/jwt_token.rs similarity index 95% rename from shared/src/auth/jwt_token.rs rename to shared/src/jwt/jwt_token.rs index cf16c2e..e546daa 100644 --- a/shared/src/auth/jwt_token.rs +++ b/shared/src/jwt/jwt_token.rs @@ -10,8 +10,9 @@ use std::iter::FromIterator; use std::marker::PhantomData; use uuid_b64::UuidB64 as Uuid; -use crate::auth::{audience, Audience, JWTSecret, Permission, JWT_EXPIRATION_MIN, JWT_ISSUER}; +use crate::auth::Permission; use crate::errors::SharedError; +use crate::jwt::{audience, Audience, JWTSecret, JWT_EXPIRATION_MIN, JWT_ISSUER}; // Type aliases for the different JWT tokens pub type ClientToken = JWTToken; @@ -61,23 +62,28 @@ pub struct JWTAnyData { impl JWTToken where A: Audience, - T: Serialize + DeserializeOwned, { - /// Encode the JSON Web Token into a string - pub fn encode(&self, key: &EncodingKey) -> Result { - Ok(encode(&Header::default(), self, key)?) - } - pub fn get_user_id(&self) -> Uuid { self.sub } /// Test if the user has permission to do something - pub fn has_permission(&self, p: Permission) -> bool { + pub fn test_has_permission(&self, p: Permission) -> bool { self.permissions.contains(&p) } } +impl JWTToken +where + A: Audience, + T: Serialize + DeserializeOwned, +{ + /// Encode the JSON Web Token into a string + pub fn encode(&self, key: &EncodingKey) -> Result { + Ok(encode(&Header::default(), self, key)?) + } +} + impl JWTToken where A: Audience, diff --git a/shared/src/jwt/mod.rs b/shared/src/jwt/mod.rs new file mode 100644 index 0000000..8d792ca --- /dev/null +++ b/shared/src/jwt/mod.rs @@ -0,0 +1,15 @@ +// +// Structures and functions related to JSON web tokens +// +pub mod audience; +mod jwt_secret; +mod jwt_token; + +pub use crate::auth::{Permission, DEFAULT_PERMISSIONS}; // Re-export +pub use audience::Audience; +pub use jwt_secret::JWTSecret; +pub use jwt_token::*; + +// Other JWT constants +pub const JWT_ISSUER: &str = "evoting"; +pub const JWT_EXPIRATION_MIN: i64 = 10; diff --git a/shared/src/lib.rs b/shared/src/lib.rs index e2d5516..f2f6e62 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -2,5 +2,6 @@ pub mod auth; #[macro_use] pub mod db; pub mod errors; +pub mod jwt; pub mod protocol; pub mod utils; diff --git a/shared/src/utils/mod.rs b/shared/src/utils/mod.rs index df59e69..5ef014f 100644 --- a/shared/src/utils/mod.rs +++ b/shared/src/utils/mod.rs @@ -4,10 +4,9 @@ mod convert_bigint; mod is_offensive_string; mod new_safe_uuid_v4; -mod password_complexity; pub mod serialize_option_bigint; +pub mod serialize_option_uri; pub use convert_bigint::ConvertBigInt; pub use is_offensive_string::is_offensive_string; pub use new_safe_uuid_v4::new_safe_uuid_v4; -pub use password_complexity::validate_password_complexity; diff --git a/shared/src/utils/password_complexity.rs b/shared/src/utils/password_complexity.rs deleted file mode 100644 index f3c0149..0000000 --- a/shared/src/utils/password_complexity.rs +++ /dev/null @@ -1,45 +0,0 @@ -use zxcvbn::{zxcvbn, Entropy, ZxcvbnError}; - -/// Response from the password complexity check -#[derive(Debug, Clone)] -pub enum PasswordComplexityResponse { - PasswordOkay, - NotEnoughEntropy(Entropy), - ZxcvbnError(ZxcvbnError), -} - -// 0 - Too guessable: risky password. (guesses < 10^3) -// 1 - Very guessable: protection from throttled online attacks. (guesses < 10^6) -// 2 - Somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8) -// 3 - Safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10) -// 4 - Very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10) -const MINIMUM_PASSWORD_COMPLEXITY: u8 = 3; - -const SITE_SPECIFIC_PASSWORD_DICTIONARY: &[&str] = &["evoting", "voting", "voter"]; - -/// Use the zxcvbn library to verify the password complexity -/// -/// # Returns -/// Nested results for error handling -pub fn validate_password_complexity(password: &str, name: &str, email: &str) -> PasswordComplexityResponse { - let mut user_inputs: Vec<&str> = vec![name, email]; - user_inputs.extend_from_slice(SITE_SPECIFIC_PASSWORD_DICTIONARY); - - match zxcvbn(password, user_inputs.as_slice()) { - Ok(entropy) if entropy.score() >= MINIMUM_PASSWORD_COMPLEXITY => PasswordComplexityResponse::PasswordOkay, - Ok(entropy) => entropy.into(), - Err(e) => e.into(), - } -} - -impl From for PasswordComplexityResponse { - fn from(entropy: Entropy) -> Self { - Self::NotEnoughEntropy(entropy) - } -} - -impl From for PasswordComplexityResponse { - fn from(error: ZxcvbnError) -> Self { - Self::ZxcvbnError(error) - } -} diff --git a/mediator/src/utils/serialize_option_uri.rs b/shared/src/utils/serialize_option_uri.rs similarity index 100% rename from mediator/src/utils/serialize_option_uri.rs rename to shared/src/utils/serialize_option_uri.rs From 2474ad144a7ce3a16dff30a2ab0e90a644e89965 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 21:53:52 -0500 Subject: [PATCH 5/7] Used 'cargo udeps' to remove some unused dependencies --- Cargo.lock | 4 ---- Cargo.toml | 2 +- collector/Cargo.toml | 4 +++- mediator/Cargo.toml | 5 +++-- shared/Cargo.toml | 4 +++- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0737b5d..594c19c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1196,7 +1196,6 @@ dependencies = [ "futures", "http", "http-serde", - "itertools", "jsonwebtoken", "kzen-paillier", "lazy_static 1.4.0", @@ -1226,7 +1225,6 @@ dependencies = [ "actix-codec", "actix-http", "actix-web", - "actix-web-actors", "actix-web-httpauth", "anyhow", "awc", @@ -1240,7 +1238,6 @@ dependencies = [ "futures", "http", "http-serde", - "itertools", "jsonwebtoken", "kzen-paillier", "lazy_static 1.4.0", @@ -1359,7 +1356,6 @@ dependencies = [ "serde_repr", "uuid", "uuid-b64", - "zxcvbn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f81f207..a5442c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,4 @@ members = [ "mediator", "collector", "notifications", -] \ No newline at end of file +] diff --git a/collector/Cargo.toml b/collector/Cargo.toml index 2faf7a4..e5f06fa 100644 --- a/collector/Cargo.toml +++ b/collector/Cargo.toml @@ -24,7 +24,6 @@ evoting-shared = { path = "../shared" } futures = "0.3.17" http = "0.2.5" http-serde = "1.0.3" -itertools = "0.10.1" jsonwebtoken = "7.2.0" kzen-paillier = "0.4.2" lazy_static = "1.4.0" @@ -44,3 +43,6 @@ structopt = "0.3.23" uuid = "0.6" uuid-b64 = { version = "0.1.1", features = ["serde", "diesel-uuid"] } validator = { version = "0.14.0", features = ["derive"] } + +[package.metadata.cargo-udeps.ignore] +normal = ["paste"] diff --git a/mediator/Cargo.toml b/mediator/Cargo.toml index 1815d6d..0c7b091 100644 --- a/mediator/Cargo.toml +++ b/mediator/Cargo.toml @@ -10,7 +10,6 @@ actix = "0.10.0" actix-codec = "0.3.0" actix-http = "2.2.1" actix-web = { version = "3", features = ["openssl"] } -actix-web-actors = "3.0.0" actix-web-httpauth = "0.5.1" anyhow = "1.0.44" awc = "2.0.3" @@ -24,7 +23,6 @@ evoting-shared = { path = "../shared" } futures = "0.3.17" http = "0.2.5" http-serde = "1.0.3" -itertools = "0.10.1" jsonwebtoken = "7.2.0" kzen-paillier = "0.4.2" lazy_static = "1.4.0" @@ -44,3 +42,6 @@ structopt = "0.3.23" uuid = "0.6" uuid-b64 = { version = "0.1.1", features = ["serde", "diesel-uuid"] } validator = { version = "0.14.0", features = ["derive"] } + +[package.metadata.cargo-udeps.ignore] +normal = ["paste"] diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 6ecea28..13d09d4 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -30,4 +30,6 @@ serde_json = "1.0.68" serde_repr = "0.1.7" uuid = "0.6" uuid-b64 = { version = "0.1.1", features = ["serde", "diesel-uuid"] } -zxcvbn = "2.1.1" + +[package.metadata.cargo-udeps.ignore] +normal = ["paste"] From 17f96f97a6994dba6bb791955d84647957651cf5 Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Tue, 18 Jan 2022 23:57:44 -0500 Subject: [PATCH 6/7] Reverted to previous version of simple_logger to fix panic issue --- Cargo.lock | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 594c19c..560bf3b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3238,14 +3238,14 @@ dependencies = [ [[package]] name = "simple_logger" -version = "1.16.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b60258a35dc3cb8a16890b8fd6723349bfa458d7960e25e633f1b1c19d7b5e" +checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" dependencies = [ "atty", + "chrono", "colored", "log", - "time 0.3.5", "winapi 0.3.9", ] @@ -3505,22 +3505,11 @@ dependencies = [ "libc", "standback", "stdweb", - "time-macros 0.1.1", + "time-macros", "version_check", "winapi 0.3.9", ] -[[package]] -name = "time" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" -dependencies = [ - "itoa 0.4.8", - "libc", - "time-macros 0.2.3", -] - [[package]] name = "time-macros" version = "0.1.1" @@ -3531,12 +3520,6 @@ dependencies = [ "time-macros-impl", ] -[[package]] -name = "time-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" - [[package]] name = "time-macros-impl" version = "0.1.2" From af20ed10ac5c6a48fece5dfe407f6d9f8f734c2b Mon Sep 17 00:00:00 2001 From: Bryan McClain Date: Wed, 19 Jan 2022 00:47:27 -0500 Subject: [PATCH 7/7] Now embeds database migrations inside executables --- Cargo.lock | 34 +++++++++++++++ collector/Cargo.toml | 1 + collector/src/main.rs | 7 +++- mediator/Cargo.toml | 1 + mediator/src/main.rs | 7 +++- server/Cargo.toml | 1 + server/src/main.rs | 7 +++- shared/src/db/migration_logger.rs | 70 +++++++++++++++++++++++++++++++ shared/src/db/mod.rs | 2 + 9 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 shared/src/db/migration_logger.rs diff --git a/Cargo.lock b/Cargo.lock index 560bf3b..e6ee817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1069,6 +1069,16 @@ dependencies = [ "syn 1.0.85", ] +[[package]] +name = "diesel_migrations" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" +dependencies = [ + "migrations_internals", + "migrations_macros", +] + [[package]] name = "digest" version = "0.8.1" @@ -1191,6 +1201,7 @@ dependencies = [ "chrono", "curv-kzen", "diesel", + "diesel_migrations", "dotenv", "evoting-shared", "futures", @@ -1233,6 +1244,7 @@ dependencies = [ "chrono", "curv-kzen", "diesel", + "diesel_migrations", "dotenv", "evoting-shared", "futures", @@ -1303,6 +1315,7 @@ dependencies = [ "chrono", "curv-kzen", "diesel", + "diesel_migrations", "dotenv", "evoting-shared", "futures", @@ -2073,6 +2086,27 @@ dependencies = [ "cfg-if 0.1.10", ] +[[package]] +name = "migrations_internals" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b4fc84e4af020b837029e017966f86a1c2d5e83e64b589963d5047525995860" +dependencies = [ + "diesel", +] + +[[package]] +name = "migrations_macros" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9753f12909fd8d923f75ae5c3258cae1ed3c8ec052e1b38c93c21a6d157f789c" +dependencies = [ + "migrations_internals", + "proc-macro2 1.0.36", + "quote 1.0.14", + "syn 1.0.85", +] + [[package]] name = "mime" version = "0.3.16" diff --git a/collector/Cargo.toml b/collector/Cargo.toml index e5f06fa..896bee3 100644 --- a/collector/Cargo.toml +++ b/collector/Cargo.toml @@ -19,6 +19,7 @@ bigdecimal = { version = "0.1.2", features = ["serde"] } chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } +diesel_migrations = "1.4.0" dotenv = "0.15.0" evoting-shared = { path = "../shared" } futures = "0.3.17" diff --git a/collector/src/main.rs b/collector/src/main.rs index da06f85..b5d0a75 100644 --- a/collector/src/main.rs +++ b/collector/src/main.rs @@ -15,6 +15,10 @@ use evoting_collector::errors::{ClientRequestError, ServiceError}; use evoting_collector::handlers; use evoting_collector::jwt::{CollectorToken, JWTSecret, Permission}; +#[macro_use] +extern crate diesel_migrations; +embed_migrations!(); + #[actix_web::main] async fn main() -> anyhow::Result<()> { // Parse ".env" configuration files and command-line arguments @@ -32,10 +36,11 @@ async fn main() -> anyhow::Result<()> { // Let the mediator know about this collector register_collector_with_mediator().await?; - // Database connection pool + // Database connection pool and migrations let database_url = config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; let connection_pool = db::open_new_connection_pool(&database_url)?; + embedded_migrations::run_with_output(&connection_pool.get()?, &mut db::MigrationLogger::default())?; // Build the web server let mut server = HttpServer::new(move || { diff --git a/mediator/Cargo.toml b/mediator/Cargo.toml index 0c7b091..0852841 100644 --- a/mediator/Cargo.toml +++ b/mediator/Cargo.toml @@ -18,6 +18,7 @@ bigdecimal = { version = "0.1.2", features = ["serde"] } chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } +diesel_migrations = "1.4.0" dotenv = "0.15.0" evoting-shared = { path = "../shared" } futures = "0.3.17" diff --git a/mediator/src/main.rs b/mediator/src/main.rs index 8c6680a..c3620e5 100644 --- a/mediator/src/main.rs +++ b/mediator/src/main.rs @@ -10,6 +10,10 @@ use evoting_mediator::errors::ServiceError; use evoting_mediator::handlers; use evoting_mediator::jwt; +#[macro_use] +extern crate diesel_migrations; +embed_migrations!(); + #[actix_web::main] async fn main() -> anyhow::Result<()> { // Parse ".env" configuration files and command-line arguments @@ -26,10 +30,11 @@ async fn main() -> anyhow::Result<()> { log::set_max_level(LevelFilter::Info); } - // Database connection pool + // Database connection pool and migrations let database_url = config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; let connection_pool = db::open_new_connection_pool(&database_url)?; + embedded_migrations::run_with_output(&connection_pool.get()?, &mut db::MigrationLogger::default())?; // Build the web server let mut server = HttpServer::new(move || { diff --git a/server/Cargo.toml b/server/Cargo.toml index 6ad4c68..62beab9 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -18,6 +18,7 @@ censor = "0.2.0" chrono = "0.4.19" curv-kzen = { package = "curv-kzen", version = "0.9.0" } diesel = { version = "1.4.8", features = ["postgres", "extras"] } +diesel_migrations = "1.4.0" dotenv = "0.15.0" evoting-shared = { path = "../shared" } futures = "0.3.17" diff --git a/server/src/main.rs b/server/src/main.rs index 24351e5..263ae3a 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -10,6 +10,10 @@ use evoting_server::errors::ServiceError; use evoting_server::handlers; use evoting_server::jwt; +#[macro_use] +extern crate diesel_migrations; +embed_migrations!(); + #[actix_web::main] async fn main() -> anyhow::Result<()> { // Parse ".env" configuration files and command-line arguments @@ -24,10 +28,11 @@ async fn main() -> anyhow::Result<()> { log::set_max_level(LevelFilter::Info); } - // Database connection pool + // Database connection pool and migrations let database_url = config::get_database_url().ok_or_else(|| anyhow::anyhow!("DATABASE_URL environment variable not set"))?; let connection_pool = db::open_new_connection_pool(&database_url)?; + embedded_migrations::run_with_output(&connection_pool.get()?, &mut db::MigrationLogger::default())?; // Build the web server let mut server = HttpServer::new(move || { diff --git a/shared/src/db/migration_logger.rs b/shared/src/db/migration_logger.rs new file mode 100644 index 0000000..a8697b1 --- /dev/null +++ b/shared/src/db/migration_logger.rs @@ -0,0 +1,70 @@ +use log::Level; +use std::io::{self, ErrorKind, Write}; +use std::str; + +#[derive(Debug)] +pub struct MigrationLogger { + level: Level, + buffer: String, +} + +impl MigrationLogger { + pub fn new(level: Level) -> Self { + Self { + level, + buffer: String::new(), + } + } + + fn write_lines(&mut self, write_remainder: bool) { + let (lines, remainder) = match self.buffer.rsplit_once('\n') { + None => return, + Some(split) => split, + }; + + // Log all lines currently stored in the buffer + for line in lines.lines() { + // Only log a line if it is NOT blank (all whitespace) + let trimmed = line.trim(); + if trimmed.len() > 0 { + log::log!(self.level, "{}", trimmed); + } + } + + // A call to "flush" will force-log the remainder, even if not a complete line + if write_remainder { + let trimmed_remainder = remainder.trim(); + if trimmed_remainder.len() > 0 { + log::log!(self.level, "{}", trimmed_remainder); + } + } + + self.buffer = remainder.to_string(); + } +} + +impl Default for MigrationLogger { + fn default() -> Self { + Self::new(Level::Info) + } +} + +impl Write for MigrationLogger { + fn write(&mut self, buf: &[u8]) -> io::Result { + // Append to the internal string buffer + let text = str::from_utf8(buf).map_err(|e| io::Error::new(ErrorKind::InvalidData, e))?; + self.buffer += text; + + // Then, write any complete lines to the log file + self.write_lines(false); + + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + // Write any complete lines, and the remaining text, to the log file + self.write_lines(true); + + Ok(()) + } +} diff --git a/shared/src/db/mod.rs b/shared/src/db/mod.rs index dfdb990..a72d558 100644 --- a/shared/src/db/mod.rs +++ b/shared/src/db/mod.rs @@ -4,6 +4,7 @@ mod db_connection; mod init; mod many_many_constructor; +mod migration_logger; mod types; #[macro_use] @@ -16,4 +17,5 @@ mod subtypes; pub use db_connection::{get_connection_from_request, DbConnection}; pub use init::{open_new_connection, open_new_connection_pool}; pub use many_many_constructor::ManyToManyConstructor; +pub use migration_logger::MigrationLogger; pub use types::{PgPool, PgPooledConnection};