started work on db
This commit is contained in:
parent
8593af2441
commit
ab616cb181
File diff suppressed because it is too large
Load Diff
17
Cargo.toml
17
Cargo.toml
|
@ -20,16 +20,27 @@ clap = { version = "4.3.24", features = ["derive"] }
|
||||||
stv-rs = "0.3.0"
|
stv-rs = "0.3.0"
|
||||||
|
|
||||||
|
|
||||||
serde = "1.0"
|
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_yaml = "0.9.34"
|
serde_yaml = "0.9.28"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
base64 = "~0.22.1"
|
base64 = "~0.22.1"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
hyper = "1.3.1"
|
hyper = "1.3.1"
|
||||||
url = "2.5.0"
|
url = "2.5.0"
|
||||||
|
|
||||||
sqlx = "0.7.4"
|
oauth2 = "4.4.2"
|
||||||
|
reqwest = { version = "0.12", features = ["blocking", "json"] }
|
||||||
|
jsonwebtoken = "9.3.0"
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio-native-tls"] }
|
||||||
|
anyhow = "1.0"
|
||||||
|
bcrypt = "0.15.1"
|
||||||
|
|
||||||
|
itertools = "0.13"
|
||||||
|
indoc = "1.0.3"
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio-core = "*"
|
tokio-core = "*"
|
||||||
|
|
|
@ -18,5 +18,5 @@ the aim of this is rather to create the webui for participants to submit their v
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo +nightly -Z unstable-options build --out-dir ./build
|
cargo -Z unstable-options build --out-dir ./build
|
||||||
```
|
```
|
||||||
|
|
416
flake.lock
416
flake.lock
|
@ -1,88 +1,5 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"cachix": {
|
|
||||||
"inputs": {
|
|
||||||
"devenv": "devenv_2",
|
|
||||||
"flake-compat": [
|
|
||||||
"devenv",
|
|
||||||
"flake-compat"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"pre-commit-hooks": [
|
|
||||||
"devenv",
|
|
||||||
"pre-commit-hooks"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1712055811,
|
|
||||||
"narHash": "sha256-7FcfMm5A/f02yyzuavJe06zLa9hcMHsagE28ADcmQvk=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "cachix",
|
|
||||||
"rev": "02e38da89851ec7fec3356a5c04bc8349cae0e30",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "cachix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devenv": {
|
|
||||||
"inputs": {
|
|
||||||
"cachix": "cachix",
|
|
||||||
"flake-compat": "flake-compat_2",
|
|
||||||
"nix": "nix_2",
|
|
||||||
"nixpkgs": "nixpkgs_2",
|
|
||||||
"pre-commit-hooks": "pre-commit-hooks"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1716484006,
|
|
||||||
"narHash": "sha256-2gtN5jf21HS9TAZXhf9G+OSUY1TQ/95n6clcuFjYQ58=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "devenv",
|
|
||||||
"rev": "800f19d1b999f89464fd8e0226abf4b3b444b0fa",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "devenv",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devenv_2": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": [
|
|
||||||
"devenv",
|
|
||||||
"cachix",
|
|
||||||
"flake-compat"
|
|
||||||
],
|
|
||||||
"nix": "nix",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"poetry2nix": "poetry2nix",
|
|
||||||
"pre-commit-hooks": [
|
|
||||||
"devenv",
|
|
||||||
"cachix",
|
|
||||||
"pre-commit-hooks"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1708704632,
|
|
||||||
"narHash": "sha256-w+dOIW60FKMaHI1q5714CSibk99JfYxm0CzTinYWr+Q=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "devenv",
|
|
||||||
"rev": "2ee4450b0f4b95a1b90f2eb5ffea98b90e48c196",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"ref": "python-rewrite",
|
|
||||||
"repo": "devenv",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fenix": {
|
"fenix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -104,254 +21,7 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1673956053,
|
|
||||||
"narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-compat_2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1696426674,
|
|
||||||
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "edolstra",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1689068808,
|
|
||||||
"narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils_2": {
|
|
||||||
"inputs": {
|
|
||||||
"systems": "systems_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710146030,
|
|
||||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "flake-utils",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gitignore": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"pre-commit-hooks",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709087332,
|
|
||||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"cachix",
|
|
||||||
"devenv",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1712911606,
|
|
||||||
"narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=",
|
|
||||||
"owner": "domenkozar",
|
|
||||||
"repo": "nix",
|
|
||||||
"rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "domenkozar",
|
|
||||||
"ref": "devenv-2.21",
|
|
||||||
"repo": "nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix-github-actions": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"cachix",
|
|
||||||
"devenv",
|
|
||||||
"poetry2nix",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1688870561,
|
|
||||||
"narHash": "sha256-4UYkifnPEw1nAzqqPOTL2MvWtm3sNGw1UTYTalkTcGY=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nix-github-actions",
|
|
||||||
"rev": "165b1650b753316aa7f1787f3005a8d2da0f5301",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "nix-github-actions",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nix_2": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": [
|
|
||||||
"devenv",
|
|
||||||
"flake-compat"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"nixpkgs-regression": "nixpkgs-regression_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1712911606,
|
|
||||||
"narHash": "sha256-BGvBhepCufsjcUkXnEEXhEVjwdJAwPglCC2+bInc794=",
|
|
||||||
"owner": "domenkozar",
|
|
||||||
"repo": "nix",
|
|
||||||
"rev": "b24a9318ea3f3600c1e24b4a00691ee912d4de12",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "domenkozar",
|
|
||||||
"ref": "devenv-2.21",
|
|
||||||
"repo": "nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
|
||||||
"lastModified": 1692808169,
|
|
||||||
"narHash": "sha256-x9Opq06rIiwdwGeK2Ykj69dNc2IvUH1fY55Wm7atwrE=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "9201b5ff357e781bf014d0330d18555695df7ba8",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-regression": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1643052045,
|
|
||||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-regression_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1643052045,
|
|
||||||
"narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-stable": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1710695816,
|
|
||||||
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-23.11",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1713361204,
|
|
||||||
"narHash": "sha256-TA6EDunWTkc5FvDCqU3W2T3SFn0gRZqh6D/hJnM02MM=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "devenv-nixpkgs",
|
|
||||||
"rev": "285676e87ad9f0ca23d8714a6ab61e7e027020c6",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"ref": "rolling",
|
|
||||||
"repo": "devenv-nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1716509168,
|
"lastModified": 1716509168,
|
||||||
"narHash": "sha256-4zSIhSRRIoEBwjbPm3YiGtbd8HDWzFxJjw5DYSDy1n8=",
|
"narHash": "sha256-4zSIhSRRIoEBwjbPm3YiGtbd8HDWzFxJjw5DYSDy1n8=",
|
||||||
|
@ -367,64 +37,10 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"poetry2nix": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-utils": "flake-utils",
|
|
||||||
"nix-github-actions": "nix-github-actions",
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"cachix",
|
|
||||||
"devenv",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1692876271,
|
|
||||||
"narHash": "sha256-IXfZEkI0Mal5y1jr6IRWMqK8GW2/f28xJenZIPQqkY0=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "poetry2nix",
|
|
||||||
"rev": "d5006be9c2c2417dafb2e2e5034d83fabd207ee3",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "poetry2nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pre-commit-hooks": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": [
|
|
||||||
"devenv",
|
|
||||||
"flake-compat"
|
|
||||||
],
|
|
||||||
"flake-utils": "flake-utils_2",
|
|
||||||
"gitignore": "gitignore",
|
|
||||||
"nixpkgs": [
|
|
||||||
"devenv",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"nixpkgs-stable": "nixpkgs-stable"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1713775815,
|
|
||||||
"narHash": "sha256-Wu9cdYTnGQQwtT20QQMg7jzkANKQjwBD9iccfGKkfls=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "pre-commit-hooks.nix",
|
|
||||||
"rev": "2ac4dcbf55ed43f3be0bae15e181f08a57af24a4",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "pre-commit-hooks.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"devenv": "devenv",
|
|
||||||
"fenix": "fenix",
|
"fenix": "fenix",
|
||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rust-analyzer-src": {
|
"rust-analyzer-src": {
|
||||||
|
@ -443,36 +59,6 @@
|
||||||
"repo": "rust-analyzer",
|
"repo": "rust-analyzer",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"systems": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"systems_2": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1681028828,
|
|
||||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-systems",
|
|
||||||
"repo": "default",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
39
flake.nix
39
flake.nix
|
@ -1,28 +1,37 @@
|
||||||
{
|
{
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
devenv.url = "github:cachix/devenv";
|
|
||||||
|
|
||||||
fenix.url = "github:nix-community/fenix";
|
fenix.url = "github:nix-community/fenix";
|
||||||
fenix.inputs.nixpkgs.follows = "nixpkgs";
|
fenix.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, devenv, ... }@inputs:
|
|
||||||
|
outputs = { self, nixpkgs, fenix }@inputs:
|
||||||
let
|
let
|
||||||
|
systems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: let
|
||||||
|
toolchain = fenix.packages.${system}.complete;
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
system = "x86_64-linux";
|
inherit system;
|
||||||
};
|
overlays = [
|
||||||
in {
|
(_: super: let pkgs = fenix.inputs.nixpkgs.legacyPackages.${system}; in fenix.overlays.default pkgs pkgs)
|
||||||
devShell.x86_64-linux = devenv.lib.mkShell {
|
|
||||||
inherit inputs pkgs;
|
|
||||||
modules = [
|
|
||||||
{
|
|
||||||
languages.rust = {
|
|
||||||
enable = true;
|
|
||||||
channel = "stable";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
in f system pkgs toolchain);
|
||||||
|
in {
|
||||||
|
devShell = forAllSystems (system: pkgs: toolchain: pkgs.mkShell {
|
||||||
|
packages = [
|
||||||
|
(toolchain.withComponents [
|
||||||
|
"cargo" "rustc" "rustfmt" "clippy"
|
||||||
|
])
|
||||||
|
pkgs.openssl
|
||||||
|
pkgs.pkg-config
|
||||||
|
];
|
||||||
|
RUST_SRC_PATH = "${toolchain.rust-src}/lib/rustlib/src/rust/library";
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
19
src/api.rs
19
src/api.rs
|
@ -7,6 +7,9 @@
|
||||||
use rocket::http::Status;
|
use rocket::http::Status;
|
||||||
use rocket_contrib::json::{Json, JsonValue};
|
use rocket_contrib::json::{Json, JsonValue};
|
||||||
|
|
||||||
|
use crate::auth::login;
|
||||||
|
|
||||||
|
|
||||||
// Define data models
|
// Define data models
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct User {
|
struct User {
|
||||||
|
@ -49,15 +52,19 @@ struct Vote {
|
||||||
data: Vec<VoteItem>,
|
data: Vec<VoteItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Routes
|
|
||||||
#[post("/auth/login", format = "application/json", data = "<credentials>")]
|
#[post("/auth/login", format = "application/json", data = "<credentials>")]
|
||||||
fn login(credentials: Json<User>) -> JsonValue {
|
async fn handle_login(credentials: Json<User>, db: Db) -> JsonValue {
|
||||||
// Authentication logic here
|
match login(credentials.email, credentials.password, db).await {
|
||||||
json!({
|
Ok(token) => json!({
|
||||||
"token": "your_generated_token"
|
"token": token
|
||||||
})
|
}),
|
||||||
|
Err(error) => json!({
|
||||||
|
"error": error
|
||||||
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/auth/token", format = "application/json", data = "<token>")]
|
#[post("/auth/token", format = "application/json", data = "<token>")]
|
||||||
fn generate_token(token: Json<Authorization>) -> JsonValue {
|
fn generate_token(token: Json<Authorization>) -> JsonValue {
|
||||||
// Token generation logic here
|
// Token generation logic here
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
use jsonwebtoken::{encode, Header, EncodingKey};
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use chrono::{Utc, Duration};
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Claims {
|
||||||
|
sub: String,
|
||||||
|
exp: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn login(username: &str, _password: &str, _db: &sqlx::SqlitePool) -> Result<String, Box<dyn Error>> {
|
||||||
|
// Normally, you would validate the username and password against the database here.
|
||||||
|
// For the mock, we just generate a token for any username.
|
||||||
|
|
||||||
|
let expiration = Utc::now()
|
||||||
|
.checked_add_signed(Duration::minutes(60))
|
||||||
|
.expect("valid timestamp")
|
||||||
|
.timestamp() as usize;
|
||||||
|
|
||||||
|
let claims = Claims {
|
||||||
|
sub: username.to_owned(),
|
||||||
|
exp: expiration,
|
||||||
|
};
|
||||||
|
|
||||||
|
let token = encode(
|
||||||
|
&Header::default(),
|
||||||
|
&claims,
|
||||||
|
&EncodingKey::from_secret("secret".as_ref()),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(token)
|
||||||
|
}
|
|
@ -0,0 +1,239 @@
|
||||||
|
use sqlx::{sqlite::SqlitePool, Pool, Row};
|
||||||
|
use std::error::Error;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use indoc::indoc;
|
||||||
|
|
||||||
|
pub struct Connection {
|
||||||
|
pool: Pool<sqlx::Sqlite>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn connect() -> Result<Connection, Box<dyn Error>> {
|
||||||
|
let database_url = "sqlite::memory:"; // Use an in-memory SQLite database for testing
|
||||||
|
let pool = SqlitePool::connect(database_url).await?;
|
||||||
|
Ok(Connection { pool })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn init_db(conn: &Connection) -> Result<(), Box<dyn Error>> {
|
||||||
|
sqlx::query(indoc! {"
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username TEXT NOT NULL UNIQUE,
|
||||||
|
jwt_token TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS elections (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
username TEXT NOT NULL,
|
||||||
|
namespace TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
start_date TEXT NOT NULL,
|
||||||
|
end_date TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (username) REFERENCES users(username)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS authorizations (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
from_date TEXT NOT NULL,
|
||||||
|
to_date TEXT NOT NULL,
|
||||||
|
from_user TEXT NOT NULL,
|
||||||
|
to_user TEXT NOT NULL,
|
||||||
|
namespace TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (from_user) REFERENCES users(username),
|
||||||
|
FOREIGN KEY (to_user) REFERENCES users(username)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS votes (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
value INTEGER NOT NULL,
|
||||||
|
option_id INTEGER NOT NULL,
|
||||||
|
election_id INTEGER NOT NULL,
|
||||||
|
option_name TEXT NOT NULL,
|
||||||
|
user TEXT NOT NULL,
|
||||||
|
namespace TEXT NOT NULL,
|
||||||
|
date TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (election_id) REFERENCES elections(id),
|
||||||
|
FOREIGN KEY (user) REFERENCES users(username)
|
||||||
|
);
|
||||||
|
"})
|
||||||
|
.execute(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Users
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct User {
|
||||||
|
pub id: i64,
|
||||||
|
pub username: String,
|
||||||
|
pub jwt_token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert_user(conn: &Connection, username: &str, jwt_token: &str) -> Result<(), Box<dyn Error>> {
|
||||||
|
sqlx::query("INSERT INTO users (username, jwt_token) VALUES (?, ?)")
|
||||||
|
.bind(username)
|
||||||
|
.bind(jwt_token)
|
||||||
|
.execute(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_user(conn: &Connection, username: &str) -> Result<Option<User>, Box<dyn Error>> {
|
||||||
|
let row = sqlx::query("SELECT id, username, jwt_token FROM users WHERE username = ?")
|
||||||
|
.bind(username)
|
||||||
|
.fetch_optional(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
if let Some(row) = row {
|
||||||
|
Ok(Some(User {
|
||||||
|
id: row.get("id"),
|
||||||
|
username: row.get("username"),
|
||||||
|
jwt_token: row.get("jwt_token"),
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elections
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Election {
|
||||||
|
pub id: i64,
|
||||||
|
pub name: String,
|
||||||
|
pub username: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub description: String,
|
||||||
|
pub start_date: String,
|
||||||
|
pub end_date: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert_election(conn: &Connection, election: &Election) -> Result<(), Box<dyn Error>> {
|
||||||
|
sqlx::query(indoc! {"
|
||||||
|
INSERT INTO elections (name, username, namespace, description, start_date, end_date)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
|
"})
|
||||||
|
.bind(&election.name)
|
||||||
|
.bind(&election.username)
|
||||||
|
.bind(&election.namespace)
|
||||||
|
.bind(&election.description)
|
||||||
|
.bind(&election.start_date)
|
||||||
|
.bind(&election.end_date)
|
||||||
|
.execute(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_election(conn: &Connection, id: i64) -> Result<Option<Election>, Box<dyn Error>> {
|
||||||
|
let row = sqlx::query("SELECT id, name, username, namespace, description, start_date, end_date FROM elections WHERE id = ?")
|
||||||
|
.bind(id)
|
||||||
|
.fetch_optional(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
if let Some(row) = row {
|
||||||
|
Ok(Some(Election {
|
||||||
|
id: row.get("id"),
|
||||||
|
name: row.get("name"),
|
||||||
|
username: row.get("username"),
|
||||||
|
namespace: row.get("namespace"),
|
||||||
|
description: row.get("description"),
|
||||||
|
start_date: row.get("start_date"),
|
||||||
|
end_date: row.get("end_date"),
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authorizations
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Authorization {
|
||||||
|
pub id: i64,
|
||||||
|
pub from_date: String,
|
||||||
|
pub to_date: String,
|
||||||
|
pub from_user: String,
|
||||||
|
pub to_user: String,
|
||||||
|
pub namespace: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert_authorization(conn: &Connection, authorization: &Authorization) -> Result<(), Box<dyn Error>> {
|
||||||
|
sqlx::query(indoc! {"
|
||||||
|
INSERT INTO authorizations (from_date, to_date, from_user, to_user, namespace)
|
||||||
|
VALUES (?, ?, ?, ?, ?)
|
||||||
|
"})
|
||||||
|
.bind(&authorization.from_date)
|
||||||
|
.bind(&authorization.to_date)
|
||||||
|
.bind(&authorization.from_user)
|
||||||
|
.bind(&authorization.to_user)
|
||||||
|
.bind(&authorization.namespace)
|
||||||
|
.execute(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_authorization(conn: &Connection, id: i64) -> Result<Option<Authorization>, Box<dyn Error>> {
|
||||||
|
let row = sqlx::query("SELECT id, from_date, to_date, from_user, to_user, namespace FROM authorizations WHERE id = ?")
|
||||||
|
.bind(id)
|
||||||
|
.fetch_optional(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
if let Some(row) = row {
|
||||||
|
Ok(Some(Authorization {
|
||||||
|
id: row.get("id"),
|
||||||
|
from_date: row.get("from_date"),
|
||||||
|
to_date: row.get("to_date"),
|
||||||
|
from_user: row.get("from_user"),
|
||||||
|
to_user: row.get("to_user"),
|
||||||
|
namespace: row.get("namespace"),
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Votes
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Vote {
|
||||||
|
pub id: i64,
|
||||||
|
pub value: i32,
|
||||||
|
pub option_id: i64,
|
||||||
|
pub election_id: i64,
|
||||||
|
pub option_name: String,
|
||||||
|
pub user: String,
|
||||||
|
pub namespace: String,
|
||||||
|
pub date: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert_vote(conn: &Connection, vote: &Vote) -> Result<(), Box<dyn Error>> {
|
||||||
|
sqlx::query(indoc! {"
|
||||||
|
INSERT INTO votes (value, option_id, election_id, option_name, user, namespace, date)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||||
|
"})
|
||||||
|
.bind(vote.value)
|
||||||
|
.bind(vote.option_id)
|
||||||
|
.bind(vote.election_id)
|
||||||
|
.bind(&vote.option_name)
|
||||||
|
.bind(&vote.user)
|
||||||
|
.bind(&vote.namespace)
|
||||||
|
.bind(&vote.date)
|
||||||
|
.execute(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_vote(conn: &Connection, id: i64) -> Result<Option<Vote>, Box<dyn Error>> {
|
||||||
|
let row = sqlx::query("SELECT id, value, option_id, election_id, option_name, user, namespace, date FROM votes WHERE id = ?")
|
||||||
|
.bind(id)
|
||||||
|
.fetch_optional(&conn.pool)
|
||||||
|
.await?;
|
||||||
|
if let Some(row) = row {
|
||||||
|
Ok(Some(Vote {
|
||||||
|
id: row.get("id"),
|
||||||
|
value: row.get("value"),
|
||||||
|
option_id: row.get("option_id"),
|
||||||
|
election_id: row.get("election_id"),
|
||||||
|
option_name: row.get("option_name"),
|
||||||
|
user: row.get("user"),
|
||||||
|
namespace: row.get("namespace"),
|
||||||
|
date: row.get("date"),
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
11
src/lib.rs
11
src/lib.rs
|
@ -1,11 +0,0 @@
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
|
||||||
|
|
||||||
extern crate hyper;
|
|
||||||
extern crate serde;
|
|
||||||
extern crate serde_json;
|
|
||||||
extern crate futures;
|
|
||||||
extern crate url;
|
|
||||||
|
|
||||||
pub mod apis;
|
|
||||||
pub mod models;
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
// main.rs
|
||||||
|
|
||||||
|
mod db;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::db;
|
||||||
|
use tokio;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_connection() {
|
||||||
|
let result = db::connect().await;
|
||||||
|
assert!(result.is_ok(), "Database connection failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_insert_user() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
let result = db::insert_user(&conn, "test_user", "test_jwt").await;
|
||||||
|
assert!(result.is_ok(), "Insert user operation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_user() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "test_user", "test_jwt").await.unwrap();
|
||||||
|
let result = db::get_user(&conn, "test_user").await;
|
||||||
|
assert!(result.is_ok(), "Get user operation failed");
|
||||||
|
let user = result.unwrap();
|
||||||
|
assert!(user.is_some(), "User not found");
|
||||||
|
let user = user.unwrap();
|
||||||
|
assert_eq!(user.username, "test_user", "Username does not match");
|
||||||
|
assert_eq!(user.jwt_token, "test_jwt", "JWT token does not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_insert_election() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "test_user", "test_jwt").await.unwrap();
|
||||||
|
let election = db::Election {
|
||||||
|
id: 0,
|
||||||
|
name: "Election 1".to_string(),
|
||||||
|
username: "test_user".to_string(),
|
||||||
|
namespace: "namespace2".to_string(),
|
||||||
|
description: "Description 1".to_string(),
|
||||||
|
start_date: "2024-05-01T08:00".to_string(),
|
||||||
|
end_date: "2024-05-10T20:00".to_string(),
|
||||||
|
};
|
||||||
|
let result = db::insert_election(&conn, &election).await;
|
||||||
|
assert!(result.is_ok(), "Insert election operation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_election() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "test_user", "test_jwt").await.unwrap();
|
||||||
|
let election = db::Election {
|
||||||
|
id: 0,
|
||||||
|
name: "Election 1".to_string(),
|
||||||
|
username: "test_user".to_string(),
|
||||||
|
namespace: "namespace2".to_string(),
|
||||||
|
description: "Description 1".to_string(),
|
||||||
|
start_date: "2024-05-01T08:00".to_string(),
|
||||||
|
end_date: "2024-05-10T20:00".to_string(),
|
||||||
|
};
|
||||||
|
db::insert_election(&conn, &election).await.unwrap();
|
||||||
|
let result = db::get_election(&conn, 1).await;
|
||||||
|
assert!(result.is_ok(), "Get election operation failed");
|
||||||
|
let election = result.unwrap();
|
||||||
|
assert!(election.is_some(), "Election not found");
|
||||||
|
let election = election.unwrap();
|
||||||
|
assert_eq!(election.name, "Election 1", "Election name does not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_insert_authorization() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "user1", "jwt1").await.unwrap();
|
||||||
|
db::insert_user(&conn, "user2", "jwt2").await.unwrap();
|
||||||
|
let authorization = db::Authorization {
|
||||||
|
id: 0,
|
||||||
|
from_date: "2024-05-01T00:00".to_string(),
|
||||||
|
to_date: "2024-05-10T23:59".to_string(),
|
||||||
|
from_user: "user1".to_string(),
|
||||||
|
to_user: "user2".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
};
|
||||||
|
let result = db::insert_authorization(&conn, &authorization).await;
|
||||||
|
assert!(result.is_ok(), "Insert authorization operation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_authorization() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "user1", "jwt1").await.unwrap();
|
||||||
|
db::insert_user(&conn, "user2", "jwt2").await.unwrap();
|
||||||
|
let authorization = db::Authorization {
|
||||||
|
id: 0,
|
||||||
|
from_date: "2024-05-01T00:00".to_string(),
|
||||||
|
to_date: "2024-05-10T23:59".to_string(),
|
||||||
|
from_user: "user1".to_string(),
|
||||||
|
to_user: "user2".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
};
|
||||||
|
db::insert_authorization(&conn, &authorization).await.unwrap();
|
||||||
|
let result = db::get_authorization(&conn, 1).await;
|
||||||
|
assert!(result.is_ok(), "Get authorization operation failed");
|
||||||
|
let authorization = result.unwrap();
|
||||||
|
assert!(authorization.is_some(), "Authorization not found");
|
||||||
|
let authorization = authorization.unwrap();
|
||||||
|
assert_eq!(authorization.from_user, "user1", "From user does not match");
|
||||||
|
assert_eq!(authorization.to_user, "user2", "To user does not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_insert_vote() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "user1", "jwt1").await.unwrap();
|
||||||
|
db::insert_election(&conn, &db::Election {
|
||||||
|
id: 0,
|
||||||
|
name: "Election 1".to_string(),
|
||||||
|
username: "user1".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
description: "Description 1".to_string(),
|
||||||
|
start_date: "2024-05-01T08:00".to_string(),
|
||||||
|
end_date: "2024-05-10T20:00".to_string(),
|
||||||
|
}).await.unwrap();
|
||||||
|
let vote = db::Vote {
|
||||||
|
id: 0,
|
||||||
|
value: 1,
|
||||||
|
option_id: 1,
|
||||||
|
election_id: 1,
|
||||||
|
option_name: "Option 1".to_string(),
|
||||||
|
user: "user1".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
date: "2024-05-01T12:00".to_string(),
|
||||||
|
};
|
||||||
|
let result = db::insert_vote(&conn, &vote).await;
|
||||||
|
assert!(result.is_ok(), "Insert vote operation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_get_vote() {
|
||||||
|
let conn = db::connect().await.unwrap();
|
||||||
|
db::init_db(&conn).await.unwrap();
|
||||||
|
db::insert_user(&conn, "user1", "jwt1").await.unwrap();
|
||||||
|
db::insert_election(&conn, &db::Election {
|
||||||
|
id: 0,
|
||||||
|
name: "Election 1".to_string(),
|
||||||
|
username: "user1".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
description: "Description 1".to_string(),
|
||||||
|
start_date: "2024-05-01T08:00".to_string(),
|
||||||
|
end_date: "2024-05-10T20:00".to_string(),
|
||||||
|
}).await.unwrap();
|
||||||
|
let vote = db::Vote {
|
||||||
|
id: 0,
|
||||||
|
value: 1,
|
||||||
|
option_id: 1,
|
||||||
|
election_id: 1,
|
||||||
|
option_name: "Option 1".to_string(),
|
||||||
|
user: "user1".to_string(),
|
||||||
|
namespace: "namespace".to_string(),
|
||||||
|
date: "2024-05-01T12:00".to_string(),
|
||||||
|
};
|
||||||
|
db::insert_vote(&conn, &vote).await.unwrap();
|
||||||
|
let result = db::get_vote(&conn, 1).await;
|
||||||
|
assert!(result.is_ok(), "Get vote operation failed");
|
||||||
|
let vote = result.unwrap();
|
||||||
|
assert!(vote.is_some(), "Vote not found");
|
||||||
|
let vote = vote.unwrap();
|
||||||
|
assert_eq!(vote.option_name, "Option 1", "Option name does not match");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
println!("This is the main function. Run `cargo test` to execute tests.");
|
||||||
|
}
|
|
@ -59,6 +59,7 @@
|
||||||
<label for="namespace">Namespace:</label>
|
<label for="namespace">Namespace:</label>
|
||||||
<input type="text" id="namespace" name="namespace" placeholder="Enter namespace" required>
|
<input type="text" id="namespace" name="namespace" placeholder="Enter namespace" required>
|
||||||
<input type="submit" value="Give Acces">
|
<input type="submit" value="Give Acces">
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
|
@ -76,6 +76,8 @@
|
||||||
// Add more users as needed
|
// Add more users as needed
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const usersContainer = document.getElementById("usersContainer");
|
const usersContainer = document.getElementById("usersContainer");
|
||||||
|
|
||||||
users.forEach(user => {
|
users.forEach(user => {
|
Loading…
Reference in New Issue