setup sqlx with migrations

This commit is contained in:
Quentin Gliech
2021-07-09 10:50:51 +02:00
parent 0c3139f046
commit 453544b755
12 changed files with 698 additions and 18 deletions

515
Cargo.lock generated
View File

@@ -101,6 +101,17 @@ dependencies = [
"opaque-debug 0.3.0",
]
[[package]]
name = "ahash"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98"
dependencies = [
"getrandom 0.2.3",
"once_cell",
"version_check",
]
[[package]]
name = "aho-corasick"
version = "0.7.18"
@@ -271,6 +282,17 @@ dependencies = [
"winapi",
]
[[package]]
name = "async-rustls"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c86f33abd5a4f3e2d6d9251a9e0c6a7e52eb1113caf893dae8429bf4a53f378"
dependencies = [
"futures-lite",
"rustls",
"webpki",
]
[[package]]
name = "async-session"
version = "2.0.1"
@@ -352,6 +374,15 @@ dependencies = [
"syn",
]
[[package]]
name = "atoi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5"
dependencies = [
"num-traits",
]
[[package]]
name = "atomic"
version = "0.5.0"
@@ -406,6 +437,18 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitvec"
version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "blake3"
version = "0.3.8"
@@ -483,6 +526,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "build_const"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7"
[[package]]
name = "bumpalo"
version = "3.7.0"
@@ -650,6 +699,25 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba"
[[package]]
name = "crc"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
dependencies = [
"build_const",
]
[[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",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.2"
@@ -768,18 +836,50 @@ dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "dirs"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[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 = "dtoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "event-listener"
version = "2.5.1"
@@ -847,6 +947,27 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "funty"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
[[package]]
name = "futures"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7e43a803dae2fa37c1f6a8fe121e1f7bf9548b4dfc0522a42f34145dadfc27"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.15"
@@ -854,6 +975,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@@ -862,6 +984,17 @@ version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
[[package]]
name = "futures-executor"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.15"
@@ -896,6 +1029,12 @@ dependencies = [
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282"
[[package]]
name = "futures-task"
version = "0.3.15"
@@ -909,9 +1048,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
dependencies = [
"autocfg",
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite 0.2.6",
"pin-utils",
"proc-macro-hack",
@@ -1007,6 +1150,33 @@ dependencies = [
"web-sys",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]]
name = "hashlink"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
dependencies = [
"hashbrown",
]
[[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.18"
@@ -1016,6 +1186,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hkdf"
version = "0.10.0"
@@ -1202,6 +1378,19 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lexical-core"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
dependencies = [
"arrayvec",
"bitflags",
"cfg-if 1.0.0",
"ryu",
"static_assertions",
]
[[package]]
name = "libc"
version = "0.2.96"
@@ -1214,6 +1403,15 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
[[package]]
name = "lock_api"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
@@ -1258,6 +1456,7 @@ dependencies = [
"mime",
"oauth2-types",
"serde",
"sqlx",
"tera",
"thiserror",
"tide",
@@ -1268,6 +1467,17 @@ dependencies = [
"url",
]
[[package]]
name = "md-5"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
dependencies = [
"block-buffer 0.9.0",
"digest 0.9.0",
"opaque-debug 0.3.0",
]
[[package]]
name = "memchr"
version = "2.4.0"
@@ -1280,6 +1490,19 @@ version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
[[package]]
name = "nom"
version = "6.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2"
dependencies = [
"bitvec",
"funty",
"lexical-core",
"memchr",
"version_check",
]
[[package]]
name = "num-integer"
version = "0.1.44"
@@ -1346,6 +1569,31 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]]
name = "parking_lot"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018"
dependencies = [
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "parse-display"
version = "0.5.0"
@@ -1450,7 +1698,7 @@ checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
dependencies = [
"maplit",
"pest",
"sha-1",
"sha-1 0.8.2",
]
[[package]]
@@ -1574,6 +1822,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
[[package]]
name = "rand"
version = "0.7.3"
@@ -1655,6 +1909,25 @@ dependencies = [
"rand_core 0.6.2",
]
[[package]]
name = "redox_syscall"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
dependencies = [
"bitflags",
]
[[package]]
name = "redox_users"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
dependencies = [
"getrandom 0.2.3",
"redox_syscall",
]
[[package]]
name = "regex"
version = "1.5.4"
@@ -1681,6 +1954,21 @@ version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[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",
]
[[package]]
name = "route-recognizer"
version = "0.2.0"
@@ -1696,6 +1984,19 @@ dependencies = [
"semver",
]
[[package]]
name = "rustls"
version = "0.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
dependencies = [
"base64 0.13.0",
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "ryu"
version = "1.0.5"
@@ -1711,6 +2012,22 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "semver"
version = "0.9.0"
@@ -1805,6 +2122,19 @@ dependencies = [
"opaque-debug 0.2.3",
]
[[package]]
name = "sha-1"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
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"
@@ -1892,6 +2222,114 @@ dependencies = [
"winapi",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "sqlformat"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d86e3c77ff882a828346ba401a7ef4b8e440df804491c6064fe8295765de71c"
dependencies = [
"lazy_static",
"maplit",
"nom",
"regex",
"unicode_categories",
]
[[package]]
name = "sqlx"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba82f79b31f30acebf19905bcd8b978f46891b9d0723f578447361a8910b6584"
dependencies = [
"sqlx-core",
"sqlx-macros",
]
[[package]]
name = "sqlx-core"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f23af36748ec8ea8d49ef8499839907be41b0b1178a4e82b8cb45d29f531dc9"
dependencies = [
"ahash",
"atoi",
"base64 0.13.0",
"bitflags",
"byteorder",
"bytes",
"crc",
"crossbeam-channel",
"crossbeam-queue",
"crossbeam-utils",
"dirs",
"either",
"futures-channel",
"futures-core",
"futures-util",
"hashlink",
"hex",
"hmac 0.10.1",
"itoa",
"libc",
"log",
"md-5",
"memchr",
"once_cell",
"parking_lot",
"percent-encoding",
"rand 0.8.3",
"rustls",
"serde",
"serde_json",
"sha-1 0.9.6",
"sha2",
"smallvec",
"sqlformat",
"sqlx-rt",
"stringprep",
"thiserror",
"url",
"webpki",
"webpki-roots",
"whoami",
]
[[package]]
name = "sqlx-macros"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e4a2349d1ffd60a03ca0de3f116ba55d7f406e55a0d84c64a5590866d94c06"
dependencies = [
"dotenv",
"either",
"futures",
"heck",
"once_cell",
"proc-macro2",
"quote",
"sha2",
"sqlx-core",
"sqlx-rt",
"syn",
"url",
]
[[package]]
name = "sqlx-rt"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8199b421ecf3493ee9ef3e7bc90c904844cfb2ea7ea2f57347a93f52bfd3e057"
dependencies = [
"async-rustls",
"async-std",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@@ -1907,6 +2345,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "stdweb"
version = "0.4.20"
@@ -1965,6 +2409,16 @@ dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "stringprep"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "structmeta"
version = "0.1.3"
@@ -2011,6 +2465,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tera"
version = "1.11.0"
@@ -2335,12 +2795,24 @@ 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-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "unicode_categories"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "unindent"
version = "0.1.7"
@@ -2357,6 +2829,12 @@ dependencies = [
"subtle",
]
[[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"
@@ -2494,6 +2972,25 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
dependencies = [
"webpki",
]
[[package]]
name = "wepoll-sys"
version = "3.0.1"
@@ -2503,6 +3000,16 @@ dependencies = [
"cc",
]
[[package]]
name = "whoami"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4abacf325c958dfeaf1046931d37f2a901b6dfe0968ee965a29e94c6766b2af6"
dependencies = [
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "winapi"
version = "0.3.9"
@@ -2534,6 +3041,12 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "wyz"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
[[package]]
name = "yaml-rust"
version = "0.4.5"

View File

@@ -23,3 +23,4 @@ data-encoding = "2.3.2"
time = "0.2.27"
tide-tracing = "0.0.11"
mime = "0.3.16"
sqlx = { version = "0.5.5", features = ["runtime-async-std-rustls", "postgres", "migrate"] }

View File

@@ -0,0 +1 @@
-- Add migration script here

View File

@@ -0,0 +1,86 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::time::Duration;
use serde::Deserialize;
use sqlx::postgres::{PgPool, PgPoolOptions};
fn default_uri() -> String {
"postgresql://".to_string()
}
fn default_max_connections() -> u32 {
10
}
fn default_connect_timeout() -> Duration {
Duration::from_secs(30)
}
fn default_idle_timeout() -> Option<Duration> {
Some(Duration::from_secs(10 * 60))
}
fn default_max_lifetime() -> Option<Duration> {
Some(Duration::from_secs(30 * 60))
}
impl Default for Config {
fn default() -> Self {
Self {
uri: default_uri(),
max_connections: default_max_connections(),
min_connections: Default::default(),
connect_timeout: default_connect_timeout(),
idle_timeout: default_idle_timeout(),
max_lifetime: default_max_lifetime(),
}
}
}
#[derive(Debug, Deserialize)]
pub struct Config {
#[serde(default = "default_uri")]
uri: String,
#[serde(default = "default_max_connections")]
max_connections: u32,
#[serde(default)]
min_connections: u32,
#[serde(default = "default_connect_timeout")]
connect_timeout: Duration,
#[serde(default = "default_idle_timeout")]
idle_timeout: Option<Duration>,
#[serde(default = "default_max_lifetime")]
max_lifetime: Option<Duration>,
}
impl Config {
#[tracing::instrument(err)]
pub async fn connect(&self) -> Result<PgPool, sqlx::Error> {
PgPoolOptions::new()
.max_connections(self.max_connections)
.min_connections(self.min_connections)
.connect_timeout(self.connect_timeout)
.idle_timeout(self.idle_timeout)
.max_lifetime(self.max_lifetime)
.connect(&self.uri)
.await
}
}

View File

@@ -19,9 +19,11 @@ use figment::{
};
use serde::Deserialize;
mod database;
mod http;
mod oauth2;
pub use self::database::Config as DatabaseConfig;
pub use self::http::Config as HttpConfig;
pub use self::oauth2::{ClientConfig as OAuth2ClientConfig, Config as OAuth2Config};
@@ -30,6 +32,7 @@ pub use self::oauth2::{ClientConfig as OAuth2ClientConfig, Config as OAuth2Confi
pub struct RootConfig {
pub oauth2: OAuth2Config,
pub http: HttpConfig,
pub database: DatabaseConfig,
}
impl RootConfig {

View File

@@ -0,0 +1,30 @@
// Copyright 2021 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use tide::Request;
use tracing::{info_span, Instrument};
use crate::state::State;
pub async fn get(req: Request<State>) -> tide::Result {
let pool = req.state().storage().pool();
sqlx::query("SELECT $1")
.bind(1_i64)
.execute(pool)
.instrument(info_span!("DB health"))
.await?;
Ok("ok".into())
}

View File

@@ -27,6 +27,7 @@ use crate::{
storage::{ClientLookupError, InvalidRedirectUriError, Storage},
};
mod health;
mod oauth2;
mod views;
@@ -53,9 +54,9 @@ struct QueryParams {
redirect_uri: Option<String>,
}
async fn redirect_uri_from_params(
async fn redirect_uri_from_params<T>(
params: QueryParams,
storage: &Storage,
storage: &Storage<T>,
) -> Result<Url, RedirectUriLookupError> {
use RedirectUriLookupError::*;
let client_id = params.client_id.ok_or(MissingClientId)?;
@@ -110,6 +111,8 @@ pub fn install(app: &mut Server<State>) {
.allow_origin(Origin::from("*"))
.allow_credentials(false);
app.at("/health").get(self::health::get);
app.at("/").nest({
let mut views = tide::with_state(state.clone());
views.with(state.session_middleware());

View File

@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#![forbid(unsafe_code)]
use anyhow::Context;
use tracing::{info_span, Instrument};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};
mod config;
@@ -24,6 +28,7 @@ mod templates;
use self::config::RootConfig;
use self::state::State;
use self::storage::MIGRATOR;
#[async_std::main]
async fn main() -> tide::Result<()> {
@@ -32,26 +37,45 @@ async fn main() -> tide::Result<()> {
let filter_layer = EnvFilter::try_from_default_env().or_else(|_| EnvFilter::try_new("info"))?;
let subscriber = Registry::default().with(filter_layer).with(fmt_layer);
subscriber.try_init()?;
subscriber
.try_init()
.context("could not initialize logging")?;
// Loading the config
let config = RootConfig::load()?;
let config = RootConfig::load().context("could not load config")?;
// Connect to the database
let pool = config
.database
.connect()
.await
.context("could not connect to database")?;
// Load and compile the templates
let templates = self::templates::load()?;
let templates = self::templates::load().context("could not load templates")?;
// Create the shared state
let state = State::new(config, templates);
let state = State::new(config, templates, pool);
state
.storage()
.load_static_clients(&state.config().oauth2.clients)
.await;
// Run pending migrations
// TODO: make this a separate command
MIGRATOR
.run(state.storage().pool())
.instrument(info_span!("migrations"))
.await
.context("could not run migrations")?;
// Start the server
let address = state.config().http.address.clone();
let mut app = tide::with_state(state);
app.with(tide_tracing::TraceMiddleware::new());
self::handlers::install(&mut app);
app.listen(address).await?;
app.listen(address)
.await
.context("could not start server")?;
Ok(())
}

View File

@@ -16,6 +16,7 @@ use std::sync::Arc;
use async_trait::async_trait;
use csrf::AesGcmCsrfProtection;
use sqlx::PgPool;
use tera::Tera;
use tide::{
sessions::{MemoryStore, SessionMiddleware, SessionStore},
@@ -29,23 +30,23 @@ use crate::{config::RootConfig, storage::Storage};
pub struct State {
config: Arc<RootConfig>,
templates: Arc<Tera>,
storage: Arc<Storage>,
storage: Arc<Storage<PgPool>>,
session_store: Arc<MemoryStore>,
csrf: Arc<AesGcmCsrfProtection>,
}
impl std::fmt::Debug for State {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "State")
f.debug_struct("State").finish_non_exhaustive()
}
}
impl State {
pub fn new(config: RootConfig, templates: Tera) -> Self {
pub fn new(config: RootConfig, templates: Tera, pool: PgPool) -> Self {
Self {
config: Arc::new(config),
templates: Arc::new(templates),
storage: Default::default(),
storage: Arc::new(Storage::new(pool)),
session_store: Arc::new(MemoryStore::new()),
csrf: Arc::new(AesGcmCsrfProtection::from_key(
*b"01234567012345670123456701234567",
@@ -57,7 +58,7 @@ impl State {
&self.config
}
pub fn storage(&self) -> &Storage {
pub fn storage(&self) -> &Storage<PgPool> {
&self.storage
}

View File

@@ -57,7 +57,7 @@ impl Client {
}
}
impl super::Storage {
impl<T> super::Storage<T> {
pub async fn load_static_clients(&self, clients: &[OAuth2ClientConfig]) {
let mut storage = self.clients.write().await;
for config in clients {
@@ -93,7 +93,7 @@ mod tests {
#[async_std::test]
async fn test_login() {
let storage = Storage::default();
let storage = Storage::new(());
// "bad" is a bad password and should not insert
assert_eq!(storage.users.read().await.len(), 0);

View File

@@ -15,6 +15,7 @@
use std::collections::HashMap;
use async_std::sync::RwLock;
use sqlx::migrate::Migrator;
mod client;
mod user;
@@ -22,8 +23,25 @@ mod user;
pub use self::client::{Client, ClientLookupError, InvalidRedirectUriError};
pub use self::user::User;
#[derive(Debug, Default)]
pub struct Storage {
pub static MIGRATOR: Migrator = sqlx::migrate!();
#[derive(Debug)]
pub struct Storage<Pool> {
pool: Pool,
clients: RwLock<HashMap<String, Client>>,
users: RwLock<HashMap<String, User>>,
}
impl<Pool> Storage<Pool> {
pub fn new(pool: Pool) -> Self {
Self {
pool,
clients: Default::default(),
users: Default::default(),
}
}
pub fn pool(&self) -> &Pool {
&self.pool
}
}

View File

@@ -35,7 +35,7 @@ pub struct UserLoginError;
#[error("Could not find user")]
pub struct UserLookupError;
impl super::Storage {
impl<T> super::Storage<T> {
pub async fn login(&self, name: &str, password: &str) -> Result<User, UserLoginError> {
// Hardcoded bad password to test login failures
if password == "bad" {