diff --git a/Cargo.lock b/Cargo.lock index 2e374ee..cda40e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,6 +206,15 @@ version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +[[package]] +name = "arc-swap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" +dependencies = [ + "rustversion", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -238,6 +247,487 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-config" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47712fde1909402600ccfbb26e47d482d2e58bb9e9e603d9f17e67cc435a6319" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.4.0", + "sha1 0.10.7", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e93964ffdaf57857f544be3666a5f57570bb699e934700f11b49708f61bb556e" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + +[[package]] +name = "aws-lc-rs" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4342d8937fc7e5dd9b1c60292261c0670c882a2cd1719cfc11b1af41731e32ad" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9ceb1da931507a12f4fccea479dccd00da1943e1b4ae72d8e502d707361444" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + +[[package]] +name = "aws-runtime" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7816e98ee912159f45d307e5ee6bfea4a335a55aee15f7f3e32f81a6f3000f1d" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "bytes-utils", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-s3" +version = "1.138.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c29be98554a0deea25d4eaca131240a224dcbcaf20357e35cc432e17b721ab5" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-checksums", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "bytes", + "fastrand", + "hex", + "hmac 0.13.0", + "http 0.2.12", + "http 1.4.0", + "http-body 1.0.1", + "lru", + "percent-encoding", + "regex-lite", + "sha2 0.11.0", + "tracing", + "url", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.103.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0469f435f645ad2162cfb463b15bde37115966ee3acf2d87fb4871ee309b8401" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.105.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "085faefb253f770655e162b9304321e62a1e71adf7f019ee1f4454228a377b3a" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.108.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c72b08911d8128dd360fe1b22a9fec0fa8b552dde8ec828dcf20ef5ec974e9f" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723c2234ad7511ceef63eab016b7ba6ff7c55590fefb96fa8467af014a07309f" +dependencies = [ + "aws-credential-types", + "aws-smithy-eventstream", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "crypto-bigint", + "form_urlencoded", + "hex", + "hmac 0.13.0", + "http 0.2.12", + "http 1.4.0", + "p256", + "percent-encoding", + "sha2 0.11.0", + "subtle", + "time", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-async" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f02e407fb3b54891734224b9ffac8a71fdd35f542500fa1af95754a6b2beb316" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-checksums" +version = "0.65.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67ecd999972b58e67cab052f5129906c08c25883bd0788ceefc55ef97d61307" +dependencies = [ + "aws-smithy-http", + "aws-smithy-types", + "bytes", + "crc-fast", + "hex", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "md-5 0.11.0", + "pin-project-lite", + "sha1 0.11.0", + "sha2 0.11.0", + "tracing", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9381123ab62d20c13082b151f30f962a3b112b727345394536dfa39a482944" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37843d9add67c3aff5856f409c6dc315d3cdff60f9c0cb5b670dab1e9920306d" +dependencies = [ + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "635d23afda0a6ab48d666c4d447c4873e8d1e83518a2be2093122397e50b838e" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2 0.3.27", + "h2 0.4.13", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper 1.9.0", + "hyper-rustls 0.24.2", + "hyper-rustls 0.27.9", + "hyper-util", + "pin-project-lite", + "rustls 0.21.12", + "rustls 0.23.41", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dc65a121adb4b33729919fcfa14fa36fb33c1555a8f06bb0e2188dbfdc1d9ef" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e86338c869539a581bf161247762a6e87f92c5c075060057b5ed6d06632ed0c" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd22a6ba36e3f113cb8d5b3d1fe0ed31c76ee608ef63322d753bb8d2c9479e77" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea94a9ff8464016338c851e24b472d7131c388c88898a502e781815b2ee6045" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ed1ebe6e0a95ea84570225f5a8208dec4b8f77e61a9b0d6f51773fcb4612f0" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api-macros", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.4.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-runtime-api-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221eaa237ddf1ca79b60d1372aad77e47f9c0ea5b3ce5099da8c61d027dc77b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "aws-smithy-schema" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d56e0a4e53127a632224e43633b0fe045fa9e1e3cfc68b9830f1115e103f910" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "http 1.4.0", +] + +[[package]] +name = "aws-smithy-types" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6dc683efb34b9e755675b37fedbe0103141e5b6df7bdc9eb6967756a8c167d8" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "futures-core", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", + "tokio", + "tokio-util", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea3f68eec3607f02acd24067969ce2abc6ba16aa7d5ce59ca450ed2fb5f78957" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e957a6c6dbce82b7a91f44231c09273159703769f447cbe85e854dfe9cf67f86" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "rustc_version", + "tracing", +] + [[package]] name = "axum" version = "0.8.9" @@ -248,7 +738,7 @@ dependencies = [ "bytes", "futures-util", "http 1.4.0", - "http-body", + "http-body 1.0.1", "http-body-util", "itoa", "matchit", @@ -272,7 +762,7 @@ dependencies = [ "bytes", "futures-core", "http 1.4.0", - "http-body", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -306,12 +796,28 @@ dependencies = [ "windows-link", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "base64ct" version = "1.8.3" @@ -392,6 +898,16 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + [[package]] name = "bytestring" version = "1.5.1" @@ -408,6 +924,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -468,6 +986,15 @@ dependencies = [ "inout 0.2.2", ] +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "cmov" version = "0.5.3" @@ -483,6 +1010,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const-oid" version = "0.10.2" @@ -553,6 +1086,16 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" +[[package]] +name = "crc-fast" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75b2483e97a5a7da73ac68a05b629f9c53cff58d8ed1c77866079e18b00dba5" +dependencies = [ + "digest 0.10.7", + "spin 0.10.0", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -577,6 +1120,18 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -625,13 +1180,24 @@ dependencies = [ "uuid", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid 0.9.6", + "pem-rfc7468 0.7.0", + "zeroize", +] + [[package]] name = "der" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ - "pem-rfc7468", + "pem-rfc7468 1.0.0", "zeroize", ] @@ -674,6 +1240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid 0.9.6", "crypto-common 0.1.7", "subtle", ] @@ -685,7 +1252,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", - "const-oid", + "const-oid 0.10.2", "crypto-common 0.2.1", "ctutils", ] @@ -723,6 +1290,26 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.15.0" @@ -732,6 +1319,26 @@ dependencies = [ "serde", ] +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pem-rfc7468 0.7.0", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encoding_rs" version = "0.8.35" @@ -784,6 +1391,16 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -826,7 +1443,7 @@ checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ "futures-core", "futures-sink", - "spin", + "spin 0.9.8", ] [[package]] @@ -871,6 +1488,27 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.32" @@ -915,6 +1553,17 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "futures-sink" version = "0.3.32" @@ -933,8 +1582,10 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -950,6 +1601,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -995,6 +1647,36 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.13" @@ -1120,6 +1802,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.1" @@ -1139,7 +1832,7 @@ dependencies = [ "bytes", "futures-core", "http 1.4.0", - "http-body", + "http-body 1.0.1", "pin-project-lite", ] @@ -1165,6 +1858,30 @@ dependencies = [ "typenum", ] +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.27", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.9.0" @@ -1175,9 +1892,9 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2", + "h2 0.4.13", "http 1.4.0", - "http-body", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -1187,6 +1904,21 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-rustls" version = "0.27.9" @@ -1194,11 +1926,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http 1.4.0", - "hyper", + "hyper 1.9.0", "hyper-util", - "rustls", + "rustls 0.23.41", + "rustls-native-certs", "tokio", - "tokio-rustls", + "tokio-rustls 0.26.4", "tower-service", ] @@ -1208,7 +1941,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper", + "hyper 1.9.0", "hyper-util", "pin-project-lite", "tokio", @@ -1223,7 +1956,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.9.0", "hyper-util", "native-tls", "tokio", @@ -1242,8 +1975,8 @@ dependencies = [ "futures-channel", "futures-util", "http 1.4.0", - "http-body", - "hyper", + "http-body 1.0.1", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", @@ -1444,6 +2177,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.2", + "libc", +] + [[package]] name = "js-sys" version = "0.3.97" @@ -1535,6 +2278,15 @@ version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +[[package]] +name = "lru" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" +dependencies = [ + "hashbrown 0.16.1", +] + [[package]] name = "macros" version = "0.1.1" @@ -1687,6 +2439,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1938,6 +2699,24 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "outref" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + [[package]] name = "parking" version = "2.2.1" @@ -1973,6 +2752,15 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "pem-rfc7468" version = "1.0.0" @@ -2025,6 +2813,22 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.33" @@ -2065,6 +2869,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -2261,6 +3074,15 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + [[package]] name = "rand_core" version = "0.9.5" @@ -2349,12 +3171,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.4.13", "http 1.4.0", - "http-body", + "http-body 1.0.1", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.9.0", + "hyper-rustls 0.27.9", "hyper-tls", "hyper-util", "js-sys", @@ -2377,6 +3199,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + [[package]] name = "ring" version = "0.17.14" @@ -2445,6 +3277,27 @@ dependencies = [ [[package]] name = "rnex-ds" version = "0.1.0" +dependencies = [ + "aws-config", + "aws-sdk-s3", + "base64", + "chrono", + "futures", + "hex", + "hmac 0.13.0", + "rnex-base", + "rnex-base-protos", + "rnex-ds-protos", + "rnex-rmc", + "rnex-server", + "rnex-util", + "serde_json", + "sha2 0.11.0", + "sqlx", + "thiserror", + "tracing", + "urlencoding", +] [[package]] name = "rnex-ds-protos" @@ -2614,6 +3467,7 @@ dependencies = [ "bytemuck", "chrono", "md-5 0.11.0", + "thiserror", "tokio", "tracing", ] @@ -2646,21 +3500,46 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.15.0" @@ -2670,12 +3549,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustls-webpki" version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -2708,6 +3598,30 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der 0.7.10", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "3.7.0" @@ -2914,6 +3828,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a978451301f4db1d02937a4ab3ccce137717b81826e79b7d49ffe3244a13c3b8" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + [[package]] name = "sha1" version = "0.11.0" @@ -2972,6 +3897,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.9" @@ -3049,6 +3984,22 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + [[package]] name = "sqlx" version = "0.9.0" @@ -3154,7 +4105,7 @@ dependencies = [ "log", "percent-encoding", "serde", - "sha1", + "sha1 0.11.0", "sha2 0.11.0", "sqlx-core", "thiserror", @@ -3432,13 +4383,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls", + "rustls 0.23.41", "tokio", ] @@ -3476,11 +4437,11 @@ dependencies = [ "axum", "base64", "bytes", - "h2", + "h2 0.4.13", "http 1.4.0", - "http-body", + "http-body 1.0.1", "http-body-util", - "hyper", + "hyper 1.9.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -3563,7 +4524,7 @@ dependencies = [ "bytes", "futures-util", "http 1.4.0", - "http-body", + "http-body 1.0.1", "pin-project-lite", "tower", "tower-layer", @@ -3720,12 +4681,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64", - "der", + "der 0.8.1", "flate2", "log", "native-tls", "percent-encoding", - "rustls", + "rustls 0.23.41", "rustls-pki-types", "ureq-proto", "utf8-zero", @@ -3758,6 +4719,12 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8-zero" version = "0.8.1" @@ -3808,6 +4775,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vsimd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" + [[package]] name = "want" version = "0.3.1" @@ -4236,6 +5209,12 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yoke" version = "0.8.2" diff --git a/rnex-prudp/src/socket_addr.rs b/rnex-prudp/src/socket_addr.rs index 09c22af..87846ab 100644 --- a/rnex-prudp/src/socket_addr.rs +++ b/rnex-prudp/src/socket_addr.rs @@ -22,7 +22,7 @@ impl PRUDPSockAddr { } pub fn calculate_connection_signature(&self) -> [u8; 16] { - let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("?"); + let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("incorrect slice size"); let data = match self.regular_socket_addr.ip() { IpAddr::V4(v) => v.octets().to_vec(), @@ -33,7 +33,7 @@ impl PRUDPSockAddr { hmac.update(&data); let result: [u8; 16] = hmac.finalize().into_bytes()[0..16] .try_into() - .expect("fuck"); + .expect("incorrect result size"); result } } diff --git a/rnex-rmc/src/networking.rs b/rnex-rmc/src/networking.rs index cb65e3b..f9879d4 100644 --- a/rnex-rmc/src/networking.rs +++ b/rnex-rmc/src/networking.rs @@ -73,7 +73,7 @@ impl RmcSerialize for SocketAddrV6 { )) } fn serialize_write_size(&self) -> Result { - Ok(6) + Ok(26) } } /* diff --git a/rnex-rmc/src/primitives.rs b/rnex-rmc/src/primitives.rs index d0e3f3a..62e0393 100644 --- a/rnex-rmc/src/primitives.rs +++ b/rnex-rmc/src/primitives.rs @@ -124,7 +124,7 @@ impl RmcSerialize for u128 { } #[inline(always)] fn serialize_write_size(&self) -> Result { - Ok(8) + Ok(16) } } diff --git a/rnex-rmc/src/response.rs b/rnex-rmc/src/response.rs index 7f71f6e..197ef8c 100644 --- a/rnex-rmc/src/response.rs +++ b/rnex-rmc/src/response.rs @@ -465,6 +465,6 @@ impl From for ErrorCode { impl Into for ErrorCode { fn into(self) -> u32 { - unsafe { transmute(self) } + self as u32 } } diff --git a/rnex-rmc/src/rmc_struct.rs b/rnex-rmc/src/rmc_struct.rs index 2a12bbf..fa7b315 100644 --- a/rnex-rmc/src/rmc_struct.rs +++ b/rnex-rmc/src/rmc_struct.rs @@ -77,7 +77,7 @@ impl<'a, T: Read + ?Sized> SubRead<'a, T> { impl Read for SubRead<'_, T> { #[inline(always)] fn read(&mut self, buf: &mut [u8]) -> io::Result { - let max_read = usize::max(self.left_to_read, buf.len()); + let max_read = usize::min(self.left_to_read, buf.len()); let read = self.origin.read(&mut buf[..max_read])?; self.left_to_read -= read; Ok(read) diff --git a/rnex-rmc/src/station_url.rs b/rnex-rmc/src/station_url.rs index 6d2a6af..0aa187a 100644 --- a/rnex-rmc/src/station_url.rs +++ b/rnex-rmc/src/station_url.rs @@ -1,5 +1,6 @@ use std::fmt::Write; use std::io::{self, Read}; +use std::str::FromStr; use rnex_util::station_url::StationUrl; @@ -12,7 +13,7 @@ impl RmcSerialize for StationUrl { fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { let str = String::deserialize(reader)?; - Self::try_from(str.as_str()).map_err(|_| StationUrlInvalid) + Self::from_str(str.as_str()).map_err(|_| StationUrlInvalid) } fn serialize(&self, writer: &mut (impl io::Write + ?Sized)) -> Result<()> { let str: String = self.into(); diff --git a/rnex-server-nex-modules/rnex-ds/Cargo.toml b/rnex-server-nex-modules/rnex-ds/Cargo.toml index fbdbd11..c61b373 100644 --- a/rnex-server-nex-modules/rnex-ds/Cargo.toml +++ b/rnex-server-nex-modules/rnex-ds/Cargo.toml @@ -4,6 +4,25 @@ version = "0.1.0" edition = "2024" [dependencies] +rnex-rmc = { path = "../../rnex-rmc" } +rnex-util = { path = "../../rnex-util" } +rnex-base = { path = "../rnex-base" } +rnex-base-protos = { path = "../../rnex-protocols/base-protos" } +rnex-ds-protos = { path = "../../rnex-protocols/ds-protos" } +rnex-server = { path = "../../rnex-server" } +sqlx = "0.9.0" +tracing = "0.1.44" +thiserror = "2.0.18" +chrono = "0.4.45" +aws-sdk-s3 = "1.138.0" +aws-config = "1.9.0" +sha2 = "0.11.0" +hmac = "0.13.0" +base64 = "0.22.1" +serde_json = "1.0.150" +hex = "0.4.3" +urlencoding = "2.1.3" +futures = "0.3.32" [lints] workspace = true diff --git a/rnex-core-deprecated/src/nex/datastore.rs b/rnex-server-nex-modules/rnex-ds/src/datastore.rs similarity index 61% rename from rnex-core-deprecated/src/nex/datastore.rs rename to rnex-server-nex-modules/rnex-ds/src/datastore.rs index 6a095a3..e897375 100644 --- a/rnex-core-deprecated/src/nex/datastore.rs +++ b/rnex-server-nex-modules/rnex-ds/src/datastore.rs @@ -1,207 +1,221 @@ -use crate::rmc::protocols::datastore::DataStoreGetCustomRankingParam; use chrono::Utc; -use futures::TryStreamExt; use futures::future::join_all; -use rnex_core::PID; -use rnex_core::executables::common::{ - RNEX_DATASTORE_S3_BUCKET, RNEX_DATASTORE_S3_ENDPOINT, get_db, +use rnex_base::user::BaseUser; +use rnex_ds_protos::{ + LocalDatastoreProtocol, + datastore::{ + AttachFileParam, BufferQueueParam, CompletePostParam, DataStore, DataStoreChangeMetaParam, + DataStoreCustomRankingResult, DataStoreDeleteParam, DataStoreFileServerObjectInfo, + DataStoreGetCourseRecordParam, DataStoreGetCourseRecordResult, + DataStoreGetCustomRankingByDataIDParam, DataStoreGetCustomRankingParam, + DataStorePrepareGetParam, DataStoreRateObjectParam, DataStoreRatingTarget, + DataStoreReportCourseParam, DataStoreReqGetInfo, DataStoreSearchParam, + DataStoreUploadCourseRecordParam, GetMetaInfo, GetMetaParam, KeyValue, Permission, + PersistenceTarget, PreparePostParam, RatingInfo, RatingInfoWithSlot, + RatingInitParamWithSlot, ReqPostInfo, + }, }; -use rnex_core::kerberos::KerberosDateTime; -use rnex_core::nex::s3presigner::S3Presigner; -use rnex_core::nex::user::User; -use rnex_core::rmc::protocols::datastore::{ - AttachFileParam, DataStore, DataStoreRateObjectParam, DataStoreRatingTarget, PreparePostParam, - ReqPostInfo, -}; -use rnex_core::rmc::protocols::datastore::{ - BufferQueueParam, CompletePostParam, DataStoreChangeMetaParam, DataStoreCustomRankingResult, - DataStoreDeleteParam, DataStoreFileServerObjectInfo, DataStoreGetCourseRecordParam, - DataStoreGetCourseRecordResult, DataStoreGetCustomRankingByDataIDParam, - DataStorePrepareGetParam, DataStoreReportCourseParam, DataStoreReqGetInfo, - DataStoreSearchParam, DataStoreUploadCourseRecordParam, GetMetaInfo, GetMetaParam, KeyValue, - Permission, PersistenceTarget, RateCustomRankingParam, RatingInfo, RatingInfoWithSlot, - RatingInitParamWithSlot, -}; -use rnex_core::rmc::response::ErrorCode; -use rnex_core::rmc::structures::qbuffer::QBuffer; -use rnex_core::rmc::structures::qresult::QResult; +use rnex_rmc::{qbuffer::QBuffer, qresult::QResult, response::ErrorCode, rmc_struct}; +use rnex_server::PassthroughInitModule; +use rnex_util::{PID, date_time::DateTime}; +use sqlx::query; use std::convert; +use tracing::{error, info, warn}; -fn map_row_to_meta_info( - row_data_id: i64, - row_owner: i32, - row_size: i32, - row_name: String, - row_data_type: i16, - row_meta_binary: Vec, - row_permission: i16, - row_permission_recipients: Vec, - row_delete_permission: i16, - row_delete_permission_recipients: Vec, - row_period: i16, - row_refer_data_id: i64, - row_flag: i32, - row_tags: Vec, - row_creation_date: chrono::NaiveDateTime, - row_update_date: chrono::NaiveDateTime, - ratings: Vec, -) -> GetMetaInfo { - GetMetaInfo { - dataid: row_data_id, - owner: row_owner as PID, - size: row_size as u32, - name: row_name, - data_type: row_data_type as u16, - meta_binary: QBuffer(row_meta_binary), - permission: Permission { - permission: row_permission as u8, - recipient_ids: row_permission_recipients - .into_iter() - .map(|id| id as PID) - .collect(), - }, - del_permission: Permission { - permission: row_delete_permission as u8, - recipient_ids: row_delete_permission_recipients - .into_iter() - .map(|id| id as PID) - .collect(), - }, - period: row_period as u16, - status: 0, - referred_count: 0, - refer_dat_id: row_refer_data_id as u32, - flag: row_flag as u32, - tags: row_tags, - expire_time: KerberosDateTime::PRACTICALLY_NEVER, - created_time: KerberosDateTime::from_naive(row_creation_date), - updated_time: KerberosDateTime::from_naive(row_update_date), - referred_time: KerberosDateTime::from_naive(row_creation_date), - ratings, - } +use crate::{DatastoreManager, s3presigner::S3Presigner}; +// todo: refactor this further to make some of the helper functions attached to the user and some to +// the manager and also move the usages of pid into the helper functions attached to user + +#[rmc_struct(DatastoreProtocol)] +pub struct DatastoreUser { + pub base: PassthroughInitModule, + pub dm: PassthroughInitModule, } -pub async fn check_object_availability(data_id: i64, password: i64) -> Result<(), ErrorCode> { - let row = sqlx::query!( - r#" +impl DatastoreUser { + fn map_row_to_meta_info( + &self, + row_data_id: i64, + row_owner: i32, + row_size: i32, + row_name: String, + row_data_type: i16, + row_meta_binary: Vec, + row_permission: i16, + row_permission_recipients: Vec, + row_delete_permission: i16, + row_delete_permission_recipients: Vec, + row_period: i16, + row_refer_data_id: i64, + row_flag: i32, + row_tags: Vec, + row_creation_date: chrono::NaiveDateTime, + row_update_date: chrono::NaiveDateTime, + ratings: Vec, + ) -> GetMetaInfo { + GetMetaInfo { + dataid: row_data_id, + owner: row_owner as PID, + size: row_size as u32, + name: row_name, + data_type: row_data_type as u16, + meta_binary: QBuffer(row_meta_binary), + permission: Permission { + permission: row_permission as u8, + recipient_ids: row_permission_recipients + .into_iter() + .map(|id| id as PID) + .collect(), + }, + del_permission: Permission { + permission: row_delete_permission as u8, + recipient_ids: row_delete_permission_recipients + .into_iter() + .map(|id| id as PID) + .collect(), + }, + period: row_period as u16, + status: 0, + referred_count: 0, + refer_dat_id: row_refer_data_id as u32, + flag: row_flag as u32, + tags: row_tags, + expire_time: DateTime::PRACTICALLY_NEVER, + created_time: DateTime::from_naive(row_creation_date), + updated_time: DateTime::from_naive(row_update_date), + referred_time: DateTime::from_naive(row_creation_date), + ratings, + } + } + + pub async fn check_object_availability( + &self, + data_id: i64, + password: i64, + ) -> Result<(), ErrorCode> { + let row = sqlx::query!( + r#" SELECT under_review, access_password FROM datastore.objects WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE "#, - data_id - ) - .fetch_optional(get_db()) - .await - .map_err(|e| { - eprintln!("Availability check DB error: {:?}", e); - ErrorCode::DataStore_NotFound - })? - .ok_or(ErrorCode::DataStore_NotFound)?; + data_id + ) + .fetch_optional(&self.dm.db_pool) + .await + .map_err(|e| { + eprintln!("Availability check DB error: {:?}", e); + ErrorCode::DataStore_NotFound + })? + .ok_or(ErrorCode::DataStore_NotFound)?; - let access_password = row.access_password; - if access_password != 0 && access_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); + let access_password = row.access_password; + if access_password != 0 && access_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } + + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + Ok(()) } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + pub async fn get_object_ratings( + &self, + data_id: i64, + password: i64, + ) -> Result, ErrorCode> { + self.check_object_availability(data_id, password).await?; - Ok(()) -} - -pub async fn get_object_ratings( - data_id: i64, - password: i64, -) -> Result, ErrorCode> { - check_object_availability(data_id, password).await?; - - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT slot, total_value, count, initial_value FROM datastore.object_ratings WHERE data_id = $1 "#, - data_id - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - eprintln!("Ratings fetch error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + data_id + ) + .fetch_all(&self.dm.db_pool) + .await + .map_err(|e| { + eprintln!("Ratings fetch error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; - let ratings = rows - .into_iter() - .map(|row| RatingInfoWithSlot { - slot: row.slot as i8, - rating: RatingInfo { - total_value: row.total_value.unwrap_or(0), - count: row.count as u32, - initial_value: row.initial_value.unwrap_or(0), - }, - }) - .collect(); + let ratings = rows + .into_iter() + .map(|row| RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + }) + .collect(); - Ok(ratings) -} + Ok(ratings) + } -pub async fn get_object_info_by_data_id( - data_id: i64, - password: i64, -) -> Result { - check_object_availability(data_id, password).await?; + pub async fn get_object_info_by_data_id( + &self, + data_id: i64, + password: i64, + ) -> Result { + self.check_object_availability(data_id, password).await?; - let row = sqlx::query!( + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date FROM datastore.objects WHERE data_id = $1"#, data_id ) - .fetch_optional(get_db()) + .fetch_optional(&self.dm.db_pool) .await .map_err(|_| ErrorCode::DataStore_NotFound)? .ok_or(ErrorCode::DataStore_NotFound)?; - let ratings = get_object_ratings(data_id, password).await?; + let ratings = self.get_object_ratings(data_id, password).await?; - // lots of ugly unwraps please fix the db eventually to correctly represent what states it can and cant be in + // lots of ugly unwraps please fix the db eventually to correctly represent what states it can and cant be in - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name, - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.unwrap_or_default(), - row.update_date.unwrap_or_default(), - ratings, - )) -} + Ok(self.map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name, + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.unwrap_or_default(), + row.update_date.unwrap_or_default(), + ratings, + )) + } -async fn get_object_info_by_persistence_target( - target: PersistenceTarget, - password: i64, -) -> Result { - let row = sqlx::query!( + async fn get_object_info_by_persistence_target( + &self, + target: PersistenceTarget, + password: i64, + ) -> Result { + let row = sqlx::query!( r#"SELECT data_id, owner, size, name, data_type, meta_binary, permission, permission_recipients, delete_permission, delete_permission_recipients, period, refer_data_id, flag, tags, creation_date, update_date, @@ -212,121 +226,123 @@ async fn get_object_info_by_persistence_target( target.owner as i32, target.persistence_slot_id as i16 ) - .fetch_optional(get_db()) + .fetch_optional(&self.dm.db_pool) .await .map_err(|_| ErrorCode::DataStore_NotFound)? .ok_or(ErrorCode::DataStore_NotFound)?; - let db_password = row.access_password; - if db_password != 0 && db_password != password { - return Err(ErrorCode::DataStore_InvalidPassword); + let db_password = row.access_password; + if db_password != 0 && db_password != password { + return Err(ErrorCode::DataStore_InvalidPassword); + } + + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + let ratings = self.get_object_ratings(row.data_id, password).await?; + + Ok(self.map_row_to_meta_info( + row.data_id, + row.owner.unwrap_or(0), + row.size.unwrap_or(0), + row.name, + row.data_type.unwrap_or(0) as i16, + row.meta_binary.unwrap_or_default(), + row.permission.unwrap_or(0) as i16, + row.permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.delete_permission.unwrap_or(0) as i16, + row.delete_permission_recipients + .unwrap_or_default() + .into_iter() + .map(|id| id as i64) + .collect(), + row.period.unwrap_or(0) as i16, + row.refer_data_id.unwrap_or(0), + row.flag.unwrap_or(0), + row.tags.unwrap_or_default(), + row.creation_date.unwrap_or_default(), + row.update_date.unwrap_or_default(), + ratings, + )) } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + async fn get_buffer_queues_by_data_id_and_slot( + &self, + data_id: i64, + slot: i32, + ) -> Result, ErrorCode> { + self.check_object_availability(data_id, 0).await?; - let ratings = get_object_ratings(row.data_id, password).await?; - - Ok(map_row_to_meta_info( - row.data_id, - row.owner.unwrap_or(0), - row.size.unwrap_or(0), - row.name, - row.data_type.unwrap_or(0) as i16, - row.meta_binary.unwrap_or_default(), - row.permission.unwrap_or(0) as i16, - row.permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.delete_permission.unwrap_or(0) as i16, - row.delete_permission_recipients - .unwrap_or_default() - .into_iter() - .map(|id| id as i64) - .collect(), - row.period.unwrap_or(0) as i16, - row.refer_data_id.unwrap_or(0), - row.flag.unwrap_or(0), - row.tags.unwrap_or_default(), - row.creation_date.unwrap_or_default(), - row.update_date.unwrap_or_default(), - ratings, - )) -} - -async fn get_buffer_queues_by_data_id_and_slot( - data_id: i64, - slot: i32, -) -> Result, ErrorCode> { - check_object_availability(data_id, 0).await?; - - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT buffer FROM datastore.buffer_queues WHERE data_id = $1 AND slot = $2 ORDER BY creation_date ASC "#, - data_id, - slot as i32 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("Buffer queue fetch error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + data_id, + slot as i32 + ) + .fetch_all(&self.dm.db_pool) + .await + .map_err(|e| { + error!("Buffer queue fetch error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; - let buffer_queues = rows.into_iter().map(|row| QBuffer(row.buffer)).collect(); + let buffer_queues = rows.into_iter().map(|row| QBuffer(row.buffer)).collect(); - Ok(buffer_queues) -} - -async fn verify_object_permission( - owner_id: PID, - viewer_id: PID, - permission: &Permission, -) -> Result<(), ErrorCode> { - if owner_id == viewer_id { - return Ok(()); + Ok(buffer_queues) } - match permission.permission { - 0 => Ok(()), // All can read - 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented - 2 => { - // Recipient IDs can read - if permission.recipient_ids.contains(&viewer_id) { - Ok(()) - } else { - Err(ErrorCode::DataStore_PermissionDenied) - } + fn verify_object_permission( + &self, + owner_id: PID, + viewer_id: PID, + permission: &Permission, + ) -> Result<(), ErrorCode> { + if owner_id == viewer_id { + return Ok(()); } - 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant (maple: we should still check if its - // the owner and return true if it is, otherwise the owner would be unable to access their own objects) - _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r - } -} -fn filter_properties_by_result_option(meta_info: &mut GetMetaInfo, result_option: u8) { - if (result_option & 0x01) == 0 { - meta_info.meta_binary = QBuffer(Vec::new()); + match permission.permission { + 0 => Ok(()), // All can read + 1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented + 2 => { + // Recipient IDs can read + if permission.recipient_ids.contains(&viewer_id) { + Ok(()) + } else { + Err(ErrorCode::DataStore_PermissionDenied) + } + } + 3 => Err(ErrorCode::DataStore_PermissionDenied), // Owner only, redundant (maple: we should still check if its + // the owner and return true if it is, otherwise the owner would be unable to access their own objects) + _ => Err(ErrorCode::DataStore_InvalidArgument), // ??? haxx0r + } } - if (result_option & 0x04) == 0 { - meta_info.ratings = Vec::new(); + fn filter_properties_by_result_option(&self, meta_info: &mut GetMetaInfo, result_option: u8) { + if (result_option & 0x01) == 0 { + meta_info.meta_binary = QBuffer(Vec::new()); + } + + if (result_option & 0x04) == 0 { + meta_info.ratings = Vec::new(); + } + + // No idea what the other things do. :shrug: } - // No idea what the other things do. :shrug: -} - -async fn init_object_rating_slot(data_id: i64, rating_param: RatingInitParamWithSlot) { - log::info!("running init object rating slot"); - sqlx::query!( - r#" + async fn init_object_rating_slot(&self, data_id: i64, rating_param: RatingInitParamWithSlot) { + info!("running init object rating slot"); + sqlx::query!( + r#" INSERT INTO datastore.object_ratings ( data_id, slot, @@ -343,36 +359,37 @@ async fn init_object_rating_slot(data_id: i64, rating_param: RatingInitParamWith $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11 ) "#, - data_id, - rating_param.slot as i16, - rating_param.param.flag as i16, - rating_param.param.internal_flag as i16, - rating_param.param.lock_type as i16, - rating_param.param.initial_value, - rating_param.param.range_min, - rating_param.param.range_max, - rating_param.param.period_hour as i16, - rating_param.param.period_duration as i32, - rating_param.param.initial_value, - ) - .execute(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - }); - log::info!("done running"); -} + data_id, + rating_param.slot as i16, + rating_param.param.flag as i16, + rating_param.param.internal_flag as i16, + rating_param.param.lock_type as i16, + rating_param.param.initial_value, + rating_param.param.range_min, + rating_param.param.range_max, + rating_param.param.period_hour as i16, + rating_param.param.period_duration as i32, + rating_param.param.initial_value, + ) + .execute(&self.dm.db_pool) + .await + .map_err(|e| { + error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + }); + info!("done running"); + } -// Dawg... -async fn get_custom_rankings_by_data_ids( - application_id: u32, - data_ids: Vec, -) -> Vec { - let mut results = Vec::with_capacity(data_ids.len()); + // Dawg... + async fn get_custom_rankings_by_data_ids( + &self, + application_id: u32, + data_ids: Vec, + ) -> Vec { + let mut results = Vec::with_capacity(data_ids.len()); - let rows = sqlx::query!( - r#" + let rows = sqlx::query!( + r#" SELECT rankings.data_id, rankings.value @@ -382,317 +399,325 @@ async fn get_custom_rankings_by_data_ids( AND rankings.application_id = $2 ORDER BY rows.ord "#, - &data_ids.iter().map(|&id| id).collect::>(), - application_id as i32 - ) - .fetch_all(get_db()) - .await; + &data_ids.iter().map(|&id| id).collect::>(), + application_id as i32 + ) + .fetch_all(&self.dm.db_pool) + .await; - let rows = match rows { - Ok(r) => r, - Err(e) => { - log::error!("Custom ranking query error: {:?}", e); - return results; + let rows = match rows { + Ok(r) => r, + Err(e) => { + error!("Custom ranking query error: {:?}", e); + return results; + } + }; + + for row in rows { + let data_id = row.data_id; + let score = row.value.unwrap_or(0) as u32; + + if let Ok(meta) = self.get_object_info_by_data_id(data_id, 0).await { + results.push(DataStoreCustomRankingResult { + order: 0, + score, + meta_info: meta, + }); + } else { + warn!("Could not find metadata for ranked object {}", data_id); + } } - }; - for row in rows { - let data_id = row.data_id; - let score = row.value.unwrap_or(0) as u32; - - if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { - results.push(DataStoreCustomRankingResult { - order: 0, - score, - meta_info: meta, - }); - } else { - log::warn!("Could not find metadata for ranked object {}", data_id); - } + results } - results -} - -async fn get_user_course_object_ids(owner_pid: PID) -> Result, ErrorCode> { - let rows = sqlx::query!( - r#" + async fn get_user_course_object_ids(&self, owner_pid: PID) -> Result, ErrorCode> { + let rows = sqlx::query!( + r#" SELECT data_id FROM datastore.objects WHERE owner = $1 AND data_type > 2 AND data_type < 50 "#, - owner_pid - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); - ErrorCode::DataStore_NotFound - })?; + owner_pid + ) + .fetch_all(&self.dm.db_pool) + .await + .map_err(|e| { + error!("error fetching course IDs for PID {}: {:?}", owner_pid, e); + ErrorCode::DataStore_NotFound + })?; - let mut valid_ids = Vec::new(); - for row in rows { - let data_id = row.data_id; - // always check avail - if check_object_availability(data_id, 0).await.is_ok() { - valid_ids.push(data_id); + let mut valid_ids = Vec::new(); + for row in rows { + let data_id = row.data_id; + // always check avail + if self.check_object_availability(data_id, 0).await.is_ok() { + valid_ids.push(data_id); + } } + + Ok(valid_ids) } - Ok(valid_ids) -} + fn get_blacklist_1(&self) -> Vec { + vec![ + "けされ", + "消され", + "削除され", + "リセットされ", + "BANされ", + "BANされ", + "キミのコース", + "君のコース", + "きみのコース", + "い い ね", + "遊びます", + "地震", + "震災", + "被災", + "津波", + "バンされ", + "い~ね", + "震度", + "じしん", + "banされ", + "くわしくは", + "詳しくは", + "ちんちん", + "ち0こ", + "bicth", + "い.い.ね", + "ナイ~ス", + "い&い", + "い-いね", + "いぃね", + "nigger", + "ngger", + "star if u", + "Star if u", + "Star if you", + "star if you", + "PENlS", + "マンコ", + "butthole", + "LILI", + "vagina", + "vagyna", + "うんち", + "うんこ", + "ウンコ", + "Iine", + "EENE", + "まんこ", + "ウンチ", + "niglet", + "nigglet", + "please like", + "きんたま", + "Butthole", + "llね", + "iいね", + "give a star", + "ちんぽ", + "亀頭", + "penis", + "ウンコ", + "plz more stars", + "star plz", + "い()ね", + "PLEASE star", + "Bitte Sterne", + ] + .into_iter() + .map(String::from) + .collect() + } -fn get_blacklist_1() -> Vec { - vec![ - "けされ", - "消され", - "削除され", - "リセットされ", - "BANされ", - "BANされ", - "キミのコース", - "君のコース", - "きみのコース", - "い い ね", - "遊びます", - "地震", - "震災", - "被災", - "津波", - "バンされ", - "い~ね", - "震度", - "じしん", - "banされ", - "くわしくは", - "詳しくは", - "ちんちん", - "ち0こ", - "bicth", - "い.い.ね", - "ナイ~ス", - "い&い", - "い-いね", - "いぃね", - "nigger", - "ngger", - "star if u", - "Star if u", - "Star if you", - "star if you", - "PENlS", - "マンコ", - "butthole", - "LILI", - "vagina", - "vagyna", - "うんち", - "うんこ", - "ウンコ", - "Iine", - "EENE", - "まんこ", - "ウンチ", - "niglet", - "nigglet", - "please like", - "きんたま", - "Butthole", - "llね", - "iいね", - "give a star", - "ちんぽ", - "亀頭", - "penis", - "ウンコ", - "plz more stars", - "star plz", - "い()ね", - "PLEASE star", - "Bitte Sterne", - ] - .into_iter() - .map(String::from) - .collect() -} + fn get_blacklist_2(&self) -> Vec { + vec![ + "ゼロから", + "0から", + "0から", + "い  い  ね", + "いい", + "東日本", + "大震", + ] + .into_iter() + .map(String::from) + .collect() + } -fn get_blacklist_2() -> Vec { - vec![ - "ゼロから", - "0から", - "0から", - "い  い  ね", - "いい", - "東日本", - "大震", - ] - .into_iter() - .map(String::from) - .collect() -} + fn get_blacklist_3(&self) -> Vec { + vec![ + "いいね", + "下さい", + "ください", + "押して", + "おして", + "返す", + "かえす", + "星", + "してくれ", + "するよ", + "☆くれたら", + "☆あげます", + "★くれたら", + "★あげます", + "しね", + "ころす", + "ころされた", + "アナル", + "ファック", + "キンタマ", + "○ね", + "キチガイ", + "うんこ", + "KITIGAI", + "金玉", + "おっぱい", + "☆おす", + "☆押す", + "★おす", + "★押す", + "いいする", + "いいよ", + "イイネ", + "ケツ", + "うんち", + "かくせいざい", + "覚せい剤", + "シャブ", + "きんたま", + "ちんちん", + "おしっこ", + "ちんぽこ", + "ころして", + "グッド", + "グット", + "レ●プ", + "バーカ", + "きちがい", + "ちんげ", + "マンコ", + "まんこ", + "チンポ", + "クズ", + "ウンコ", + "ナイスおねがいします", + "penis", + "イイね", + "☆よろ", + "ナイス!して", + "ま/んこ", + "まん/こ", + ] + .into_iter() + .map(String::from) + .collect() + } -fn get_blacklist_3() -> Vec { - vec![ - "いいね", - "下さい", - "ください", - "押して", - "おして", - "返す", - "かえす", - "星", - "してくれ", - "するよ", - "☆くれたら", - "☆あげます", - "★くれたら", - "★あげます", - "しね", - "ころす", - "ころされた", - "アナル", - "ファック", - "キンタマ", - "○ね", - "キチガイ", - "うんこ", - "KITIGAI", - "金玉", - "おっぱい", - "☆おす", - "☆押す", - "★おす", - "★押す", - "いいする", - "いいよ", - "イイネ", - "ケツ", - "うんち", - "かくせいざい", - "覚せい剤", - "シャブ", - "きんたま", - "ちんちん", - "おしっこ", - "ちんぽこ", - "ころして", - "グッド", - "グット", - "レ●プ", - "バーカ", - "きちがい", - "ちんげ", - "マンコ", - "まんこ", - "チンポ", - "クズ", - "ウンコ", - "ナイスおねがいします", - "penis", - "イイね", - "☆よろ", - "ナイス!して", - "ま/んこ", - "まん/こ", - ] - .into_iter() - .map(String::from) - .collect() -} + // couldn't find a better way to do this im going crazyy + async fn rate_object( + &self, + dataid: i64, + slot: i8, + rating_value: i32, + access_password: i64, + ) -> Result { + self.check_object_availability(dataid, access_password) + .await?; -// couldn't find a better way to do this im going crazyy -async fn rate_object( - dataid: i64, - slot: i8, - rating_value: i32, - access_password: i64, -) -> Result { - check_object_availability(dataid, access_password).await?; + let rating = RatingInfo::default(); - let rating = RatingInfo::default(); - - sqlx::query!( - r#" + sqlx::query!( + r#" UPDATE datastore.object_ratings SET total_value=total_value+$1, count=count+1 WHERE data_id=$2 AND slot=$3 RETURNING total_value, count, initial_value "#, - rating_value as i64, - dataid, - slot as i16 - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; + rating_value as i64, + dataid, + slot as i16 + ) + .fetch_all(&self.dm.db_pool) + .await + .map_err(|e| { + error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + })?; - Ok(rating) -} + Ok(rating) + } -async fn change_meta_object_check(param: &DataStoreChangeMetaParam) -> Result<(), ErrorCode> { - let row = sqlx::query!( + async fn change_meta_object_check( + &self, + param: &DataStoreChangeMetaParam, + ) -> Result<(), ErrorCode> { + let row = sqlx::query!( r#" SELECT update_password, under_review FROM datastore.objects WHERE data_id=$1 AND upload_completed=TRUE AND deleted=FALSE "#, param.dataid ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; - if row.update_password != 0 && row.update_password != param.update_password { - return Err(ErrorCode::DataStore_InvalidPassword); + if row.update_password != 0 && row.update_password != param.update_password { + return Err(ErrorCode::DataStore_InvalidPassword); + } + + if row.under_review { + return Err(ErrorCode::DataStore_UnderReviewing); + } + + Ok(()) } - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } + async fn get_rating_with_slot_data_id( + &self, + dataid: i64, + ) -> Result, ErrorCode> { + self.check_object_availability(dataid, 0).await?; - Ok(()) -} - -async fn get_rating_with_slot_data_id(dataid: i64) -> Result, ErrorCode> { - check_object_availability(dataid, 0).await?; - - let rows = sqlx::query!( + let rows = sqlx::query!( r#" SELECT slot, total_value, count, initial_value FROM datastore.object_ratings WHERE data_id=$1 "#, dataid ) - .fetch_all(get_db()) + .fetch_all(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; - let ratings = rows - .into_iter() - .map(|row| RatingInfoWithSlot { - slot: row.slot as i8, - rating: RatingInfo { - total_value: row.total_value.unwrap_or(0), - count: row.count as u32, - initial_value: row.initial_value.unwrap_or(0), - }, - }) - .collect::>(); + let ratings = rows + .into_iter() + .map(|row| RatingInfoWithSlot { + slot: row.slot as i8, + rating: RatingInfo { + total_value: row.total_value.unwrap_or(0), + count: row.count as u32, + initial_value: row.initial_value.unwrap_or(0), + }, + }) + .collect::>(); - Ok(ratings) -} + Ok(ratings) + } -pub async fn insert_buffer(dataid: i64, slot: i32, buffer: &QBuffer) { - let db_now = Utc::now().naive_utc(); + pub async fn insert_buffer(&self, dataid: i64, slot: i32, buffer: &QBuffer) { + let db_now = Utc::now().naive_utc(); - sqlx::query!( - r#" + sqlx::query!( + r#" INSERT INTO datastore.buffer_queues ( data_id, slot, @@ -705,25 +730,26 @@ pub async fn insert_buffer(dataid: i64, slot: i32, buffer: &QBuffer) { $4 ) ON CONFLICT (data_id, slot, buffer) DO UPDATE SET creation_date=$3 "#, - dataid, - slot, - db_now, - buffer.0 - ) - .execute(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - }); + dataid, + slot, + db_now, + buffer.0 + ) + .execute(&self.dm.db_pool) + .await + .map_err(|e| { + error!("DB Error: {:?}", e); + ErrorCode::DataStore_NotFound + }); + } } - -impl DataStore for User { +impl DataStore for DatastoreUser { async fn get_meta(&self, metaparam: GetMetaParam) -> Result { let mut meta_info = if metaparam.dataid != 0 { - get_object_info_by_data_id(metaparam.dataid, metaparam.access_password).await? + self.get_object_info_by_data_id(metaparam.dataid, metaparam.access_password) + .await? } else { - get_object_info_by_persistence_target( + self.get_object_info_by_persistence_target( metaparam.persistence_target, metaparam.access_password, ) @@ -731,9 +757,9 @@ impl DataStore for User { }; let current_pid = self.pid; - verify_object_permission(meta_info.owner, current_pid, &meta_info.permission).await?; + self.verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?; - filter_properties_by_result_option(&mut meta_info, metaparam.result_option); + self.filter_properties_by_result_option(&mut meta_info, metaparam.result_option); Ok(meta_info) } @@ -786,7 +812,7 @@ impl DataStore for User { now, now ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|e| { log::error!("DB Error: {:?}", e); @@ -794,22 +820,18 @@ impl DataStore for User { })?; let data_id = row.data_id; - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; - log::info!("param is: {:?}", postparam); - log::info!("RIP len is: {}", postparam.rating_init_params.len()); + info!("param is: {:?}", postparam); + info!("RIP len is: {}", postparam.rating_init_params.len()); for rating_param in &postparam.rating_init_params { - log::info!("running init params"); - init_object_rating_slot(data_id, rating_param.clone()).await + info!("running init params"); + self.init_object_rating_slot(data_id, rating_param.clone()) + .await } let key = format!("data/{}.bin", data_id); - let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + let (upload_url, fields) = self.dm.s3_presigner.generate_presigned_post(&key).await; let form_fields = fields .into_iter() @@ -829,14 +851,14 @@ impl DataStore for User { &self, completeparam: CompletePostParam, ) -> Result<(), ErrorCode> { - log::info!("Data ID: {:?}", completeparam.dataid); - log::info!("Success: {:?}", completeparam.success); + info!("Data ID: {:?}", completeparam.dataid); + info!("Success: {:?}", completeparam.success); let record = sqlx::query!( r#"SELECT owner, under_review FROM datastore.objects WHERE data_id = $1"#, completeparam.dataid ) - .fetch_optional(get_db()) + .fetch_optional(&self.dm.db_pool) .await .map_err(|e| { eprintln!("select error: {:?}", e); @@ -849,7 +871,7 @@ impl DataStore for User { return Err(ErrorCode::DataStore_UnderReviewing); } - if record.owner.unwrap_or(0) as PID != self.pid { + if record.owner.unwrap_or(0) as PID != self.base.pid { return Err(ErrorCode::DataStore_PermissionDenied); } @@ -858,7 +880,7 @@ impl DataStore for User { r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, completeparam.dataid ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { eprintln!("update error: {:?}", e); @@ -880,7 +902,7 @@ impl DataStore for User { r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, abcparam.dataid ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|_| ErrorCode::DataStore_NotFound)?; @@ -899,10 +921,10 @@ impl DataStore for User { abcparam.appid as i32, abcparam.score as i32 ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { - log::error!("update/insert error: {:?}", e); + error!("update/insert error: {:?}", e); ErrorCode::DataStore_NotFound })?; } @@ -992,11 +1014,12 @@ impl DataStore for User { println!("dataid list: {:?}", custom_ranking_param.data_id_list); println!("result option: {:?}", custom_ranking_param.result_option); - let mut ranking_results = get_custom_rankings_by_data_ids( - custom_ranking_param.application_id, - custom_ranking_param.data_id_list, - ) - .await; + let mut ranking_results = self + .get_custom_rankings_by_data_ids( + custom_ranking_param.application_id, + custom_ranking_param.data_id_list, + ) + .await; let mut q_results = Vec::with_capacity(ranking_results.len()); @@ -1029,8 +1052,9 @@ impl DataStore for User { ) -> Result, ErrorCode> { // log::info!("GetBufferQueue: dataid={}, slot={}", param.dataid, param.slot); - let buffers = - get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot).await?; + let buffers = self + .get_buffer_queues_by_data_id_and_slot(bufferparam.dataid, bufferparam.slot) + .await?; Ok(buffers) } @@ -1040,30 +1064,27 @@ impl DataStore for User { prepare_get_param: DataStorePrepareGetParam, ) -> Result { let meta_info = if prepare_get_param.dataid != 0 { - log::info!("getting object by meta info"); - log::info!("Data ID: {:?}", prepare_get_param.dataid); - get_object_info_by_data_id(prepare_get_param.dataid, prepare_get_param.access_password) - .await? + info!("getting object by meta info"); + info!("Data ID: {:?}", prepare_get_param.dataid); + self.get_object_info_by_data_id( + prepare_get_param.dataid, + prepare_get_param.access_password, + ) + .await? } else { - log::info!("getting object by persistence info"); - get_object_info_by_persistence_target( + info!("getting object by persistence info"); + self.get_object_info_by_persistence_target( prepare_get_param.persistence_target, prepare_get_param.access_password, ) .await? }; - log::info!("verifying object permission"); - verify_object_permission(meta_info.owner, self.pid, &meta_info.permission).await?; - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; + info!("verifying object permission"); + self.verify_object_permission(meta_info.owner, self.base.pid, &meta_info.permission)?; let key = format!("data/{}.bin", meta_info.dataid); - let download_url = presigner.generate_presigned_get(&key); + let download_url = self.dm.s3_presigner.generate_presigned_get(&key); Ok(DataStoreReqGetInfo { url: download_url, @@ -1082,13 +1103,13 @@ impl DataStore for User { let mut all_results = Vec::new(); for &owner_pid in &course_search_param.owner_ids { - let course_ids = get_user_course_object_ids(owner_pid).await?; + let course_ids = self.get_user_course_object_ids(owner_pid).await?; if course_ids.is_empty() { continue; } - let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; + let mut results = self.get_custom_rankings_by_data_ids(0, course_ids).await; // Flag 0x1: Return Tags // Flag 0x2: Return Ratings @@ -1123,11 +1144,11 @@ impl DataStore for User { application_id: u32, ) -> Result, ErrorCode> { let config = match application_id { - 128 => get_blacklist_1(), - 129 => get_blacklist_2(), - 130 => get_blacklist_3(), + 128 => self.get_blacklist_1(), + 129 => self.get_blacklist_2(), + 130 => self.get_blacklist_3(), _ => { - log::warn!( + warn!( "unsupported application_id in GetApplicationConfigString: {}", application_id ); @@ -1147,9 +1168,10 @@ impl DataStore for User { for param in params { let info_result = if param.dataid != 0 { - get_object_info_by_data_id(param.dataid, param.access_password).await + self.get_object_info_by_data_id(param.dataid, param.access_password) + .await } else { - get_object_info_by_persistence_target( + self.get_object_info_by_persistence_target( param.persistence_target, param.access_password, ) @@ -1159,7 +1181,7 @@ impl DataStore for User { match info_result { Ok(mut meta) => { if let Err(e) = - verify_object_permission(meta.owner, self.pid, &meta.permission).await + self.verify_object_permission(meta.owner, self.base.pid, &meta.permission) { metas.push(GetMetaInfo::default()); results.push(QResult::error(e)); @@ -1171,8 +1193,7 @@ impl DataStore for User { meta.ratings = Vec::new(); } if param.result_option & 0x4 == 0 { - meta.meta_binary = - rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); + meta.meta_binary = QBuffer(Vec::new()); } metas.push(meta); @@ -1252,29 +1273,24 @@ impl DataStore for User { now, now ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; let data_id = row.data_id; for rating_param in ¶m.post_param.rating_init_params { - log::info!("running init params"); - init_object_rating_slot(data_id, rating_param.clone()).await + info!("running init params"); + self.init_object_rating_slot(data_id, rating_param.clone()) + .await } - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; - let key = format!("data/{}.jpg", data_id); - let (upload_url, fields) = presigner.generate_presigned_post(&key).await; + let (upload_url, fields) = self.dm.s3_presigner.generate_presigned_post(&key).await; let form_fields = fields .into_iter() @@ -1294,17 +1310,11 @@ impl DataStore for User { &self, complete_attach_param: CompletePostParam, ) -> Result { - log::info!("Data ID: {:?}", complete_attach_param.dataid); - log::info!("Success: {:?}", complete_attach_param.success); - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; + info!("Data ID: {:?}", complete_attach_param.dataid); + info!("Success: {:?}", complete_attach_param.success); let key = format!("data/{}.jpg", complete_attach_param.dataid); - let download_url = presigner.generate_presigned_get(&key); + let download_url = self.dm.s3_presigner.generate_presigned_get(&key); Ok(download_url) } @@ -1331,26 +1341,31 @@ impl DataStore for User { .into_iter() .zip(params.into_iter()) .map(|(target, param)| async move { - log::info!("Data ID: {:?}", target.dataid); - log::info!("Slot: {:?}", target.slot); - log::info!("Access Password: {:?}", param.access_password); + info!("Data ID: {:?}", target.dataid); + info!("Slot: {:?}", target.slot); + info!("Access Password: {:?}", param.access_password); - let object_info = - get_object_info_by_data_id(target.dataid, param.access_password).await?; - log::info!("object info get complete"); - verify_object_permission(object_info.owner, self.pid, &object_info.permission) + let object_info = self + .get_object_info_by_data_id(target.dataid, param.access_password) .await?; - log::info!("object permission complete"); + info!("object info get complete"); + self.verify_object_permission( + object_info.owner, + self.base.pid, + &object_info.permission, + )?; + info!("object permission complete"); if fetch_ratings { - let rating = rate_object( - target.dataid, - target.slot, - param.rating_value, - param.access_password, - ) - .await?; - log::info!("rating complete"); + let rating = self + .rate_object( + target.dataid, + target.slot, + param.rating_value, + param.access_password, + ) + .await?; + info!("rating complete"); Result::, ErrorCode>::Ok(Some(rating)) } else { Result::, ErrorCode>::Ok(None) @@ -1382,7 +1397,7 @@ impl DataStore for User { param.period as i16, param.dataid ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { eprintln!("update error: {:?}", e); @@ -1398,7 +1413,7 @@ impl DataStore for User { param.meta_binary.0, param.dataid ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { eprintln!("update error: {:?}", e); @@ -1414,7 +1429,7 @@ impl DataStore for User { param.data_type as i16, param.dataid ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { eprintln!("update error: {:?}", e); @@ -1470,7 +1485,7 @@ impl DataStore for User { LIMIT 100 "# ) - .fetch(get_db()); + .fetch(&self.dm.db_pool); while let Some(row) = stream.try_next().await.map_err(|e| { eprintln!("stream error: {:?}", e); @@ -1490,17 +1505,17 @@ impl DataStore for User { let created_time = row .creation_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let updated_time = row .update_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let referred_time = row .creation_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let meta_info = GetMetaInfo { @@ -1518,11 +1533,11 @@ impl DataStore for User { refer_dat_id: row.refer_data_id.unwrap_or(0) as u32, flag: row.flag.unwrap_or(0) as u32, tags: row.tags.unwrap_or_default(), - expire_time: KerberosDateTime::PRACTICALLY_NEVER, + expire_time: DateTime::PRACTICALLY_NEVER, created_time, updated_time, referred_time, - ratings: get_rating_with_slot_data_id(row.data_id).await?, + ratings: self.get_rating_with_slot_data_id(row.data_id).await?, }; let course = DataStoreCustomRankingResult { @@ -1574,10 +1589,10 @@ impl DataStore for User { now, now ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; @@ -1601,10 +1616,10 @@ impl DataStore for User { get_course_record_param.dataid, get_course_record_param.slot as i16 ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; @@ -1614,8 +1629,8 @@ impl DataStore for User { first_pid: row.first_pid as u32, best_pid: row.best_pid as u32, best_score: row.best_score, - created_time: KerberosDateTime::PRACTICALLY_NEVER, - updated_time: KerberosDateTime::PRACTICALLY_NEVER, + created_time: DateTime::PRACTICALLY_NEVER, + updated_time: DateTime::PRACTICALLY_NEVER, }) } @@ -1630,14 +1645,14 @@ impl DataStore for User { for (param, buffer) in bufferparam.iter().zip(buffers.iter()) { if param.slot == 0 { - let object_info = get_object_info_by_data_id(param.dataid, 0).await?; + let object_info = self.get_object_info_by_data_id(param.dataid, 0).await?; if object_info.data_type == 1 && object_info.owner != client_pid { return Err(ErrorCode::DataStore_PermissionDenied); } } - insert_buffer(param.dataid, param.slot, buffer).await; + self.insert_buffer(param.dataid, param.slot, buffer).await; results.push(QResult::success(ErrorCode::Core_Unknown)); } @@ -1651,16 +1666,10 @@ impl DataStore for User { ) -> Result, ErrorCode> { let mut list = Vec::with_capacity(dataids.len()); for dataid in dataids.into_iter() { - let object_info = get_object_info_by_data_id(dataid, 0).await?; - - let presigner = S3Presigner::new( - &format!("https://{}", *RNEX_DATASTORE_S3_ENDPOINT), - format!("{}", *RNEX_DATASTORE_S3_BUCKET), - ) - .await; + let object_info = self.get_object_info_by_data_id(dataid, 0).await?; let key = format!("data/{}.bin", dataid); - let download_url = presigner.generate_presigned_get(&key); + let download_url = self.dm.s3_presigner.generate_presigned_get(&key); list.push(DataStoreFileServerObjectInfo { dataid, @@ -1708,10 +1717,10 @@ impl DataStore for User { report_course_param.report_category as i16, report_course_param.report_reason ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::Core_NotImplemented // i don't know why, but returning this makes the game show "Report sent OK" so i'll use it })?; @@ -1727,10 +1736,10 @@ impl DataStore for User { "#, param.dataid ) - .fetch_one(get_db()) + .fetch_one(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; @@ -1740,16 +1749,16 @@ impl DataStore for User { return Err(ErrorCode::DataStore_PermissionDenied); } - log::info!("update password check passed"); + info!("update password check passed"); sqlx::query!( "UPDATE datastore.objects SET deleted=true WHERE data_id=$1", param.dataid ) - .execute(get_db()) + .execute(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; @@ -1762,7 +1771,7 @@ impl DataStore for User { ) -> Result<(Vec, Vec), ErrorCode> { let mut ranking_results = Vec::new(); - let rows = sqlx::query!( + let rows = query!( r#" SELECT data_id, @@ -1780,10 +1789,10 @@ impl DataStore for User { param.result_range.size as i64, param.result_range.offset as i64, ) - .fetch_all(get_db()) + .fetch_all(&self.dm.db_pool) .await .map_err(|e| { - log::error!("DB Error: {:?}", e); + error!("DB Error: {:?}", e); ErrorCode::DataStore_NotFound })?; @@ -1793,14 +1802,14 @@ impl DataStore for User { let data_id = row.data_id; let score = row.value.unwrap_or(0) as u32; - if let Ok(meta) = get_object_info_by_data_id(data_id, 0).await { + if let Ok(meta) = self.get_object_info_by_data_id(data_id, 0).await { ranking_results.push(DataStoreCustomRankingResult { order: current_order, score, meta_info: meta, }); } else { - log::warn!("could not find metadata for ranked object {}", data_id); + warn!("could not find metadata for ranked object {}", data_id); } current_order += 1; @@ -1877,7 +1886,7 @@ impl DataStore for User { LIMIT 100 "# ) - .fetch(get_db()); + .fetch(&self.dm.db_pool); while let Some(row) = stream.try_next().await.map_err(|e| { eprintln!("stream error: {:?}", e); @@ -1897,17 +1906,17 @@ impl DataStore for User { let created_time = row .creation_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let updated_time = row .update_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let referred_time = row .creation_date - .map(KerberosDateTime::from_naive) + .map(DateTime::from_naive) .unwrap_or_default(); let meta_info = GetMetaInfo { @@ -1925,11 +1934,11 @@ impl DataStore for User { refer_dat_id: row.refer_data_id.unwrap_or(0) as u32, flag: row.flag.unwrap_or(0) as u32, tags: row.tags.unwrap_or_default(), - expire_time: KerberosDateTime::PRACTICALLY_NEVER, + expire_time: DateTime::PRACTICALLY_NEVER, created_time, updated_time, referred_time, - ratings: get_rating_with_slot_data_id(row.data_id).await?, + ratings: self.get_rating_with_slot_data_id(row.data_id).await?, }; let course = DataStoreCustomRankingResult { diff --git a/rnex-server-nex-modules/rnex-ds/src/lib.rs b/rnex-server-nex-modules/rnex-ds/src/lib.rs new file mode 100644 index 0000000..73f67bc --- /dev/null +++ b/rnex-server-nex-modules/rnex-ds/src/lib.rs @@ -0,0 +1,61 @@ +use std::env; + +use rnex_server::{ConnectionInitData, RnexManager, RnexModule}; +use sqlx::PgPool; +use thiserror::Error; + +use crate::{datastore::DatastoreUser, s3presigner::S3Presigner}; + +pub mod datastore; +pub(crate) mod s3presigner; + +struct DatastoreManager { + db_pool: PgPool, + s3_presigner: S3Presigner, +} +struct DatastoreModule; +impl RnexManager for DatastoreManager { + type User = DatastoreUser; + type InitData = ConnectionInitData; + async fn init_new_user( + this: rnex_server::PassthroughInitModule, + mod_holder: &rnex_server::ModuleHolder, + remote: &rnex_rmc::RmcConnection, + init_data: &Self::InitData, + weak_user: rnex_server::WeakPassthroughInitModule, + ) -> Self::User { + DatastoreUser { + dm: this, + base: mod_holder + .get_ref_init_pt() + .expect("datastore module cannot work without base module"), + } + } +} + +#[derive(Error, Debug)] +pub enum ModuleInitError { + #[error(transparent)] + Sqlx(#[from] sqlx::Error), + #[error(transparent)] + Env(#[from] env::VarError), +} + +impl RnexModule for DatastoreModule { + type Manager = DatastoreManager; + type InitError = ModuleInitError; + + async fn create_manager( + mod_holder: &rnex_server::ModuleHolder, + ) -> Result { + Ok(DatastoreManager { + db_pool: PgPool::connect(&env::var("RNEX_DATASTORE_DATABASE")?).await?, + s3_presigner: S3Presigner::new( + env::var("RNEX_DATASTORE_S3_ENDPOINT")? + .trim_end_matches('/') + .to_string(), + env::var("RNEX_DATASTORE_S3_BUCKET")?, + ), + }) + } +} diff --git a/rnex-server-nex-modules/rnex-ds/src/main.rs b/rnex-server-nex-modules/rnex-ds/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/rnex-server-nex-modules/rnex-ds/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/rnex-core-deprecated/src/nex/s3presigner.rs b/rnex-server-nex-modules/rnex-ds/src/s3presigner.rs similarity index 82% rename from rnex-core-deprecated/src/nex/s3presigner.rs rename to rnex-server-nex-modules/rnex-ds/src/s3presigner.rs index 3e42217..e78a23c 100644 --- a/rnex-core-deprecated/src/nex/s3presigner.rs +++ b/rnex-server-nex-modules/rnex-ds/src/s3presigner.rs @@ -1,9 +1,8 @@ -use base64::{engine::general_purpose, Engine as _}; -use hmac::{Hmac, Mac}; -use sha2::{Sha256, Digest}; -use chrono::{Utc, Duration}; +use base64::{Engine, engine::general_purpose::STANDARD}; +use chrono::{Duration, Utc}; +use hmac::{Hmac, KeyInit, Mac}; use serde_json::json; -use rnex_core::executables::common::RNEX_DATASTORE_S3_ENDPOINT; +use sha2::{Digest, Sha256}; pub struct S3Presigner { endpoint: String, @@ -11,9 +10,9 @@ pub struct S3Presigner { } impl S3Presigner { - pub async fn new(endpoint: &str, bucket: String) -> Self { + pub fn new(endpoint: String, bucket: String) -> Self { Self { - endpoint: endpoint.trim_end_matches('/').to_string(), + endpoint: endpoint, bucket, } } @@ -23,7 +22,9 @@ impl S3Presigner { let region = "us-east-1"; // hardcoded because its the default region for most s3 clones let date_short = Utc::now().format("%Y%m%d").to_string(); let date_full = Utc::now().format("%Y%m%dT%H%M%SZ").to_string(); - let expiration = (Utc::now() + Duration::minutes(15)).format("%Y-%m-%dT%H:%M:%SZ").to_string(); + let expiration = (Utc::now() + Duration::minutes(15)) + .format("%Y-%m-%dT%H:%M:%SZ") + .to_string(); let credential = format!("{}/{}/{}/s3/aws4_request", access_key, date_short, region); @@ -38,20 +39,23 @@ impl S3Presigner { ] }); - let policy_base64 = general_purpose::STANDARD.encode(policy_json.to_string()); + let policy_base64 = STANDARD.encode(policy_json.to_string()); let signature = self.calculate_signature(&secret_key, &date_short, region, &policy_base64); let fields = vec![ ("key".to_string(), key.to_string()), - ("X-Amz-Algorithm".to_string(), "AWS4-HMAC-SHA256".to_string()), + ( + "X-Amz-Algorithm".to_string(), + "AWS4-HMAC-SHA256".to_string(), + ), ("X-Amz-Credential".to_string(), credential), ("X-Amz-Date".to_string(), date_full), ("Policy".to_string(), policy_base64), ("X-Amz-Signature".to_string(), signature), ]; - let url = format!("https://{}/{}", *RNEX_DATASTORE_S3_ENDPOINT, self.bucket); + let url = format!("https://{}/{}", self.endpoint, self.bucket); (url, fields) } @@ -77,7 +81,7 @@ impl S3Presigner { let canonical_request = format!( "GET\n/{}/{}\n{}\nhost:{}\n\nhost\nUNSIGNED-PAYLOAD", - self.bucket, key, query_string, *RNEX_DATASTORE_S3_ENDPOINT + self.bucket, key, query_string, self.endpoint ); let hashed_request = hex::encode(Sha256::digest(canonical_request.as_bytes())); @@ -95,7 +99,7 @@ impl S3Presigner { format!( "https://{}/{}/{}?{}&X-Amz-Signature={}", - *RNEX_DATASTORE_S3_ENDPOINT, self.bucket, key, query_string, signature + self.endpoint, self.bucket, key, query_string, signature ) } @@ -113,4 +117,4 @@ impl S3Presigner { mac.update(data.as_bytes()); mac.finalize().into_bytes().to_vec() } -} \ No newline at end of file +} diff --git a/rnex-util/Cargo.toml b/rnex-util/Cargo.toml index 8dddbaa..855e4bb 100644 --- a/rnex-util/Cargo.toml +++ b/rnex-util/Cargo.toml @@ -9,6 +9,7 @@ tracing = "0.1.44" chrono = "0.4.39" bytemuck = { version = "1.25.0", features = ["derive"] } md-5 = "0.11.0" +thiserror = "2.0.18" [features] nx = [] diff --git a/rnex-util/src/station_url.rs b/rnex-util/src/station_url.rs index d08ae1a..528ee72 100644 --- a/rnex-util/src/station_url.rs +++ b/rnex-util/src/station_url.rs @@ -1,8 +1,10 @@ use std::{ fmt::{Debug, Display, Formatter}, net::IpAddr, + str::FromStr, }; +use thiserror::Error; use tracing::error; use crate::PID; @@ -86,11 +88,15 @@ impl StationUrl { } } -impl TryFrom<&str> for StationUrl { - type Error = (); +// todo: add more specific error messages to parsing +#[derive(Error, Debug)] +#[error("failed to parse station url")] +pub struct StationUrlParseError; - fn try_from(value: &str) -> Result { - let (url_type, options) = value.split_at(value.find(":/").ok_or(())?); +impl FromStr for StationUrl { + type Err = StationUrlParseError; + fn from_str(value: &str) -> Result { + let (url_type, options) = value.split_at(value.find(":/").ok_or(StationUrlParseError)?); let options = &options[2..]; @@ -100,10 +106,10 @@ impl TryFrom<&str> for StationUrl { "udp" => UDP, "prudp" => PRUDP, "prudps" => PRUDPS, - _ => return Err(()), + _ => return Err(StationUrlParseError), }; - let options = Self::read_options(options).ok_or(())?; + let options = Self::read_options(options).ok_or(StationUrlParseError)?; Ok(Self { url_type, options }) }