:3
This commit is contained in:
		
							parent
							
								
									81e68770c6
								
							
						
					
					
						commit
						111bcedf2c
					
				
							
								
								
									
										118
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										118
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| 
						 | 
					@ -44,6 +44,18 @@ version = "1.0.99"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
 | 
					checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "argon2"
 | 
				
			||||||
 | 
					version = "0.5.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64ct",
 | 
				
			||||||
 | 
					 "blake2",
 | 
				
			||||||
 | 
					 "cpufeatures",
 | 
				
			||||||
 | 
					 "password-hash",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "askama"
 | 
					name = "askama"
 | 
				
			||||||
version = "0.14.0"
 | 
					version = "0.14.0"
 | 
				
			||||||
| 
						 | 
					@ -233,6 +245,15 @@ dependencies = [
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "blake2"
 | 
				
			||||||
 | 
					version = "0.10.6"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "digest",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "block-buffer"
 | 
					name = "block-buffer"
 | 
				
			||||||
version = "0.10.4"
 | 
					version = "0.10.4"
 | 
				
			||||||
| 
						 | 
					@ -626,6 +647,15 @@ dependencies = [
 | 
				
			||||||
 "version_check",
 | 
					 "version_check",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "getopts"
 | 
				
			||||||
 | 
					version = "0.2.24"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "unicode-width",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "getrandom"
 | 
					name = "getrandom"
 | 
				
			||||||
version = "0.2.16"
 | 
					version = "0.2.16"
 | 
				
			||||||
| 
						 | 
					@ -1121,7 +1151,7 @@ dependencies = [
 | 
				
			||||||
 "num-integer",
 | 
					 "num-integer",
 | 
				
			||||||
 "num-iter",
 | 
					 "num-iter",
 | 
				
			||||||
 "num-traits",
 | 
					 "num-traits",
 | 
				
			||||||
 "rand",
 | 
					 "rand 0.8.5",
 | 
				
			||||||
 "smallvec",
 | 
					 "smallvec",
 | 
				
			||||||
 "zeroize",
 | 
					 "zeroize",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
| 
						 | 
					@ -1206,6 +1236,17 @@ dependencies = [
 | 
				
			||||||
 "windows-targets 0.52.6",
 | 
					 "windows-targets 0.52.6",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "password-hash"
 | 
				
			||||||
 | 
					version = "0.5.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64ct",
 | 
				
			||||||
 | 
					 "rand_core 0.6.4",
 | 
				
			||||||
 | 
					 "subtle",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "pem-rfc7468"
 | 
					name = "pem-rfc7468"
 | 
				
			||||||
version = "0.7.0"
 | 
					version = "0.7.0"
 | 
				
			||||||
| 
						 | 
					@ -1226,11 +1267,16 @@ name = "persmgr-gui"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "anyhow",
 | 
					 "anyhow",
 | 
				
			||||||
 | 
					 "argon2",
 | 
				
			||||||
 "askama",
 | 
					 "askama",
 | 
				
			||||||
 "axum",
 | 
					 "axum",
 | 
				
			||||||
 | 
					 "base64",
 | 
				
			||||||
 | 
					 "pulldown-cmark",
 | 
				
			||||||
 | 
					 "rand 0.9.2",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 "sqlx",
 | 
					 "sqlx",
 | 
				
			||||||
 | 
					 "time",
 | 
				
			||||||
 "tokio",
 | 
					 "tokio",
 | 
				
			||||||
 "toml",
 | 
					 "toml",
 | 
				
			||||||
 "tower",
 | 
					 "tower",
 | 
				
			||||||
| 
						 | 
					@ -1314,6 +1360,25 @@ dependencies = [
 | 
				
			||||||
 "unicode-ident",
 | 
					 "unicode-ident",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "pulldown-cmark"
 | 
				
			||||||
 | 
					version = "0.13.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags",
 | 
				
			||||||
 | 
					 "getopts",
 | 
				
			||||||
 | 
					 "memchr",
 | 
				
			||||||
 | 
					 "pulldown-cmark-escape",
 | 
				
			||||||
 | 
					 "unicase",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "pulldown-cmark-escape"
 | 
				
			||||||
 | 
					version = "0.11.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "quote"
 | 
					name = "quote"
 | 
				
			||||||
version = "1.0.40"
 | 
					version = "1.0.40"
 | 
				
			||||||
| 
						 | 
					@ -1336,8 +1401,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 | 
					checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "rand_chacha",
 | 
					 "rand_chacha 0.3.1",
 | 
				
			||||||
 "rand_core",
 | 
					 "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 0.9.0",
 | 
				
			||||||
 | 
					 "rand_core 0.9.3",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -1347,7 +1422,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 | 
					checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "ppv-lite86",
 | 
					 "ppv-lite86",
 | 
				
			||||||
 "rand_core",
 | 
					 "rand_core 0.6.4",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rand_chacha"
 | 
				
			||||||
 | 
					version = "0.9.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "ppv-lite86",
 | 
				
			||||||
 | 
					 "rand_core 0.9.3",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -1359,6 +1444,15 @@ dependencies = [
 | 
				
			||||||
 "getrandom 0.2.16",
 | 
					 "getrandom 0.2.16",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rand_core"
 | 
				
			||||||
 | 
					version = "0.9.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "getrandom 0.3.3",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "redox_syscall"
 | 
					name = "redox_syscall"
 | 
				
			||||||
version = "0.5.17"
 | 
					version = "0.5.17"
 | 
				
			||||||
| 
						 | 
					@ -1381,7 +1475,7 @@ dependencies = [
 | 
				
			||||||
 "num-traits",
 | 
					 "num-traits",
 | 
				
			||||||
 "pkcs1",
 | 
					 "pkcs1",
 | 
				
			||||||
 "pkcs8",
 | 
					 "pkcs8",
 | 
				
			||||||
 "rand_core",
 | 
					 "rand_core 0.6.4",
 | 
				
			||||||
 "signature",
 | 
					 "signature",
 | 
				
			||||||
 "spki",
 | 
					 "spki",
 | 
				
			||||||
 "subtle",
 | 
					 "subtle",
 | 
				
			||||||
| 
						 | 
					@ -1534,7 +1628,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
 | 
					checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "digest",
 | 
					 "digest",
 | 
				
			||||||
 "rand_core",
 | 
					 "rand_core 0.6.4",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -1695,7 +1789,7 @@ dependencies = [
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "percent-encoding",
 | 
					 "percent-encoding",
 | 
				
			||||||
 "rand",
 | 
					 "rand 0.8.5",
 | 
				
			||||||
 "rsa",
 | 
					 "rsa",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "sha1",
 | 
					 "sha1",
 | 
				
			||||||
| 
						 | 
					@ -1733,7 +1827,7 @@ dependencies = [
 | 
				
			||||||
 "md-5",
 | 
					 "md-5",
 | 
				
			||||||
 "memchr",
 | 
					 "memchr",
 | 
				
			||||||
 "once_cell",
 | 
					 "once_cell",
 | 
				
			||||||
 "rand",
 | 
					 "rand 0.8.5",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 "sha2",
 | 
					 "sha2",
 | 
				
			||||||
| 
						 | 
					@ -2121,7 +2215,7 @@ dependencies = [
 | 
				
			||||||
 "futures",
 | 
					 "futures",
 | 
				
			||||||
 "http",
 | 
					 "http",
 | 
				
			||||||
 "parking_lot",
 | 
					 "parking_lot",
 | 
				
			||||||
 "rand",
 | 
					 "rand 0.8.5",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
| 
						 | 
					@ -2239,6 +2333,12 @@ version = "0.1.3"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
 | 
					checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-width"
 | 
				
			||||||
 | 
					version = "0.2.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "url"
 | 
					name = "url"
 | 
				
			||||||
version = "2.5.7"
 | 
					version = "2.5.7"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,11 +5,16 @@ edition = "2024"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
anyhow = "1.0.99"
 | 
					anyhow = "1.0.99"
 | 
				
			||||||
 | 
					argon2 = { version = "0.5.3", features = ["simple", "std"] }
 | 
				
			||||||
askama = "0.14.0"
 | 
					askama = "0.14.0"
 | 
				
			||||||
axum = "0.8.4"
 | 
					axum = "0.8.4"
 | 
				
			||||||
 | 
					base64 = "0.22.1"
 | 
				
			||||||
 | 
					pulldown-cmark = "0.13.0"
 | 
				
			||||||
 | 
					rand = "0.9.2"
 | 
				
			||||||
serde = { version = "1.0.219", features = ["derive"] }
 | 
					serde = { version = "1.0.219", features = ["derive"] }
 | 
				
			||||||
serde_json = "1.0.143"
 | 
					serde_json = "1.0.143"
 | 
				
			||||||
sqlx = { version = "0.8.6", features = ["macros", "postgres", "runtime-tokio"] }
 | 
					sqlx = { version = "0.8.6", features = ["macros", "postgres", "runtime-tokio"] }
 | 
				
			||||||
 | 
					time = "0.3.43"
 | 
				
			||||||
tokio = { version = "1.47.1", features = ["full"] }
 | 
					tokio = { version = "1.47.1", features = ["full"] }
 | 
				
			||||||
toml = "0.9.5"
 | 
					toml = "0.9.5"
 | 
				
			||||||
tower = { version = "0.5.2", features = ["full"] }
 | 
					tower = { version = "0.5.2", features = ["full"] }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								migrations/20250906202709_sessions.down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								migrations/20250906202709_sessions.down.sql
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					-- Add down migration script here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DROP TABLE IF EXISTS sessions;
 | 
				
			||||||
							
								
								
									
										7
									
								
								migrations/20250906202709_sessions.up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								migrations/20250906202709_sessions.up.sql
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					-- Add up migration script here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CREATE TABLE IF NOT EXISTS sessions (
 | 
				
			||||||
 | 
					    user_id BIGINT NOT NULL,
 | 
				
			||||||
 | 
					    session_key TEXT NOT NULL UNIQUE,
 | 
				
			||||||
 | 
					    expires BIGINT NOT NULL
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,82 @@
 | 
				
			||||||
use axum::{
 | 
					use argon2::{
 | 
				
			||||||
    body::Body,
 | 
					    Argon2, Params,
 | 
				
			||||||
    extract::State,
 | 
					    password_hash::{PasswordHasher, SaltString, rand_core::OsRng},
 | 
				
			||||||
    http::{HeaderMap, HeaderValue, StatusCode},
 | 
					 | 
				
			||||||
    response::{IntoResponse, Response},
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					use axum::{
 | 
				
			||||||
 | 
					    extract::{Json, State},
 | 
				
			||||||
 | 
					    http::{Response, StatusCode},
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use base64::{Engine as _, engine::general_purpose};
 | 
				
			||||||
 | 
					use serde::Deserialize;
 | 
				
			||||||
 | 
					use time::{Duration, OffsetDateTime};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::db::Database;
 | 
					use crate::db::Database;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn route(State(db): State<Database>) -> Response {
 | 
					#[derive(Debug, Clone, Deserialize)]
 | 
				
			||||||
 | 
					pub struct ReqBody {
 | 
				
			||||||
 | 
					    email: String,
 | 
				
			||||||
 | 
					    username: String,
 | 
				
			||||||
 | 
					    password: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn route(State(db): State<Database>, Json(body): Json<ReqBody>) -> Response<String> {
 | 
				
			||||||
 | 
					    let salt = SaltString::generate(&mut OsRng);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let argon2 = Argon2::new(
 | 
				
			||||||
 | 
					        argon2::Algorithm::Argon2id,
 | 
				
			||||||
 | 
					        argon2::Version::V0x13,
 | 
				
			||||||
 | 
					        Params::DEFAULT,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    let hash = argon2
 | 
				
			||||||
 | 
					        .hash_password(body.password.as_bytes(), salt.as_salt())
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut user = crate::db::tables::user::User::default();
 | 
				
			||||||
 | 
					    user.username = body.username;
 | 
				
			||||||
 | 
					    user.email = body.email;
 | 
				
			||||||
 | 
					    user.pw_salt = salt.to_string();
 | 
				
			||||||
 | 
					    user.pw_hash = hash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(e) = user.insert_new(&db.pool()).await {
 | 
				
			||||||
 | 
					        return Response::builder()
 | 
				
			||||||
 | 
					            .status(StatusCode::INTERNAL_SERVER_ERROR)
 | 
				
			||||||
 | 
					            .body(format!("ERROR: Failed to create user: {e}"))
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let Ok(user) = crate::db::tables::user::User::get_by_username(&db.pool(), user.username).await
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        return Response::builder()
 | 
				
			||||||
 | 
					            .status(StatusCode::INTERNAL_SERVER_ERROR)
 | 
				
			||||||
 | 
					            .body(String::from("ERROR: Failed to get created user"))
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let session_key = {
 | 
				
			||||||
 | 
					        let mut buf = [0u8; 32];
 | 
				
			||||||
 | 
					        rand::fill(&mut buf);
 | 
				
			||||||
 | 
					        general_purpose::STANDARD.encode(&buf)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut session = crate::db::tables::sessions::Session::default();
 | 
				
			||||||
 | 
					    session.user_id = user.id;
 | 
				
			||||||
 | 
					    session.session_key = session_key;
 | 
				
			||||||
 | 
					    session.expires = OffsetDateTime::now_utc()
 | 
				
			||||||
 | 
					        .saturating_add(Duration::days(30))
 | 
				
			||||||
 | 
					        .unix_timestamp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(e) = session.insert_new(db.pool()).await {
 | 
				
			||||||
 | 
					        return Response::builder()
 | 
				
			||||||
 | 
					            .status(StatusCode::INTERNAL_SERVER_ERROR)
 | 
				
			||||||
 | 
					            .body(format!("ERROR: Failed to create session for user: {e}",))
 | 
				
			||||||
 | 
					            .unwrap();
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Response::builder()
 | 
					    Response::builder()
 | 
				
			||||||
        .header("Location", "/")
 | 
					        .header("Location", "/")
 | 
				
			||||||
        .header("Set-Cookie", &format!("session=meowmeowmeow"))
 | 
					        .header("Set-Cookie", &format!("session={}", session.session_key))
 | 
				
			||||||
        .status(StatusCode::SEE_OTHER)
 | 
					        .status(StatusCode::SEE_OTHER)
 | 
				
			||||||
        .body(Body::empty())
 | 
					        .body(String::new())
 | 
				
			||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1 +1,2 @@
 | 
				
			||||||
 | 
					pub mod sessions;
 | 
				
			||||||
pub mod user;
 | 
					pub mod user;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								src/db/tables/sessions.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/db/tables/sessions.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					use anyhow::Result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::db::CurrPool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Default, Clone)]
 | 
				
			||||||
 | 
					pub struct Session {
 | 
				
			||||||
 | 
					    pub user_id: i64,
 | 
				
			||||||
 | 
					    pub session_key: String,
 | 
				
			||||||
 | 
					    pub expires: i64,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Session {
 | 
				
			||||||
 | 
					    pub async fn insert_new(&self, pool: &CurrPool) -> Result<Self> {
 | 
				
			||||||
 | 
					        let session = sqlx::query_as!(
 | 
				
			||||||
 | 
					            Session,
 | 
				
			||||||
 | 
					            r#"
 | 
				
			||||||
 | 
					                INSERT INTO sessions (user_id, session_key, expires)
 | 
				
			||||||
 | 
					                VALUES ($1, $2, $3)
 | 
				
			||||||
 | 
					                RETURNING *
 | 
				
			||||||
 | 
					            "#,
 | 
				
			||||||
 | 
					            self.user_id,
 | 
				
			||||||
 | 
					            self.session_key,
 | 
				
			||||||
 | 
					            self.expires
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_one(pool)
 | 
				
			||||||
 | 
					        .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(session)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub async fn get_by_username(pool: &CurrPool, user_id: i64) -> anyhow::Result<Self> {
 | 
				
			||||||
 | 
					        let session = sqlx::query_as!(
 | 
				
			||||||
 | 
					            Session,
 | 
				
			||||||
 | 
					            "SELECT * FROM sessions WHERE user_id = $1",
 | 
				
			||||||
 | 
					            user_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_one(pool)
 | 
				
			||||||
 | 
					        .await?;
 | 
				
			||||||
 | 
					        Ok(session)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    pub async fn get_by_session_key(pool: &CurrPool, session_key: String) -> anyhow::Result<Self> {
 | 
				
			||||||
 | 
					        let session = sqlx::query_as!(
 | 
				
			||||||
 | 
					            Session,
 | 
				
			||||||
 | 
					            "SELECT * FROM sessions WHERE session_key = $1",
 | 
				
			||||||
 | 
					            session_key
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .fetch_one(pool)
 | 
				
			||||||
 | 
					        .await?;
 | 
				
			||||||
 | 
					        Ok(session)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub async fn remove_old_sessions(pool: &CurrPool) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					        let curr_time = time::OffsetDateTime::now_utc().unix_timestamp();
 | 
				
			||||||
 | 
					        sqlx::query!("DELETE FROM sessions WHERE expires < $1", curr_time)
 | 
				
			||||||
 | 
					            .execute(pool)
 | 
				
			||||||
 | 
					            .await?;
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user