switch to role based auth
This commit is contained in:
parent
019a163176
commit
b15eb449dc
@ -13,16 +13,16 @@ const JWT_EXPIRATION_MINUTES: i64 = 60;
|
||||
pub struct Claims {
|
||||
pub id: i64,
|
||||
pub username: String,
|
||||
pub permissions: Vec<String>,
|
||||
pub role: String,
|
||||
exp: i64,
|
||||
}
|
||||
|
||||
impl Claims {
|
||||
pub fn new(id: i64, username: String, permissions: Vec<String>) -> Self {
|
||||
pub fn new(id: i64, username: String, role: String) -> Self {
|
||||
Self {
|
||||
id,
|
||||
username,
|
||||
permissions,
|
||||
role,
|
||||
exp: (Utc::now() + Duration::minutes(JWT_EXPIRATION_MINUTES)).timestamp(),
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +128,6 @@ pub async fn db_get_settings(id: &i64) -> Result<Settings, sqlx::Error> {
|
||||
let result: Settings = sqlx::query_as(query).bind(id).fetch_one(&conn).await?;
|
||||
conn.close().await;
|
||||
|
||||
println!("{:#?}", result);
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use actix_web::{get, http::StatusCode, patch, post, put, web, Responder};
|
||||
use actix_web_grants::proc_macro::has_permissions;
|
||||
use actix_web_grants::proc_macro::has_any_role;
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHash, SaltString},
|
||||
Argon2, PasswordHasher, PasswordVerifier,
|
||||
@ -14,6 +14,7 @@ use crate::api::{
|
||||
db_add_user, db_get_settings, db_login, db_role, db_update_settings, db_update_user,
|
||||
},
|
||||
models::{LoginUser, Settings, User},
|
||||
utils::Role,
|
||||
};
|
||||
|
||||
#[derive(Serialize)]
|
||||
@ -25,7 +26,7 @@ struct ResponseObj<T> {
|
||||
|
||||
/// curl -X GET http://127.0.0.1:8080/api/settings/1 -H "Authorization: Bearer <TOKEN>"
|
||||
#[get("/settings/{id}")]
|
||||
#[has_permissions("admin", "user")]
|
||||
#[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 {
|
||||
@ -43,7 +44,7 @@ async fn get_settings(id: web::Path<i64>) -> Result<impl Responder, ServiceError
|
||||
/// "config_path":"/etc/ffplayout/ffplayout.yml","extra_extensions":".jpg,.jpeg,.png"}' \
|
||||
/// -H "Authorization: Bearer <TOKEN>"
|
||||
#[patch("/settings/{id}")]
|
||||
#[has_permissions("admin")]
|
||||
#[has_any_role("Role::Admin", type = "Role")]
|
||||
async fn patch_settings(
|
||||
id: web::Path<i64>,
|
||||
data: web::Json<Settings>,
|
||||
@ -55,10 +56,22 @@ async fn patch_settings(
|
||||
Err(ServiceError::InternalServerError)
|
||||
}
|
||||
|
||||
#[get("/playout/config/{id}")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn get_playout_config(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
|
||||
if let Ok(settings) = db_get_settings(&id).await {
|
||||
println!("{:?}", settings.config_path);
|
||||
|
||||
return Ok("settings");
|
||||
};
|
||||
|
||||
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/{id}")]
|
||||
#[has_permissions("admin", "user")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn update_user(
|
||||
id: web::Path<i64>,
|
||||
user: web::ReqData<LoginUser>,
|
||||
@ -98,7 +111,7 @@ async fn update_user(
|
||||
/// -d '{"email": "<EMAIL>", "username": "<USER>", "password": "<PASS>", "role_id": 1}' \
|
||||
/// --header 'Authorization: Bearer <TOKEN>'
|
||||
#[post("/user/")]
|
||||
#[has_permissions("admin")]
|
||||
#[has_any_role("Role::Admin", type = "Role")]
|
||||
async fn add_user(data: web::Json<User>) -> Result<impl Responder, ServiceError> {
|
||||
match db_add_user(data.into_inner()).await {
|
||||
Ok(_) => Ok("Add User Success"),
|
||||
@ -127,7 +140,7 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
|
||||
let role = db_role(&user.role_id.unwrap_or_default())
|
||||
.await
|
||||
.unwrap_or_else(|_| "guest".to_string());
|
||||
let claims = Claims::new(user.id, user.username.clone(), vec![role.clone()]);
|
||||
let claims = Claims::new(user.id, user.username.clone(), role.clone());
|
||||
|
||||
if let Ok(token) = create_jwt(claims) {
|
||||
user.token = Some(token);
|
||||
|
@ -7,6 +7,23 @@ use crate::api::{
|
||||
models::User,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
pub enum Role {
|
||||
Admin,
|
||||
User,
|
||||
Guest,
|
||||
}
|
||||
|
||||
impl Role {
|
||||
pub fn set_role(role: &str) -> Self {
|
||||
match role {
|
||||
"admin" => Role::Admin,
|
||||
"user" => Role::User,
|
||||
_ => Role::Guest,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct GlobalSettings {
|
||||
pub secret: String,
|
||||
|
@ -13,8 +13,8 @@ use ffplayout_engine::{
|
||||
args_parse::Args,
|
||||
auth,
|
||||
models::LoginUser,
|
||||
routes::{add_user, get_settings, login, patch_settings, update_user},
|
||||
utils::{init_config, run_args},
|
||||
routes::{add_user, get_playout_config, get_settings, login, patch_settings, update_user},
|
||||
utils::{init_config, run_args, Role},
|
||||
},
|
||||
utils::{init_logging, GlobalConfig},
|
||||
};
|
||||
@ -22,10 +22,12 @@ use ffplayout_engine::{
|
||||
async fn validator(req: ServiceRequest, credentials: BearerAuth) -> Result<ServiceRequest, Error> {
|
||||
// We just get permissions from JWT
|
||||
let claims = auth::decode_jwt(credentials.token()).await?;
|
||||
req.attach(claims.permissions);
|
||||
req.attach(vec![Role::set_role(&claims.role)]);
|
||||
|
||||
req.extensions_mut()
|
||||
.insert(LoginUser::new(claims.id, claims.username));
|
||||
|
||||
println!("{:#?}", req);
|
||||
Ok(req)
|
||||
}
|
||||
|
||||
@ -63,6 +65,7 @@ async fn main() -> std::io::Result<()> {
|
||||
web::scope("/api")
|
||||
.wrap(auth)
|
||||
.service(add_user)
|
||||
.service(get_playout_config)
|
||||
.service(get_settings)
|
||||
.service(patch_settings)
|
||||
.service(update_user),
|
||||
|
Loading…
x
Reference in New Issue
Block a user