Add session

This commit is contained in:
Adrian Woźniak 2023-08-02 21:31:33 +02:00 committed by eraden
parent 9384aa540f
commit ad918232c2
7 changed files with 190 additions and 0 deletions

View File

@ -0,0 +1,29 @@
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
Argon2,
};
pub fn encrypt(password: &str) -> argon2::password_hash::Result<String> {
let salt = SaltString::generate(&mut OsRng);
let argon2 = Argon2::default();
argon2
.hash_password(password.as_bytes(), &salt)
.map(|hash| hash.to_string())
}
pub fn verify(password_hash: &str, password: &str) -> argon2::password_hash::Result<()> {
let parsed_hash = PasswordHash::new(&password_hash)?;
Argon2::default().verify_password(password.as_bytes(), &parsed_hash)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_always_random_salt() {
let pass = "ahs9dya8tsd7fa8tsa86tT&^R%^DS^%ARS&A";
let hash = encrypt(pass).unwrap();
assert!(verify(hash.as_str(), pass).is_ok());
}
}

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<title>OS Wilno</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/assets/build.js" type="module"></script>
{% block head %}
{% endblock %}
</head>
<body>
<base url="/" />
<main>
{% block body %}
{% endblock %}
</main>
</body>
</html>

View File

@ -0,0 +1,22 @@
{% extends "../base.html" %}
{% block body %}
<section>
<form>
<div>
<label for="login">Login</label>
<input id="login" name="login" />
</div>
<div>
<label for="email">E-Mail</label>
<input id="email" name="email" type="email" />
</div>
<div>
<label for="password">Password</label>
<input id="password" name="password" type="password" />
</div>
<div>
<input type="submit" value="Sign Up" />
</div>
</form>
</section>
{% endblock %}

View File

@ -0,0 +1,18 @@
{% extends "../base.html" %}
{% block body %}
<section>
<form>
<div>
<label for="login">Login</label>
<input id="login" name="login" />
</div>
<div>
<label for="password">Password</label>
<input id="password" name="password" type="password" />
</div>
<div>
<input type="submit" value="Sign In" />
</div>
</form>
</section>
{% endblock %}

View File

@ -0,0 +1,7 @@
[package]
name = "oswilno-view"
version = "0.1.0"
edition = "2021"
[dependencies]
askama = { version = "0.12.0", features = ["serde", "with-actix-web", "comrak", "mime"] }

View File

@ -0,0 +1,5 @@
use askama::Result;
pub fn t(text: &str) -> Result<String> {
Ok(text.to_string())
}

View File

@ -0,0 +1,91 @@
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
pub mod helpers;
#[derive(Clone)]
pub struct TranslationStorage {
storage: Arc<RwLock<HashMap<String, HashMap<String, Translation>>>>,
}
impl TranslationStorage {
pub fn new() -> Self {
Self {
storage: Arc::new(RwLock::new(HashMap::with_capacity(32))),
}
}
pub fn to_lang(&self, lang: &str, s: &str) -> String {
let lock = self.storage.read().unwrap();
let lang_storage = lock.get(lang);
match lang_storage {
Some(h) => h,
_ => return s.into(),
}
.get(s)
.map(|f| format!("{f}"))
.unwrap_or_else(|| s.into())
}
pub fn with_lang(&mut self, lang: &'static str) -> TranslationPusher {
TranslationPusher {
lang,
storage: self.clone(),
}
}
pub fn transform<D>(&mut self, lang: &str, from_text: &str, to_display: D)
where
D: std::fmt::Display + 'static + Sync + Send,
{
self.storage
.write()
.unwrap()
.entry(lang.to_string())
.or_insert_with(|| HashMap::with_capacity(1_000))
.insert(
from_text.to_string(),
Translation::Format(Box::new(to_display)),
);
}
}
pub struct TranslationPusher {
lang: &'static str,
storage: TranslationStorage,
}
impl TranslationPusher {
#[must_use]
pub fn add(self, from_text: &str, to_text: &str) -> Self {
self.storage
.storage
.write()
.unwrap()
.entry(self.lang.to_string())
.or_insert_with(|| HashMap::with_capacity(1_000))
.insert(
from_text.to_string(),
Translation::Simple(to_text.to_string()),
);
self
}
pub fn done(self) -> TranslationStorage {
self.storage
}
}
pub enum Translation {
Simple(String),
Format(Box<dyn std::fmt::Display + 'static + Send + Sync>),
}
impl std::fmt::Display for Translation {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Simple(s) => f.write_str(&s),
Self::Format(inner) => inner.fmt(f),
}
}
}