get and patch settngs

This commit is contained in:
jb-alvarado 2022-06-12 22:37:29 +02:00
parent ca5ac810be
commit c4d599ff31
4 changed files with 76 additions and 19 deletions

View File

@ -1,11 +1,12 @@
use std::path::Path;
use actix_web::web;
use faccess::PathExt;
use rand::{distributions::Alphanumeric, Rng};
use simplelog::*;
use sqlx::{migrate::MigrateDatabase, sqlite::SqliteQueryResult, Pool, Sqlite, SqlitePool};
use crate::api::models::User;
use crate::api::models::{Settings, User};
use crate::api::utils::GlobalSettings;
#[derive(Debug, sqlx::FromRow)]
@ -46,7 +47,7 @@ async fn cretea_schema() -> Result<SqliteQueryResult, sqlx::Error> {
id INTEGER PRIMARY KEY AUTOINCREMENT,
channel_name TEXT NOT NULL,
preview_url TEXT NOT NULL,
settings_path TEXT NOT NULL,
config_path TEXT NOT NULL,
extra_extensions TEXT NOT NULL,
UNIQUE(channel_name)
);
@ -93,7 +94,7 @@ pub async fn db_init() -> Result<&'static str, Box<dyn std::error::Error>> {
END;
INSERT INTO global(secret) VALUES($1);
INSERT INTO roles(name) VALUES('admin'), ('user'), ('guest');
INSERT INTO settings(channel_name, preview_url, settings_path, extra_extensions)
INSERT INTO settings(channel_name, preview_url, config_path, extra_extensions)
VALUES('Channel 1', 'http://localhost/live/preview.m3u8',
'/etc/ffplayout/ffplayout.yml', '.jpg,.jpeg,.png');";
sqlx::query(query).bind(secret).execute(&instances).await?;
@ -118,6 +119,36 @@ pub async fn db_global() -> Result<GlobalSettings, sqlx::Error> {
Ok(result)
}
pub async fn db_get_settings(id: &i64) -> Result<Settings, sqlx::Error> {
let conn = db_connection().await?;
let query = "SELECT * FROM settings WHERE id = $1";
let result: Settings = sqlx::query_as(query).bind(id).fetch_one(&conn).await?;
conn.close().await;
println!("{:#?}", result);
Ok(result)
}
pub async fn db_update_settings(
id: i64,
s: web::Json<Settings>,
) -> Result<SqliteQueryResult, sqlx::Error> {
let conn = db_connection().await?;
let query = "UPDATE settings SET channel_name = $2, preview_url = $3, config_path = $4, extra_extensions = $5 WHERE id = $1";
let result: SqliteQueryResult = sqlx::query(query)
.bind(id)
.bind(s.channel_name.clone())
.bind(s.preview_url.clone())
.bind(s.config_path.clone())
.bind(s.extra_extensions.clone())
.execute(&conn)
.await?;
conn.close().await;
Ok(result)
}
pub async fn db_role(id: &i64) -> Result<String, sqlx::Error> {
let conn = db_connection().await?;
let query = "SELECT name FROM roles WHERE id = $1";

View File

@ -39,12 +39,13 @@ impl LoginUser {
#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
pub struct Settings {
#[serde(skip_deserializing)]
pub id: i64,
pub channel_name: String,
pub preview_url: String,
pub settings_path: String,
pub config_path: String,
pub extra_extensions: String,
#[sqlx(default)]
#[serde(skip_serializing)]
#[serde(skip_serializing, skip_deserializing)]
pub secret: String,
}

View File

@ -1,4 +1,4 @@
use actix_web::{get, http::StatusCode, post, put, web, Responder};
use actix_web::{get, http::StatusCode, patch, post, put, web, Responder};
use actix_web_grants::proc_macro::has_permissions;
use argon2::{
password_hash::{rand_core::OsRng, PasswordHash, SaltString},
@ -10,8 +10,8 @@ use simplelog::*;
use crate::api::{
auth::{create_jwt, Claims},
errors::ServiceError,
handles::{db_login, db_role, db_update_user},
models::{LoginUser, User},
handles::{db_get_settings, db_login, db_role, db_update_settings, db_update_user},
models::{LoginUser, Settings, User},
};
#[derive(Serialize)]
@ -21,24 +21,48 @@ struct ResponseObj<T> {
data: Option<T>,
}
/// curl -X GET http://127.0.0.1:8080/api/settings -H "Authorization: Bearer <TOKEN>"
#[get("/settings")]
/// curl -X GET http://127.0.0.1:8080/api/settings/1 -H "Authorization: Bearer <TOKEN>"
#[get("/settings/{id}")]
#[has_permissions("admin", "user")]
async fn get_settings(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
if let Ok(settings) = db_get_settings(&id).await {
return Ok(web::Json(ResponseObj {
message: format!("Settings from {}", settings.channel_name),
status: 200,
data: Some(settings),
}));
}
Err(ServiceError::InternalServerError)
}
/// curl -X PATCH http://127.0.0.1:8080/api/settings/1 -H "Content-Type: application/json" \
/// --data '{"id":1,"channel_name":"Channel 1","preview_url":"http://localhost/live/stream.m3u8", \
/// "config_path":"/etc/ffplayout/ffplayout.yml","extra_extensions":".jpg,.jpeg,.png"}' \
/// -H "Authorization: Bearer <TOKEN>"
#[patch("/settings/{id}")]
#[has_permissions("admin")]
async fn settings(user: web::ReqData<LoginUser>) -> Result<impl Responder, ServiceError> {
println!("{:?}", user);
Ok("Hello from settings!")
async fn patch_settings(
id: web::Path<i64>,
data: web::Json<Settings>,
) -> Result<impl Responder, ServiceError> {
if db_update_settings(*id, data).await.is_ok() {
return Ok("Update Success");
};
Err(ServiceError::InternalServerError)
}
/// curl -X PUT http://localhost:8080/api/user/1 --header 'Content-Type: application/json' \
/// --data '{"email": "<EMAIL>", "password": "<PASS>"}' --header 'Authorization: <TOKEN>'
#[put("/user/{user_id}")]
#[has_permissions("admin")]
#[put("/user/{id}")]
#[has_permissions("admin", "user")]
async fn update_user(
user_id: web::Path<i64>,
id: web::Path<i64>,
user: web::ReqData<LoginUser>,
data: web::Json<User>,
) -> Result<impl Responder, ServiceError> {
if user_id.into_inner() == user.id {
if id.into_inner() == user.id {
let mut fields = String::new();
if let Some(email) = data.email.clone() {

View File

@ -13,7 +13,7 @@ use ffplayout_engine::{
args_parse::Args,
auth,
models::LoginUser,
routes::{login, settings, update_user},
routes::{get_settings, login, patch_settings, update_user},
utils::{init_config, run_args},
},
utils::{init_logging, GlobalConfig},
@ -62,7 +62,8 @@ async fn main() -> std::io::Result<()> {
.service(
web::scope("/api")
.wrap(auth)
.service(settings)
.service(get_settings)
.service(patch_settings)
.service(update_user),
)
})