add login
This commit is contained in:
parent
49af829221
commit
58b0df5757
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -222,6 +222,17 @@ dependencies = [
|
||||
"alloc-no-stdlib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argon2"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a27e27b63e4a34caee411ade944981136fdfa535522dc9944d6700196cbd899f"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"blake2",
|
||||
"password-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atoi"
|
||||
version = "0.4.0"
|
||||
@ -254,12 +265,27 @@ version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.2"
|
||||
@ -537,6 +563,7 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -600,6 +627,7 @@ name = "ffplayout-engine"
|
||||
version = "0.9.8"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"argon2",
|
||||
"chrono 0.4.19 (git+https://github.com/sbrocket/chrono?branch=parse-error-kind-public)",
|
||||
"clap",
|
||||
"crossbeam-channel",
|
||||
@ -612,12 +640,12 @@ dependencies = [
|
||||
"notify",
|
||||
"openssl",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"sha-crypt",
|
||||
"shlex",
|
||||
"simplelog",
|
||||
"sqlx",
|
||||
@ -1593,6 +1621,17 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "password-hash"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e029e94abc8fb0065241c308f1ac6bc8d20f450e8f7c5f0b25cd9b8d526ba294"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"rand_core",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.7"
|
||||
@ -1933,17 +1972,6 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-crypt"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0193e80e8a92aa7173dad160cfd5f5eda57ba146aac9826ea5c9dc3d5492072"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"sha2",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.2"
|
||||
|
@ -10,6 +10,7 @@ default-run = "ffplayout"
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4"
|
||||
argon2 = "0.4"
|
||||
chrono = { git = "https://github.com/sbrocket/chrono", branch = "parse-error-kind-public" }
|
||||
clap = { version = "3.1", features = ["derive"] }
|
||||
crossbeam-channel = "0.5"
|
||||
@ -21,9 +22,9 @@ lettre = "0.10.0-rc.6"
|
||||
log = "0.4"
|
||||
notify = "4.0"
|
||||
rand = "0.8"
|
||||
rand_core = { version = "0.6", features = ["std"] }
|
||||
regex = "1"
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
||||
sha-crypt = { version = "0.4", features = ["simple"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.8"
|
||||
|
@ -43,6 +43,7 @@ async fn cretea_schema() -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
email TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
salt TEXT NOT NULL,
|
||||
group_id INTEGER NOT NULL DEFAULT 2,
|
||||
FOREIGN KEY (group_id) REFERENCES groups (id) ON UPDATE SET NULL ON DELETE SET NULL,
|
||||
UNIQUE(email, username)
|
||||
@ -89,13 +90,16 @@ pub async fn add_user(
|
||||
mail: &str,
|
||||
user: &str,
|
||||
pass: &str,
|
||||
salt: &str,
|
||||
group: &i64,
|
||||
) -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
let query = "INSERT INTO user (email, username, password, group_id) VALUES($1, $2, $3, $4)";
|
||||
let query =
|
||||
"INSERT INTO user (email, username, password, salt, group_id) VALUES($1, $2, $3, $4, $5)";
|
||||
let result = sqlx::query(query)
|
||||
.bind(mail)
|
||||
.bind(user)
|
||||
.bind(pass)
|
||||
.bind(salt)
|
||||
.bind(group)
|
||||
.execute(instances)
|
||||
.await?;
|
||||
@ -120,7 +124,7 @@ pub async fn get_users(
|
||||
|
||||
pub async fn get_login(user: &str) -> Result<Vec<User>, sqlx::Error> {
|
||||
let pool = db_connection().await?;
|
||||
let query = "SELECT id, username, password FROM user WHERE username = $1";
|
||||
let query = "SELECT id, username, password, salt FROM user WHERE username = $1";
|
||||
let result: Vec<User> = sqlx::query_as(query).bind(user).fetch_all(&pool).await?;
|
||||
pool.close().await;
|
||||
|
||||
|
@ -9,6 +9,8 @@ pub struct User {
|
||||
#[sqlx(default)]
|
||||
pub password: String,
|
||||
#[sqlx(default)]
|
||||
pub salt: Option<String>,
|
||||
#[sqlx(default)]
|
||||
pub group_id: Option<i64>,
|
||||
}
|
||||
|
||||
|
@ -1,44 +1,46 @@
|
||||
use crate::api::{
|
||||
handles::{add_user, db_connection, get_login, get_users},
|
||||
handles::{db_connection, get_login, get_users},
|
||||
models::User,
|
||||
};
|
||||
use actix_web::{get, post, web, Responder};
|
||||
use sha_crypt::{sha512_check, sha512_simple, Sha512Params};
|
||||
use argon2::{password_hash::PasswordHash, Argon2, PasswordVerifier};
|
||||
use simplelog::*;
|
||||
|
||||
#[get("/hello/{name}")]
|
||||
async fn greet(name: web::Path<String>) -> impl Responder {
|
||||
format!("Hello {name}!")
|
||||
}
|
||||
|
||||
/// curl -X POST -H "Content-Type: application/json" -d '{"username": "USER", "password": "abc123", "email":"user@example.org" }' http://127.0.0.1:8080/api/user/
|
||||
#[post("/api/user/")]
|
||||
pub async fn user(user: web::Json<User>) -> impl Responder {
|
||||
let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||
let hashed_password = sha512_simple(&user.password, ¶ms).expect("Should not fail");
|
||||
// /// curl -X POST -H "Content-Type: application/json" -d '{"username": "USER", "password": "abc123", "email":"user@example.org" }' http://127.0.0.1:8080/api/user/
|
||||
// #[post("/api/user/")]
|
||||
// pub async fn user(user: web::Json<User>) -> impl Responder {
|
||||
// let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||
// let hashed_password = sha512_simple(&user.password, ¶ms).expect("Should not fail");
|
||||
|
||||
// // Verifying a stored password
|
||||
// assert!(sha512_check("Not so secure password", &hashed_password).is_ok());
|
||||
// // // Verifying a stored password
|
||||
// // assert!(sha512_check("Not so secure password", &hashed_password).is_ok());
|
||||
|
||||
if let Ok(pool) = db_connection().await {
|
||||
if let Err(e) = add_user(
|
||||
&pool,
|
||||
&user.email.clone().unwrap(),
|
||||
&user.username,
|
||||
&hashed_password,
|
||||
&user.group_id.unwrap(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
pool.close().await;
|
||||
return e.to_string();
|
||||
};
|
||||
// if let Ok(pool) = db_connection().await {
|
||||
// if let Err(e) = add_user(
|
||||
// &pool,
|
||||
// &user.email.clone().unwrap(),
|
||||
// &user.username,
|
||||
// &hashed_password,
|
||||
// &user.group_id.unwrap(),
|
||||
// )
|
||||
// .await
|
||||
// {
|
||||
// pool.close().await;
|
||||
// return e.to_string();
|
||||
// };
|
||||
|
||||
pool.close().await;
|
||||
}
|
||||
// pool.close().await;
|
||||
// }
|
||||
|
||||
format!("User {} added", user.username)
|
||||
}
|
||||
// format!("User {} added", user.username)
|
||||
// }
|
||||
|
||||
/// curl -X GET http://127.0.0.1:8080/api/user/1
|
||||
#[get("/api/user/{id}")]
|
||||
pub async fn get_user(id: web::Path<i64>) -> impl Responder {
|
||||
if let Ok(pool) = db_connection().await {
|
||||
@ -54,21 +56,26 @@ pub async fn get_user(id: web::Path<i64>) -> impl Responder {
|
||||
|
||||
web::Json(vec![])
|
||||
}
|
||||
|
||||
/// curl -X POST -H "Content-Type: application/json" -d '{"username": "USER", "password": "abc123" }' http://127.0.0.1:8080/auth/login/
|
||||
#[post("/auth/login/")]
|
||||
pub async fn login(credentials: web::Json<User>) -> impl Responder {
|
||||
let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||
let hashed_password = sha512_simple(&credentials.password, ¶ms).expect("Should not fail");
|
||||
|
||||
println!("{hashed_password}");
|
||||
|
||||
if let Ok(u) = get_login(&credentials.username).await {
|
||||
println!("{}", &u[0].password);
|
||||
println!("{:?}", sha512_check(&u[0].password, &hashed_password));
|
||||
if !u.is_empty() && sha512_check(&u[0].password, &hashed_password).is_ok() {
|
||||
return "login correct!";
|
||||
if u.is_empty() {
|
||||
return "User not found";
|
||||
}
|
||||
let pass = u[0].password.clone();
|
||||
|
||||
if let Ok(hash) = PasswordHash::new(&pass) {
|
||||
if Argon2::default()
|
||||
.verify_password(credentials.password.as_bytes(), &hash)
|
||||
.is_ok()
|
||||
{
|
||||
info!("user {} login", credentials.username);
|
||||
return "login correct!";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
error!("Login {} failed!", credentials.username);
|
||||
"Login failed!"
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
use sha_crypt::{sha512_simple, Sha512Params};
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHasher, SaltString},
|
||||
Argon2,
|
||||
};
|
||||
use simplelog::*;
|
||||
|
||||
use crate::api::{
|
||||
@ -27,15 +30,29 @@ pub async fn run_args(args: Args) -> Result<(), i32> {
|
||||
return Err(1);
|
||||
}
|
||||
|
||||
let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let argon2 = Argon2::default();
|
||||
let password = args.password.unwrap();
|
||||
|
||||
let hashed_password =
|
||||
sha512_simple(&args.password.unwrap(), ¶ms).expect("Should not fail");
|
||||
let password_hash = match argon2.hash_password(password.as_bytes(), &salt) {
|
||||
Ok(hash) => hash.to_string(),
|
||||
Err(e) => {
|
||||
error!("{e}");
|
||||
return Err(1);
|
||||
}
|
||||
};
|
||||
|
||||
match db_connection().await {
|
||||
Ok(pool) => {
|
||||
if let Err(e) =
|
||||
add_user(&pool, &args.email.unwrap(), &username, &hashed_password, &1).await
|
||||
if let Err(e) = add_user(
|
||||
&pool,
|
||||
&args.email.unwrap(),
|
||||
&username,
|
||||
&password_hash.to_string(),
|
||||
&salt.to_string(),
|
||||
&1,
|
||||
)
|
||||
.await
|
||||
{
|
||||
pool.close().await;
|
||||
error!("{e}");
|
||||
|
@ -7,7 +7,7 @@ use simplelog::*;
|
||||
use ffplayout_engine::{
|
||||
api::{
|
||||
args_parse::Args,
|
||||
routes::{get_user, login, user},
|
||||
routes::{get_user, login},
|
||||
utils::run_args,
|
||||
},
|
||||
utils::{init_logging, GlobalConfig},
|
||||
@ -35,7 +35,7 @@ async fn main() -> std::io::Result<()> {
|
||||
let port = ip_port[1].parse::<u16>().unwrap();
|
||||
info!("running ffplayout API, listen on {conn}");
|
||||
|
||||
HttpServer::new(|| App::new().service(get_user).service(login).service(user))
|
||||
HttpServer::new(|| App::new().service(get_user).service(login))
|
||||
.bind((addr, port))?
|
||||
.run()
|
||||
.await
|
||||
|
Loading…
x
Reference in New Issue
Block a user