add more routes, channel id to presets, no full paths, change email to mail
This commit is contained in:
parent
ecccc86264
commit
7352735f15
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1027,7 +1027,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-api"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
dependencies = [
|
||||
"actix-multipart",
|
||||
"actix-web",
|
||||
|
13
Cargo.toml
13
Cargo.toml
@ -1,15 +1,6 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"ffplayout-api",
|
||||
"ffplayout-engine",
|
||||
"lib",
|
||||
]
|
||||
|
||||
default-members = [
|
||||
"ffplayout-api",
|
||||
"ffplayout-engine",
|
||||
]
|
||||
members = ["ffplayout-api", "ffplayout-engine", "lib"]
|
||||
default-members = ["ffplayout-api", "ffplayout-engine"]
|
||||
|
||||
[profile.release]
|
||||
opt-level = 3
|
||||
|
15
docs/api.md
15
docs/api.md
@ -32,6 +32,9 @@ From here on all request **must** contain the authorization header:\
|
||||
|
||||
#### User
|
||||
|
||||
- **GET** `/api/user`\
|
||||
Get current user, response is in JSON format
|
||||
|
||||
- **PUT** `/api/user/{user id}`\
|
||||
JSON Data: `{"email": "<EMAIL>", "password": "<PASS>"}`
|
||||
|
||||
@ -48,8 +51,10 @@ JSON Data:
|
||||
|
||||
#### API Settings
|
||||
|
||||
- **GET** `/api/settings`\
|
||||
Response is in JSON format
|
||||
|
||||
- **GET** `/api/settings/{id}`\
|
||||
HEADER:
|
||||
Response is in JSON format
|
||||
|
||||
- **PATCH** `/api/settings/{id}`\
|
||||
@ -157,11 +162,17 @@ Response is in JSON format
|
||||
- **DELETE** `/api/playlist/{id}/2022-06-20`\
|
||||
Response is in TEXT format
|
||||
|
||||
#### File Operations
|
||||
#### Log File
|
||||
|
||||
- **GET** `/api/file/{id}/browse/`\
|
||||
Response is in JSON format
|
||||
|
||||
|
||||
#### File Operations
|
||||
|
||||
- **GET** `/api/log/{id}(/{date})`\
|
||||
Response is in TEXT format
|
||||
|
||||
- **POST** `/api/file/{id}/move/`\
|
||||
JSON Data: `{"source": "<SOURCE>", "target": "<TARGET>"}`\
|
||||
Response is in JSON format
|
||||
|
@ -4,7 +4,7 @@ description = "Rest API for ffplayout"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Jonathan Baecker jonbae77@gmail.com"]
|
||||
readme = "README.md"
|
||||
version = "0.3.2"
|
||||
version = "0.3.3"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
@ -12,7 +12,7 @@ ffpapi -i
|
||||
Then add an admin user:
|
||||
|
||||
```BASH
|
||||
ffpapi -u <USERNAME> -p <PASSWORD> -e <EMAIL ADDRESS>
|
||||
ffpapi -u <USERNAME> -p <PASSWORD> -m <MAIL ADDRESS>
|
||||
```
|
||||
|
||||
Then run the API thru the systemd service, or like:
|
||||
|
@ -15,11 +15,11 @@ use utils::{
|
||||
auth, db_path, init_config,
|
||||
models::LoginUser,
|
||||
routes::{
|
||||
add_preset, add_user, del_playlist, file_browser, gen_playlist, get_playlist,
|
||||
get_playout_config, get_presets, get_settings, jump_to_last, jump_to_next, login,
|
||||
media_current, media_last, media_next, move_rename, patch_settings, process_control,
|
||||
remove, reset_playout, save_file, save_playlist, send_text_message, update_playout_config,
|
||||
update_preset, update_user,
|
||||
add_preset, add_user, del_playlist, file_browser, gen_playlist, get_all_settings, get_log,
|
||||
get_playlist, get_playout_config, get_presets, get_settings, get_user, jump_to_last,
|
||||
jump_to_next, login, media_current, media_last, media_next, move_rename, patch_settings,
|
||||
process_control, remove, reset_playout, save_file, save_playlist, send_text_message,
|
||||
update_playout_config, update_preset, update_user,
|
||||
},
|
||||
run_args, Role,
|
||||
};
|
||||
@ -77,12 +77,14 @@ async fn main() -> std::io::Result<()> {
|
||||
web::scope("/api")
|
||||
.wrap(auth)
|
||||
.service(add_user)
|
||||
.service(get_user)
|
||||
.service(get_playout_config)
|
||||
.service(update_playout_config)
|
||||
.service(add_preset)
|
||||
.service(get_presets)
|
||||
.service(update_preset)
|
||||
.service(get_settings)
|
||||
.service(get_all_settings)
|
||||
.service(patch_settings)
|
||||
.service(update_user)
|
||||
.service(send_text_message)
|
||||
@ -97,6 +99,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(save_playlist)
|
||||
.service(gen_playlist)
|
||||
.service(del_playlist)
|
||||
.service(get_log)
|
||||
.service(file_browser)
|
||||
.service(move_rename)
|
||||
.service(remove)
|
||||
|
@ -17,8 +17,8 @@ pub struct Args {
|
||||
#[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 mail address")]
|
||||
pub mail: Option<String>,
|
||||
|
||||
#[clap(short, long, help = "Admin password")]
|
||||
pub password: Option<String>,
|
||||
|
@ -62,22 +62,22 @@ pub async fn browser(id: i64, path_obj: &PathObject) -> Result<PathObject, Servi
|
||||
|
||||
for path in paths {
|
||||
let file_path = path.path().to_owned();
|
||||
let path_str = file_path.display().to_string();
|
||||
let path = file_path.clone();
|
||||
|
||||
// ignore hidden files/folders on unix
|
||||
if path_str.contains("/.") {
|
||||
if path.display().to_string().contains("/.") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if file_path.is_dir() {
|
||||
if let Some(ref mut folders) = obj.folders {
|
||||
folders.push(path_str);
|
||||
folders.push(path.file_name().unwrap().to_string_lossy().to_string());
|
||||
}
|
||||
} else if file_path.is_file() {
|
||||
if let Some(ext) = file_extension(&file_path) {
|
||||
if extensions.contains(&ext.to_string().to_lowercase()) {
|
||||
if let Some(ref mut files) = obj.files {
|
||||
files.push(path_str);
|
||||
files.push(path.file_name().unwrap().to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ async fn create_schema() -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
CREATE TABLE IF NOT EXISTS presets
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
channel_id INTEGER,
|
||||
name TEXT NOT NULL,
|
||||
text TEXT NOT NULL,
|
||||
x TEXT NOT NULL,
|
||||
@ -56,19 +57,20 @@ async fn create_schema() -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
preview_url TEXT NOT NULL,
|
||||
config_path TEXT NOT NULL,
|
||||
extra_extensions TEXT NOT NULL,
|
||||
service TEXT NOT NULL,
|
||||
timezone TEXT NOT NULL,
|
||||
service TEXT NOT NULL,
|
||||
UNIQUE(channel_name)
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS user
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
email TEXT NOT NULL,
|
||||
mail TEXT NOT NULL,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
salt TEXT NOT NULL,
|
||||
role_id INTEGER NOT NULL DEFAULT 2,
|
||||
FOREIGN KEY (role_id) REFERENCES roles (id) ON UPDATE SET NULL ON DELETE SET NULL,
|
||||
UNIQUE(email, username)
|
||||
UNIQUE(mail, username)
|
||||
);";
|
||||
let result = sqlx::query(query).execute(&conn).await;
|
||||
conn.close().await;
|
||||
@ -101,17 +103,17 @@ pub async fn db_init() -> Result<&'static str, Box<dyn std::error::Error>> {
|
||||
SELECT RAISE(FAIL, 'Database is already init!');
|
||||
END;
|
||||
INSERT INTO global(secret) VALUES($1);
|
||||
INSERT INTO presets(name, text, x, y, fontsize, line_spacing, fontcolor, alpha, box, boxcolor, boxborderw)
|
||||
VALUES('Default', 'Wellcome to ffplayout messenger!', '(w-text_w)/2', '(h-text_h)/2', '24', '4', '#ffffff@0xff', '1.0', '0', '#000000@0x80', '4'),
|
||||
('Empty Text', '', '0', '0', '24', '4', '#000000', '0', '0', '#000000', '0'),
|
||||
('Bottom Text fade in', 'The upcoming event will be delayed by a few minutes.', '(w-text_w)/2', '(h-line_h)*0.9', '24', '4', '#ffffff',
|
||||
INSERT INTO presets(channel_id, name, text, x, y, fontsize, line_spacing, fontcolor, alpha, box, boxcolor, boxborderw)
|
||||
VALUES('1', 'Default', 'Wellcome to ffplayout messenger!', '(w-text_w)/2', '(h-text_h)/2', '24', '4', '#ffffff@0xff', '1.0', '0', '#000000@0x80', '4'),
|
||||
('1', 'Empty Text', '', '0', '0', '24', '4', '#000000', '0', '0', '#000000', '0'),
|
||||
('1', 'Bottom Text fade in', 'The upcoming event will be delayed by a few minutes.', '(w-text_w)/2', '(h-line_h)*0.9', '24', '4', '#ffffff',
|
||||
'ifnot(ld(1),st(1,t));if(lt(t,ld(1)+1),0,if(lt(t,ld(1)+2),(t-(ld(1)+1))/1,if(lt(t,ld(1)+8),1,if(lt(t,ld(1)+9),(1-(t-(ld(1)+8)))/1,0))))', '1', '#000000@0x80', '4'),
|
||||
('Scrolling Text', 'We have a very important announcement to make.', 'ifnot(ld(1),st(1,t));if(lt(t,ld(1)+1),w+4,w-w/12*mod(t-ld(1),12*(w+tw)/w))', '(h-line_h)*0.9',
|
||||
('1', 'Scrolling Text', 'We have a very important announcement to make.', 'ifnot(ld(1),st(1,t));if(lt(t,ld(1)+1),w+4,w-w/12*mod(t-ld(1),12*(w+tw)/w))', '(h-line_h)*0.9',
|
||||
'24', '4', '#ffffff', '1.0', '1', '#000000@0x80', '4');
|
||||
INSERT INTO roles(name) VALUES('admin'), ('user'), ('guest');
|
||||
INSERT INTO settings(channel_name, preview_url, config_path, extra_extensions, service)
|
||||
INSERT INTO settings(channel_name, preview_url, config_path, extra_extensions, timezone, service)
|
||||
VALUES('Channel 1', 'http://localhost/live/preview.m3u8',
|
||||
'/etc/ffplayout/ffplayout.yml', '.jpg,.jpeg,.png', 'ffplayout.service');";
|
||||
'/etc/ffplayout/ffplayout.yml', '.jpg,.jpeg,.png', 'UTC', 'ffplayout.service');";
|
||||
sqlx::query(query).bind(secret).execute(&instances).await?;
|
||||
instances.close().await;
|
||||
|
||||
@ -143,6 +145,15 @@ pub async fn db_get_settings(id: &i64) -> Result<Settings, sqlx::Error> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn db_get_all_settings() -> Result<Vec<Settings>, sqlx::Error> {
|
||||
let conn = db_connection().await?;
|
||||
let query = "SELECT * FROM settings";
|
||||
let result: Vec<Settings> = sqlx::query_as(query).fetch_all(&conn).await?;
|
||||
conn.close().await;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn db_update_settings(
|
||||
id: i64,
|
||||
settings: Settings,
|
||||
@ -174,7 +185,16 @@ pub async fn db_role(id: &i64) -> Result<String, sqlx::Error> {
|
||||
|
||||
pub async fn db_login(user: &str) -> Result<User, sqlx::Error> {
|
||||
let conn = db_connection().await?;
|
||||
let query = "SELECT id, email, username, password, salt, role_id FROM user WHERE username = $1";
|
||||
let query = "SELECT id, mail, username, password, salt, role_id FROM user WHERE username = $1";
|
||||
let result: User = sqlx::query_as(query).bind(user).fetch_one(&conn).await?;
|
||||
conn.close().await;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn db_get_user(user: &str) -> Result<User, sqlx::Error> {
|
||||
let conn = db_connection().await?;
|
||||
let query = "SELECT id, mail, username, role_id FROM user WHERE username = $1";
|
||||
let result: User = sqlx::query_as(query).bind(user).fetch_one(&conn).await?;
|
||||
conn.close().await;
|
||||
|
||||
@ -189,9 +209,9 @@ pub async fn db_add_user(user: User) -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
.unwrap();
|
||||
|
||||
let query =
|
||||
"INSERT INTO user (email, username, password, salt, role_id) VALUES($1, $2, $3, $4, $5)";
|
||||
"INSERT INTO user (mail, username, password, salt, role_id) VALUES($1, $2, $3, $4, $5)";
|
||||
let result = sqlx::query(query)
|
||||
.bind(user.email)
|
||||
.bind(user.mail)
|
||||
.bind(user.username)
|
||||
.bind(password_hash.to_string())
|
||||
.bind(salt.to_string())
|
||||
@ -212,10 +232,10 @@ pub async fn db_update_user(id: i64, fields: String) -> Result<SqliteQueryResult
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn db_get_presets() -> Result<Vec<TextPreset>, sqlx::Error> {
|
||||
pub async fn db_get_presets(id: i64) -> Result<Vec<TextPreset>, sqlx::Error> {
|
||||
let conn = db_connection().await?;
|
||||
let query = "SELECT * FROM presets";
|
||||
let result: Vec<TextPreset> = sqlx::query_as(query).fetch_all(&conn).await?;
|
||||
let query = "SELECT * FROM presets WHERE channel_id = $1";
|
||||
let result: Vec<TextPreset> = sqlx::query_as(query).bind(id).fetch_all(&conn).await?;
|
||||
conn.close().await;
|
||||
|
||||
Ok(result)
|
||||
@ -252,9 +272,10 @@ pub async fn db_update_preset(
|
||||
pub async fn db_add_preset(preset: TextPreset) -> Result<SqliteQueryResult, sqlx::Error> {
|
||||
let conn = db_connection().await?;
|
||||
let query =
|
||||
"INSERT INTO presets (name, text, x, y, fontsize, line_spacing, fontcolor, alpha, box, boxcolor, boxborderw)
|
||||
VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)";
|
||||
"INSERT INTO presets (channel_id, name, text, x, y, fontsize, line_spacing, fontcolor, alpha, box, boxcolor, boxborderw)
|
||||
VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)";
|
||||
let result: SqliteQueryResult = sqlx::query(query)
|
||||
.bind(preset.channel_id)
|
||||
.bind(preset.name)
|
||||
.bind(preset.text)
|
||||
.bind(preset.x)
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::{
|
||||
error::Error,
|
||||
fs::File,
|
||||
fs::{self, File},
|
||||
io::{stdin, stdout, Write},
|
||||
path::Path,
|
||||
};
|
||||
@ -129,32 +129,32 @@ pub async fn run_args(mut args: Args) -> Result<(), i32> {
|
||||
|
||||
args.password = password.ok();
|
||||
|
||||
let mut email = String::new();
|
||||
print!("EMail: ");
|
||||
let mut mail = String::new();
|
||||
print!("Mail: ");
|
||||
stdout().flush().unwrap();
|
||||
|
||||
stdin()
|
||||
.read_line(&mut email)
|
||||
.read_line(&mut mail)
|
||||
.expect("Did not enter a correct name?");
|
||||
if let Some('\n') = email.chars().next_back() {
|
||||
email.pop();
|
||||
if let Some('\n') = mail.chars().next_back() {
|
||||
mail.pop();
|
||||
}
|
||||
if let Some('\r') = email.chars().next_back() {
|
||||
email.pop();
|
||||
if let Some('\r') = mail.chars().next_back() {
|
||||
mail.pop();
|
||||
}
|
||||
|
||||
args.email = Some(email);
|
||||
args.mail = Some(mail);
|
||||
}
|
||||
|
||||
if let Some(username) = args.username {
|
||||
if args.email.is_none() || args.password.is_none() {
|
||||
error!("Email/password missing!");
|
||||
if args.mail.is_none() || args.password.is_none() {
|
||||
error!("Mail/password missing!");
|
||||
return Err(1);
|
||||
}
|
||||
|
||||
let user = User {
|
||||
id: 0,
|
||||
email: Some(args.email.unwrap()),
|
||||
mail: Some(args.mail.unwrap()),
|
||||
username: username.clone(),
|
||||
password: args.password.unwrap(),
|
||||
salt: None,
|
||||
@ -193,3 +193,30 @@ pub async fn playout_config(channel_id: &i64) -> Result<(PlayoutConfig, Settings
|
||||
"Error in getting config!".to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn read_log_file(channel_id: &i64, date: &str) -> Result<String, ServiceError> {
|
||||
if let Ok(settings) = db_get_settings(channel_id).await {
|
||||
let mut date_str = "".to_string();
|
||||
|
||||
if !date.is_empty() {
|
||||
date_str.push('.');
|
||||
date_str.push_str(date);
|
||||
}
|
||||
|
||||
if let Ok(config) = read_playout_config(&settings.config_path) {
|
||||
let mut log_path = Path::new(&config.logging.log_path)
|
||||
.join("ffplayout.log")
|
||||
.display()
|
||||
.to_string();
|
||||
log_path.push_str(&date_str);
|
||||
|
||||
let file = fs::read_to_string(log_path)?;
|
||||
|
||||
return Ok(file);
|
||||
}
|
||||
}
|
||||
|
||||
Err(ServiceError::BadRequest(
|
||||
"Requested log file not exists, or not readable.".to_string(),
|
||||
))
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ pub struct User {
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i64,
|
||||
#[sqlx(default)]
|
||||
pub email: Option<String>,
|
||||
pub mail: Option<String>,
|
||||
pub username: String,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing, default = "empty_string")]
|
||||
@ -41,6 +41,7 @@ pub struct TextPreset {
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i64,
|
||||
pub channel_id: i64,
|
||||
#[serde(skip_deserializing)]
|
||||
pub name: String,
|
||||
pub text: String,
|
||||
@ -63,6 +64,7 @@ pub struct Settings {
|
||||
pub preview_url: String,
|
||||
pub config_path: String,
|
||||
pub extra_extensions: String,
|
||||
pub timezone: String,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing, skip_deserializing)]
|
||||
pub secret: String,
|
||||
|
@ -16,12 +16,12 @@ use crate::utils::{
|
||||
errors::ServiceError,
|
||||
files::{browser, remove_file_or_folder, rename_file, upload, MoveObject, PathObject},
|
||||
handles::{
|
||||
db_add_preset, db_add_user, db_get_presets, db_get_settings, db_login, db_role,
|
||||
db_update_preset, db_update_settings, db_update_user,
|
||||
db_add_preset, db_add_user, db_get_all_settings, db_get_presets, db_get_settings,
|
||||
db_get_user, db_login, db_role, db_update_preset, db_update_settings, db_update_user,
|
||||
},
|
||||
models::{LoginUser, Settings, TextPreset, User},
|
||||
playlist::{delete_playlist, generate_playlist, read_playlist, write_playlist},
|
||||
read_playout_config, Role,
|
||||
read_log_file, read_playout_config, Role,
|
||||
};
|
||||
use ffplayout_lib::utils::{JsonPlaylist, PlayoutConfig};
|
||||
|
||||
@ -32,6 +32,12 @@ struct ResponseObj<T> {
|
||||
data: Option<T>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct UserObj<T> {
|
||||
message: String,
|
||||
user: Option<T>,
|
||||
}
|
||||
|
||||
/// curl -X POST http://127.0.0.1:8080/auth/login/ -H "Content-Type: application/json" \
|
||||
/// -d '{"username": "<USER>", "password": "<PASS>" }'
|
||||
#[post("/auth/login/")]
|
||||
@ -58,19 +64,17 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
|
||||
|
||||
info!("user {} login, with role: {role}", credentials.username);
|
||||
|
||||
web::Json(ResponseObj {
|
||||
web::Json(UserObj {
|
||||
message: "login correct!".into(),
|
||||
status: 200,
|
||||
data: Some(user),
|
||||
user: Some(user),
|
||||
})
|
||||
.customize()
|
||||
.with_status(StatusCode::OK)
|
||||
} else {
|
||||
error!("Wrong password for {}!", credentials.username);
|
||||
web::Json(ResponseObj {
|
||||
web::Json(UserObj {
|
||||
message: "Wrong password!".into(),
|
||||
status: 403,
|
||||
data: None,
|
||||
user: None,
|
||||
})
|
||||
.customize()
|
||||
.with_status(StatusCode::FORBIDDEN)
|
||||
@ -78,10 +82,9 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Login {} failed! {e}", credentials.username);
|
||||
return web::Json(ResponseObj {
|
||||
return web::Json(UserObj {
|
||||
message: format!("Login {} failed!", credentials.username),
|
||||
status: 400,
|
||||
data: None,
|
||||
user: None,
|
||||
})
|
||||
.customize()
|
||||
.with_status(StatusCode::BAD_REQUEST);
|
||||
@ -89,8 +92,22 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
|
||||
}
|
||||
}
|
||||
|
||||
/// curl -X GET 'http://localhost:8080/api/user' --header 'Content-Type: application/json' \
|
||||
/// --header 'Authorization: Bearer <TOKEN>'
|
||||
#[get("/user")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn get_user(user: web::ReqData<LoginUser>) -> Result<impl Responder, ServiceError> {
|
||||
match db_get_user(&user.username).await {
|
||||
Ok(user) => Ok(web::Json(user)),
|
||||
Err(e) => {
|
||||
error!("{e}");
|
||||
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>'
|
||||
/// --data '{"mail": "<MAIL>", "password": "<PASS>"}' --header 'Authorization: <TOKEN>'
|
||||
#[put("/user/{id}")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn update_user(
|
||||
@ -101,8 +118,8 @@ async fn update_user(
|
||||
if id.into_inner() == user.id {
|
||||
let mut fields = String::new();
|
||||
|
||||
if let Some(email) = data.email.clone() {
|
||||
fields.push_str(format!("email = '{email}'").as_str());
|
||||
if let Some(mail) = data.mail.clone() {
|
||||
fields.push_str(format!("mail = '{mail}'").as_str());
|
||||
}
|
||||
|
||||
if !data.password.is_empty() {
|
||||
@ -129,7 +146,7 @@ async fn update_user(
|
||||
}
|
||||
|
||||
/// curl -X POST 'http://localhost:8080/api/user/' --header 'Content-Type: application/json' \
|
||||
/// -d '{"email": "<EMAIL>", "username": "<USER>", "password": "<PASS>", "role_id": 1}' \
|
||||
/// -d '{"mail": "<MAIL>", "username": "<USER>", "password": "<PASS>", "role_id": 1}' \
|
||||
/// --header 'Authorization: Bearer <TOKEN>'
|
||||
#[post("/user/")]
|
||||
#[has_any_role("Role::Admin", type = "Role")]
|
||||
@ -148,11 +165,18 @@ async fn add_user(data: web::Json<User>) -> Result<impl Responder, ServiceError>
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
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),
|
||||
}));
|
||||
return Ok(web::Json(settings));
|
||||
}
|
||||
|
||||
Err(ServiceError::InternalServerError)
|
||||
}
|
||||
|
||||
/// curl -X GET http://127.0.0.1:8080/api/settings -H "Authorization: Bearer <TOKEN>"
|
||||
#[get("/settings")]
|
||||
#[has_any_role("Role::Admin", type = "Role")]
|
||||
async fn get_all_settings() -> Result<impl Responder, ServiceError> {
|
||||
if let Ok(settings) = db_get_all_settings().await {
|
||||
return Ok(web::Json(settings));
|
||||
}
|
||||
|
||||
Err(ServiceError::InternalServerError)
|
||||
@ -217,11 +241,11 @@ async fn update_playout_config(
|
||||
}
|
||||
|
||||
/// curl -X GET http://localhost:8080/api/presets/ --header 'Content-Type: application/json' \
|
||||
/// --data '{"email": "<EMAIL>", "password": "<PASS>"}' --header 'Authorization: <TOKEN>'
|
||||
#[get("/presets/")]
|
||||
/// --data '{"mail": "<MAIL>", "password": "<PASS>"}' --header 'Authorization: <TOKEN>'
|
||||
#[get("/presets/{id}")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn get_presets() -> Result<impl Responder, ServiceError> {
|
||||
if let Ok(presets) = db_get_presets().await {
|
||||
async fn get_presets(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
|
||||
if let Ok(presets) = db_get_presets(*id).await {
|
||||
return Ok(web::Json(presets));
|
||||
}
|
||||
|
||||
@ -423,6 +447,21 @@ pub async fn del_playlist(
|
||||
}
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------------------------------
|
||||
/// read log file
|
||||
///
|
||||
/// ----------------------------------------------------------------------------
|
||||
|
||||
#[get("/log/{req:.*}")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
pub async fn get_log(req: web::Path<String>) -> Result<impl Responder, ServiceError> {
|
||||
let mut segments = req.split('/');
|
||||
let id: i64 = segments.next().unwrap_or_default().parse().unwrap_or(0);
|
||||
let date = segments.next().unwrap_or_default();
|
||||
|
||||
read_log_file(&id, date).await
|
||||
}
|
||||
|
||||
/// ----------------------------------------------------------------------------
|
||||
/// file operations
|
||||
///
|
||||
|
@ -43,7 +43,7 @@ pub fn send_mail(cfg: &PlayoutConfig, msg: String) {
|
||||
message = message.to(r.parse().unwrap());
|
||||
}
|
||||
|
||||
if let Ok(email) = message.body(clean_string(&msg)) {
|
||||
if let Ok(mail) = message.body(clean_string(&msg)) {
|
||||
let credentials =
|
||||
Credentials::new(cfg.mail.sender_addr.clone(), cfg.mail.sender_pass.clone());
|
||||
|
||||
@ -55,9 +55,9 @@ pub fn send_mail(cfg: &PlayoutConfig, msg: String) {
|
||||
|
||||
let mailer = transporter.unwrap().credentials(credentials).build();
|
||||
|
||||
// Send the email
|
||||
if let Err(e) = mailer.send(&email) {
|
||||
error!("Could not send email: {:?}", e);
|
||||
// Send the mail
|
||||
if let Err(e) = mailer.send(&mail) {
|
||||
error!("Could not send mail: {:?}", e);
|
||||
}
|
||||
} else {
|
||||
error!("Mail Message failed!");
|
||||
|
Loading…
x
Reference in New Issue
Block a user