mirror of https://github.com/mastodon/flodgatt
Postgres (#137)
* Revise Postgres to use `simple_query` * Fix bug in logging `ENV` config errors * Improve parsing of values from Postgres * Finish Postgres changes
This commit is contained in:
parent
016f49a2d8
commit
91186fb9f7
|
@ -37,6 +37,16 @@ dependencies = [
|
|||
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.11"
|
||||
|
@ -130,7 +140,7 @@ version = "0.4.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -406,7 +416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "flodgatt"
|
||||
version = "0.8.5"
|
||||
version = "0.9.0"
|
||||
dependencies = [
|
||||
"criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -414,7 +424,7 @@ dependencies = [
|
|||
"hashbrown 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lru 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres-openssl 0.2.0-rc.1 (git+https://github.com/sfackler/rust-postgres.git)",
|
||||
"pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -710,7 +720,7 @@ dependencies = [
|
|||
"h2 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -756,11 +766,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.2"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -908,7 +917,7 @@ dependencies = [
|
|||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -923,7 +932,7 @@ name = "mio-uds"
|
|||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -1159,7 +1168,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.1.2"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -1174,15 +1183,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "postgres"
|
||||
version = "0.17.0"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-postgres 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-postgres 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1235,7 +1244,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "postgres-types"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1325,7 +1334,7 @@ name = "r2d2_postgres"
|
|||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"r2d2 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1870,16 +1879,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.2.4"
|
||||
version = "0.2.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -1966,9 +1977,10 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-postgres"
|
||||
version = "0.5.1"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fallible-iterator 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1977,11 +1989,11 @@ dependencies = [
|
|||
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"phf 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres-protocol 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"postgres-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2018,7 +2030,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2080,7 +2092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2092,15 +2104,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.2.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytes 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2332,6 +2344,7 @@ dependencies = [
|
|||
"checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d"
|
||||
"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5"
|
||||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||
"checksum async-trait 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
|
@ -2412,7 +2425,7 @@ dependencies = [
|
|||
"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
|
||||
"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
|
||||
"checksum input_buffer 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8e1b822cc844905551931d6f81608ed5f50a79c1078a4e2b4d42dbc7c1eedfbf"
|
||||
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
|
||||
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
|
@ -2460,14 +2473,14 @@ dependencies = [
|
|||
"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662"
|
||||
"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0"
|
||||
"checksum phf_shared 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
|
||||
"checksum pin-project-lite 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e8822eb8bb72452f038ebf6048efa02c3fe22bf83f76519c9583e47fc194a422"
|
||||
"checksum pin-project-lite 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
|
||||
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
|
||||
"checksum pkg-config 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c1d2cfa5a714db3b5f24f0915e74fcdf91d09d496ba61329705dda7774d2af"
|
||||
"checksum postgres 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96dd5c8eddec65a5497798ebde2e5c74a93ef8b66782c1b09eeab9bb8538aebc"
|
||||
"checksum postgres 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18741b59a558e4dfdb9c968e8126dccbefd6a16bf54e3bc5668d420b4c4ed71b"
|
||||
"checksum postgres-openssl 0.2.0-rc.1 (git+https://github.com/sfackler/rust-postgres.git)" = "<none>"
|
||||
"checksum postgres-protocol 0.4.1 (git+https://github.com/sfackler/rust-postgres.git)" = "<none>"
|
||||
"checksum postgres-protocol 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a30f0e172ae0fb0653dbf777ad10a74b8e58d6de95a892f2e1d3e94a9df9a844"
|
||||
"checksum postgres-types 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eab1dd99401779ab03bc3872f196fb02c420e76f416c850be494a6f2d67287ad"
|
||||
"checksum postgres-types 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e634590e8812c500088d88db721195979223dabb05149f43cb50931d0ff5865d"
|
||||
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
|
||||
"checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
|
||||
"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
|
||||
|
@ -2543,7 +2556,7 @@ dependencies = [
|
|||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
|
||||
"checksum tokio 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "cec6c34409089be085de9403ba2010b80e36938c9ca992c4f67f407bb13db0b1"
|
||||
"checksum tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bcced6bb623d4bff3739c176c415f13c418f426395c169c9c3cd9a492c715b16"
|
||||
"checksum tokio 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "34ef16d072d2b6dc8b4a56c70f5c5ced1a37752116f8e7c1e80c659aa7cb6713"
|
||||
"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f"
|
||||
"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443"
|
||||
"checksum tokio-executor 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "83ea44c6c0773cc034771693711c35c677b4b5a4b21b9e7071704c54de7d555e"
|
||||
|
@ -2551,7 +2564,7 @@ dependencies = [
|
|||
"checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926"
|
||||
"checksum tokio-openssl 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "771d6246b170ae108d67d9963c23f31a579016c016d73bd4bd7d6ef0252afda7"
|
||||
"checksum tokio-postgres 0.4.0-rc.3 (git+https://github.com/sfackler/rust-postgres.git)" = "<none>"
|
||||
"checksum tokio-postgres 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c03cb0c66092269a9b280e9e4956cb23ce00b8a6b1b393f7700f7732ac4bf133"
|
||||
"checksum tokio-postgres 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "524da2f17264514c854ac770177bdb810f0db7e706ae69f143d6e6828e3c4fe3"
|
||||
"checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce"
|
||||
"checksum tokio-sync 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "5b2f843ffdf8d6e1f90bddd48da43f99ab071660cd92b7ec560ef3cdfd7a409a"
|
||||
"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119"
|
||||
|
@ -2560,7 +2573,7 @@ dependencies = [
|
|||
"checksum tokio-trace-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "350c9edade9830dc185ae48ba45667a445ab59f6167ef6d0254ec9d2430d9dd3"
|
||||
"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92"
|
||||
"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445"
|
||||
"checksum tokio-util 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "571da51182ec208780505a32528fc5512a8fe1443ab960b3f2f3ef093cd16930"
|
||||
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
|
||||
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
|
||||
"checksum tungstenite 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "577caf571708961603baf59d2e148d12931e0da2e4bb6c5b471dd4a524fef3aa"
|
||||
"checksum twoway 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "flodgatt"
|
||||
description = "A blazingly fast drop-in replacement for the Mastodon streaming api server"
|
||||
version = "0.8.5"
|
||||
version = "0.9.0"
|
||||
authors = ["Daniel Long Sockwell <daniel@codesections.com", "Julian Laubstein <contact@julianlaubstein.de>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -26,13 +26,25 @@ pub fn merge_dotenv() -> Result<()> {
|
|||
let res = dotenv::from_filename(env_file);
|
||||
|
||||
if let Ok(log_level) = env::var("RUST_LOG") {
|
||||
if res.is_err() && ["warn", "info", "trace", "debug"].contains(&log_level.as_str()) {
|
||||
eprintln!(
|
||||
if ["warn", "info", "trace", "debug"].contains(&log_level.as_str()) {
|
||||
let env_file = env::current_dir()
|
||||
.unwrap_or_else(|_| "./".into())
|
||||
.join(env_file);
|
||||
|
||||
match res {
|
||||
Err(dotenv::Error::LineParse(msg, line)) => eprintln!(
|
||||
" ERROR: could not parse environmental file at {:?}\n\
|
||||
{:8}could not parse line {}, `{}`",
|
||||
env_file, "", line, msg
|
||||
),
|
||||
Err(dotenv::Error::Io(_)) => eprintln!(
|
||||
" WARN: could not load environmental variables from {:?}\n\
|
||||
{:8}Are you in the right directory? Proceeding with variables from the environment.",
|
||||
env::current_dir().unwrap_or_else(|_|"./".into()).join(env_file), ""
|
||||
|
||||
);
|
||||
env_file, ""
|
||||
),
|
||||
Err(_) => eprintln!(" ERROR: could not load environmental file at {:?}", env_file),
|
||||
Ok(_) => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -20,7 +20,7 @@ from_env_var!(
|
|||
from_env_var!(
|
||||
/// How frequently to poll Redis
|
||||
let name = RedisInterval;
|
||||
let default: Duration = Duration::from_millis(100);
|
||||
let default: Duration = Duration::from_millis(10);
|
||||
let (env_var, allowed_values) = ("REDIS_FREQ", "a number of milliseconds");
|
||||
let from_str = |s| s.parse().map(Duration::from_millis).ok();
|
||||
);
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::config::Postgres;
|
|||
use warp::filters::BoxedFilter;
|
||||
use warp::http::StatusCode;
|
||||
use warp::path;
|
||||
use warp::reply;
|
||||
use warp::{Filter, Rejection};
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -54,7 +55,7 @@ macro_rules! parse_sse_query {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct Handler {
|
||||
pg_conn: PgPool,
|
||||
}
|
||||
|
@ -118,14 +119,23 @@ impl Handler {
|
|||
}
|
||||
|
||||
pub fn err(r: Rejection) -> std::result::Result<impl warp::Reply, warp::Rejection> {
|
||||
let json_err = match r.cause() {
|
||||
Some(text) if text.to_string() == "Missing request header 'authorization'" => {
|
||||
warp::reply::json(&"Error: Missing access token".to_string())
|
||||
}
|
||||
Some(text) => warp::reply::json(&text.to_string()),
|
||||
None => warp::reply::json(&"Error: Nonexistant endpoint".to_string()),
|
||||
use StatusCode as Code;
|
||||
let (msg, code) = match &r.cause().map(|s| s.to_string()).as_deref() {
|
||||
Some(PgPool::BAD_TOKEN) => (PgPool::BAD_TOKEN, Code::UNAUTHORIZED),
|
||||
Some(PgPool::PG_NULL) => (PgPool::PG_NULL, Code::BAD_REQUEST),
|
||||
Some(PgPool::MISSING_HASHTAG) => (PgPool::MISSING_HASHTAG, Code::BAD_REQUEST),
|
||||
Some(PgPool::SERVER_ERR) | Some(_) => (PgPool::SERVER_ERR, Code::INTERNAL_SERVER_ERROR),
|
||||
None if r.is_not_found() => return Err(r),
|
||||
|
||||
None => (PgPool::SERVER_ERR, Code::INTERNAL_SERVER_ERROR),
|
||||
};
|
||||
Ok(warp::reply::with_status(json_err, StatusCode::UNAUTHORIZED))
|
||||
|
||||
if code == Code::INTERNAL_SERVER_ERROR {
|
||||
log::error!("Internal error: {:?}", &r);
|
||||
} else {
|
||||
log::info!("Request rejected: {} - {:?}", code, &r);
|
||||
};
|
||||
Ok(reply::with_status(reply::json(&msg), code))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
PgPool(r2d2::Error),
|
||||
|
@ -28,7 +29,7 @@ impl From<postgres::Error> for Error {
|
|||
Self::Pg(e)
|
||||
}
|
||||
}
|
||||
// TODO make Timeline & TimelineErr their own top-level module
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Timeline {
|
||||
MissingHashtag,
|
||||
|
|
|
@ -4,12 +4,14 @@ use super::timeline::{Scope, UserData};
|
|||
use crate::config;
|
||||
use crate::Id;
|
||||
|
||||
use ::postgres;
|
||||
use ::postgres::{self, SimpleQueryMessage};
|
||||
use hashbrown::HashSet;
|
||||
use r2d2_postgres::PostgresConnectionManager;
|
||||
use std::convert::TryFrom;
|
||||
#[allow(deprecated)] // one fn is deprecated, not whole module
|
||||
use warp::reject;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct PgPool {
|
||||
conn: r2d2::Pool<PostgresConnectionManager<postgres::NoTls>>,
|
||||
whitelist_mode: bool,
|
||||
|
@ -19,6 +21,11 @@ type Result<T> = std::result::Result<T, err::Error>;
|
|||
type Rejectable<T> = std::result::Result<T, warp::Rejection>;
|
||||
|
||||
impl PgPool {
|
||||
pub(crate) const BAD_TOKEN: &'static str = "Error: Missing access token";
|
||||
pub(crate) const SERVER_ERR: &'static str = "Error: Internal server error";
|
||||
pub(crate) const PG_NULL: &'static str = "Error: Unexpected null from Postgres";
|
||||
pub(crate) const MISSING_HASHTAG: &'static str = "Error: Hashtag does not exist";
|
||||
|
||||
pub(crate) fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result<Self> {
|
||||
let mut cfg = postgres::Config::new();
|
||||
cfg.user(&pg_cfg.user)
|
||||
|
@ -32,38 +39,54 @@ impl PgPool {
|
|||
cfg.connect(postgres::NoTls)?; // Test connection, letting us immediately exit with an error
|
||||
// when Postgres isn't running instead of timing out below
|
||||
let manager = PostgresConnectionManager::new(cfg, postgres::NoTls);
|
||||
let pool = r2d2::Pool::builder().max_size(10).build(manager)?;
|
||||
|
||||
Ok(Self {
|
||||
conn: pool,
|
||||
conn: r2d2::Pool::builder().max_size(10).build(manager)?,
|
||||
whitelist_mode,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_safe(txt: &str) -> bool {
|
||||
txt.chars()
|
||||
.all(|c| c.is_alphanumeric() || c == '_' || c == '-')
|
||||
}
|
||||
|
||||
pub(crate) fn select_user(self, token: &Option<String>) -> Rejectable<UserData> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
|
||||
if let Some(token) = token {
|
||||
let query_rows = conn
|
||||
.query("
|
||||
if !Self::is_safe(token) {
|
||||
Err(reject::custom(Self::BAD_TOKEN))?;
|
||||
};
|
||||
|
||||
let rows = conn
|
||||
.simple_query(&format!("
|
||||
SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes
|
||||
FROM oauth_access_tokens
|
||||
INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id
|
||||
WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL
|
||||
LIMIT 1",
|
||||
&[&token.to_owned()],
|
||||
).map_err(warp::reject::custom)?;
|
||||
WHERE oauth_access_tokens.token='{}' AND oauth_access_tokens.revoked_at IS NULL
|
||||
LIMIT 1", &token.to_owned())
|
||||
).map_err(reject::custom)?;
|
||||
|
||||
if let Some(result_columns) = query_rows.get(0) {
|
||||
let id = Id(result_columns.get(1));
|
||||
let allowed_langs = result_columns
|
||||
.try_get::<_, Vec<_>>(2)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.collect();
|
||||
let row = match rows.get(0) {
|
||||
Some(postgres::SimpleQueryMessage::Row(row)) => row,
|
||||
_ => Err(reject::custom(Self::PG_NULL))?, // Wildcard required by #[non_exhaustive]
|
||||
};
|
||||
|
||||
let mut scopes: HashSet<Scope> = result_columns
|
||||
.get::<_, String>(3)
|
||||
let id = Id(get_col_or_reject(row, 1)?.parse().map_err(reject::custom)?);
|
||||
|
||||
let allowed_langs: HashSet<_> = row
|
||||
.try_get(2)
|
||||
.map_err(reject::custom)? // looks like `Some("{en,eo,es}")`
|
||||
.map_or_else(HashSet::new, |str| {
|
||||
str.trim_start_matches('{')
|
||||
.trim_end_matches('}')
|
||||
.split(',')
|
||||
.map(String::from)
|
||||
.collect()
|
||||
});
|
||||
|
||||
let mut scopes: HashSet<Scope> = get_col_or_reject(row, 3)?
|
||||
.split(' ')
|
||||
.filter_map(|scope| Scope::try_from(scope).ok())
|
||||
.collect();
|
||||
|
@ -79,23 +102,30 @@ LIMIT 1",
|
|||
allowed_langs,
|
||||
scopes,
|
||||
})
|
||||
} else {
|
||||
Err(warp::reject::custom("Error: Invalid access token"))
|
||||
}
|
||||
} else if self.whitelist_mode {
|
||||
Err(warp::reject::custom("Error: Invalid access token"))
|
||||
Err(reject::custom(Self::BAD_TOKEN))
|
||||
} else {
|
||||
Ok(UserData::public())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn select_hashtag_id(self, tag_name: &str) -> Rejectable<i64> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query("SELECT id FROM tags WHERE name = $1 LIMIT 1", &[&tag_name])
|
||||
.map_err(warp::reject::custom)?
|
||||
.get(0)
|
||||
.map(|row| row.get(0))
|
||||
.ok_or_else(|| warp::reject::custom("Error: Hashtag does not exist."))
|
||||
if !Self::is_safe(tag_name) {
|
||||
Err(reject::custom(Self::MISSING_HASHTAG))?;
|
||||
};
|
||||
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
let rows = conn
|
||||
.simple_query(&format!(
|
||||
"SELECT id FROM tags WHERE name='{}' LIMIT 1",
|
||||
&tag_name
|
||||
))
|
||||
.map_err(reject::custom)?;
|
||||
match rows.get(0).ok_or_else(|| reject::custom(Self::PG_NULL))? {
|
||||
SimpleQueryMessage::Row(row) => get_col_or_reject(row, 0),
|
||||
_ => Err(reject::custom(Self::MISSING_HASHTAG))?,
|
||||
}
|
||||
.map(|s| s.parse().map_err(reject::custom))?
|
||||
}
|
||||
|
||||
/// Query Postgres for everyone the user has blocked or muted
|
||||
|
@ -103,16 +133,21 @@ LIMIT 1",
|
|||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocked_users(self, user_id: Id) -> Rejectable<HashSet<Id>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT target_account_id FROM blocks WHERE account_id = $1
|
||||
UNION SELECT target_account_id FROM mutes WHERE account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
conn.simple_query(&format!(
|
||||
"SELECT target_account_id FROM blocks WHERE account_id = {0}
|
||||
UNION SELECT target_account_id FROM mutes WHERE account_id = {0}",
|
||||
&*user_id
|
||||
))
|
||||
.map_err(reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(Id(row.get(0))))
|
||||
.collect()
|
||||
.try_fold(HashSet::new(), |mut set, row| match row {
|
||||
SimpleQueryMessage::Row(row) => {
|
||||
set.insert(get_col_or_reject(row, 0)?.parse().map_err(reject::custom)?);
|
||||
Ok(set)
|
||||
}
|
||||
_ => Ok(set),
|
||||
})
|
||||
}
|
||||
|
||||
/// Query Postgres for everyone who has blocked the user
|
||||
|
@ -120,15 +155,20 @@ LIMIT 1",
|
|||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocking_users(self, user_id: Id) -> Rejectable<HashSet<Id>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT account_id FROM blocks WHERE target_account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
conn.simple_query(&format!(
|
||||
"SELECT account_id FROM blocks WHERE target_account_id = {}",
|
||||
&*user_id
|
||||
))
|
||||
.map_err(reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(Id(row.get(0))))
|
||||
.collect()
|
||||
.try_fold(HashSet::new(), |mut set, row| match row {
|
||||
SimpleQueryMessage::Row(row) => {
|
||||
set.insert(get_col_or_reject(row, 0)?.parse().map_err(reject::custom)?);
|
||||
Ok(set)
|
||||
}
|
||||
_ => Ok(set),
|
||||
})
|
||||
}
|
||||
|
||||
/// Query Postgres for all current domain blocks
|
||||
|
@ -136,27 +176,45 @@ LIMIT 1",
|
|||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocked_domains(self, user_id: Id) -> Rejectable<HashSet<String>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT domain FROM account_domain_blocks WHERE account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
conn.simple_query(&format!(
|
||||
"SELECT domain FROM account_domain_blocks WHERE account_id = {}",
|
||||
&*user_id,
|
||||
))
|
||||
.map_err(reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(row.get(0)))
|
||||
.collect()
|
||||
.try_fold(HashSet::new(), |mut set, row| match row {
|
||||
SimpleQueryMessage::Row(row) => {
|
||||
set.insert(get_col_or_reject(row, 0)?.to_string());
|
||||
Ok(set)
|
||||
}
|
||||
_ => Ok(set),
|
||||
})
|
||||
}
|
||||
|
||||
/// Test whether a user owns a list
|
||||
pub(crate) fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable<bool> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
// For the Postgres query, `id` = list number; `account_id` = user.id
|
||||
let rows = &conn
|
||||
.query(
|
||||
"SELECT id, account_id FROM lists WHERE id = $1 LIMIT 1",
|
||||
&[&list_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?;
|
||||
Ok(rows.get(0).map_or(false, |row| Id(row.get(1)) == user_id))
|
||||
let mut conn = self.conn.get().map_err(reject::custom)?;
|
||||
let rows = conn
|
||||
.simple_query(&format!(
|
||||
"SELECT id, account_id FROM lists WHERE id={} LIMIT 1",
|
||||
&list_id,
|
||||
))
|
||||
.map_err(reject::custom)?;
|
||||
|
||||
match rows.get(0).ok_or_else(|| reject::custom(Self::PG_NULL))? {
|
||||
SimpleQueryMessage::Row(row) => {
|
||||
Ok(Id(get_col_or_reject(row, 1)?.parse().map_err(reject::custom)?) == user_id)
|
||||
}
|
||||
_ => Err(reject::custom(Self::MISSING_HASHTAG))?,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_col_or_reject(row: &postgres::row::SimpleQueryRow, col: usize) -> Rejectable<&str> {
|
||||
Ok(row
|
||||
.try_get(col)
|
||||
.map_err(reject::custom)?
|
||||
.ok_or(reject::custom(PgPool::PG_NULL))?)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
//! Postgres queries
|
||||
use super::err;
|
||||
use super::timeline::{Scope, UserData};
|
||||
use crate::config;
|
||||
use crate::event::Id;
|
||||
|
||||
use ::postgres;
|
||||
use hashbrown::HashSet;
|
||||
use r2d2_postgres::PostgresConnectionManager;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PgPool {
|
||||
conn: r2d2::Pool<PostgresConnectionManager<postgres::NoTls>>,
|
||||
whitelist_mode: bool,
|
||||
}
|
||||
|
||||
type Result<T> = std::result::Result<T, err::RequestErr>;
|
||||
type Rejectable<T> = std::result::Result<T, warp::Rejection>;
|
||||
|
||||
impl PgPool {
|
||||
pub(crate) fn new(pg_cfg: &config::Postgres, whitelist_mode: bool) -> Result<Self> {
|
||||
let mut cfg = postgres::Config::new();
|
||||
log::info!(
|
||||
"Connecting to postgres.\nuser: {:?}, password: {:?}",
|
||||
&pg_cfg.user,
|
||||
&pg_cfg.password
|
||||
);
|
||||
cfg.user(&pg_cfg.user)
|
||||
.host(&*pg_cfg.host.to_string())
|
||||
.port(*pg_cfg.port)
|
||||
.dbname(&pg_cfg.database);
|
||||
if let Some(password) = &*pg_cfg.password {
|
||||
cfg.password(password);
|
||||
};
|
||||
|
||||
cfg.connect(postgres::NoTls)?; // Test connection, letting us immediately exit with an error
|
||||
// when Postgres isn't running instead of timing out below
|
||||
let manager = PostgresConnectionManager::new(cfg, postgres::NoTls);
|
||||
let pool = r2d2::Pool::builder().max_size(10).build(manager)?;
|
||||
|
||||
Ok(Self {
|
||||
conn: pool,
|
||||
whitelist_mode,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn select_user(self, token: &Option<String>) -> Rejectable<UserData> {
|
||||
log::info!("Running `select_user`");
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
log::info!(" got conn");
|
||||
if let Some(token) = token {
|
||||
let query_rows = conn
|
||||
.query("
|
||||
SELECT oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes
|
||||
FROM oauth_access_tokens
|
||||
INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id
|
||||
WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL
|
||||
LIMIT 1",
|
||||
&[&token.to_owned()],
|
||||
).map_err(warp::reject::custom)?;
|
||||
log::info!(" got rows");
|
||||
if let Some(result_columns) = query_rows.get(0) {
|
||||
let id = Id(result_columns.get(1));
|
||||
log::info!(" got id: {:?}", id);
|
||||
let allowed_langs = result_columns
|
||||
.try_get::<_, Vec<_>>(2)
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let mut scopes: HashSet<Scope> = result_columns
|
||||
.get::<_, String>(3)
|
||||
.split(' ')
|
||||
.filter_map(|scope| Scope::try_from(scope).ok())
|
||||
.collect();
|
||||
// We don't need to separately track read auth - it's just all three others
|
||||
if scopes.contains(&Scope::Read) {
|
||||
scopes = vec![Scope::Statuses, Scope::Notifications, Scope::Lists]
|
||||
.into_iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
Ok(UserData {
|
||||
id,
|
||||
allowed_langs,
|
||||
scopes,
|
||||
})
|
||||
} else {
|
||||
Err(warp::reject::custom("Error: Invalid access token"))
|
||||
}
|
||||
} else if self.whitelist_mode {
|
||||
Err(warp::reject::custom("Error: Invalid access token"))
|
||||
} else {
|
||||
Ok(UserData::public())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn select_hashtag_id(self, tag_name: &str) -> Rejectable<i64> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query("SELECT id FROM tags WHERE name = $1 LIMIT 1", &[&tag_name])
|
||||
.map_err(warp::reject::custom)?
|
||||
.get(0)
|
||||
.map(|row| row.get(0))
|
||||
.ok_or_else(|| warp::reject::custom("Error: Hashtag does not exist."))
|
||||
}
|
||||
|
||||
/// Query Postgres for everyone the user has blocked or muted
|
||||
///
|
||||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocked_users(self, user_id: Id) -> Rejectable<HashSet<Id>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT target_account_id FROM blocks WHERE account_id = $1
|
||||
UNION SELECT target_account_id FROM mutes WHERE account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(Id(row.get(0))))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Query Postgres for everyone who has blocked the user
|
||||
///
|
||||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocking_users(self, user_id: Id) -> Rejectable<HashSet<Id>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT account_id FROM blocks WHERE target_account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(Id(row.get(0))))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Query Postgres for all current domain blocks
|
||||
///
|
||||
/// **NOTE**: because we check this when the user connects, it will not include any blocks
|
||||
/// the user adds until they refresh/reconnect.
|
||||
pub(crate) fn select_blocked_domains(self, user_id: Id) -> Rejectable<HashSet<String>> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
conn.query(
|
||||
"SELECT domain FROM account_domain_blocks WHERE account_id = $1",
|
||||
&[&*user_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?
|
||||
.iter()
|
||||
.map(|row| Ok(row.get(0)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Test whether a user owns a list
|
||||
pub(crate) fn user_owns_list(self, user_id: Id, list_id: i64) -> Rejectable<bool> {
|
||||
let mut conn = self.conn.get().map_err(warp::reject::custom)?;
|
||||
// For the Postgres query, `id` = list number; `account_id` = user.id
|
||||
let rows = &conn
|
||||
.query(
|
||||
"SELECT id, account_id FROM lists WHERE id = $1 LIMIT 1",
|
||||
&[&list_id],
|
||||
)
|
||||
.map_err(warp::reject::custom)?;
|
||||
Ok(rows.get(0).map_or(false, |row| Id(row.get(1)) == user_id))
|
||||
}
|
||||
}
|
|
@ -53,6 +53,7 @@ impl TryFrom<&str> for Scope {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct UserData {
|
||||
pub(crate) id: Id,
|
||||
pub(crate) allowed_langs: HashSet<String>,
|
||||
|
|
|
@ -29,9 +29,9 @@ impl RedisCmd {
|
|||
.concat(),
|
||||
[
|
||||
b"*3\r\n$3\r\nSET\r\n$",
|
||||
tl.len().to_string().as_bytes(),
|
||||
b"\r\n",
|
||||
tl.as_bytes(),
|
||||
(tl.len() + "subscribed:".len()).to_string().as_bytes(),
|
||||
b"\r\nsubscribed:",
|
||||
tl.to_string().as_bytes(),
|
||||
b"\r\n$1\r\n1\r\n",
|
||||
]
|
||||
.concat(),
|
||||
|
@ -47,9 +47,9 @@ impl RedisCmd {
|
|||
.concat(),
|
||||
[
|
||||
b"*3\r\n$3\r\nSET\r\n$",
|
||||
tl.len().to_string().as_bytes(),
|
||||
b"\r\n",
|
||||
tl.as_bytes(),
|
||||
(tl.len() + "subscribed:".len()).to_string().as_bytes(),
|
||||
b"\r\nsubscribed:",
|
||||
tl.to_string().as_bytes(),
|
||||
b"\r\n$1\r\n0\r\n",
|
||||
]
|
||||
.concat(),
|
||||
|
|
|
@ -63,7 +63,7 @@ impl RedisConn {
|
|||
}
|
||||
}
|
||||
Err(e) if matches!(e.kind(), io::ErrorKind::WouldBlock) => {
|
||||
return Ok(Async::NotReady);
|
||||
break;
|
||||
}
|
||||
Err(e) => break log::error!("{}", e),
|
||||
};
|
||||
|
@ -96,19 +96,18 @@ impl RedisConn {
|
|||
}
|
||||
Some(_non_matching_namespace) => (Ok(Ready(None)), msg.leftover_input),
|
||||
},
|
||||
|
||||
Ok(NonMsg(leftover)) => (Ok(Ready(None)), leftover),
|
||||
Err(RedisParseErr::Incomplete) => (Ok(NotReady), input),
|
||||
Err(other_parse_err) => (Err(ManagerErr::RedisParseErr(other_parse_err)), input),
|
||||
};
|
||||
|
||||
self.cursor = [leftover.as_bytes(), invalid_bytes]
|
||||
.concat()
|
||||
.bytes()
|
||||
.fold(0, |acc, cur| {
|
||||
// TODO - make clearer and comment side-effect
|
||||
self.redis_input[acc] = cur.expect("TODO");
|
||||
acc + 1
|
||||
});
|
||||
// Store leftover in same buffer and set cursor to start after leftover next time
|
||||
self.cursor = 0;
|
||||
for byte in [leftover.as_bytes(), invalid_bytes].concat().iter() {
|
||||
self.redis_input[self.cursor] = *byte;
|
||||
self.cursor += 1;
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
|
@ -123,6 +122,12 @@ impl RedisConn {
|
|||
|
||||
let (primary_cmd, secondary_cmd) = cmd.into_sendable(&tl);
|
||||
self.primary.write_all(&primary_cmd)?;
|
||||
|
||||
// We also need to set a key to tell the Puma server that we've subscribed
|
||||
// or unsubscribed to the channel because it stops publishing updates when it
|
||||
// thinks no one is subscribed. (Documented in [PR
|
||||
// #3278](https://github.com/tootsuite/mastodon/pull/3278))
|
||||
// Question: why can't the Puma server just use NUMSUB for this?
|
||||
self.secondary.write_all(&secondary_cmd)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ impl Ws {
|
|||
let incoming_events = self.ws_rx.clone().map_err(|_| ());
|
||||
|
||||
incoming_events.for_each(move |(tl, event)| {
|
||||
//TODO log::info!("{:?}, {:?}", &tl, &event);
|
||||
if matches!(event, Event::Ping) {
|
||||
self.send_msg(&event)?
|
||||
} else if target_timeline == tl {
|
||||
|
@ -67,20 +68,30 @@ impl Ws {
|
|||
}
|
||||
|
||||
fn send_or_filter(&mut self, tl: Timeline, event: &Event, update: &impl Payload) -> Result<()> {
|
||||
let blocks = &self.subscription.blocks;
|
||||
let allowed_langs = &self.subscription.allowed_langs;
|
||||
let (blocks, allowed_langs) = (&self.subscription.blocks, &self.subscription.allowed_langs);
|
||||
const SKIP: Result<()> = Ok(());
|
||||
|
||||
match tl {
|
||||
tl if tl.is_public()
|
||||
&& !update.language_unset()
|
||||
&& !allowed_langs.is_empty()
|
||||
&& !allowed_langs.contains(&update.language()) =>
|
||||
{
|
||||
log::info!("{:?} msg skipped - disallowed language", tl);
|
||||
SKIP
|
||||
}
|
||||
tl if !blocks.blocked_users.is_disjoint(&update.involved_users()) => {
|
||||
log::info!("{:?} msg skipped - involves blocked user", tl);
|
||||
SKIP
|
||||
}
|
||||
tl if blocks.blocking_users.contains(update.author()) => {
|
||||
log::info!("{:?} msg skipped - from blocking user", tl);
|
||||
SKIP
|
||||
}
|
||||
tl if blocks.blocked_domains.contains(update.sent_from()) => {
|
||||
log::info!("{:?} msg skipped - from blocked domain", tl);
|
||||
SKIP
|
||||
}
|
||||
_ if !blocks.blocked_users.is_disjoint(&update.involved_users()) => SKIP,
|
||||
_ if blocks.blocking_users.contains(update.author()) => SKIP,
|
||||
_ if blocks.blocked_domains.contains(update.sent_from()) => SKIP,
|
||||
_ => Ok(self.send_msg(&event)?),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue