BLOG-90 Intergrate error tracking with Sentry #120
475
backend/Cargo.lock
generated
475
backend/Cargo.lock
generated
@ -424,9 +424,11 @@ version = "0.2.0"
|
||||
dependencies = [
|
||||
"actix-session",
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"log",
|
||||
"openidconnect",
|
||||
"sentry",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"utoipa",
|
||||
@ -656,6 +658,16 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@ -804,6 +816,16 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "debugid"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.7.10"
|
||||
@ -1081,6 +1103,18 @@ version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||
|
||||
[[package]]
|
||||
name = "findshlibs"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.1"
|
||||
@ -1114,6 +1148,21 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[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.2.1"
|
||||
@ -1372,6 +1421,17 @@ dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.12"
|
||||
@ -1465,6 +1525,22 @@ dependencies = [
|
||||
"webpki-roots 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.16"
|
||||
@ -1664,10 +1740,12 @@ version = "0.2.0"
|
||||
dependencies = [
|
||||
"actix-multipart",
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"auth",
|
||||
"futures",
|
||||
"log",
|
||||
"sentry",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"utoipa",
|
||||
@ -1922,6 +2000,23 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
@ -2057,6 +2152,50 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "2.10.1"
|
||||
@ -2066,6 +2205,18 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_info"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0e1ac5fde8d43c34139135df8ea9ee9465394b2d8d20f032d38998f64afffc3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"plist",
|
||||
"serde",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "p256"
|
||||
version = "0.13.2"
|
||||
@ -2199,6 +2350,19 @@ version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.9.0",
|
||||
"quick-xml",
|
||||
"serde",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.2"
|
||||
@ -2231,10 +2395,12 @@ name = "post"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"auth",
|
||||
"chrono",
|
||||
"log",
|
||||
"sentry",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"utoipa",
|
||||
@ -2273,6 +2439,15 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-xml"
|
||||
version = "0.38.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9845d9dccf565065824e69f9f235fafba1587031eda353c1f1561cd6a6be78f4"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.8"
|
||||
@ -2505,9 +2680,11 @@ dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"js-sys",
|
||||
"log",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
@ -2518,6 +2695,7 @@ dependencies = [
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tower",
|
||||
"tower-http",
|
||||
@ -2621,6 +2799,15 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.11.0"
|
||||
@ -2653,6 +2840,15 @@ version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.9.0"
|
||||
@ -2697,12 +2893,168 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0"
|
||||
|
||||
[[package]]
|
||||
name = "sentry"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "989425268ab5c011e06400187eed6c298272f8ef913e49fcadc3fda788b45030"
|
||||
dependencies = [
|
||||
"httpdate",
|
||||
"native-tls",
|
||||
"reqwest",
|
||||
"sentry-actix",
|
||||
"sentry-anyhow",
|
||||
"sentry-backtrace",
|
||||
"sentry-contexts",
|
||||
"sentry-core",
|
||||
"sentry-debug-images",
|
||||
"sentry-panic",
|
||||
"sentry-tracing",
|
||||
"tokio",
|
||||
"ureq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-actix"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5c675bdf6118764a8e265c3395c311b4d905d12866c92df52870c0223d2ffc1"
|
||||
dependencies = [
|
||||
"actix-http",
|
||||
"actix-web",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-anyhow"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1b4523c2595d6730bfbe401e95a6423fe9cb16dc3b6046f340551591cffe723"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-backtrace"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68e299dd3f7bcf676875eee852c9941e1d08278a743c32ca528e2debf846a653"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"regex",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-contexts"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fac0c5d6892cd4c414492fc957477b620026fb3411fca9fa12774831da561c88"
|
||||
dependencies = [
|
||||
"hostname",
|
||||
"libc",
|
||||
"os_info",
|
||||
"rustc_version",
|
||||
"sentry-core",
|
||||
"uname",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-core"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "deaa38b94e70820ff3f1f9db3c8b0aef053b667be130f618e615e0ff2492cbcc"
|
||||
dependencies = [
|
||||
"rand 0.9.1",
|
||||
"sentry-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-debug-images"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00950648aa0d371c7f57057434ad5671bd4c106390df7e7284739330786a01b6"
|
||||
dependencies = [
|
||||
"findshlibs",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-panic"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b7a23b13c004873de3ce7db86eb0f59fe4adfc655a31f7bbc17fd10bacc9bfe"
|
||||
dependencies = [
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-tracing"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fac841c7050aa73fc2bec8f7d8e9cb1159af0b3095757b99820823f3e54e5080"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-types"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e477f4d4db08ddb4ab553717a8d3a511bc9e81dde0c808c680feacbb8105c412"
|
||||
dependencies = [
|
||||
"debugid",
|
||||
"hex",
|
||||
"rand 0.9.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
@ -2822,6 +3174,7 @@ dependencies = [
|
||||
"openidconnect",
|
||||
"percent-encoding",
|
||||
"post",
|
||||
"sentry",
|
||||
"sqlx",
|
||||
"utoipa",
|
||||
"utoipa-redoc",
|
||||
@ -3302,6 +3655,16 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-retry"
|
||||
version = "0.3.0"
|
||||
@ -3422,6 +3785,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||
dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3436,6 +3809,15 @@ version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
|
||||
|
||||
[[package]]
|
||||
name = "uname"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.18"
|
||||
@ -3485,6 +3867,36 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "3.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f0fde9bc91026e381155f8c67cb354bcd35260b2f4a29bcc84639f762760c39"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"der",
|
||||
"log",
|
||||
"native-tls",
|
||||
"percent-encoding",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"ureq-proto",
|
||||
"utf-8",
|
||||
"webpki-root-certs 0.26.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ureq-proto"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59db78ad1923f2b1be62b6da81fe80b173605ca0d57f85da2e005382adf693f7"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"http 1.3.1",
|
||||
"httparse",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.5.4"
|
||||
@ -3497,6 +3909,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf-8"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utf16_iter"
|
||||
version = "1.0.5"
|
||||
@ -3552,6 +3970,23 @@ dependencies = [
|
||||
"utoipa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
@ -3685,6 +4120,24 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "0.26.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e"
|
||||
dependencies = [
|
||||
"webpki-root-certs 1.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-root-certs"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.10"
|
||||
@ -3713,6 +4166,28 @@ dependencies = [
|
||||
"wasite",
|
||||
]
|
||||
|
||||
[[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-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 = "windows-core"
|
||||
version = "0.61.0"
|
||||
|
@ -10,6 +10,7 @@ edition = "2024"
|
||||
actix-multipart = "0.7.2"
|
||||
actix-session = { version = "0.10.1", features = ["redis-session"] }
|
||||
actix-web = "4.10.2"
|
||||
anyhow = "1.0.98"
|
||||
async-trait = "0.1.88"
|
||||
chrono = "0.4.41"
|
||||
dotenv = "0.15.0"
|
||||
@ -22,6 +23,7 @@ openidconnect = { version = "4.0.1", features = [
|
||||
"reqwest-blocking",
|
||||
] }
|
||||
percent-encoding = "2.3.1"
|
||||
sentry = { version = "0.42.0", features = ["actix", "anyhow"] }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
sqlx = { version = "0.8.5", features = [
|
||||
"chrono",
|
||||
|
@ -13,6 +13,7 @@ COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/server .
|
||||
EXPOSE 8080
|
||||
VOLUME ["/app/static"]
|
||||
ENV RUST_LOG=info
|
||||
ENV RUST_BACKTRACE=1
|
||||
ENV HOST=0.0.0.0
|
||||
ENV PORT=8080
|
||||
ENV STORAGE_PATH=/app/static
|
||||
@ -27,5 +28,6 @@ ENV OIDC_ISSUER_URL=
|
||||
ENV OIDC_REDIRECT_URL=
|
||||
ENV OIDC_CLIENT_ID=
|
||||
ENV OIDC_CLIENT_SECRET=
|
||||
ENV SENTRY_DSN=
|
||||
|
||||
CMD ["./server"]
|
||||
|
@ -6,9 +6,11 @@ edition.workspace = true
|
||||
[dependencies]
|
||||
actix-session.workspace = true
|
||||
actix-web.workspace = true
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
log.workspace = true
|
||||
openidconnect.workspace = true
|
||||
sentry.workspace = true
|
||||
serde.workspace = true
|
||||
sqlx.workspace = true
|
||||
utoipa.workspace = true
|
||||
|
@ -1,10 +1,24 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AuthError {
|
||||
DatabaseError(String),
|
||||
OidcError(String),
|
||||
InvalidState,
|
||||
InvalidNonce,
|
||||
InvalidAuthCode,
|
||||
InvalidIdToken,
|
||||
UserNotFound,
|
||||
Unexpected(anyhow::Error),
|
||||
}
|
||||
|
||||
impl Display for AuthError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AuthError::InvalidState => write!(f, "Invalid state"),
|
||||
AuthError::InvalidNonce => write!(f, "Invalid nonce"),
|
||||
AuthError::InvalidAuthCode => write!(f, "Invalid authentication code"),
|
||||
AuthError::InvalidIdToken => write!(f, "Invalid ID token"),
|
||||
AuthError::UserNotFound => write!(f, "User not found"),
|
||||
AuthError::Unexpected(e) => write!(f, "Unexpected error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ impl UserDbService for UserDbServiceImpl {
|
||||
)
|
||||
.fetch_optional(&self.db_pool)
|
||||
.await
|
||||
.map_err(|e| AuthError::DatabaseError(e.to_string()))?;
|
||||
.map_err(|e| AuthError::Unexpected(e.into()))?;
|
||||
|
||||
match record {
|
||||
Some(record) => Ok(record.into_mapper()),
|
||||
@ -56,7 +56,7 @@ impl UserDbService for UserDbServiceImpl {
|
||||
)
|
||||
.fetch_optional(&self.db_pool)
|
||||
.await
|
||||
.map_err(|e| AuthError::DatabaseError(e.to_string()))?;
|
||||
.map_err(|e| AuthError::Unexpected(e.into()))?;
|
||||
|
||||
match record {
|
||||
Some(record) => Ok(record.into_mapper()),
|
||||
@ -78,7 +78,7 @@ impl UserDbService for UserDbServiceImpl {
|
||||
)
|
||||
.fetch_one(&self.db_pool)
|
||||
.await
|
||||
.map_err(|e| AuthError::DatabaseError(e.to_string()))?;
|
||||
.map_err(|e| AuthError::Unexpected(e.into()))?;
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ impl AuthOidcService for AuthOidcServiceImpl {
|
||||
let token_response = self
|
||||
.oidc_client
|
||||
.exchange_code(AuthorizationCode::new(code.to_string()))
|
||||
.map_err(|e| AuthError::OidcError(e.to_string()))?
|
||||
.map_err(|e| AuthError::Unexpected(e.into()))?
|
||||
.request_async(&self.http_client)
|
||||
.await
|
||||
.map_err(|_| AuthError::InvalidAuthCode)?;
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::future::{self, Ready};
|
||||
use std::{
|
||||
fmt::Display,
|
||||
future::{self, Ready},
|
||||
};
|
||||
|
||||
use actix_session::SessionExt;
|
||||
use actix_web::{Error, FromRequest, HttpRequest, dev::Payload, error::ErrorUnauthorized};
|
||||
use actix_web::{FromRequest, HttpRequest, dev::Payload};
|
||||
|
||||
use crate::framework::web::constants::SESSION_KEY_USER_ID;
|
||||
|
||||
@ -14,20 +17,39 @@ impl UserId {
|
||||
}
|
||||
|
||||
impl FromRequest for UserId {
|
||||
type Error = Error;
|
||||
type Future = Ready<Result<Self, Self::Error>>;
|
||||
type Error = UnauthorizedError;
|
||||
type Future = Ready<Result<Self, UnauthorizedError>>;
|
||||
|
||||
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
|
||||
let user_id_result = req.get_session().get::<i32>(SESSION_KEY_USER_ID);
|
||||
|
||||
let user_id = match user_id_result {
|
||||
Ok(id) => id,
|
||||
_ => return future::ready(Err(ErrorUnauthorized(""))),
|
||||
_ => return future::ready(Err(UnauthorizedError)),
|
||||
};
|
||||
|
||||
match user_id {
|
||||
Some(id) => future::ready(Ok(UserId(id))),
|
||||
None => future::ready(Err(ErrorUnauthorized(""))),
|
||||
None => future::ready(Err(UnauthorizedError)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnauthorizedError;
|
||||
|
||||
impl Display for UnauthorizedError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Unauthorized access")
|
||||
}
|
||||
}
|
||||
|
||||
impl actix_web::ResponseError for UnauthorizedError {
|
||||
fn status_code(&self) -> actix_web::http::StatusCode {
|
||||
actix_web::http::StatusCode::UNAUTHORIZED
|
||||
}
|
||||
|
||||
fn error_response(&self) -> actix_web::HttpResponse {
|
||||
actix_web::HttpResponse::Unauthorized().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::{
|
||||
adapter::delivery::{auth_controller::AuthController, user_response_dto::UserResponseDto},
|
||||
application::error::auth_error::AuthError,
|
||||
framework::web::auth_middleware::UserId,
|
||||
};
|
||||
|
||||
@ -26,7 +29,10 @@ pub async fn get_logged_in_user_handler(
|
||||
match result {
|
||||
Ok(user) => HttpResponse::Ok().json(user),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
AuthError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use actix_session::Session;
|
||||
use actix_web::{HttpResponse, Responder, http::header, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
@ -48,7 +50,7 @@ pub async fn oidc_callback_handler(
|
||||
match result {
|
||||
Ok(user) => {
|
||||
if let Err(e) = session.insert::<i32>(SESSION_KEY_USER_ID, user.id) {
|
||||
log::error!("{e:?}");
|
||||
capture_anyhow(&e.into());
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
HttpResponse::Found()
|
||||
@ -61,7 +63,10 @@ pub async fn oidc_callback_handler(
|
||||
| AuthError::InvalidNonce
|
||||
| AuthError::InvalidState => HttpResponse::BadRequest().finish(),
|
||||
_ => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
AuthError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
},
|
||||
|
@ -1,8 +1,11 @@
|
||||
use actix_session::Session;
|
||||
use actix_web::{HttpResponse, Responder, http::header, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::{
|
||||
adapter::delivery::auth_controller::AuthController,
|
||||
application::error::auth_error::AuthError,
|
||||
framework::web::constants::{SESSION_KEY_AUTH_NONCE, SESSION_KEY_AUTH_STATE},
|
||||
};
|
||||
|
||||
@ -24,11 +27,11 @@ pub async fn oidc_login_handler(
|
||||
match result {
|
||||
Ok(auth_url) => {
|
||||
if let Err(e) = session.insert::<String>(SESSION_KEY_AUTH_STATE, auth_url.state) {
|
||||
log::error!("{e:?}");
|
||||
capture_anyhow(&e.into());
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
if let Err(e) = session.insert::<String>(SESSION_KEY_AUTH_NONCE, auth_url.nonce) {
|
||||
log::error!("{e:?}");
|
||||
capture_anyhow(&e.into());
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
}
|
||||
HttpResponse::Found()
|
||||
@ -36,7 +39,10 @@ pub async fn oidc_login_handler(
|
||||
.finish()
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
AuthError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ edition.workspace = true
|
||||
[dependencies]
|
||||
actix-multipart.workspace = true
|
||||
actix-web.workspace = true
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
futures.workspace = true
|
||||
log.workspace = true
|
||||
sentry.workspace = true
|
||||
serde.workspace = true
|
||||
sqlx.workspace = true
|
||||
utoipa.workspace = true
|
||||
|
@ -57,7 +57,7 @@ impl ImageController for ImageControllerImpl {
|
||||
image: ImageRequestDto,
|
||||
) -> Result<ImageInfoResponseDto, ImageError> {
|
||||
if !self.mime_type_whitelist.contains(&image.mime_type) {
|
||||
return Err(ImageError::UnsupportedMimeType);
|
||||
return Err(ImageError::UnsupportedMimeType(image.mime_type));
|
||||
}
|
||||
|
||||
let mime_type = image.mime_type.clone();
|
||||
|
@ -1,7 +1,18 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ImageError {
|
||||
DatabaseError(String),
|
||||
StorageError(String),
|
||||
NotFound,
|
||||
UnsupportedMimeType,
|
||||
UnsupportedMimeType(String),
|
||||
Unexpected(anyhow::Error),
|
||||
}
|
||||
|
||||
impl Display for ImageError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
ImageError::NotFound => write!(f, "Image not found"),
|
||||
ImageError::UnsupportedMimeType(mime) => write!(f, "Unsupported MIME type: {}", mime),
|
||||
ImageError::Unexpected(e) => write!(f, "Unexpected error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ impl ImageDbService for ImageDbServiceImpl {
|
||||
|
||||
match id {
|
||||
Ok(id) => Ok(id),
|
||||
Err(e) => Err(ImageError::DatabaseError(e.to_string())),
|
||||
Err(e) => Err(ImageError::Unexpected(anyhow::Error::from(e))),
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ impl ImageDbService for ImageDbServiceImpl {
|
||||
}),
|
||||
None => Err(ImageError::NotFound),
|
||||
},
|
||||
Err(e) => Err(ImageError::DatabaseError(e.to_string())),
|
||||
Err(e) => Err(ImageError::Unexpected(anyhow::Error::from(e))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,20 +22,19 @@ impl ImageStorageImpl {
|
||||
impl ImageStorage for ImageStorageImpl {
|
||||
fn write_data(&self, id: i32, data: &[u8]) -> Result<(), ImageError> {
|
||||
let dir_path = format!("{}/images", self.sotrage_path);
|
||||
fs::create_dir_all(&dir_path).map_err(|e| ImageError::StorageError(e.to_string()))?;
|
||||
fs::create_dir_all(&dir_path).map_err(|e| ImageError::Unexpected(e.into()))?;
|
||||
|
||||
let file_path = format!("{}/{}", dir_path, id);
|
||||
let mut file =
|
||||
File::create(&file_path).map_err(|e| ImageError::StorageError(e.to_string()))?;
|
||||
let mut file = File::create(&file_path).map_err(|e| ImageError::Unexpected(e.into()))?;
|
||||
file.write_all(data)
|
||||
.map_err(|e| ImageError::StorageError(e.to_string()))?;
|
||||
.map_err(|e| ImageError::Unexpected(e.into()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_data(&self, id: i32) -> Result<Vec<u8>, ImageError> {
|
||||
let file_path = format!("{}/images/{}", self.sotrage_path, id);
|
||||
let data = fs::read(&file_path).map_err(|e| ImageError::StorageError(e.to_string()))?;
|
||||
let data = fs::read(&file_path).map_err(|e| ImageError::Unexpected(e.into()))?;
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::{
|
||||
@ -29,8 +31,12 @@ pub async fn get_image_by_id_handler(
|
||||
.body(image_response.data),
|
||||
Err(e) => match e {
|
||||
ImageError::NotFound => HttpResponse::NotFound().finish(),
|
||||
ImageError::Unexpected(e) => {
|
||||
capture_anyhow(&e);
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
_ => {
|
||||
log::error!("{e:?}");
|
||||
capture_anyhow(&anyhow!(e));
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
},
|
||||
|
@ -1,7 +1,9 @@
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use auth::framework::web::auth_middleware::UserId;
|
||||
use futures::StreamExt;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use crate::{
|
||||
@ -73,9 +75,15 @@ pub async fn upload_image_handler(
|
||||
match result {
|
||||
Ok(image_info) => HttpResponse::Created().json(image_info),
|
||||
Err(e) => match e {
|
||||
ImageError::UnsupportedMimeType => HttpResponse::BadRequest().body(format!("{e:?}")),
|
||||
ImageError::UnsupportedMimeType(mime_type) => {
|
||||
HttpResponse::BadRequest().body(format!("Unsupported MIME type: {}", mime_type))
|
||||
}
|
||||
ImageError::Unexpected(e) => {
|
||||
capture_anyhow(&e);
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
_ => {
|
||||
log::error!("{e:?}");
|
||||
capture_anyhow(&anyhow!(e));
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
},
|
||||
|
@ -5,9 +5,11 @@ edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
actix-web.workspace = true
|
||||
anyhow.workspace = true
|
||||
async-trait.workspace = true
|
||||
chrono.workspace = true
|
||||
log.workspace = true
|
||||
sentry.workspace = true
|
||||
serde.workspace = true
|
||||
sqlx.workspace = true
|
||||
utoipa.workspace = true
|
||||
|
@ -1,5 +1,16 @@
|
||||
#[derive(Debug, PartialEq)]
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PostError {
|
||||
DatabaseError(String),
|
||||
NotFound,
|
||||
Unexpected(anyhow::Error),
|
||||
}
|
||||
|
||||
impl Display for PostError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
PostError::NotFound => write!(f, "Post not found"),
|
||||
PostError::Unexpected(e) => write!(f, "Unexpected error: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ impl LabelDbService for LabelDbServiceImpl {
|
||||
)
|
||||
.fetch_one(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
@ -49,7 +49,7 @@ impl LabelDbService for LabelDbServiceImpl {
|
||||
)
|
||||
.execute(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?
|
||||
.rows_affected();
|
||||
|
||||
if affected_rows == 0 {
|
||||
@ -71,7 +71,7 @@ impl LabelDbService for LabelDbServiceImpl {
|
||||
)
|
||||
.fetch_optional(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
match record {
|
||||
Some(record) => Ok(record.into_mapper()),
|
||||
@ -91,7 +91,7 @@ impl LabelDbService for LabelDbServiceImpl {
|
||||
)
|
||||
.fetch_all(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
let mappers = records
|
||||
.into_iter()
|
||||
|
@ -64,7 +64,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
.build_query_as::<PostInfoWithLabelRecord>()
|
||||
.fetch_all(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
let mut post_info_mappers_map = HashMap::<i32, PostInfoMapper>::new();
|
||||
|
||||
@ -136,7 +136,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
.build_query_as::<PostWithLabelRecord>()
|
||||
.fetch_all(&self.db_pool)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
if records.is_empty() {
|
||||
return Err(PostError::NotFound);
|
||||
@ -188,7 +188,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
.db_pool
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
let post_id = sqlx::query_scalar!(
|
||||
r#"
|
||||
@ -205,7 +205,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
)
|
||||
.fetch_one(&mut *tx)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
for (order, &label_id) in label_ids.iter().enumerate() {
|
||||
sqlx::query!(
|
||||
@ -221,12 +221,12 @@ impl PostDbService for PostDbServiceImpl {
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
}
|
||||
|
||||
tx.commit()
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
Ok(post_id)
|
||||
}
|
||||
@ -236,7 +236,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
.db_pool
|
||||
.begin()
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
let affected_rows = sqlx::query!(
|
||||
r#"
|
||||
@ -258,7 +258,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?
|
||||
.rows_affected();
|
||||
|
||||
if affected_rows == 0 {
|
||||
@ -274,7 +274,7 @@ impl PostDbService for PostDbServiceImpl {
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
for (order, &label_id) in label_ids.iter().enumerate() {
|
||||
sqlx::query!(
|
||||
@ -290,12 +290,12 @@ impl PostDbService for PostDbServiceImpl {
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
}
|
||||
|
||||
tx.commit()
|
||||
.await
|
||||
.map_err(|err| PostError::DatabaseError(err.to_string()))?;
|
||||
.map_err(|e| PostError::Unexpected(e.into()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use auth::framework::web::auth_middleware::UserId;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::adapter::delivery::{
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
create_label_request_dto::CreateLabelRequestDto, label_response_dto::LabelResponseDto,
|
||||
post_controller::PostController,
|
||||
},
|
||||
application::error::post_error::PostError,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
@ -28,7 +33,10 @@ pub async fn create_label_handler(
|
||||
match result {
|
||||
Ok(label) => HttpResponse::Created().json(label),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
PostError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use auth::framework::web::auth_middleware::UserId;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::adapter::delivery::{
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
create_post_request_dto::CreatePostRequestDto, post_controller::PostController,
|
||||
post_response_dto::PostResponseDto,
|
||||
},
|
||||
application::error::post_error::PostError,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
@ -28,7 +33,10 @@ pub async fn create_post_handler(
|
||||
match result {
|
||||
Ok(post) => HttpResponse::Created().json(post),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
PostError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::adapter::delivery::{
|
||||
label_response_dto::LabelResponseDto, post_controller::PostController,
|
||||
use crate::{
|
||||
adapter::delivery::{label_response_dto::LabelResponseDto, post_controller::PostController},
|
||||
application::error::post_error::PostError,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
@ -21,7 +24,10 @@ pub async fn get_all_labels_handler(
|
||||
match result {
|
||||
Ok(labels) => HttpResponse::Ok().json(labels),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
PostError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use anyhow::anyhow;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::adapter::delivery::{
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
post_controller::PostController, post_info_query_dto::PostQueryDto,
|
||||
post_info_response_dto::PostInfoResponseDto,
|
||||
},
|
||||
application::error::post_error::PostError,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
@ -26,7 +31,10 @@ pub async fn get_all_post_info_handler(
|
||||
match result {
|
||||
Ok(post_info_list) => HttpResponse::Ok().json(post_info_list),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
PostError::Unexpected(e) => capture_anyhow(&e),
|
||||
_ => capture_anyhow(&anyhow!(e)),
|
||||
};
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::{
|
||||
adapter::delivery::{post_controller::PostController, post_response_dto::PostResponseDto},
|
||||
@ -24,13 +25,12 @@ pub async fn get_post_by_id_handler(
|
||||
|
||||
match result {
|
||||
Ok(post) => HttpResponse::Ok().json(post),
|
||||
Err(e) => {
|
||||
if e == PostError::NotFound {
|
||||
HttpResponse::NotFound().finish()
|
||||
} else {
|
||||
log::error!("{e:?}");
|
||||
Err(e) => match e {
|
||||
PostError::NotFound => HttpResponse::NotFound().finish(),
|
||||
PostError::Unexpected(e) => {
|
||||
capture_anyhow(&e);
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use auth::framework::web::auth_middleware::UserId;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
@ -37,8 +38,8 @@ pub async fn update_label_handler(
|
||||
Ok(label) => HttpResponse::Ok().json(label),
|
||||
Err(e) => match e {
|
||||
PostError::NotFound => HttpResponse::NotFound().finish(),
|
||||
_ => {
|
||||
log::error!("{e:?}");
|
||||
PostError::Unexpected(e) => {
|
||||
capture_anyhow(&e);
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
},
|
||||
|
@ -1,9 +1,13 @@
|
||||
use actix_web::{HttpResponse, Responder, web};
|
||||
use auth::framework::web::auth_middleware::UserId;
|
||||
use sentry::integrations::anyhow::capture_anyhow;
|
||||
|
||||
use crate::adapter::delivery::{
|
||||
use crate::{
|
||||
adapter::delivery::{
|
||||
post_controller::PostController, post_response_dto::PostResponseDto,
|
||||
update_post_request_dto::UpdatePostRequestDto,
|
||||
},
|
||||
application::error::post_error::PostError,
|
||||
};
|
||||
|
||||
#[utoipa::path(
|
||||
@ -30,14 +34,12 @@ pub async fn update_post_handler(
|
||||
|
||||
match result {
|
||||
Ok(post) => HttpResponse::Ok().json(post),
|
||||
Err(e) => {
|
||||
log::error!("{e:?}");
|
||||
match e {
|
||||
crate::application::error::post_error::PostError::NotFound => {
|
||||
HttpResponse::NotFound().finish()
|
||||
}
|
||||
_ => HttpResponse::InternalServerError().finish(),
|
||||
}
|
||||
Err(e) => match e {
|
||||
PostError::NotFound => HttpResponse::NotFound().finish(),
|
||||
PostError::Unexpected(e) => {
|
||||
capture_anyhow(&e);
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ env_logger.workspace = true
|
||||
hex.workspace = true
|
||||
openidconnect.workspace = true
|
||||
percent-encoding.workspace = true
|
||||
sentry.workspace = true
|
||||
sqlx.workspace = true
|
||||
utoipa.workspace = true
|
||||
utoipa-redoc.workspace = true
|
||||
|
@ -1,12 +1,13 @@
|
||||
use openidconnect::reqwest;
|
||||
|
||||
use crate::configuration::{
|
||||
db::DbConfiguration, oidc::OidcConfiguration, server::ServerConfiguration,
|
||||
session::SessionConfiguration, storage::StorageConfiguration,
|
||||
db::DbConfiguration, oidc::OidcConfiguration, sentry::SentryConfiguration,
|
||||
server::ServerConfiguration, session::SessionConfiguration, storage::StorageConfiguration,
|
||||
};
|
||||
|
||||
pub mod db;
|
||||
pub mod oidc;
|
||||
pub mod sentry;
|
||||
pub mod server;
|
||||
pub mod session;
|
||||
pub mod storage;
|
||||
@ -15,6 +16,7 @@ pub mod storage;
|
||||
pub struct Configuration {
|
||||
pub db: DbConfiguration,
|
||||
pub oidc: OidcConfiguration,
|
||||
pub sentry: SentryConfiguration,
|
||||
pub server: ServerConfiguration,
|
||||
pub session: SessionConfiguration,
|
||||
pub storage: StorageConfiguration,
|
||||
@ -25,6 +27,7 @@ impl Configuration {
|
||||
Self {
|
||||
db: DbConfiguration::new(),
|
||||
oidc: OidcConfiguration::new(http_client).await,
|
||||
sentry: SentryConfiguration::new(),
|
||||
server: ServerConfiguration::new(),
|
||||
session: SessionConfiguration::new(),
|
||||
storage: StorageConfiguration::new(),
|
||||
|
22
backend/server/src/configuration/sentry.rs
Normal file
22
backend/server/src/configuration/sentry.rs
Normal file
@ -0,0 +1,22 @@
|
||||
#[derive(Clone)]
|
||||
pub struct SentryConfiguration {
|
||||
pub dsn: String,
|
||||
pub options: sentry::ClientOptions,
|
||||
}
|
||||
|
||||
impl SentryConfiguration {
|
||||
pub fn new() -> Self {
|
||||
let dsn = std::env::var("SENTRY_DSN").unwrap_or("".to_string());
|
||||
|
||||
Self {
|
||||
dsn: dsn,
|
||||
options: sentry::ClientOptions {
|
||||
release: sentry::release_name!(),
|
||||
traces_sample_rate: 1.0,
|
||||
send_default_pii: true,
|
||||
max_request_body_size: sentry::MaxRequestBodySize::Always,
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
@ -5,17 +5,19 @@ use actix_web::{
|
||||
App, Error, HttpServer,
|
||||
body::MessageBody,
|
||||
dev::{ServiceFactory, ServiceRequest, ServiceResponse},
|
||||
rt::Runtime,
|
||||
web,
|
||||
};
|
||||
use auth::framework::web::auth_web_routes::configure_auth_routes;
|
||||
use image::framework::web::image_web_routes::configure_image_routes;
|
||||
use openidconnect::reqwest;
|
||||
use post::framework::web::post_web_routes::configure_post_routes;
|
||||
use server::{api_doc::configure_api_doc_routes, configuration::Configuration, container::Container};
|
||||
use server::{
|
||||
api_doc::configure_api_doc_routes, configuration::Configuration, container::Container,
|
||||
};
|
||||
use sqlx::{Pool, Postgres};
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
fn main() -> std::io::Result<()> {
|
||||
dotenv::dotenv().ok();
|
||||
env_logger::init();
|
||||
|
||||
@ -24,8 +26,15 @@ async fn main() -> std::io::Result<()> {
|
||||
.build()
|
||||
.expect("Failed to create HTTP client");
|
||||
|
||||
let configuration = Configuration::new(http_client.clone()).await;
|
||||
let rt = Runtime::new().unwrap();
|
||||
let configuration = rt.block_on(async { Configuration::new(http_client.clone()).await });
|
||||
|
||||
let _guard = sentry::init((
|
||||
configuration.sentry.dsn.clone(),
|
||||
configuration.sentry.options.clone(),
|
||||
));
|
||||
|
||||
actix_web::rt::System::new().block_on(async {
|
||||
let host = configuration.server.host.clone();
|
||||
let port = configuration.server.port;
|
||||
|
||||
@ -37,6 +46,9 @@ async fn main() -> std::io::Result<()> {
|
||||
create_app(
|
||||
db_pool.clone(),
|
||||
http_client.clone(),
|
||||
sentry::integrations::actix::Sentry::builder()
|
||||
.capture_server_errors(true)
|
||||
.start_transaction(true),
|
||||
SessionMiddleware::builder(session_store.clone(), session_key.clone()),
|
||||
configuration.clone(),
|
||||
)
|
||||
@ -44,11 +56,15 @@ async fn main() -> std::io::Result<()> {
|
||||
.bind((host, port))?
|
||||
.run()
|
||||
.await
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_app(
|
||||
db_pool: Pool<Postgres>,
|
||||
http_client: reqwest::Client,
|
||||
sentry_builder: sentry::integrations::actix::SentryBuilder,
|
||||
session_middleware_builder: SessionMiddlewareBuilder<RedisSessionStore>,
|
||||
configuration: Configuration,
|
||||
) -> App<
|
||||
@ -64,6 +80,7 @@ fn create_app(
|
||||
|
||||
App::new()
|
||||
// The middlewares are executed in opposite order as registration.
|
||||
.wrap(sentry_builder.finish())
|
||||
.wrap(session_middleware_builder.build())
|
||||
.app_data(web::Data::from(container.auth_controller))
|
||||
.app_data(web::Data::from(container.image_controller))
|
||||
|
Loading…
x
Reference in New Issue
Block a user