some type of authentication for the site
This commit is contained in:
parent
b3451a641e
commit
cdaf5febb7
13 changed files with 318 additions and 7 deletions
126
Cargo.lock
generated
126
Cargo.lock
generated
|
@ -8,6 +8,41 @@ version = "1.0.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cipher",
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aes-gcm"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"aes",
|
||||
"cipher",
|
||||
"ctr",
|
||||
"ghash",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.4"
|
||||
|
@ -161,13 +196,29 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cipher"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"inout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"base64",
|
||||
"hkdf",
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"time",
|
||||
"version_check",
|
||||
]
|
||||
|
@ -232,9 +283,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835"
|
||||
dependencies = [
|
||||
"cipher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.8"
|
||||
|
@ -571,6 +632,16 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ghash"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40"
|
||||
dependencies = [
|
||||
"opaque-debug",
|
||||
"polyval",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
|
@ -628,6 +699,24 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "hkdf"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
|
||||
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.9"
|
||||
|
@ -756,6 +845,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.8.0"
|
||||
|
@ -996,6 +1094,12 @@ version = "1.18.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.57"
|
||||
|
@ -1184,6 +1288,18 @@ version = "0.3.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "polyval"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"opaque-debug",
|
||||
"universal-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
|
@ -2023,6 +2139,16 @@ version = "0.2.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "universal-hash"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.4.1"
|
||||
|
|
|
@ -12,8 +12,8 @@ maplit = "1.0.2"
|
|||
password-auth = "0.3.0"
|
||||
rand = "0.8.5"
|
||||
regex = "1.9.4"
|
||||
reqwest = { version = "0.11.20", features = ["blocking"] }
|
||||
rocket = "=0.5.0-rc.3"
|
||||
reqwest = "0.11.20"
|
||||
rocket = { version = "=0.5.0-rc.3", features = ["secrets"]}
|
||||
rocket_dyn_templates = { version = "0.1.0-rc.3", features = ["handlebars"] }
|
||||
roxmltree = "0.18.0"
|
||||
serde = { version = "1.0.188", features = ["derive"] }
|
||||
|
|
|
@ -44,4 +44,27 @@ pre {
|
|||
|
||||
a {
|
||||
color: #89b4fa;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #f38ba8;
|
||||
}
|
||||
|
||||
.success {
|
||||
color: #a6e3a1;
|
||||
}
|
||||
|
||||
.fancy-button {
|
||||
outline: 0;
|
||||
border: none;
|
||||
background-color: #89b4fa;
|
||||
color: #11111b;
|
||||
font-size: 1.2rem;
|
||||
padding: 0.4em 0.8em;
|
||||
margin: 0.5em;
|
||||
border-radius: 16px;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition: 0.1s background-color;
|
||||
}
|
|
@ -38,4 +38,5 @@ i've run out of ideas.
|
|||
- ip actions
|
||||
- better song support
|
||||
- authentication caching (ip? redis?)
|
||||
- use log instead of println
|
||||
- use log instead of println
|
||||
- store everything in 1 cookie?
|
|
@ -45,7 +45,7 @@ pub fn login_account(input: Form<FromLoginAccount>) -> status::Custom<&'static s
|
|||
let query_result = accounts
|
||||
.select(id)
|
||||
.filter(username.eq(input.userName.clone()))
|
||||
.get_result::<i32>(connection);
|
||||
.get_result::<i32, >(connection);
|
||||
|
||||
match query_result {
|
||||
Ok(account_id_val) => {
|
||||
|
|
|
@ -4,4 +4,5 @@ pub mod difficulty;
|
|||
pub mod encryption;
|
||||
pub mod format;
|
||||
pub mod levels;
|
||||
pub mod reupload;
|
||||
pub mod reupload;
|
||||
pub mod templates;
|
19
src/helpers/templates.rs
Normal file
19
src/helpers/templates.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
macro_rules! auth {
|
||||
($cookies: expr) => {
|
||||
match $cookies.get_private("blackmail_data") {
|
||||
Some(cookie_val) => {
|
||||
let parts = cookie_val.value().split(":").collect::<Vec<&str>>();
|
||||
|
||||
let username = parts[0].to_string();
|
||||
let account_id = parts[1].parse::<i32>().expect("account id is not an integer! this should NOT happen!");
|
||||
let user_id = parts[2].parse::<i32>().expect("user id is not an integer! this should NOT happen!");
|
||||
|
||||
(true, Some(username), Some(account_id), Some(user_id))
|
||||
}
|
||||
None => {
|
||||
(false, None, None, None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub(crate) use auth;
|
|
@ -53,7 +53,12 @@ fn rocket() -> _ {
|
|||
template_endpoints::index::index,
|
||||
|
||||
template_endpoints::reupload::post_reupload,
|
||||
template_endpoints::reupload::get_reupload
|
||||
template_endpoints::reupload::get_reupload,
|
||||
|
||||
template_endpoints::login::post_login,
|
||||
template_endpoints::login::get_login,
|
||||
|
||||
template_endpoints::logout::logout,
|
||||
])
|
||||
// assets
|
||||
.mount("/", routes![
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
pub mod index;
|
||||
pub mod login;
|
||||
pub mod logout;
|
||||
pub mod reupload;
|
68
src/template_endpoints/login.rs
Normal file
68
src/template_endpoints/login.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use rocket::response::Redirect;
|
||||
|
||||
use rocket_dyn_templates::{Template, context};
|
||||
|
||||
use rocket::form::Form;
|
||||
|
||||
use rocket::http::{Cookie, CookieJar};
|
||||
|
||||
use diesel::prelude::*;
|
||||
|
||||
use crate::db;
|
||||
use crate::helpers;
|
||||
|
||||
#[derive(FromForm)]
|
||||
pub struct FormLogin {
|
||||
username: String,
|
||||
password: String
|
||||
}
|
||||
|
||||
#[post("/login", data = "<input>")]
|
||||
pub fn post_login(jar: &CookieJar<'_>, input: Form<FormLogin>) -> Template {
|
||||
let connection = &mut db::establish_connection_pg();
|
||||
|
||||
use crate::schema::accounts::dsl::*;
|
||||
|
||||
let result = accounts
|
||||
.select((id, username))
|
||||
.filter(username.eq(input.username.clone()))
|
||||
.get_result::<(i32, String), >(connection);
|
||||
|
||||
match result {
|
||||
Ok(account_id_username_val) => {
|
||||
match helpers::accounts::auth(account_id_username_val.0, Some(input.password.clone()), None, None) {
|
||||
Ok(account_id_user_id_val) => {
|
||||
jar.add_private(Cookie::build(
|
||||
"blackmail_data",
|
||||
format!("{}:{}:{}", account_id_username_val.1, account_id_user_id_val.0, account_id_user_id_val.1))
|
||||
.finish());
|
||||
|
||||
return Template::render("login", context! {
|
||||
success: "Successfully logged in"
|
||||
})
|
||||
},
|
||||
Err(_) => {
|
||||
return Template::render("login", context! {
|
||||
error: "Invalid password"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
return Template::render("login", context! {
|
||||
error: "Invalid username or password"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/login")]
|
||||
pub fn get_login(cookies: &CookieJar<'_>) -> Result<Redirect, Template> {
|
||||
let (logged_in, _username, _account_id, _user_id) = crate::helpers::templates::auth!(cookies);
|
||||
|
||||
if logged_in {
|
||||
Ok(Redirect::to("/"))
|
||||
} else {
|
||||
Err(Template::render("login", context! { }))
|
||||
}
|
||||
}
|
11
src/template_endpoints/logout.rs
Normal file
11
src/template_endpoints/logout.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use rocket::http::{Cookie, CookieJar};
|
||||
use rocket::response::Redirect;
|
||||
|
||||
#[post("/accounts/logout")]
|
||||
pub fn logout(jar: &CookieJar<'_>) -> Redirect {
|
||||
jar.remove_private(Cookie::named("username"));
|
||||
jar.remove_private(Cookie::named("account_id"));
|
||||
jar.remove_private(Cookie::named("user_id"));
|
||||
|
||||
Redirect::to("/")
|
||||
}
|
55
templates/login.html.hbs
Normal file
55
templates/login.html.hbs
Normal file
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<title>Login</title>
|
||||
<style>
|
||||
body {
|
||||
min-height: 100vh;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
max-width: 800px;
|
||||
height: 100%;
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<form method="post">
|
||||
<img src="/favicon.png" width="64" height="auto">
|
||||
<br>
|
||||
<label for="username">Username</label>
|
||||
<input type="text" id="username" name="username" minlength="3" maxlength="20" required />
|
||||
<label for="password">Password</label>
|
||||
<input type="password" id="password" name="password" minlength="6" required />
|
||||
|
||||
{{#if error}}
|
||||
<div class="error">{{error}}</div>
|
||||
{{/if}}
|
||||
{{#if success}}
|
||||
<div class="success">{{success}}</div>
|
||||
{{/if}}
|
||||
|
||||
<input type="submit" value="Login" class="fancy-button" />
|
||||
</form>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -13,7 +13,7 @@
|
|||
<h1>Level Reupload</h1>
|
||||
|
||||
{{#if error}}
|
||||
<div>Error while uploading: {{ error }}</div><br />
|
||||
<div class="error">Error while uploading: {{ error }}</div><br />
|
||||
{{/if}}
|
||||
{{#if level_id}}
|
||||
<div>Uploaded successfully! Level ID: <b>{{ level_id }}</b></div><br />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue