support multiple channel ids
This commit is contained in:
parent
afc94b3b7a
commit
9f422706ea
@ -15,17 +15,17 @@ const JWT_EXPIRATION_DAYS: i64 = 7;
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||
pub struct Claims {
|
||||
pub id: i32,
|
||||
pub channel: i32,
|
||||
pub channels: Vec<i32>,
|
||||
pub username: String,
|
||||
pub role: Role,
|
||||
exp: i64,
|
||||
}
|
||||
|
||||
impl Claims {
|
||||
pub fn new(id: i32, channel: i32, username: String, role: Role) -> Self {
|
||||
pub fn new(id: i32, channels: Vec<i32>, username: String, role: Role) -> Self {
|
||||
Self {
|
||||
id,
|
||||
channel,
|
||||
channels,
|
||||
username,
|
||||
role,
|
||||
exp: (Utc::now() + TimeDelta::try_days(JWT_EXPIRATION_DAYS).unwrap()).timestamp(),
|
||||
|
@ -186,7 +186,7 @@ pub async fn login(pool: web::Data<Pool<Sqlite>>, credentials: web::Json<User>)
|
||||
if verified_password.is_ok() {
|
||||
let claims = Claims::new(
|
||||
user.id,
|
||||
user.channel_id.unwrap_or_default(),
|
||||
user.channel_ids.clone(),
|
||||
username.clone(),
|
||||
role.clone(),
|
||||
);
|
||||
@ -417,7 +417,7 @@ async fn remove_user(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn get_channel(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -459,7 +459,7 @@ async fn get_all_channels(pool: web::Data<Pool<Sqlite>>) -> Result<impl Responde
|
||||
"Role::GlobalAdmin",
|
||||
"Role::ChannelAdmin",
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn patch_channel(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -537,7 +537,7 @@ async fn remove_channel(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn get_advanced_config(
|
||||
id: web::Path<i32>,
|
||||
@ -562,7 +562,7 @@ async fn get_advanced_config(
|
||||
"Role::GlobalAdmin",
|
||||
"Role::ChannelAdmin",
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn update_advanced_config(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -682,7 +682,7 @@ async fn update_advanced_config(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn get_playout_config(
|
||||
id: web::Path<i32>,
|
||||
@ -707,7 +707,7 @@ async fn get_playout_config(
|
||||
"Role::GlobalAdmin",
|
||||
"Role::ChannelAdmin",
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn update_playout_config(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -826,7 +826,7 @@ async fn update_playout_config(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn get_presets(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -852,7 +852,7 @@ async fn get_presets(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn update_preset(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -882,7 +882,7 @@ async fn update_preset(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn add_preset(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -911,7 +911,7 @@ async fn add_preset(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn delete_preset(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -948,7 +948,7 @@ async fn delete_preset(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn send_text_message(
|
||||
id: web::Path<i32>,
|
||||
@ -979,7 +979,7 @@ pub async fn send_text_message(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn control_playout(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
@ -1025,7 +1025,7 @@ pub async fn control_playout(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn media_current(
|
||||
id: web::Path<i32>,
|
||||
@ -1056,7 +1056,7 @@ pub async fn media_current(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn process_control(
|
||||
id: web::Path<i32>,
|
||||
@ -1103,7 +1103,7 @@ pub async fn process_control(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn get_playlist(
|
||||
id: web::Path<i32>,
|
||||
@ -1132,7 +1132,7 @@ pub async fn get_playlist(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn save_playlist(
|
||||
id: web::Path<i32>,
|
||||
@ -1172,7 +1172,7 @@ pub async fn save_playlist(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn gen_playlist(
|
||||
id: web::Path<i32>,
|
||||
@ -1224,7 +1224,7 @@ pub async fn gen_playlist(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn del_playlist(
|
||||
id: web::Path<i32>,
|
||||
@ -1254,7 +1254,7 @@ pub async fn del_playlist(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn get_log(
|
||||
id: web::Path<i32>,
|
||||
@ -1277,7 +1277,7 @@ pub async fn get_log(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn file_browser(
|
||||
id: web::Path<i32>,
|
||||
@ -1306,7 +1306,7 @@ pub async fn file_browser(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn add_dir(
|
||||
id: web::Path<i32>,
|
||||
@ -1331,7 +1331,7 @@ pub async fn add_dir(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn move_rename(
|
||||
id: web::Path<i32>,
|
||||
@ -1359,7 +1359,7 @@ pub async fn move_rename(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn remove(
|
||||
id: web::Path<i32>,
|
||||
@ -1388,7 +1388,7 @@ pub async fn remove(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn save_file(
|
||||
id: web::Path<i32>,
|
||||
@ -1483,7 +1483,7 @@ async fn get_public(public: web::Path<String>) -> Result<actix_files::NamedFile,
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn import_playlist(
|
||||
id: web::Path<i32>,
|
||||
@ -1544,7 +1544,7 @@ async fn import_playlist(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
async fn get_program(
|
||||
id: web::Path<i32>,
|
||||
@ -1642,7 +1642,7 @@ async fn get_program(
|
||||
#[protect(
|
||||
any("Role::GlobalAdmin", "Role::ChannelAdmin", "Role::User"),
|
||||
ty = "Role",
|
||||
expr = "*id == user.channel || role.has_authority(&Role::GlobalAdmin)"
|
||||
expr = "user.channels.contains(&*id) || role.has_authority(&Role::GlobalAdmin)"
|
||||
)]
|
||||
pub async fn get_system_stat(
|
||||
id: web::Path<i32>,
|
||||
|
@ -306,13 +306,13 @@ pub async fn select_role(conn: &Pool<Sqlite>, id: &i32) -> Result<Role, sqlx::Er
|
||||
|
||||
pub async fn select_login(conn: &Pool<Sqlite>, user: &str) -> Result<User, sqlx::Error> {
|
||||
let query =
|
||||
"SELECT id, mail, username, password, role_id, channel_id FROM user WHERE username = $1";
|
||||
"SELECT id, mail, username, password, role_id, channel_ids FROM user WHERE username = $1";
|
||||
|
||||
sqlx::query_as(query).bind(user).fetch_one(conn).await
|
||||
}
|
||||
|
||||
pub async fn select_user(conn: &Pool<Sqlite>, id: i32) -> Result<User, sqlx::Error> {
|
||||
let query = "SELECT id, mail, username, role_id, channel_id FROM user WHERE id = $1";
|
||||
let query = "SELECT id, mail, username, role_id, channel_ids FROM user WHERE id = $1";
|
||||
|
||||
sqlx::query_as(query).bind(id).fetch_one(conn).await
|
||||
}
|
||||
@ -338,13 +338,20 @@ pub async fn insert_user(
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let query = "INSERT INTO user (mail, username, password, role_id) VALUES($1, $2, $3, $4)";
|
||||
let query = "INSERT INTO user (mail, username, password, role_id, channel_ids) VALUES($1, $2, $3, $4, $5)";
|
||||
|
||||
sqlx::query(query)
|
||||
.bind(user.mail)
|
||||
.bind(user.username)
|
||||
.bind(password_hash)
|
||||
.bind(user.role_id)
|
||||
.bind(
|
||||
user.channel_ids
|
||||
.iter()
|
||||
.map(|i| i.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(","),
|
||||
)
|
||||
.execute(conn)
|
||||
.await
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use serde::{
|
||||
de::{self, Visitor},
|
||||
Deserialize, Serialize,
|
||||
};
|
||||
use serde_with::{formats::CommaSeparator, serde_as, StringWithSeparator};
|
||||
use sqlx::{sqlite::SqliteRow, FromRow, Pool, Row, Sqlite};
|
||||
|
||||
use crate::db::handles;
|
||||
@ -52,29 +53,44 @@ pub async fn init_globales(conn: &Pool<Sqlite>) {
|
||||
INSTANCE.set(config).unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
|
||||
#[serde_as]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct User {
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_deserializing)]
|
||||
pub id: i32,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mail: Option<String>,
|
||||
pub username: String,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing, default = "empty_string")]
|
||||
pub password: String,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing)]
|
||||
pub role_id: Option<i32>,
|
||||
#[sqlx(default)]
|
||||
#[serde(skip_serializing)]
|
||||
pub channel_id: Option<i32>,
|
||||
#[sqlx(default)]
|
||||
#[serde_as(as = "StringWithSeparator::<CommaSeparator, i32>")]
|
||||
pub channel_ids: Vec<i32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub token: Option<String>,
|
||||
}
|
||||
|
||||
impl FromRow<'_, SqliteRow> for User {
|
||||
fn from_row(row: &SqliteRow) -> sqlx::Result<Self> {
|
||||
Ok(Self {
|
||||
id: row.try_get("id").unwrap_or_default(),
|
||||
mail: row.get("mail"),
|
||||
username: row.try_get("username").unwrap_or_default(),
|
||||
password: row.try_get("password").unwrap_or_default(),
|
||||
role_id: row.get("role_id"),
|
||||
channel_ids: row
|
||||
.try_get::<String, &str>("channel_ids")
|
||||
.unwrap_or_default()
|
||||
.split(',')
|
||||
.map(|i| i.parse::<i32>().unwrap_or_default())
|
||||
.collect(),
|
||||
token: row.get("token"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn empty_string() -> String {
|
||||
"".to_string()
|
||||
}
|
||||
@ -82,12 +98,12 @@ fn empty_string() -> String {
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct UserMeta {
|
||||
pub id: i32,
|
||||
pub channel: i32,
|
||||
pub channels: Vec<i32>,
|
||||
}
|
||||
|
||||
impl UserMeta {
|
||||
pub fn new(id: i32, channel: i32) -> Self {
|
||||
Self { id, channel }
|
||||
pub fn new(id: i32, channels: Vec<i32>) -> Self {
|
||||
Self { id, channels }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ async fn validator(
|
||||
req.attach(vec![claims.role]);
|
||||
|
||||
req.extensions_mut()
|
||||
.insert(UserMeta::new(claims.id, claims.channel));
|
||||
.insert(UserMeta::new(claims.id, claims.channels));
|
||||
|
||||
Ok(req)
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ pub async fn run_args(pool: &Pool<Sqlite>) -> Result<(), i32> {
|
||||
username: username.clone(),
|
||||
password: args.password.unwrap(),
|
||||
role_id: Some(1),
|
||||
channel_id: Some(1),
|
||||
channel_ids: vec![1],
|
||||
token: None,
|
||||
};
|
||||
|
||||
|
@ -57,9 +57,8 @@ CREATE TABLE
|
||||
username TEXT NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
role_id INTEGER NOT NULL DEFAULT 3,
|
||||
channel_id INTEGER NOT NULL DEFAULT 1,
|
||||
channel_ids TEXT NOT NULL DEFAULT "1",
|
||||
FOREIGN KEY (role_id) REFERENCES roles (id) ON UPDATE SET NULL ON DELETE SET DEFAULT,
|
||||
FOREIGN KEY (channel_id) REFERENCES channels (id) ON UPDATE CASCADE ON DELETE SET DEFAULT,
|
||||
UNIQUE (mail, username)
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user