From 3f07e45f083b2b169e55704d6e2bedbda1086223 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Mon, 13 Jul 2026 19:38:43 +0200 Subject: [PATCH] datastore refactor --- Cargo.lock | 1035 +++++++++- rnex-core-deprecated/src/nex/datastore.rs | 1946 ------------------- rnex-core-deprecated/src/nex/s3presigner.rs | 116 -- rnex-prudp/src/socket_addr.rs | 4 +- rnex-rmc/src/networking.rs | 2 +- rnex-rmc/src/primitives.rs | 2 +- rnex-rmc/src/response.rs | 2 +- rnex-rmc/src/rmc_struct.rs | 2 +- rnex-rmc/src/station_url.rs | 3 +- rnex-util/Cargo.toml | 1 + rnex-util/src/station_url.rs | 18 +- 11 files changed, 1028 insertions(+), 2103 deletions(-) delete mode 100644 rnex-core-deprecated/src/nex/datastore.rs delete mode 100644 rnex-core-deprecated/src/nex/s3presigner.rs 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-core-deprecated/src/nex/datastore.rs b/rnex-core-deprecated/src/nex/datastore.rs deleted file mode 100644 index 6a095a3..0000000 --- a/rnex-core-deprecated/src/nex/datastore.rs +++ /dev/null @@ -1,1946 +0,0 @@ -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_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 std::convert; - -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, - } -} - -pub async fn check_object_availability(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)?; - - 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(()) -} - -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#" - 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 - })?; - - 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) -} - -pub async fn get_object_info_by_data_id( - data_id: i64, - password: i64, -) -> Result { - check_object_availability(data_id, password).await?; - - 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()) - .await - .map_err(|_| ErrorCode::DataStore_NotFound)? - .ok_or(ErrorCode::DataStore_NotFound)?; - - let ratings = 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 - - 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_object_info_by_persistence_target( - 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, - access_password, under_review - FROM datastore.objects - WHERE owner = $1 AND persistence_slot_id = $2 - AND upload_completed = TRUE AND deleted = FALSE"#, - target.owner as i32, - target.persistence_slot_id as i16 - ) - .fetch_optional(get_db()) - .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); - } - - if row.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - 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#" - 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 - })?; - - 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(()); - } - - 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 - } -} - -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()); - } - - if (result_option & 0x04) == 0 { - meta_info.ratings = Vec::new(); - } - - // 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#" - INSERT INTO datastore.object_ratings ( - data_id, - slot, - flag, - internal_flag, - lock_type, - initial_value, - range_min, - range_max, - period_hour, - period_duration, - total_value - ) VALUES ( - $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"); -} - -// 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()); - - let rows = sqlx::query!( - r#" - SELECT - rankings.data_id, - rankings.value - FROM datastore.object_custom_rankings rankings - JOIN UNNEST($1::bigint[]) WITH ORDINALITY AS rows(data_id, ord) - ON rankings.data_id = rows.data_id - 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; - - let rows = match rows { - Ok(r) => r, - Err(e) => { - log::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) = 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 -} - -async fn get_user_course_object_ids(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 - })?; - - 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); - } - } - - Ok(valid_ids) -} - -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() -> Vec { - vec![ - "ゼロから", - "0から", - "0から", - "い  い  ね", - "いい", - "東日本", - "大震", - ] - .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( - dataid: i64, - slot: i8, - rating_value: i32, - access_password: i64, -) -> Result { - check_object_availability(dataid, access_password).await?; - - let rating = RatingInfo::default(); - - 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 - })?; - - Ok(rating) -} - -async fn change_meta_object_check(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()) - .await - .map_err(|e| { - log::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.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - Ok(()) -} - -async fn get_rating_with_slot_data_id(dataid: i64) -> Result, ErrorCode> { - check_object_availability(dataid, 0).await?; - - 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()) - .await - .map_err(|e| { - log::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::>(); - - Ok(ratings) -} - -pub async fn insert_buffer(dataid: i64, slot: i32, buffer: &QBuffer) { - let db_now = Utc::now().naive_utc(); - - sqlx::query!( - r#" - INSERT INTO datastore.buffer_queues ( - data_id, - slot, - creation_date, - buffer - ) VALUES ( - $1, - $2, - $3, - $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 - }); -} - -impl DataStore for User { - 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? - } else { - get_object_info_by_persistence_target( - metaparam.persistence_target, - metaparam.access_password, - ) - .await? - }; - - let current_pid = self.pid; - verify_object_permission(meta_info.owner, current_pid, &meta_info.permission).await?; - - filter_properties_by_result_option(&mut meta_info, metaparam.result_option); - - Ok(meta_info) - } - - async fn prepare_post_object( - &self, - postparam: PreparePostParam, - ) -> Result { - let recipient_ids: Vec = postparam - .permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - let del_recipient_ids: Vec = postparam - .del_permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - let now = Utc::now().naive_utc(); - - let row = sqlx::query!( - r#" - INSERT INTO datastore.objects ( - owner, size, name, data_type, meta_binary, - permission, permission_recipients, - delete_permission, delete_permission_recipients, - flag, period, refer_data_id, tags, - persistence_slot_id, extra_data, creation_date, update_date - ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 - ) RETURNING data_id - "#, - self.pid as i32, - postparam.size as i32, - postparam.name, - postparam.data_type as i32, - &postparam.meta_binary.0, - postparam.permission.permission as i32, - &recipient_ids, - postparam.del_permission.permission as i32, - &del_recipient_ids, - postparam.flag as i32, - postparam.period as i32, - postparam.refer_data_id as i64, - &postparam.tags, - postparam.persistence_init_param.persistence_slot_id as i32, - &postparam.extra_data, - now, - now - ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - 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()); - for rating_param in &postparam.rating_init_params { - log::info!("running init params"); - 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 form_fields = fields - .into_iter() - .map(|(k, v)| KeyValue { key: k, value: v }) - .collect(); - - Ok(ReqPostInfo { - dataid: data_id, - url: upload_url, - request_headers: vec![], - form_fields, - root_ca_cert: vec![], - }) - } - - async fn complete_post_object( - &self, - completeparam: CompletePostParam, - ) -> Result<(), ErrorCode> { - log::info!("Data ID: {:?}", completeparam.dataid); - log::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()) - .await - .map_err(|e| { - eprintln!("select error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - let record = record.ok_or(ErrorCode::DataStore_NotFound)?; - - if record.under_review { - return Err(ErrorCode::DataStore_UnderReviewing); - } - - if record.owner.unwrap_or(0) as PID != self.pid { - return Err(ErrorCode::DataStore_PermissionDenied); - } - - if completeparam.success { - sqlx::query!( - r#"UPDATE datastore.objects SET upload_completed = true WHERE data_id = $1"#, - completeparam.dataid - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - } else { - return Err(ErrorCode::DataStore_InvalidArgument); - } - - Ok(()) - } - - async fn rate_custom_ranking( - &self, - rankingparam: Vec, - ) -> Result<(), ErrorCode> { - for abcparam in rankingparam { - let exists = sqlx::query_scalar!( - r#"SELECT EXISTS(SELECT 1 FROM datastore.objects WHERE data_id = $1)"#, - abcparam.dataid - ) - .fetch_one(get_db()) - .await - .map_err(|_| ErrorCode::DataStore_NotFound)?; - - if !exists.unwrap_or(false) { - return Err(ErrorCode::DataStore_NotFound); - } - - sqlx::query!( - r#" - INSERT INTO datastore.object_custom_rankings (data_id, application_id, value) - VALUES ($1, $2, $3) - ON CONFLICT (data_id, application_id) - DO UPDATE SET value = datastore.object_custom_rankings.value + EXCLUDED.value - "#, - abcparam.dataid, - abcparam.appid as i32, - abcparam.score as i32 - ) - .execute(get_db()) - .await - .map_err(|e| { - log::error!("update/insert error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - } - - Ok(()) - } - - async fn get_application_config(&self, appid: u32) -> Result, ErrorCode> { - const MAX_COURSE_UPLOADS: i32 = 100; - - let config = match appid { - 0 => vec![ - 0x0000_0001, - 0x0000_0032, - 0x0000_0096, - 0x0000_012c, - 0x0000_01f4, - 0x0000_0320, - 0x0000_0514, - 0x0000_07d0, - 0x0000_0bb8, - 0x0000_1388, - MAX_COURSE_UPLOADS, - 0x0000_0014, - 0x0000_001e, - 0x0000_0028, - 0x0000_0032, - 0x0000_003c, - 0x0000_0046, - 0x0000_0050, - 0x0000_005a, - 0x0000_0064, - 0x0000_0023, - 0x0000_004b, - 0x0000_0023, - 0x0000_004b, - 0x0000_0032, - 0x0000_0000, - 0x0000_0003, - 0x0000_0003, - 0x0000_0064, - 0x0000_0006, - 0x0000_0001, - 0x0000_0060, - 0x0000_0005, - 0x0000_0060, - 0x0000_0000, - 0x0000_07e4, - 0x0000_0001, - 0x0000_0001, - 0x0000_000c, - 0x0000_0000, - ], - 1 => vec![ - 2, - 1_770_179_696, - 1_770_179_664, - 1_770_179_640, - 1_770_180_827, - 1_770_180_777, - 1_770_180_745, - 1_770_177_625, - 1_770_177_590, - ], - 2 => vec![ - 0x0000_07df, - 0x0000_000c, - 0x0000_0016, - 0x0000_0005, - 0x0000_0000, - ], - 10 => vec![35, 75, 96, 40, 5, 6], - _ => { - log::error!("unknown SMM app id: {}", appid); - return Err(ErrorCode::DataStore_Unknown); - } - }; - - Ok(config) - } - - async fn get_custom_ranking_by_data_id( - &self, - custom_ranking_param: DataStoreGetCustomRankingByDataIDParam, - ) -> Result<(Vec, Vec), ErrorCode> { - println!("appid: {:?}", custom_ranking_param.application_id); - 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 q_results = Vec::with_capacity(ranking_results.len()); - - for result in &mut ranking_results { - if (custom_ranking_param.result_option & 0x01) == 0 { - result.meta_info.tags = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x02) == 0 { - result.meta_info.ratings = Vec::new(); - } - - if (custom_ranking_param.result_option & 0x04) == 0 { - result.meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (custom_ranking_param.result_option & 0x20) == 0 { - result.score = 0; - } - - q_results.push(QResult::success(ErrorCode::Core_Unknown)); - } - - Ok((ranking_results, q_results)) - } - - async fn get_buffer_queue( - &self, - bufferparam: BufferQueueParam, - ) -> 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?; - - Ok(buffers) - } - - async fn prepare_get_object( - &self, - 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? - } else { - log::info!("getting object by persistence info"); - 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; - - let key = format!("data/{}.bin", meta_info.dataid); - let download_url = presigner.generate_presigned_get(&key); - - Ok(DataStoreReqGetInfo { - url: download_url, - request_headers: vec![], - size: meta_info.size, - root_ca_cert: vec![], - dataid: meta_info.dataid, - }) - } - - async fn followings_latest_course_search_object( - &self, - course_search_param: DataStoreSearchParam, - _extra_data: Vec, - ) -> Result, ErrorCode> { - 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?; - - if course_ids.is_empty() { - continue; - } - - let mut results = get_custom_rankings_by_data_ids(0, course_ids).await; - - // Flag 0x1: Return Tags - // Flag 0x2: Return Ratings - // Flag 0x4: Return MetaBinary - // Flag 0x20: Return Score - for res in &mut results { - if course_search_param.result_option & 0x1 == 0 { - res.meta_info.tags = Vec::new(); - } - if course_search_param.result_option & 0x2 == 0 { - res.meta_info.ratings = Vec::new(); - } - if course_search_param.result_option & 0x4 == 0 { - res.meta_info.meta_binary = - rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - if course_search_param.result_option & 0x20 == 0 { - res.score = 0; - } - } - - all_results.extend(results); - } - - // note: we assume the client sorts the data lol - - Ok(all_results) - } - - async fn get_application_config_string( - &self, - application_id: u32, - ) -> Result, ErrorCode> { - let config = match application_id { - 128 => get_blacklist_1(), - 129 => get_blacklist_2(), - 130 => get_blacklist_3(), - _ => { - log::warn!( - "unsupported application_id in GetApplicationConfigString: {}", - application_id - ); - Vec::new() - } - }; - - Ok(config) - } - - async fn get_metas_multiple_param( - &self, - params: Vec, - ) -> Result<(Vec, Vec), ErrorCode> { - let mut metas = Vec::with_capacity(params.len()); - let mut results = Vec::with_capacity(params.len()); - - for param in params { - let info_result = if param.dataid != 0 { - get_object_info_by_data_id(param.dataid, param.access_password).await - } else { - get_object_info_by_persistence_target( - param.persistence_target, - param.access_password, - ) - .await - }; - - match info_result { - Ok(mut meta) => { - if let Err(e) = - verify_object_permission(meta.owner, self.pid, &meta.permission).await - { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); - } else { - if param.result_option & 0x1 == 0 { - meta.tags = Vec::new(); - } - if param.result_option & 0x2 == 0 { - meta.ratings = Vec::new(); - } - if param.result_option & 0x4 == 0 { - meta.meta_binary = - rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new()); - } - - metas.push(meta); - results.push(QResult::success(ErrorCode::Core_Unknown)); - } - } - Err(e) => { - metas.push(GetMetaInfo::default()); - results.push(QResult::error(e)); - } - } - } - - Ok((metas, results)) - } - - async fn prepare_attach_file(&self, param: AttachFileParam) -> Result { - let recipient_ids: Vec = param - .post_param - .permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - - let del_recipient_ids: Vec = param - .post_param - .del_permission - .recipient_ids - .iter() - .map(|&id| id as i32) - .collect(); - - let tags: Vec = param - .post_param - .tags - .iter() - .map(|t| t.to_string()) - .collect(); - - let extra_data: Vec = param - .post_param - .extra_data - .iter() - .map(|e| e.to_string()) - .collect(); - - let now = Utc::now().naive_utc(); - - let row = sqlx::query!( - r#" - INSERT INTO datastore.objects ( - owner, size, name, data_type, meta_binary, - permission, permission_recipients, - delete_permission, delete_permission_recipients, - flag, period, refer_data_id, tags, - persistence_slot_id, extra_data, creation_date, update_date - ) VALUES ( - $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17 - ) RETURNING data_id - "#, - self.pid as i32, - param.post_param.size as i32, - param.post_param.name, - param.post_param.data_type as i32, - ¶m.post_param.meta_binary.0, - param.post_param.permission.permission as i32, - &recipient_ids, - param.post_param.del_permission.permission as i32, - &del_recipient_ids, - param.post_param.flag as i32, - param.post_param.period as i32, - param.refer_data_id, // Data ID of the course this is attached to - &tags, - param.post_param.persistence_init_param.persistence_slot_id as i32, - &extra_data, - now, - now - ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::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 - } - - 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 form_fields = fields - .into_iter() - .map(|(k, v)| KeyValue { key: k, value: v }) - .collect(); - - Ok(ReqPostInfo { - dataid: data_id, - url: upload_url, - request_headers: vec![], - form_fields, - root_ca_cert: vec![], - }) - } - - async fn complete_attach_file( - &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; - - let key = format!("data/{}.jpg", complete_attach_param.dataid); - let download_url = presigner.generate_presigned_get(&key); - - Ok(download_url) - } - - async fn rate_objects( - &self, - targets: Vec, - params: Vec, - _transactional: bool, - fetch_ratings: bool, - ) -> Result<(Vec, Vec), ErrorCode> { - let results: Vec = vec![]; - - // this might be good to keep as a sanity check but as long as we zip the two vecs together - // we already avoid crashes which can be caused by this - // (previous comment) SMM seems to work fine with this, no clue for other DTSR games - // binder: we should keep it anyways, just in case. no harm no foul right? - if targets.len() != params.len() { - return Err(ErrorCode::DataStore_OperationNotAllowed); - } - - let actions = - targets - .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); - - 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) - .await?; - log::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"); - Result::, ErrorCode>::Ok(Some(rating)) - } else { - Result::, ErrorCode>::Ok(None) - } - }); - - let ratings: Result, ErrorCode> = join_all(actions).await.into_iter().collect(); - let ratings = ratings?; - - let ratings = if fetch_ratings { - ratings.into_iter().filter_map(convert::identity).collect() - } else { - // skip collecting, we already know the vector is empty - vec![] - }; - - Ok((ratings, results)) - } - - async fn change_meta(&self, param: DataStoreChangeMetaParam) -> Result<(), ErrorCode> { - let object_info = get_object_info_by_data_id(param.dataid, 0).await?; - verify_object_permission(object_info.owner, self.pid, &object_info.permission).await?; - - if param.modifies_flag & 0x08 != 0 { - change_meta_object_check(¶m).await?; - - sqlx::query!( - r#"UPDATE datastore.objects SET period=$1 WHERE data_id=$2"#, - param.period as i16, - param.dataid - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - } - - if param.modifies_flag & 0x10 != 0 { - change_meta_object_check(¶m).await?; - - sqlx::query!( - r#"UPDATE datastore.objects SET meta_binary=$1 WHERE data_id=$2"#, - param.meta_binary.0, - param.dataid - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - } - - if param.modifies_flag & 0x80 != 0 { - change_meta_object_check(¶m).await?; - - sqlx::query!( - r#"UPDATE datastore.objects SET data_type=$1 WHERE data_id=$2"#, - param.data_type as i16, - param.dataid - ) - .execute(get_db()) - .await - .map_err(|e| { - eprintln!("update error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - } - - Ok(()) - } - - async fn recommended_course_search_object( - &self, - _course_search_param: DataStoreSearchParam, - _extra_data: Vec, - ) -> Result, ErrorCode> { - let mut courses = Vec::new(); - - let mut stream = sqlx::query!( - r#" - SELECT - object.data_id, - object.owner, - object.size, - object.name, - object.data_type, - object.meta_binary, - object.permission, - object.permission_recipients, - object.delete_permission, - object.delete_permission_recipients, - object.period, - object.refer_data_id, - object.flag, - object.tags, - object.creation_date, - object.update_date, - ranking.value - FROM ( - SELECT * FROM datastore.objects object - WHERE - object.upload_completed = TRUE AND - object.deleted = FALSE AND - object.under_review = FALSE - ) object - JOIN ( - SELECT data_id, value - FROM datastore.object_custom_rankings ranking - WHERE ranking.application_id = 0 - ) ranking - ON - object.data_id = ranking.data_id - ORDER BY RANDOM() - LIMIT 100 - "# - ) - .fetch(get_db()); - - while let Some(row) = stream.try_next().await.map_err(|e| { - eprintln!("stream error: {:?}", e); - ErrorCode::DataStore_NotFound - })? { - let permission = Permission { - permission: row.permission.unwrap_or(0) as u8, - recipient_ids: row.permission_recipients.unwrap_or_default(), - }; - - let del_permission = Permission { - permission: row.delete_permission.unwrap_or(0) as u8, - recipient_ids: row.delete_permission_recipients.unwrap_or_default(), - }; - - let meta_binary = row.meta_binary.map(QBuffer).unwrap_or_default(); - - let created_time = row - .creation_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let updated_time = row - .update_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let referred_time = row - .creation_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let meta_info = GetMetaInfo { - dataid: row.data_id, - owner: row.owner.unwrap_or(0), - size: row.size.unwrap_or(0) as u32, - name: row.name, - data_type: row.data_type.unwrap_or(0) as u16, - meta_binary, - permission, - del_permission, - period: row.period.unwrap_or(0) as u16, - status: 0, - referred_count: 0, - 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, - created_time, - updated_time, - referred_time, - ratings: get_rating_with_slot_data_id(row.data_id).await?, - }; - - let course = DataStoreCustomRankingResult { - order: 0, - score: row.value.unwrap_or(0) as u32, - meta_info, - }; - - courses.push(course); - } - - Ok(courses) - } - - async fn upload_course_record( - &self, - upload_course_record_param: DataStoreUploadCourseRecordParam, - ) -> Result<(), ErrorCode> { - let now = Utc::now().naive_utc(); - - sqlx::query!( - r#" - INSERT INTO datastore.course_records ( - data_id, - slot, - first_pid, - best_pid, - best_score, - creation_date, - update_date - ) VALUES ( - $1, - $2, - $3, - $4, - $5, - $6, - $7 - ) ON CONFLICT (data_id, slot) DO UPDATE - SET best_score = CASE WHEN datastore.course_records.best_score > $5 THEN $5 ELSE datastore.course_records.best_score END, - best_pid = CASE WHEN datastore.course_records.best_score > $5 THEN $4 ELSE datastore.course_records.best_pid END, - update_date = CASE WHEN datastore.course_records.best_score > $5 THEN $7 ELSE datastore.course_records.update_date END - "#, - upload_course_record_param.dataid, - upload_course_record_param.slot as i16, - self.pid, - self.pid, - upload_course_record_param.score, - now, - now - ) - .execute(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - Ok(()) - } - - async fn get_course_record( - &self, - get_course_record_param: DataStoreGetCourseRecordParam, - ) -> Result { - let row = sqlx::query!( - r#" - SELECT - first_pid, - best_pid, - best_score, - creation_date, - update_date - FROM datastore.course_records WHERE data_id=$1 AND slot=$2 - "#, - get_course_record_param.dataid, - get_course_record_param.slot as i16 - ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - Ok(DataStoreGetCourseRecordResult { - dataid: get_course_record_param.dataid, - slot: get_course_record_param.slot, - 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, - }) - } - - async fn add_to_buffer_queues( - &self, - bufferparam: Vec, - buffers: Vec, - ) -> Result, ErrorCode> { - let mut results = Vec::new(); - - let client_pid = self.pid; - - 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?; - - if object_info.data_type == 1 && object_info.owner != client_pid { - return Err(ErrorCode::DataStore_PermissionDenied); - } - } - - insert_buffer(param.dataid, param.slot, buffer).await; - - results.push(QResult::success(ErrorCode::Core_Unknown)); - } - - Ok(results) - } - - async fn get_object_infos( - &self, - dataids: Vec, - ) -> 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 key = format!("data/{}.bin", dataid); - let download_url = presigner.generate_presigned_get(&key); - - list.push(DataStoreFileServerObjectInfo { - dataid, - get_info: DataStoreReqGetInfo { - url: download_url, - request_headers: vec![], - size: object_info.size, - root_ca_cert: vec![], - dataid, - }, - }); - } - - Ok(list) - } - - async fn check_rate_custom_ranking_counter( - &self, - application_id: u32, - ) -> Result { - if application_id == 0 { - Ok(true) - } else { - Err(ErrorCode::Core_Unknown) - } - } - - async fn report_course( - &self, - report_course_param: DataStoreReportCourseParam, - ) -> Result<(), ErrorCode> { - sqlx::query!( - r#" - INSERT INTO datastore.reports ( - data_id, - reporter_pid, - category, - reason - ) VALUES ( - $1, $2, $3, $4 - ) - "#, - report_course_param.dataid, - self.pid, - report_course_param.report_category as i16, - report_course_param.report_reason - ) - .execute(get_db()) - .await - .map_err(|e| { - log::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 - })?; - - Ok(()) - } - - async fn delete_object(&self, param: DataStoreDeleteParam) -> Result<(), ErrorCode> { - let row = sqlx::query!( - r#" - SELECT update_password - FROM datastore.objects - WHERE data_id = $1 AND upload_completed = TRUE AND deleted = FALSE - "#, - param.dataid - ) - .fetch_one(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - let passwd = row.update_password; - - if param.update_password != passwd { - return Err(ErrorCode::DataStore_PermissionDenied); - } - - log::info!("update password check passed"); - - sqlx::query!( - "UPDATE datastore.objects SET deleted=true WHERE data_id=$1", - param.dataid - ) - .execute(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - Ok(()) - } - - async fn get_custom_ranking( - &self, - param: DataStoreGetCustomRankingParam, - ) -> Result<(Vec, Vec), ErrorCode> { - let mut ranking_results = Vec::new(); - - let rows = sqlx::query!( - r#" - SELECT - data_id, - value - FROM datastore.object_custom_rankings - WHERE application_id = $1 - AND value >= $2 - AND value <= $3 - ORDER BY value DESC - LIMIT $4 OFFSET $5 - "#, - param.application_id as i64, - param.condition.min_value as i64, - param.condition.max_value as i64, - param.result_range.size as i64, - param.result_range.offset as i64, - ) - .fetch_all(get_db()) - .await - .map_err(|e| { - log::error!("DB Error: {:?}", e); - ErrorCode::DataStore_NotFound - })?; - - let mut current_order = param.result_range.offset + 1; - - 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 { - ranking_results.push(DataStoreCustomRankingResult { - order: current_order, - score, - meta_info: meta, - }); - } else { - log::warn!("could not find metadata for ranked object {}", data_id); - } - - current_order += 1; - } - - let mut q_results = Vec::with_capacity(ranking_results.len()); - - for result in &mut ranking_results { - if (param.result_option & 0x01) == 0 { - result.meta_info.tags = Vec::new(); - } - - if (param.result_option & 0x02) == 0 { - result.meta_info.ratings = Vec::new(); - } - - if (param.result_option & 0x04) == 0 { - result.meta_info.meta_binary = QBuffer(Vec::new()); - } - - if (param.result_option & 0x20) == 0 { - result.score = 0; - } - - q_results.push(QResult::success(ErrorCode::Core_Unknown)); - } - - Ok((ranking_results, q_results)) - } - - // todo: respect the search parameters and extra data - async fn ctr_pickup_course_search_object( - &self, - _course_search_param: DataStoreSearchParam, - _extra_data: Vec, - ) -> Result, ErrorCode> { - let mut courses = Vec::new(); - - let mut stream = sqlx::query!( - r#" - SELECT - object.data_id, - object.owner, - object.size, - object.name, - object.data_type, - object.meta_binary, - object.permission, - object.permission_recipients, - object.delete_permission, - object.delete_permission_recipients, - object.period, - object.refer_data_id, - object.flag, - object.tags, - object.creation_date, - object.update_date, - ranking.value - FROM ( - SELECT * FROM datastore.objects object - WHERE - object.upload_completed = TRUE AND - object.deleted = FALSE AND - object.under_review = FALSE - ) object - JOIN ( - SELECT data_id, value - FROM datastore.object_custom_rankings ranking - WHERE ranking.application_id = 0 - ) ranking - ON - object.data_id = ranking.data_id - ORDER BY RANDOM() - LIMIT 100 - "# - ) - .fetch(get_db()); - - while let Some(row) = stream.try_next().await.map_err(|e| { - eprintln!("stream error: {:?}", e); - ErrorCode::DataStore_NotFound - })? { - let permission = Permission { - permission: row.permission.unwrap_or(0) as u8, - recipient_ids: row.permission_recipients.unwrap_or_default(), - }; - - let del_permission = Permission { - permission: row.delete_permission.unwrap_or(0) as u8, - recipient_ids: row.delete_permission_recipients.unwrap_or_default(), - }; - - let meta_binary = row.meta_binary.map(QBuffer).unwrap_or_default(); - - let created_time = row - .creation_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let updated_time = row - .update_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let referred_time = row - .creation_date - .map(KerberosDateTime::from_naive) - .unwrap_or_default(); - - let meta_info = GetMetaInfo { - dataid: row.data_id, - owner: row.owner.unwrap_or(0), - size: row.size.unwrap_or(0) as u32, - name: row.name, - data_type: row.data_type.unwrap_or(0) as u16, - meta_binary, - permission, - del_permission, - period: row.period.unwrap_or(0) as u16, - status: 0, - referred_count: 0, - 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, - created_time, - updated_time, - referred_time, - ratings: get_rating_with_slot_data_id(row.data_id).await?, - }; - - let course = DataStoreCustomRankingResult { - order: 0, - score: row.value.unwrap_or(0) as u32, - meta_info, - }; - - courses.push(course); - } - - Ok(courses) - } -} diff --git a/rnex-core-deprecated/src/nex/s3presigner.rs b/rnex-core-deprecated/src/nex/s3presigner.rs deleted file mode 100644 index 3e42217..0000000 --- a/rnex-core-deprecated/src/nex/s3presigner.rs +++ /dev/null @@ -1,116 +0,0 @@ -use base64::{engine::general_purpose, Engine as _}; -use hmac::{Hmac, Mac}; -use sha2::{Sha256, Digest}; -use chrono::{Utc, Duration}; -use serde_json::json; -use rnex_core::executables::common::RNEX_DATASTORE_S3_ENDPOINT; - -pub struct S3Presigner { - endpoint: String, - bucket: String, -} - -impl S3Presigner { - pub async fn new(endpoint: &str, bucket: String) -> Self { - Self { - endpoint: endpoint.trim_end_matches('/').to_string(), - bucket, - } - } - pub async fn generate_presigned_post(&self, key: &str) -> (String, Vec<(String, String)>) { - let access_key = std::env::var("AWS_ACCESS_KEY_ID").expect("Missing Access Key"); - let secret_key = std::env::var("AWS_SECRET_ACCESS_KEY").expect("Missing Secret Key"); - 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 credential = format!("{}/{}/{}/s3/aws4_request", access_key, date_short, region); - - let policy_json = json!({ - "expiration": expiration, - "conditions": [ - {"bucket": self.bucket}, - ["starts-with", "$key", key], - {"x-amz-credential": credential}, - {"x-amz-algorithm": "AWS4-HMAC-SHA256"}, - {"x-amz-date": date_full} - ] - }); - - let policy_base64 = general_purpose::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-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); - (url, fields) - } - - pub fn generate_presigned_get(&self, key: &str) -> String { - let access_key = std::env::var("AWS_ACCESS_KEY_ID").expect("Missing Access Key"); - let secret_key = std::env::var("AWS_SECRET_ACCESS_KEY").expect("Missing Secret Key"); - let region = "us-east-1"; - 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 credential_scope = format!("{}/{}/s3/aws4_request", date_short, region); - - let query_string = format!( - "X-Amz-Algorithm=AWS4-HMAC-SHA256&\ - X-Amz-Credential={}%2F{}&\ - X-Amz-Date={}&\ - X-Amz-Expires=900&\ - X-Amz-SignedHeaders=host", - access_key, - urlencoding::encode(&credential_scope), - date_full - ); - - let canonical_request = format!( - "GET\n/{}/{}\n{}\nhost:{}\n\nhost\nUNSIGNED-PAYLOAD", - self.bucket, key, query_string, *RNEX_DATASTORE_S3_ENDPOINT - ); - - let hashed_request = hex::encode(Sha256::digest(canonical_request.as_bytes())); - - let string_to_sign = format!( - "AWS4-HMAC-SHA256\n{}\n{}\n{}", - date_full, credential_scope, hashed_request - ); - - let k_date = self.hmac_sha256(format!("AWS4{}", secret_key).as_bytes(), &date_short); - let k_region = self.hmac_sha256(&k_date, region); - let k_service = self.hmac_sha256(&k_region, "s3"); - let k_signing = self.hmac_sha256(&k_service, "aws4_request"); - let signature = hex::encode(self.hmac_sha256(&k_signing, &string_to_sign)); - - format!( - "https://{}/{}/{}?{}&X-Amz-Signature={}", - *RNEX_DATASTORE_S3_ENDPOINT, self.bucket, key, query_string, signature - ) - } - - fn calculate_signature(&self, secret: &str, date: &str, region: &str, policy: &str) -> String { - let k_date = self.hmac_sha256(format!("AWS4{}", secret).as_bytes(), date); - let k_region = self.hmac_sha256(&k_date, region); - let k_service = self.hmac_sha256(&k_region, "s3"); - let k_signing = self.hmac_sha256(&k_service, "aws4_request"); - - hex::encode(self.hmac_sha256(&k_signing, policy)) - } - - fn hmac_sha256(&self, key: &[u8], data: &str) -> Vec { - let mut mac = Hmac::::new_from_slice(key).expect("HMAC can take key of any size"); - mac.update(data.as_bytes()); - mac.finalize().into_bytes().to_vec() - } -} \ No newline at end of file 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-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 }) }