From 0c256846f6eeedd7172e61b2cfdd55c9f0424ef4 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Tue, 30 Dec 2025 21:18:16 +0100 Subject: [PATCH] Added owning games and not willing to travel with them. --- backend-actix/Cargo.lock | 413 +++++++++++++++++- backend-actix/Cargo.toml | 3 +- backend-actix/build.rs | 5 +- backend-actix/gamenight-api.yaml | 22 +- backend-actix/src/request/game.rs | 15 +- .../.openapi-generator/FILES | 2 + .../.openapi-generator/VERSION | 2 +- gamenight-api-client-rs/Cargo.toml | 2 +- gamenight-api-client-rs/README.md | 5 +- gamenight-api-client-rs/docs/DefaultApi.md | 8 +- .../docs/OwnGameRequestBody.md | 12 + .../src/apis/configuration.rs | 2 +- .../src/apis/default_api.rs | 23 +- .../src/models/add_game_request_body.rs | 2 +- .../src/models/add_gamenight_request_body.rs | 2 +- .../src/models/add_location_request_body.rs | 2 +- .../models/authorize_location_request_body.rs | 2 +- gamenight-api-client-rs/src/models/failure.rs | 2 +- gamenight-api-client-rs/src/models/game.rs | 2 +- gamenight-api-client-rs/src/models/game_id.rs | 2 +- .../src/models/gamenight.rs | 2 +- .../src/models/gamenight_id.rs | 2 +- .../src/models/get_gamenight_request_body.rs | 2 +- .../src/models/location.rs | 2 +- .../src/models/location_id.rs | 2 +- gamenight-api-client-rs/src/models/login.rs | 2 +- gamenight-api-client-rs/src/models/mod.rs | 2 + .../src/models/own_game_request_body.rs | 30 ++ .../src/models/participants.rs | 2 +- .../src/models/registration.rs | 2 +- .../src/models/rename_game_request_body.rs | 2 +- gamenight-api-client-rs/src/models/token.rs | 2 +- gamenight-api-client-rs/src/models/user.rs | 2 +- gamenight-api-client-rs/src/models/user_id.rs | 2 +- gamenight-cli/src/domain/location.rs | 2 +- gamenight-cli/src/flows/add_game.rs | 18 +- gamenight-cli/src/flows/flow_helpers.rs | 25 ++ gamenight-cli/src/flows/location_authorize.rs | 2 +- gamenight-cli/src/flows/mod.rs | 1 + gamenight-cli/src/flows/own.rs | 29 +- .../down.sql | 3 + .../up.sql | 6 + gamenight-database/src/game.rs | 14 +- gamenight-database/src/owned_game.rs | 1 + gamenight-database/src/schema.rs | 2 + 45 files changed, 595 insertions(+), 92 deletions(-) create mode 100644 gamenight-api-client-rs/docs/OwnGameRequestBody.md create mode 100644 gamenight-api-client-rs/src/models/own_game_request_body.rs create mode 100644 gamenight-cli/src/flows/flow_helpers.rs create mode 100644 gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/down.sql create mode 100644 gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/up.sql diff --git a/backend-actix/Cargo.lock b/backend-actix/Cargo.lock index 466d718..6b54188 100644 --- a/backend-actix/Cargo.lock +++ b/backend-actix/Cargo.lock @@ -64,7 +64,7 @@ dependencies = [ "mime", "percent-encoding", "pin-project-lite", - "rand", + "rand 0.9.2", "sha1", "smallvec", "tokio", @@ -317,7 +317,6 @@ dependencies = [ "env_logger", "gamenight-database", "jsonwebtoken", - "rand_core 0.9.3", "serde", "serde_json", "tracing-actix-web", @@ -325,6 +324,12 @@ dependencies = [ "validator", ] +[[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" @@ -447,6 +452,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "convert_case" version = "0.10.0" @@ -491,6 +502,18 @@ dependencies = [ "cfg-if", ] +[[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" @@ -501,6 +524,33 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "darling" version = "0.20.11" @@ -571,6 +621,17 @@ dependencies = [ "syn", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.5.5" @@ -672,6 +733,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -707,12 +769,71 @@ dependencies = [ "syn", ] +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[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", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encoding_rs" version = "0.8.35" @@ -751,6 +872,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[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 = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "find-msvc-tools" version = "0.1.5" @@ -841,6 +978,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -850,10 +988,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -868,6 +1004,17 @@ dependencies = [ "wasip2", ] +[[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" @@ -905,6 +1052,24 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + [[package]] name = "http" version = "0.2.12" @@ -1134,16 +1299,24 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "10.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "c76e1c7d7df3e34443b3621b459b066a7b79644f059fc8b2db7070c825fd417e" dependencies = [ "base64", + "ed25519-dalek", + "getrandom 0.2.16", + "hmac", "js-sys", + "p256", + "p384", "pem", - "ring", + "rand 0.8.5", + "rsa", "serde", "serde_json", + "sha2", + "signature", "simple_asn1", ] @@ -1153,12 +1326,27 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + [[package]] name = "libc" version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "litemap" version = "0.8.1" @@ -1268,6 +1456,22 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1283,6 +1487,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -1290,6 +1505,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1304,6 +1520,30 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[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", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -1348,6 +1588,15 @@ dependencies = [ "serde_core", ] +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.2" @@ -1386,6 +1635,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -1442,6 +1712,15 @@ dependencies = [ "vcpkg", ] +[[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-macro-error-attr2" version = "2.0.0" @@ -1499,16 +1778,37 @@ dependencies = [ "scheduled-thread-pool", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.3", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -1582,17 +1882,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "ring" -version = "0.17.14" +name = "rfc6979" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", + "hmac", + "subtle", +] + +[[package]] +name = "rsa" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", ] [[package]] @@ -1631,6 +1947,20 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "semver" version = "1.0.27" @@ -1712,6 +2042,17 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1727,6 +2068,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.8" @@ -1777,6 +2128,22 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -2007,12 +2374,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.7" @@ -2448,6 +2809,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.3" diff --git a/backend-actix/Cargo.toml b/backend-actix/Cargo.toml index c5101d2..1121b86 100644 --- a/backend-actix/Cargo.toml +++ b/backend-actix/Cargo.toml @@ -13,8 +13,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.3.0", features = ["serde", "v4"] } chrono = { version = "0.4", features = ["serde"] } -jsonwebtoken = "9.3" +jsonwebtoken = { version = "10.2.0", features = ["rust_crypto"] } validator = { version = "0.20", features = ["derive"] } -rand_core = { version = "0.9" } env_logger = "0.11" tracing-actix-web = "0.7" \ No newline at end of file diff --git a/backend-actix/build.rs b/backend-actix/build.rs index 88053a2..215bfce 100644 --- a/backend-actix/build.rs +++ b/backend-actix/build.rs @@ -3,6 +3,7 @@ use std::{ io::Write, process::Command, }; +use std::fs::create_dir; fn main() { println!("cargo::rerun-if-changed=gamenight-api.yaml"); @@ -11,6 +12,8 @@ fn main() { remove_dir_all("src/models").unwrap(); } + create_dir("src/models/").unwrap(); + let _ = Command::new("openapi-generator") .args([ "generate", @@ -24,7 +27,7 @@ fn main() { .output() .expect("Failed to generate models sources for the gamenight API"); - let mut file = File::create("src/models/mod.rs").unwrap(); + let mut file = File::create("./src/models/mod.rs").unwrap(); let paths = read_dir("./src/models").unwrap(); for path in paths { let path = path.unwrap(); diff --git a/backend-actix/gamenight-api.yaml b/backend-actix/gamenight-api.yaml index 1d1e085..b7ccc00 100644 --- a/backend-actix/gamenight-api.yaml +++ b/backend-actix/gamenight-api.yaml @@ -6,7 +6,7 @@ info: name: Dennis Brentjes email: dennis@brentj.es url: 'https://brentj.es' - description: Api specifaction for a Gamenight server + description: Api specification for a Gamenight server license: name: MIT servers: @@ -192,7 +192,7 @@ paths: post: responses: '200': - description: "OK" + $ref: '#/components/responses/GameIdResponse' '401': $ref: '#/components/responses/FailureResponse' '422': @@ -269,7 +269,6 @@ paths: post: responses: '200': - description: 'Ok' $ref: '#/components/responses/LocationIdResponse' '401': $ref: '#/components/responses/FailureResponse' @@ -479,6 +478,15 @@ components: required: - id - name + OwnGameRequestBody: + type: object + properties: + game_id: + type: string + location_id: + type: string + required: + - game_id GameIdsResponse: type: array items: @@ -586,7 +594,7 @@ components: content: application/json: schema: - $ref: '#/components/schemas/GameId' + $ref: '#/components/schemas/OwnGameRequestBody' DisownGameRequest: content: application/json: @@ -679,6 +687,12 @@ components: application/json: schema: $ref: '#/components/schemas/Game' + GameIdResponse: + description: a game id + content: + application/json: + schema: + $ref: '#/components/schemas/GameId' GameIdsResponse: description: A list of game ids. content: diff --git a/backend-actix/src/request/game.rs b/backend-actix/src/request/game.rs index 21796e0..b42f357 100644 --- a/backend-actix/src/request/game.rs +++ b/backend-actix/src/request/game.rs @@ -9,7 +9,7 @@ use uuid::Uuid; use crate::{ models::{ add_game_request_body::AddGameRequestBody, game::Game, game_id::GameId, - rename_game_request_body::RenameGameRequestBody, + rename_game_request_body::RenameGameRequestBody, own_game_request_body::OwnGameRequestBody }, request::{authorization::AuthUser, error::ApiError}, }; @@ -69,9 +69,12 @@ pub async fn post_game( game_data: web::Json, ) -> Result { let mut conn = pool.get_conn(); - insert_game(&mut conn, game_data.0.into())?; + let game = game_data.0.into(); + insert_game(&mut conn, &game)?; - Ok(HttpResponse::Ok()) + Ok(HttpResponse::Ok() + .content_type(ContentType::json()) + .body(serde_json::to_string(&GameId{game_id: game.id.to_string()})?)) } #[post("/rename_game")] @@ -94,14 +97,15 @@ pub async fn post_rename_game( pub async fn post_own_game( pool: web::Data, user: AuthUser, - game_id: web::Json, + own_data: web::Json, ) -> Result { let mut conn = pool.get_conn(); own_game( &mut conn, OwnedGame { user_id: user.0.id, - game_id: Uuid::parse_str(&game_id.0.game_id)?, + game_id: Uuid::parse_str(&own_data.game_id)?, + location_id: own_data.location_id.clone().map(|x| Uuid::parse_str(&x).unwrap()), }, )?; @@ -120,6 +124,7 @@ pub async fn post_disown_game( OwnedGame { user_id: user.0.id, game_id: Uuid::parse_str(&game_id.0.game_id)?, + location_id: None }, )?; diff --git a/gamenight-api-client-rs/.openapi-generator/FILES b/gamenight-api-client-rs/.openapi-generator/FILES index a9ce83b..0a33990 100644 --- a/gamenight-api-client-rs/.openapi-generator/FILES +++ b/gamenight-api-client-rs/.openapi-generator/FILES @@ -16,6 +16,7 @@ docs/GetGamenightRequestBody.md docs/Location.md docs/LocationId.md docs/Login.md +docs/OwnGameRequestBody.md docs/Participants.md docs/Registration.md docs/RenameGameRequestBody.md @@ -41,6 +42,7 @@ src/models/location.rs src/models/location_id.rs src/models/login.rs src/models/mod.rs +src/models/own_game_request_body.rs src/models/participants.rs src/models/registration.rs src/models/rename_game_request_body.rs diff --git a/gamenight-api-client-rs/.openapi-generator/VERSION b/gamenight-api-client-rs/.openapi-generator/VERSION index 6328c54..1b2d969 100644 --- a/gamenight-api-client-rs/.openapi-generator/VERSION +++ b/gamenight-api-client-rs/.openapi-generator/VERSION @@ -1 +1 @@ -7.17.0 +7.18.0 diff --git a/gamenight-api-client-rs/Cargo.toml b/gamenight-api-client-rs/Cargo.toml index 9373266..4191276 100644 --- a/gamenight-api-client-rs/Cargo.toml +++ b/gamenight-api-client-rs/Cargo.toml @@ -2,7 +2,7 @@ name = "gamenight-api-client-rs" version = "0.1.0" authors = ["dennis@brentj.es"] -description = "Api specifaction for a Gamenight server" +description = "Api specification for a Gamenight server" license = "MIT" edition = "2021" diff --git a/gamenight-api-client-rs/README.md b/gamenight-api-client-rs/README.md index d09cdd8..355f48b 100644 --- a/gamenight-api-client-rs/README.md +++ b/gamenight-api-client-rs/README.md @@ -1,6 +1,6 @@ # Rust API client for gamenight-api-client-rs -Api specifaction for a Gamenight server +Api specification for a Gamenight server For more information, please visit [https://brentj.es](https://brentj.es) @@ -10,7 +10,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat - API version: 1.0 - Package version: 0.1.0 -- Generator version: 7.17.0 +- Generator version: 7.18.0 - Build package: `org.openapitools.codegen.languages.RustClientCodegen` ## Installation @@ -67,6 +67,7 @@ Class | Method | HTTP request | Description - [Location](docs/Location.md) - [LocationId](docs/LocationId.md) - [Login](docs/Login.md) + - [OwnGameRequestBody](docs/OwnGameRequestBody.md) - [Participants](docs/Participants.md) - [Registration](docs/Registration.md) - [RenameGameRequestBody](docs/RenameGameRequestBody.md) diff --git a/gamenight-api-client-rs/docs/DefaultApi.md b/gamenight-api-client-rs/docs/DefaultApi.md index bf96f58..8912504 100644 --- a/gamenight-api-client-rs/docs/DefaultApi.md +++ b/gamenight-api-client-rs/docs/DefaultApi.md @@ -116,7 +116,7 @@ Name | Type | Description | Required | Notes ## game_post -> game_post(add_game_request_body) +> models::GameId game_post(add_game_request_body) ### Parameters @@ -128,7 +128,7 @@ Name | Type | Description | Required | Notes ### Return type - (empty response body) +[**models::GameId**](GameId.md) ### Authorization @@ -419,7 +419,7 @@ This endpoint does not need any parameter. ## own_post -> own_post(game_id) +> own_post(own_game_request_body) ### Parameters @@ -427,7 +427,7 @@ This endpoint does not need any parameter. Name | Type | Description | Required | Notes ------------- | ------------- | ------------- | ------------- | ------------- -**game_id** | Option<[**GameId**](GameId.md)> | | | +**own_game_request_body** | Option<[**OwnGameRequestBody**](OwnGameRequestBody.md)> | | | ### Return type diff --git a/gamenight-api-client-rs/docs/OwnGameRequestBody.md b/gamenight-api-client-rs/docs/OwnGameRequestBody.md new file mode 100644 index 0000000..35d763b --- /dev/null +++ b/gamenight-api-client-rs/docs/OwnGameRequestBody.md @@ -0,0 +1,12 @@ +# OwnGameRequestBody + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**game_id** | **String** | | +**location_id** | Option<**String**> | | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/gamenight-api-client-rs/src/apis/configuration.rs b/gamenight-api-client-rs/src/apis/configuration.rs index c01b7b5..b365967 100644 --- a/gamenight-api-client-rs/src/apis/configuration.rs +++ b/gamenight-api-client-rs/src/apis/configuration.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/apis/default_api.rs b/gamenight-api-client-rs/src/apis/default_api.rs index 1fa6ff7..4d33346 100644 --- a/gamenight-api-client-rs/src/apis/default_api.rs +++ b/gamenight-api-client-rs/src/apis/default_api.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es @@ -330,7 +330,7 @@ pub async fn game_get(configuration: &configuration::Configuration, game_id: Opt } } -pub async fn game_post(configuration: &configuration::Configuration, add_game_request_body: Option) -> Result<(), Error> { +pub async fn game_post(configuration: &configuration::Configuration, add_game_request_body: Option) -> Result> { // add a prefix to parameters to efficiently prevent name collisions let p_body_add_game_request_body = add_game_request_body; @@ -349,9 +349,20 @@ pub async fn game_post(configuration: &configuration::Configuration, add_game_re let resp = configuration.client.execute(req).await?; let status = resp.status(); + let content_type = resp + .headers() + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"); + let content_type = super::ContentType::from(content_type); if !status.is_client_error() && !status.is_server_error() { - Ok(()) + let content = resp.text().await?; + match content_type { + ContentType::Json => serde_json::from_str(&content).map_err(Error::from), + ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::GameId`"))), + ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::GameId`")))), + } } else { let content = resp.text().await?; let entity: Option = serde_json::from_str(&content).ok(); @@ -716,9 +727,9 @@ pub async fn locations_get(configuration: &configuration::Configuration, ) -> Re } } -pub async fn own_post(configuration: &configuration::Configuration, game_id: Option) -> Result<(), Error> { +pub async fn own_post(configuration: &configuration::Configuration, own_game_request_body: Option) -> Result<(), Error> { // add a prefix to parameters to efficiently prevent name collisions - let p_body_game_id = game_id; + let p_body_own_game_request_body = own_game_request_body; let uri_str = format!("{}/own", configuration.base_path); let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str); @@ -729,7 +740,7 @@ pub async fn own_post(configuration: &configuration::Configuration, game_id: Opt if let Some(ref token) = configuration.bearer_access_token { req_builder = req_builder.bearer_auth(token.to_owned()); }; - req_builder = req_builder.json(&p_body_game_id); + req_builder = req_builder.json(&p_body_own_game_request_body); let req = req_builder.build()?; let resp = configuration.client.execute(req).await?; diff --git a/gamenight-api-client-rs/src/models/add_game_request_body.rs b/gamenight-api-client-rs/src/models/add_game_request_body.rs index 9d3f38c..2d62925 100644 --- a/gamenight-api-client-rs/src/models/add_game_request_body.rs +++ b/gamenight-api-client-rs/src/models/add_game_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/add_gamenight_request_body.rs b/gamenight-api-client-rs/src/models/add_gamenight_request_body.rs index 2ab053a..9b203f0 100644 --- a/gamenight-api-client-rs/src/models/add_gamenight_request_body.rs +++ b/gamenight-api-client-rs/src/models/add_gamenight_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/add_location_request_body.rs b/gamenight-api-client-rs/src/models/add_location_request_body.rs index 582b14e..71ee7e6 100644 --- a/gamenight-api-client-rs/src/models/add_location_request_body.rs +++ b/gamenight-api-client-rs/src/models/add_location_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/authorize_location_request_body.rs b/gamenight-api-client-rs/src/models/authorize_location_request_body.rs index 52161a4..03c7204 100644 --- a/gamenight-api-client-rs/src/models/authorize_location_request_body.rs +++ b/gamenight-api-client-rs/src/models/authorize_location_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/failure.rs b/gamenight-api-client-rs/src/models/failure.rs index 76a2332..7f60b35 100644 --- a/gamenight-api-client-rs/src/models/failure.rs +++ b/gamenight-api-client-rs/src/models/failure.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/game.rs b/gamenight-api-client-rs/src/models/game.rs index d684f46..951ba63 100644 --- a/gamenight-api-client-rs/src/models/game.rs +++ b/gamenight-api-client-rs/src/models/game.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/game_id.rs b/gamenight-api-client-rs/src/models/game_id.rs index 001d2f2..7897579 100644 --- a/gamenight-api-client-rs/src/models/game_id.rs +++ b/gamenight-api-client-rs/src/models/game_id.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/gamenight.rs b/gamenight-api-client-rs/src/models/gamenight.rs index ca66efc..d01667d 100644 --- a/gamenight-api-client-rs/src/models/gamenight.rs +++ b/gamenight-api-client-rs/src/models/gamenight.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/gamenight_id.rs b/gamenight-api-client-rs/src/models/gamenight_id.rs index ac399b5..06e1d53 100644 --- a/gamenight-api-client-rs/src/models/gamenight_id.rs +++ b/gamenight-api-client-rs/src/models/gamenight_id.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/get_gamenight_request_body.rs b/gamenight-api-client-rs/src/models/get_gamenight_request_body.rs index 5f219bc..376e1a5 100644 --- a/gamenight-api-client-rs/src/models/get_gamenight_request_body.rs +++ b/gamenight-api-client-rs/src/models/get_gamenight_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/location.rs b/gamenight-api-client-rs/src/models/location.rs index db4efb8..b2752bc 100644 --- a/gamenight-api-client-rs/src/models/location.rs +++ b/gamenight-api-client-rs/src/models/location.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/location_id.rs b/gamenight-api-client-rs/src/models/location_id.rs index 0bacc4e..ed87a74 100644 --- a/gamenight-api-client-rs/src/models/location_id.rs +++ b/gamenight-api-client-rs/src/models/location_id.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/login.rs b/gamenight-api-client-rs/src/models/login.rs index b814207..dfd3568 100644 --- a/gamenight-api-client-rs/src/models/login.rs +++ b/gamenight-api-client-rs/src/models/login.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/mod.rs b/gamenight-api-client-rs/src/models/mod.rs index 9747971..a2d86dd 100644 --- a/gamenight-api-client-rs/src/models/mod.rs +++ b/gamenight-api-client-rs/src/models/mod.rs @@ -24,6 +24,8 @@ pub mod location_id; pub use self::location_id::LocationId; pub mod login; pub use self::login::Login; +pub mod own_game_request_body; +pub use self::own_game_request_body::OwnGameRequestBody; pub mod participants; pub use self::participants::Participants; pub mod registration; diff --git a/gamenight-api-client-rs/src/models/own_game_request_body.rs b/gamenight-api-client-rs/src/models/own_game_request_body.rs new file mode 100644 index 0000000..544a5c5 --- /dev/null +++ b/gamenight-api-client-rs/src/models/own_game_request_body.rs @@ -0,0 +1,30 @@ +/* + * Gamenight + * + * Api specification for a Gamenight server + * + * The version of the OpenAPI document: 1.0 + * Contact: dennis@brentj.es + * Generated by: https://openapi-generator.tech + */ + +use crate::models; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +pub struct OwnGameRequestBody { + #[serde(rename = "game_id")] + pub game_id: String, + #[serde(rename = "location_id", skip_serializing_if = "Option::is_none")] + pub location_id: Option, +} + +impl OwnGameRequestBody { + pub fn new(game_id: String) -> OwnGameRequestBody { + OwnGameRequestBody { + game_id, + location_id: None, + } + } +} + diff --git a/gamenight-api-client-rs/src/models/participants.rs b/gamenight-api-client-rs/src/models/participants.rs index 5f2a12d..4604d7b 100644 --- a/gamenight-api-client-rs/src/models/participants.rs +++ b/gamenight-api-client-rs/src/models/participants.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/registration.rs b/gamenight-api-client-rs/src/models/registration.rs index 8ae4044..ff025e9 100644 --- a/gamenight-api-client-rs/src/models/registration.rs +++ b/gamenight-api-client-rs/src/models/registration.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/rename_game_request_body.rs b/gamenight-api-client-rs/src/models/rename_game_request_body.rs index 58f67b9..0632793 100644 --- a/gamenight-api-client-rs/src/models/rename_game_request_body.rs +++ b/gamenight-api-client-rs/src/models/rename_game_request_body.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/token.rs b/gamenight-api-client-rs/src/models/token.rs index b985517..5a2d73b 100644 --- a/gamenight-api-client-rs/src/models/token.rs +++ b/gamenight-api-client-rs/src/models/token.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/user.rs b/gamenight-api-client-rs/src/models/user.rs index ff0a408..f123fb4 100644 --- a/gamenight-api-client-rs/src/models/user.rs +++ b/gamenight-api-client-rs/src/models/user.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-api-client-rs/src/models/user_id.rs b/gamenight-api-client-rs/src/models/user_id.rs index 05d52a5..ce0b81f 100644 --- a/gamenight-api-client-rs/src/models/user_id.rs +++ b/gamenight-api-client-rs/src/models/user_id.rs @@ -1,7 +1,7 @@ /* * Gamenight * - * Api specifaction for a Gamenight server + * Api specification for a Gamenight server * * The version of the OpenAPI document: 1.0 * Contact: dennis@brentj.es diff --git a/gamenight-cli/src/domain/location.rs b/gamenight-cli/src/domain/location.rs index 808fb41..81a4d46 100644 --- a/gamenight-cli/src/domain/location.rs +++ b/gamenight-cli/src/domain/location.rs @@ -26,6 +26,6 @@ impl Display for Location { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, r#"name: {} address: {} -note: {}"#, &self.name, & as Clone>::clone(&self.address).unwrap_or_default(), & as Clone>::clone(&self.note).unwrap_or_default()) +note: {}"#, &self.name, & as Clone>::clone(&self.address).unwrap_or_default(), & as Clone>::clone(&self.note).unwrap_or_default()) } } \ No newline at end of file diff --git a/gamenight-cli/src/flows/add_game.rs b/gamenight-cli/src/flows/add_game.rs index f4871ec..6444962 100644 --- a/gamenight-cli/src/flows/add_game.rs +++ b/gamenight-cli/src/flows/add_game.rs @@ -1,10 +1,11 @@ use std::fmt::Display; use async_trait::async_trait; -use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody}; -use inquire::{Confirm, Text}; - - +use gamenight_api_client_rs::{apis::default_api::game_post, models::AddGameRequestBody, models::OwnGameRequestBody}; +use gamenight_api_client_rs::apis::default_api::{locations_get, own_post}; +use inquire::{Confirm, Select, Text}; +use crate::flows::flow_helpers::LocationSelectData; +use crate::flows::own::Own; use super::*; @@ -25,13 +26,10 @@ impl<'a> Flow<'a> for AddGame { let add_game_request = AddGameRequestBody { name }; - game_post(&state.api_configuration, Some(add_game_request)).await?; + let game_id_response = game_post(&state.api_configuration, Some(add_game_request)).await?; - if let Some(owned) = Confirm::new("Do you own this game?").prompt_skippable()? { - if owned { - todo!() - } - } + let own_flow = Own::new(Uuid::parse_str(&game_id_response.game_id)?); + return self.continue_with(state, &own_flow).await; } Ok((FlowOutcome::Cancelled, state)) } diff --git a/gamenight-cli/src/flows/flow_helpers.rs b/gamenight-cli/src/flows/flow_helpers.rs new file mode 100644 index 0000000..e3f1cdd --- /dev/null +++ b/gamenight-cli/src/flows/flow_helpers.rs @@ -0,0 +1,25 @@ +use std::fmt::{Display, Formatter}; +use gamenight_api_client_rs::models::Location; +use uuid::Uuid; +use crate::flows::FlowError; + +pub struct LocationSelectData { + pub id: Uuid, + pub name: String, +} + +impl Display for LocationSelectData { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.name) } +} + +impl TryFrom<&Location> for LocationSelectData { + type Error = FlowError; + + fn try_from(value: &Location) -> Result { + let uuid = Uuid::parse_str(&value.id)?; + Ok(LocationSelectData { + id: uuid, + name: value.name.clone(), + }) + } +} \ No newline at end of file diff --git a/gamenight-cli/src/flows/location_authorize.rs b/gamenight-cli/src/flows/location_authorize.rs index f230d40..b4ab0e5 100644 --- a/gamenight-cli/src/flows/location_authorize.rs +++ b/gamenight-cli/src/flows/location_authorize.rs @@ -60,7 +60,7 @@ impl<'a> Flow<'a> for LocationAuthorize { authorized_user_ids.contains(&t.1.id) }).unzip(); - let selections = MultiSelect::new("Which users should be able to host gamenights in this location?", options) + let selections = MultiSelect::new("Which users should be able to host game nights in this location?", options) .with_default(&authorized_indices[..]) .prompt_skippable()?; diff --git a/gamenight-cli/src/flows/mod.rs b/gamenight-cli/src/flows/mod.rs index 01ad6d0..5e251fd 100644 --- a/gamenight-cli/src/flows/mod.rs +++ b/gamenight-cli/src/flows/mod.rs @@ -35,6 +35,7 @@ mod list_locations; mod view_location; mod add_location; mod location_authorize; +mod flow_helpers; pub struct GamenightState { api_configuration: Configuration, diff --git a/gamenight-cli/src/flows/own.rs b/gamenight-cli/src/flows/own.rs index 055cd8b..362a132 100644 --- a/gamenight-cli/src/flows/own.rs +++ b/gamenight-cli/src/flows/own.rs @@ -1,11 +1,14 @@ use std::fmt::Display; +use super::{Flow, FlowError, FlowOutcome, FlowResult, GamenightState}; +use crate::flows::flow_helpers::LocationSelectData; use async_trait::async_trait; -use gamenight_api_client_rs::{apis::default_api::own_post, models::GameId}; +use gamenight_api_client_rs::apis::default_api::locations_get; +use gamenight_api_client_rs::models::OwnGameRequestBody; +use gamenight_api_client_rs::apis::default_api::own_post; +use inquire::{Confirm, Select}; use uuid::Uuid; -use super::{Flow, FlowOutcome, FlowResult, GamenightState}; - #[derive(Clone)] pub struct Own { game_id: Uuid @@ -22,7 +25,25 @@ impl Own { #[async_trait] impl<'a> Flow<'a> for Own { async fn run(&self, state: &'a mut GamenightState) -> FlowResult<'a> { - let _ = own_post(&state.api_configuration, Some(GameId{game_id: self.game_id.to_string()})).await?; + + let mut own_game_request = OwnGameRequestBody { + game_id: self.game_id.to_string(), + location_id: None + }; + + if let Some(owned) = Confirm::new("Do you own this game?").prompt_skippable()? { + if owned { + if let Some(willing_to_travel) = Confirm::new("Are you willing to travel with this game?").prompt_skippable()? { + if !willing_to_travel { + let locations = locations_get(&state.api_configuration).await?.iter().map(|x| { x.try_into() }).collect::, FlowError>>()?; + if let Some(location) = Select::new("What location can this game be played?", locations).prompt_skippable()? { + own_game_request.location_id = Some(location.id.to_string()); + } + } + } + let _ = own_post(&state.api_configuration, Some(own_game_request)).await?; + } + } clear_screen::clear(); Ok((FlowOutcome::Successful, state)) diff --git a/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/down.sql b/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/down.sql new file mode 100644 index 0000000..f3842ce --- /dev/null +++ b/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/down.sql @@ -0,0 +1,3 @@ +-- This file should undo anything in `up.sql` +alter table owned_game drop constraint FK_owned_games_location_id; +alter table owned_game drop column location_id; \ No newline at end of file diff --git a/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/up.sql b/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/up.sql new file mode 100644 index 0000000..176a3f7 --- /dev/null +++ b/gamenight-database/migrations/2025-12-26-151242_add_location_to_owned_game/up.sql @@ -0,0 +1,6 @@ +-- Your SQL goes here +ALTER TABLE owned_game + ADD location_id UUID; + +ALTER TABLE owned_game + ADD CONSTRAINT FK_owned_games_location_id FOREIGN KEY(location_id) REFERENCES location(id); \ No newline at end of file diff --git a/gamenight-database/src/game.rs b/gamenight-database/src/game.rs index dd7fd09..50330f8 100644 --- a/gamenight-database/src/game.rs +++ b/gamenight-database/src/game.rs @@ -1,10 +1,10 @@ use crate::schema::game; use diesel::{ - ExpressionMethods, Insertable, PgConnection, QueryDsl, Queryable, RunQueryDsl, dsl::insert_into, + ExpressionMethods, Insertable, QueryDsl, Queryable, RunQueryDsl, dsl::insert_into, }; use serde::{Deserialize, Serialize}; use uuid::Uuid; - +use crate::DbConnection; use super::error::DatabaseError; #[derive(Serialize, Deserialize, Debug, Insertable, Queryable)] @@ -14,20 +14,20 @@ pub struct Game { pub name: String, } -pub fn games(conn: &mut PgConnection) -> Result, DatabaseError> { +pub fn games(conn: &mut DbConnection) -> Result, DatabaseError> { Ok(game::table.load::(conn)?) } -pub fn load_game(conn: &mut PgConnection, id: Uuid) -> Result { +pub fn load_game(conn: &mut DbConnection, id: Uuid) -> Result { Ok(game::table.find(id).get_result(conn)?) } -pub fn insert_game(conn: &mut PgConnection, game: Game) -> Result { - Ok(insert_into(game::table).values(&game).execute(conn)?) +pub fn insert_game(conn: &mut DbConnection, game: &Game) -> Result { + Ok(insert_into(game::table).values(game).execute(conn)?) } pub fn rename_game( - conn: &mut PgConnection, + conn: &mut DbConnection, id: Uuid, name: String, ) -> Result { diff --git a/gamenight-database/src/owned_game.rs b/gamenight-database/src/owned_game.rs index 5ba806a..cf36455 100644 --- a/gamenight-database/src/owned_game.rs +++ b/gamenight-database/src/owned_game.rs @@ -12,6 +12,7 @@ use uuid::Uuid; pub struct OwnedGame { pub user_id: Uuid, pub game_id: Uuid, + pub location_id: Option } pub fn own_game(conn: &mut PgConnection, owned_game: OwnedGame) -> Result { diff --git a/gamenight-database/src/schema.rs b/gamenight-database/src/schema.rs index c8819f3..c5c1def 100644 --- a/gamenight-database/src/schema.rs +++ b/gamenight-database/src/schema.rs @@ -69,6 +69,7 @@ diesel::table! { owned_game (user_id, game_id) { user_id -> Uuid, game_id -> Uuid, + location_id -> Nullable, } } @@ -99,6 +100,7 @@ diesel::joinable!(location_owner -> client (user_id)); diesel::joinable!(location_owner -> location (location_id)); diesel::joinable!(owned_game -> client (user_id)); diesel::joinable!(owned_game -> game (game_id)); +diesel::joinable!(owned_game -> location (location_id)); diesel::joinable!(pwd -> client (user_id)); diesel::allow_tables_to_appear_in_same_query!(