mirror of
https://github.com/shiroyashik/sculptor.git
synced 2025-12-06 04:51:13 +03:00
Release v0.3.1
See release body for more information
This commit is contained in:
parent
9e3bca85cd
commit
d5433101f1
12 changed files with 194 additions and 134 deletions
16
.github/release-body.md
vendored
16
.github/release-body.md
vendored
|
|
@ -1,14 +1,8 @@
|
|||
## Release ☆ ~('▽^人)
|
||||
|
||||
> [!CAUTION]
|
||||
> **Update your Config.toml according to the example in the repository!**
|
||||
## Bug fix
|
||||
|
||||
What's added:
|
||||
- Ability to change authentication providers;
|
||||
- Display information about Sculptor in MOTD;
|
||||
- Checking updates for Sculptor (displayed in CLI at startup) and for Figura (reported in mod UI);
|
||||
- Saving log files in a separate directory;
|
||||
- User bans and Minecraft blacklist parser;
|
||||
- Implemented a special API for backend manipulation by third-party software.
|
||||
- Prohibit creation of two sessions on one user
|
||||
- Fixed avatar refreshing when deleting an avatar
|
||||
- Fixed session relevance check
|
||||
|
||||
**Full Changelog**: https://github.com/shiroyashik/sculptor/compare/v0.2.3...v0.3.0
|
||||
**Full Changelog**: https://github.com/shiroyashik/sculptor/compare/v0.3.0...v0.3.1
|
||||
135
Cargo.lock
generated
135
Cargo.lock
generated
|
|
@ -43,19 +43,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.86"
|
||||
version = "1.0.88"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.81"
|
||||
version = "0.1.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||
checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -149,7 +149,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -220,9 +220,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.13"
|
||||
version = "1.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48"
|
||||
checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
|
@ -330,9 +330,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
|||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.13"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
|
||||
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
|
@ -405,9 +405,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "6.0.1"
|
||||
version = "6.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28"
|
||||
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
|
|
@ -415,6 +415,7 @@ dependencies = [
|
|||
"lock_api",
|
||||
"once_cell",
|
||||
"parking_lot_core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -517,9 +518,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
|
|
@ -631,7 +632,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap 2.4.0",
|
||||
"indexmap 2.5.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
|
@ -755,9 +756,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.27.2"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
|
||||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
|
|
@ -788,9 +789,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9"
|
||||
checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
|
@ -857,9 +858,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.5",
|
||||
|
|
@ -867,9 +868,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.9.0"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4"
|
||||
|
||||
[[package]]
|
||||
name = "is_ci"
|
||||
|
|
@ -1087,7 +1088,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1175,7 +1176,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1246,9 +1247,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
|
@ -1285,9 +1286,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.3"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||
checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
|
@ -1349,9 +1350,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
|||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.6"
|
||||
version = "0.12.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6f6ddd79dc661ade721873783d159ec87d91d556ce92933e342bae8b87c48c0"
|
||||
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
|
|
@ -1413,18 +1414,18 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
|||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.34"
|
||||
version = "0.38.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"errno",
|
||||
|
|
@ -1435,9 +1436,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.12"
|
||||
version = "0.23.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044"
|
||||
checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"rustls-pki-types",
|
||||
|
|
@ -1464,9 +1465,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0"
|
|||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.6"
|
||||
version = "0.102.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
|
||||
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
|
|
@ -1487,11 +1488,11 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
|||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.23"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
|
||||
checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b"
|
||||
dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1502,7 +1503,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||
|
||||
[[package]]
|
||||
name = "sculptor"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
|
|
@ -1560,22 +1561,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.208"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2"
|
||||
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.208"
|
||||
version = "1.0.210"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf"
|
||||
checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1589,9 +1590,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.125"
|
||||
version = "1.0.128"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed"
|
||||
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -1743,9 +1744,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.75"
|
||||
version = "2.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9"
|
||||
checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -1769,9 +1770,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"core-foundation",
|
||||
|
|
@ -1833,7 +1834,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1894,9 +1895,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.39.3"
|
||||
version = "1.40.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5"
|
||||
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
|
|
@ -1918,7 +1919,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -1956,9 +1957,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.11"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||
checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
|
@ -2003,7 +2004,7 @@ version = "0.22.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
||||
dependencies = [
|
||||
"indexmap 2.4.0",
|
||||
"indexmap 2.5.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
|
@ -2087,7 +2088,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -2179,9 +2180,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
|
|
@ -2279,7 +2280,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
|
@ -2313,7 +2314,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
|
@ -2525,7 +2526,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.75",
|
||||
"syn 2.0.77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "sculptor"
|
||||
authors = ["Shiroyashik <shiroyashik@shsr.ru>"]
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ serde_json = "1.0.117"
|
|||
toml = "0.8.13"
|
||||
|
||||
# Other
|
||||
dashmap = "6.0.1"
|
||||
dashmap = { version = "6.0.1", features = ["serde"] }
|
||||
hex = "0.4.3"
|
||||
uuid = { version = "1.8.0", features = ["serde"] }
|
||||
base64 = "0.22.1"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use axum::{debug_handler, extract::{Query, State}, response::{IntoResponse, Response}, routing::get, Router};
|
||||
use reqwest::StatusCode;
|
||||
use ring::digest::{self, digest};
|
||||
use tracing::info;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::{auth::{has_joined, Userinfo}, utils::rand, AppState};
|
||||
use super::types::auth::*;
|
||||
|
|
@ -51,17 +51,23 @@ async fn verify(
|
|||
return (StatusCode::BAD_REQUEST, "You're banned!".to_string()).into_response();
|
||||
}
|
||||
info!("[Authentication] {username} logged in using {}", auth_provider.name);
|
||||
umanager.insert(
|
||||
uuid,
|
||||
server_id.clone(),
|
||||
Userinfo {
|
||||
let userinfo = Userinfo {
|
||||
username,
|
||||
uuid,
|
||||
token: Some(server_id.clone()),
|
||||
auth_provider,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
};
|
||||
match umanager.insert(uuid, server_id.clone(), userinfo.clone()) {
|
||||
Ok(_) => {},
|
||||
Err(_) => {
|
||||
umanager.remove(&uuid);
|
||||
if umanager.insert(uuid, server_id.clone(), userinfo).is_err() {
|
||||
error!("Old token error after attempting to remove it! Unexpected behavior!");
|
||||
return (StatusCode::BAD_REQUEST, "second session detected".to_string()).into_response();
|
||||
};
|
||||
}
|
||||
}
|
||||
(StatusCode::OK, server_id.to_string()).into_response()
|
||||
} else {
|
||||
info!("[Authentication] failed to verify {username}");
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
body::Bytes, extract::{Path, State}, Json
|
||||
};
|
||||
use dashmap::DashMap;
|
||||
use tracing::debug;
|
||||
use serde_json::{json, Value};
|
||||
use tokio::{
|
||||
fs,
|
||||
io::{self, AsyncReadExt, BufWriter}, sync::broadcast::Sender,
|
||||
io::{self, AsyncReadExt, BufWriter},
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
|
@ -115,7 +112,7 @@ pub async fn upload_avatar(
|
|||
pub async fn equip_avatar(Token(token): Token, State(state): State<AppState>) -> ApiResult<&'static str> {
|
||||
debug!("[API] S2C : Equip");
|
||||
let uuid = state.user_manager.get(&token).ok_or_else(|| ApiError::Unauthorized)?.uuid;
|
||||
send_event(&state.broadcasts, &uuid);
|
||||
send_event(&state, &uuid).await;
|
||||
Ok("ok")
|
||||
}
|
||||
|
||||
|
|
@ -128,18 +125,27 @@ pub async fn delete_avatar(Token(token): Token, State(state): State<AppState>) -
|
|||
);
|
||||
let avatar_file = format!("avatars/{}.moon", user_info.uuid);
|
||||
fs::remove_file(avatar_file).await.map_err(|err| internal_and_log(err))?;
|
||||
send_event(&state.broadcasts, &user_info.uuid);
|
||||
send_event(&state, &user_info.uuid).await;
|
||||
}
|
||||
// let avatar_file = format!("avatars/{}.moon",user_info.uuid);
|
||||
Ok("ok".to_string())
|
||||
}
|
||||
|
||||
pub fn send_event(broadcasts: &Arc<DashMap<Uuid, Sender<Vec<u8>>>>, uuid: &Uuid) {
|
||||
if let Some(broadcast) = broadcasts.get(&uuid) {
|
||||
pub async fn send_event(state: &AppState, uuid: &Uuid) {
|
||||
// To user subscribers
|
||||
if let Some(broadcast) = state.broadcasts.get(&uuid) {
|
||||
if broadcast.send(S2CMessage::Event(*uuid).to_vec()).is_err() {
|
||||
debug!("[WebSocket] Failed to send Event! There is no one to send. UUID: {uuid}")
|
||||
};
|
||||
} else {
|
||||
debug!("[WebSocket] Failed to send Event! Can't find UUID: {uuid}")
|
||||
};
|
||||
// To user
|
||||
if let Some(session) = state.session.get(&uuid) {
|
||||
if session.send(S2CMessage::Event(*uuid).to_vec()).await.is_err() {
|
||||
debug!("[WebSocket] Failed to send Event! WS doesn't connected? UUID: {uuid}")
|
||||
};
|
||||
} else {
|
||||
debug!("[WebSocket] Failed to send Event! Can't find UUID: {uuid}")
|
||||
};
|
||||
}
|
||||
|
|
@ -91,7 +91,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
|||
|
||||
match newmsg {
|
||||
C2SMessage::Token(token) => {
|
||||
debug!("[WebSocket{}] C2S : Token", owner.name());
|
||||
trace!("[WebSocket{}] C2S : Token", owner.name());
|
||||
let token = String::from_utf8(token.to_vec()).unwrap();
|
||||
match state.user_manager.get(&token) { // The principle is simple: if there is no token in authenticated, then it's "dirty hacker" :D
|
||||
Some(t) => {
|
||||
|
|
@ -119,7 +119,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
|||
};
|
||||
},
|
||||
C2SMessage::Ping(_, _, _) => {
|
||||
debug!("[WebSocket{}] C2S : Ping", owner.name());
|
||||
trace!("[WebSocket{}] C2S : Ping", owner.name());
|
||||
let data = into_s2c_ping(msg_vec, owner.clone().unwrap().uuid);
|
||||
match bctx.clone().unwrap().send(data) {
|
||||
Ok(_) => (),
|
||||
|
|
@ -129,7 +129,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
|||
},
|
||||
// Subscribing
|
||||
C2SMessage::Sub(uuid) => { // TODO: Eliminate the possibility of using SUB without authentication
|
||||
debug!("[WebSocket{}] C2S : Sub", owner.name());
|
||||
trace!("[WebSocket{}] C2S : Sub", owner.name());
|
||||
// Ignoring self Sub
|
||||
if uuid == owner.clone().unwrap().uuid {
|
||||
continue;
|
||||
|
|
@ -152,7 +152,7 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
|||
},
|
||||
// Unsubscribing
|
||||
C2SMessage::Unsub(uuid) => {
|
||||
debug!("[WebSocket{}] C2S : Unsub", owner.name());
|
||||
trace!("[WebSocket{}] C2S : Unsub", owner.name());
|
||||
// Ignoring self Unsub
|
||||
if uuid == owner.clone().unwrap().uuid {
|
||||
continue;
|
||||
|
|
@ -186,11 +186,13 @@ async fn handle_socket(mut socket: WebSocket, state: AppState) {
|
|||
}
|
||||
// Closing connection
|
||||
if let Some(u) = owner {
|
||||
debug!("[WebSocket ({})] Removing session data", u.username);
|
||||
state.session.remove(&u.uuid); // FIXME: Temporary solution
|
||||
// state.broadcasts.remove(&u.uuid); // NOTE: Create broadcasts manager ??
|
||||
state.user_manager.remove(&u.uuid);
|
||||
} else {
|
||||
debug!("[WebSocket] Nothing to remove");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async fn subscribe(
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ pub async fn upload_avatar(
|
|||
let avatar_file = format!("avatars/{}.moon", &uuid);
|
||||
let mut file = BufWriter::new(fs::File::create(&avatar_file).await.unwrap());
|
||||
io::copy(&mut request_data.as_ref(), &mut file).await.unwrap();
|
||||
send_event(&state.broadcasts, &uuid);
|
||||
send_event(&state, &uuid).await;
|
||||
|
||||
Ok("ok")
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ pub async fn delete_avatar(
|
|||
return Err(crate::ApiError::NotFound)
|
||||
}
|
||||
};
|
||||
send_event(&state.broadcasts, &uuid);
|
||||
send_event(&state, &uuid).await;
|
||||
|
||||
Ok("ok")
|
||||
}
|
||||
|
|
@ -11,6 +11,8 @@ pub fn router() -> Router<AppState> {
|
|||
.route("/verify", get(http2ws::verify))
|
||||
.route("/raw", post(http2ws::raw))
|
||||
.route("/sub/raw", post(http2ws::sub_raw))
|
||||
.route("/user/list", get(users::list))
|
||||
.route("/user/sessions", get(users::list_sessions))
|
||||
.route("/user/create", post(users::create_user))
|
||||
.route("/user/:uuid/ban", post(users::ban))
|
||||
.route("/user/:uuid/unban", post(users::unban))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use axum::{
|
|||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{auth::{Token, Userinfo}, ApiResult, AppState};
|
||||
use crate::{api::errors::internal_and_log, auth::{Token, Userinfo}, ApiResult, AppState};
|
||||
|
||||
pub(super) async fn create_user(
|
||||
Token(token): Token,
|
||||
|
|
@ -45,3 +45,21 @@ pub(super) async fn unban(
|
|||
state.user_manager.unban(&uuid);
|
||||
Ok("ok")
|
||||
}
|
||||
|
||||
pub(super) async fn list(
|
||||
Token(token): Token,
|
||||
State(state): State<AppState>,
|
||||
) -> ApiResult<String> {
|
||||
state.config.read().await.clone().verify_token(&token)?;
|
||||
|
||||
serde_json::to_string_pretty(&state.user_manager.get_all_registered()).map_err(|err| { internal_and_log(err) })
|
||||
}
|
||||
|
||||
pub(super) async fn list_sessions(
|
||||
Token(token): Token,
|
||||
State(state): State<AppState>,
|
||||
) -> ApiResult<String> {
|
||||
state.config.read().await.clone().verify_token(&token)?;
|
||||
|
||||
serde_json::to_string_pretty(&state.user_manager.get_all_authenticated()).map_err(|err| { internal_and_log(err) })
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{anyhow, Context};
|
||||
use axum::{
|
||||
async_trait, extract::{FromRequestParts, State}, http::{request::Parts, StatusCode}
|
||||
};
|
||||
use dashmap::DashMap;
|
||||
use tracing::{debug, error, trace};
|
||||
use thiserror::Error;
|
||||
use tracing::{debug, error, trace, warn};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{ApiError, ApiResult, AppState, TIMEOUT, USER_AGENT};
|
||||
|
|
@ -49,18 +50,28 @@ where
|
|||
|
||||
// Work with external APIs
|
||||
/// Get UUID from JSON response
|
||||
#[inline]
|
||||
fn get_id_json(json: &serde_json::Value) -> anyhow::Result<Uuid> {
|
||||
fn get_id_json(json: &serde_json::Value) -> Result<Uuid, uuid::Error> {
|
||||
trace!("json: {json:#?}"); // For debugging, we'll get to this later!
|
||||
let uuid = Uuid::parse_str(json.get("id").unwrap().as_str().unwrap())?;
|
||||
Ok(uuid)
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum FetchError {
|
||||
#[error("invalid response code (expected 200), found {0}.\n Response: {1:#?}")]
|
||||
WrongResponse(u16, Result<String, reqwest::Error>),
|
||||
#[error(transparent)]
|
||||
SendError(#[from] reqwest::Error),
|
||||
#[error(transparent)]
|
||||
Other(#[from] anyhow::Error),
|
||||
|
||||
}
|
||||
|
||||
async fn fetch_json(
|
||||
auth_provider: &AuthProvider,
|
||||
server_id: &str,
|
||||
username: &str,
|
||||
) -> anyhow::Result<anyhow::Result<(Uuid, AuthProvider)>> {
|
||||
) -> Result<(Uuid, AuthProvider), FetchError> {
|
||||
let client = reqwest::Client::builder().timeout(TIMEOUT).user_agent(USER_AGENT).build().unwrap();
|
||||
let url = auth_provider.url.clone();
|
||||
|
||||
|
|
@ -72,11 +83,11 @@ async fn fetch_json(
|
|||
trace!("{res:?}");
|
||||
match res.status().as_u16() {
|
||||
200 => {
|
||||
let json = serde_json::from_str::<serde_json::Value>(&res.text().await?)?;
|
||||
let uuid = get_id_json(&json)?;
|
||||
Ok(Ok((uuid, auth_provider.clone())))
|
||||
let json = serde_json::from_str::<serde_json::Value>(&res.text().await?).with_context(|| format!("Cant deserialize"))?;
|
||||
let uuid = get_id_json(&json).with_context(|| format!("Cant get UUID"))?;
|
||||
Ok((uuid, auth_provider.clone()))
|
||||
}
|
||||
_ => Ok(Err(anyhow!("notOK: {} data: {:?}", res.status().as_u16(), res.text().await))),
|
||||
_ => Err(FetchError::WrongResponse(res.status().as_u16(), res.text().await)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,14 +111,15 @@ pub async fn has_joined(
|
|||
let mut prov_count: usize = authproviders.len();
|
||||
while prov_count > 0 {
|
||||
if let Some(fetch_res) = rx.recv().await {
|
||||
if let Ok(user_res) = fetch_res {
|
||||
if let Ok(data) = user_res {
|
||||
return Ok(Some(data))
|
||||
} else {
|
||||
misses.push(user_res.unwrap_err());
|
||||
match fetch_res {
|
||||
Ok(data) => return Ok(Some(data)),
|
||||
Err(err) => {
|
||||
match err {
|
||||
FetchError::WrongResponse(code, data) => misses.push((code, data)),
|
||||
FetchError::SendError(err) => errors.push(err.to_string()),
|
||||
FetchError::Other(err) => errors.push(err.to_string()),
|
||||
}
|
||||
} else {
|
||||
errors.push(fetch_res.unwrap_err());
|
||||
},
|
||||
}
|
||||
} else {
|
||||
error!("Unexpected behavior!");
|
||||
|
|
@ -134,7 +146,7 @@ async fn fetch_and_send(
|
|||
provider: AuthProvider,
|
||||
server_id: String,
|
||||
username: String,
|
||||
tx: tokio::sync::mpsc::Sender<anyhow::Result<anyhow::Result<(Uuid, AuthProvider)>>>
|
||||
tx: tokio::sync::mpsc::Sender<Result<(Uuid, AuthProvider), FetchError>>
|
||||
) {
|
||||
let _ = tx.send(fetch_json(&provider, &server_id, &username).await)
|
||||
.await.map_err( |err| trace!("fetch_and_send error [note: ok res returned and mpsc clossed]: {err:?}"));
|
||||
|
|
@ -159,15 +171,34 @@ impl UManager {
|
|||
authenticated: Arc::new(DashMap::new()),
|
||||
}
|
||||
}
|
||||
pub fn get_all_registered(&self) -> DashMap<Uuid, Userinfo> {
|
||||
self.registered.as_ref().clone()
|
||||
}
|
||||
pub fn get_all_authenticated(&self) -> DashMap<String, Uuid> {
|
||||
self.authenticated.as_ref().clone()
|
||||
}
|
||||
pub fn pending_insert(&self, server_id: String, username: String) {
|
||||
self.pending.insert(server_id, username);
|
||||
}
|
||||
pub fn pending_remove(&self, server_id: &str) -> Option<(String, String)> {
|
||||
self.pending.remove(server_id)
|
||||
}
|
||||
pub fn insert(&self, uuid: Uuid, token: String, userinfo: Userinfo) {
|
||||
pub fn insert(&self, uuid: Uuid, token: String, userinfo: Userinfo) -> Result<(), ()> {
|
||||
// Check for the presence of an active session.
|
||||
if let Some(userinfo) = self.registered.get(&uuid) {
|
||||
if let Some(token) = &userinfo.token {
|
||||
if self.authenticated.contains_key(token) {
|
||||
warn!("Rejected attempt to create a second session for the same user!");
|
||||
return Err(())
|
||||
}
|
||||
debug!("`{}` already have token in registered profile (old token already removed from 'authenticated')", userinfo.username);
|
||||
}
|
||||
}
|
||||
|
||||
// Adding a user
|
||||
self.authenticated.insert(token, uuid);
|
||||
self.insert_user(uuid, userinfo);
|
||||
Ok(())
|
||||
}
|
||||
pub fn insert_user(&self, uuid: Uuid, userinfo: Userinfo) {
|
||||
// self.registered.insert(uuid, userinfo)
|
||||
|
|
@ -228,7 +259,7 @@ pub async fn check_auth(
|
|||
token: Option<Token>,
|
||||
State(state): State<AppState>,
|
||||
) -> ApiResult<&'static str> {
|
||||
|
||||
debug!("Checking auth actuality...");
|
||||
match token {
|
||||
Some(token) => {
|
||||
token.check_auth(&state).await?;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use chrono::Utc;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Userinfo {
|
||||
pub uuid: Uuid,
|
||||
|
|
@ -33,7 +33,7 @@ impl Default for Userinfo {
|
|||
|
||||
// new part
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AuthProvider {
|
||||
pub name: String,
|
||||
|
|
|
|||
|
|
@ -140,9 +140,8 @@ async fn main() -> Result<()> {
|
|||
}
|
||||
|
||||
let api = Router::new()
|
||||
.nest("//auth", api_auth::router())
|
||||
.nest("//auth", api_auth::router()) // => /api//auth ¯\_(ツ)_/¯
|
||||
.nest("/v1", api::v1::router())
|
||||
.route("/", get(check_auth))
|
||||
.route("/limits", get(api_info::limits))
|
||||
.route("/version", get(api_info::version))
|
||||
.route("/motd", get(api_info::motd))
|
||||
|
|
@ -154,10 +153,11 @@ async fn main() -> Result<()> {
|
|||
|
||||
let app = Router::new()
|
||||
.nest("/api", api)
|
||||
.route("/api/", get(check_auth))
|
||||
.route("/ws", get(ws))
|
||||
.route("/health", get(|| async { "ok" }))
|
||||
.with_state(state)
|
||||
.layer(TraceLayer::new_for_http().on_request(()));
|
||||
.layer(TraceLayer::new_for_http().on_request(()))
|
||||
.route("/health", get(|| async { "ok" }));
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(listen).await?;
|
||||
info!("Listening on {}", listener.local_addr()?);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue