work on login route
This commit is contained in:
parent
227d09bce7
commit
49af829221
24
src/api/args_parse.rs
Normal file
24
src/api/args_parse.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use clap::Parser;
|
||||||
|
|
||||||
|
#[derive(Parser, Debug, Clone)]
|
||||||
|
#[clap(version,
|
||||||
|
name = "ffpapi",
|
||||||
|
version = "0.1.0",
|
||||||
|
about = "ffplayout REST API",
|
||||||
|
long_about = None)]
|
||||||
|
pub struct Args {
|
||||||
|
#[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8080")]
|
||||||
|
pub listen: Option<String>,
|
||||||
|
|
||||||
|
#[clap(short, long, help = "Initialize Database")]
|
||||||
|
pub init: bool,
|
||||||
|
|
||||||
|
#[clap(short, long, help = "Create admin user")]
|
||||||
|
pub username: Option<String>,
|
||||||
|
|
||||||
|
#[clap(short, long, help = "Admin email")]
|
||||||
|
pub email: Option<String>,
|
||||||
|
|
||||||
|
#[clap(short, long, help = "Admin password")]
|
||||||
|
pub password: Option<String>,
|
||||||
|
}
|
@ -4,6 +4,8 @@ use faccess::PathExt;
|
|||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Pool, Sqlite, SqlitePool};
|
use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Pool, Sqlite, SqlitePool};
|
||||||
|
|
||||||
|
use crate::api::models::User;
|
||||||
|
|
||||||
pub fn db_path() -> Result<String, Box<dyn std::error::Error>> {
|
pub fn db_path() -> Result<String, Box<dyn std::error::Error>> {
|
||||||
let sys_path = Path::new("/usr/share/ffplayout");
|
let sys_path = Path::new("/usr/share/ffplayout");
|
||||||
let mut db_path = String::from("./ffplayout.db");
|
let mut db_path = String::from("./ffplayout.db");
|
||||||
@ -100,3 +102,27 @@ pub async fn add_user(
|
|||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_users(
|
||||||
|
instances: &SqlitePool,
|
||||||
|
index: Option<i64>,
|
||||||
|
) -> Result<Vec<User>, sqlx::Error> {
|
||||||
|
let query = match index {
|
||||||
|
Some(i) => format!("SELECT id, email, username FROM user WHERE id = {i}"),
|
||||||
|
None => "SELECT id, email, username FROM user".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result: Vec<User> = sqlx::query_as(&query).fetch_all(instances).await?;
|
||||||
|
instances.close().await;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 result: Vec<User> = sqlx::query_as(query).bind(user).fetch_all(&pool).await?;
|
||||||
|
pool.close().await;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
pub mod args_parse;
|
||||||
pub mod handles;
|
pub mod handles;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
pub mod utils;
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub email: String,
|
pub id: Option<i64>,
|
||||||
|
#[sqlx(default)]
|
||||||
|
pub email: Option<String>,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
|
#[sqlx(default)]
|
||||||
pub password: String,
|
pub password: String,
|
||||||
pub group_id: i64,
|
#[sqlx(default)]
|
||||||
|
pub group_id: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
pub id: i64,
|
||||||
pub channel_name: String,
|
pub channel_name: String,
|
||||||
pub preview_url: String,
|
pub preview_url: String,
|
||||||
pub settings_path: String,
|
pub settings_path: String,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use crate::api::{
|
use crate::api::{
|
||||||
handles::{add_user, db_connection},
|
handles::{add_user, db_connection, get_login, get_users},
|
||||||
models::User,
|
models::User,
|
||||||
};
|
};
|
||||||
use actix_web::{get, post, web, Responder};
|
use actix_web::{get, post, web, Responder};
|
||||||
use sha_crypt::{sha512_simple, Sha512Params};
|
use sha_crypt::{sha512_check, sha512_simple, Sha512Params};
|
||||||
|
|
||||||
#[get("/hello/{name}")]
|
#[get("/hello/{name}")]
|
||||||
async fn greet(name: web::Path<String>) -> impl Responder {
|
async fn greet(name: web::Path<String>) -> impl Responder {
|
||||||
@ -14,7 +14,6 @@ async fn greet(name: web::Path<String>) -> impl Responder {
|
|||||||
#[post("/api/user/")]
|
#[post("/api/user/")]
|
||||||
pub async fn user(user: web::Json<User>) -> impl Responder {
|
pub async fn user(user: web::Json<User>) -> impl Responder {
|
||||||
let params = Sha512Params::new(10_000).expect("RandomError!");
|
let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||||
|
|
||||||
let hashed_password = sha512_simple(&user.password, ¶ms).expect("Should not fail");
|
let hashed_password = sha512_simple(&user.password, ¶ms).expect("Should not fail");
|
||||||
|
|
||||||
// // Verifying a stored password
|
// // Verifying a stored password
|
||||||
@ -23,10 +22,10 @@ pub async fn user(user: web::Json<User>) -> impl Responder {
|
|||||||
if let Ok(pool) = db_connection().await {
|
if let Ok(pool) = db_connection().await {
|
||||||
if let Err(e) = add_user(
|
if let Err(e) = add_user(
|
||||||
&pool,
|
&pool,
|
||||||
&user.email,
|
&user.email.clone().unwrap(),
|
||||||
&user.username,
|
&user.username,
|
||||||
&hashed_password,
|
&hashed_password,
|
||||||
&user.group_id,
|
&user.group_id.unwrap(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@ -39,3 +38,37 @@ pub async fn user(user: web::Json<User>) -> impl Responder {
|
|||||||
|
|
||||||
format!("User {} added", user.username)
|
format!("User {} added", user.username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/api/user/{id}")]
|
||||||
|
pub async fn get_user(id: web::Path<i64>) -> impl Responder {
|
||||||
|
if let Ok(pool) = db_connection().await {
|
||||||
|
match get_users(&pool, Some(*id)).await {
|
||||||
|
Ok(r) => {
|
||||||
|
return web::Json(r);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
return web::Json(vec![]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
web::Json(vec![])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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!";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
"Login failed!"
|
||||||
|
}
|
||||||
|
58
src/api/utils.rs
Normal file
58
src/api/utils.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use sha_crypt::{sha512_simple, Sha512Params};
|
||||||
|
use simplelog::*;
|
||||||
|
|
||||||
|
use crate::api::{
|
||||||
|
args_parse::Args,
|
||||||
|
handles::{add_user, db_connection, db_init},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn run_args(args: Args) -> Result<(), i32> {
|
||||||
|
if !args.init && args.listen.is_none() && args.username.is_none() {
|
||||||
|
error!("Wrong number of arguments! Run ffpapi --help for more information.");
|
||||||
|
|
||||||
|
return Err(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if args.init {
|
||||||
|
if let Err(e) = db_init().await {
|
||||||
|
panic!("{e}");
|
||||||
|
};
|
||||||
|
|
||||||
|
return Err(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(username) = args.username {
|
||||||
|
if args.email.is_none() || args.password.is_none() {
|
||||||
|
error!("Email/password missing!");
|
||||||
|
return Err(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = Sha512Params::new(10_000).expect("RandomError!");
|
||||||
|
|
||||||
|
let hashed_password =
|
||||||
|
sha512_simple(&args.password.unwrap(), ¶ms).expect("Should not fail");
|
||||||
|
|
||||||
|
match db_connection().await {
|
||||||
|
Ok(pool) => {
|
||||||
|
if let Err(e) =
|
||||||
|
add_user(&pool, &args.email.unwrap(), &username, &hashed_password, &1).await
|
||||||
|
{
|
||||||
|
pool.close().await;
|
||||||
|
error!("{e}");
|
||||||
|
return Err(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
pool.close().await;
|
||||||
|
info!("Create admin user \"{username}\" done...");
|
||||||
|
|
||||||
|
return Err(0);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Add admin user failed! Did you init the database?");
|
||||||
|
panic!("{e}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -2,95 +2,31 @@ use std::process::exit;
|
|||||||
|
|
||||||
use actix_web::{App, HttpServer};
|
use actix_web::{App, HttpServer};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use sha_crypt::{sha512_simple, Sha512Params};
|
|
||||||
use simplelog::*;
|
use simplelog::*;
|
||||||
|
|
||||||
use ffplayout_engine::{
|
use ffplayout_engine::{
|
||||||
api::{
|
api::{
|
||||||
handles::{add_user, db_connection, db_init},
|
args_parse::Args,
|
||||||
routes::user,
|
routes::{get_user, login, user},
|
||||||
|
utils::run_args,
|
||||||
},
|
},
|
||||||
utils::{init_logging, GlobalConfig},
|
utils::{init_logging, GlobalConfig},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
|
||||||
#[clap(version,
|
|
||||||
name = "ffpapi",
|
|
||||||
version = "0.1.0",
|
|
||||||
about = "ffplayout REST API",
|
|
||||||
long_about = None)]
|
|
||||||
pub struct Args {
|
|
||||||
#[clap(short, long, help = "Listen on IP:PORT, like: 127.0.0.1:8080")]
|
|
||||||
pub listen: Option<String>,
|
|
||||||
|
|
||||||
#[clap(short, long, help = "Initialize Database")]
|
|
||||||
pub init: bool,
|
|
||||||
|
|
||||||
#[clap(short, long, help = "Create admin user")]
|
|
||||||
pub username: Option<String>,
|
|
||||||
|
|
||||||
#[clap(short, long, help = "Admin email")]
|
|
||||||
pub email: Option<String>,
|
|
||||||
|
|
||||||
#[clap(short, long, help = "Admin password")]
|
|
||||||
pub password: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
if !args.init && args.listen.is_none() && args.username.is_none() {
|
|
||||||
error!("Wrong number of arguments! Run ffpapi --help for more information.");
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut config = GlobalConfig::new(None);
|
let mut config = GlobalConfig::new(None);
|
||||||
config.mail.recipient = String::new();
|
config.mail.recipient = String::new();
|
||||||
config.logging.log_to_file = false;
|
config.logging.log_to_file = false;
|
||||||
|
config.logging.timestamp = false;
|
||||||
|
|
||||||
let logging = init_logging(&config, None, None);
|
let logging = init_logging(&config, None, None);
|
||||||
CombinedLogger::init(logging).unwrap();
|
CombinedLogger::init(logging).unwrap();
|
||||||
|
|
||||||
if args.init {
|
if let Err(c) = run_args(args.clone()).await {
|
||||||
if let Err(e) = db_init().await {
|
exit(c);
|
||||||
panic!("{e}");
|
|
||||||
};
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(username) = args.username {
|
|
||||||
if args.email.is_none() || args.password.is_none() {
|
|
||||||
error!("Email/password missing!");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = Sha512Params::new(10_000).expect("RandomError!");
|
|
||||||
|
|
||||||
let hashed_password =
|
|
||||||
sha512_simple(&args.password.unwrap(), ¶ms).expect("Should not fail");
|
|
||||||
|
|
||||||
match db_connection().await {
|
|
||||||
Ok(pool) => {
|
|
||||||
if let Err(e) =
|
|
||||||
add_user(&pool, &args.email.unwrap(), &username, &hashed_password, &1).await
|
|
||||||
{
|
|
||||||
pool.close().await;
|
|
||||||
error!("{e}");
|
|
||||||
exit(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
pool.close().await;
|
|
||||||
info!("Create admin user \"{username}\" done...");
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
panic!("{e}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(conn) = args.listen {
|
if let Some(conn) = args.listen {
|
||||||
@ -99,11 +35,13 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let port = ip_port[1].parse::<u16>().unwrap();
|
let port = ip_port[1].parse::<u16>().unwrap();
|
||||||
info!("running ffplayout API, listen on {conn}");
|
info!("running ffplayout API, listen on {conn}");
|
||||||
|
|
||||||
HttpServer::new(|| App::new().service(user))
|
HttpServer::new(|| App::new().service(get_user).service(login).service(user))
|
||||||
.bind((addr, port))?
|
.bind((addr, port))?
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
panic!("Run ffpapi with listen parameter!")
|
error!("Run ffpapi with listen parameter!");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user