Implement better way to define targets for messages
This commit is contained in:
parent
0b8d6e2cc2
commit
e5aace6e68
@ -62,15 +62,23 @@ impl Message {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get(pool: &PgPool, channel: Channel) -> Result<Vec<Self>, sqlx::Error> {
|
||||
pub async fn get(
|
||||
pool: &PgPool,
|
||||
channel: Channel,
|
||||
member_roles: Roles,
|
||||
member_groups: Groups,
|
||||
) -> Result<Vec<Self>, sqlx::Error> {
|
||||
let messages = sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT message_id, created_at, scheduled_at, status as \"status:MessageStatus\", title, content, channel, member_groups, member_roles, thumbnail_url FROM messages
|
||||
WHERE status = 'sent'
|
||||
AND channel & $1 > 0;
|
||||
AND (channel & $1) > 0
|
||||
AND ((member_roles & $2) > 0 AND (member_groups & $3) > 0);
|
||||
",
|
||||
channel.bits() as i64
|
||||
channel.bits() as i64,
|
||||
member_roles.bits() as i64,
|
||||
member_groups.bits() as i64,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use sqlx::{PgPool, Postgres};
|
||||
|
||||
use crate::model::member::Roles;
|
||||
use crate::model::member::{Groups, Roles};
|
||||
|
||||
use super::Member as DbMember;
|
||||
|
||||
@ -144,6 +144,36 @@ impl UserMember {
|
||||
Ok(roles)
|
||||
}
|
||||
|
||||
pub async fn get_roles_groups(
|
||||
pool: &PgPool,
|
||||
user_id: &uuid::Uuid,
|
||||
) -> Result<(Roles, Groups), sqlx::Error> {
|
||||
struct RolesGroups {
|
||||
roles: i64,
|
||||
groups: i64,
|
||||
}
|
||||
|
||||
let result = sqlx::query_as!(
|
||||
RolesGroups,
|
||||
"
|
||||
SELECT roles, groups
|
||||
FROM users_members
|
||||
INNER JOIN members ON users_members.member_id = members.member_id
|
||||
AND users_members.user_id = $1;
|
||||
",
|
||||
user_id,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let (roles, groups) = result.into_iter().fold(
|
||||
(Roles::empty(), Groups::empty()),
|
||||
|(acc_roles, acc_groups), r| (acc_roles | r.roles.into(), acc_groups | r.groups.into()),
|
||||
);
|
||||
|
||||
Ok((roles, groups))
|
||||
}
|
||||
|
||||
pub async fn get_members_from_user(
|
||||
pool: &PgPool,
|
||||
user_id: &uuid::Uuid,
|
||||
|
@ -11,8 +11,8 @@ pub struct Message {
|
||||
pub title: String,
|
||||
pub content: String,
|
||||
pub channel: Channel,
|
||||
pub member_groups: Option<Groups>,
|
||||
pub member_roles: Option<Roles>,
|
||||
pub member_groups: Groups,
|
||||
pub member_roles: Roles,
|
||||
pub thumbnail_url: Option<String>,
|
||||
}
|
||||
|
||||
@ -43,30 +43,57 @@ pub struct MessageCreate {
|
||||
pub scheduled_at: Option<DateTime<Utc>>,
|
||||
pub title: String,
|
||||
pub content: String,
|
||||
pub channel: Channel,
|
||||
pub member_groups: Option<Groups>,
|
||||
pub member_roles: Option<Roles>,
|
||||
pub channel: String,
|
||||
pub member_groups: String,
|
||||
pub member_roles: String,
|
||||
pub thumbnail_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Message {
|
||||
pub fn new(message_create: MessageCreate) -> Self {
|
||||
pub fn new(message_create: MessageCreate) -> Result<Self, crate::Error> {
|
||||
let message_id = uuid::Uuid::new_v4();
|
||||
|
||||
let created_at = Utc::now();
|
||||
|
||||
Self {
|
||||
let channel: Channel =
|
||||
bitflags::parser::from_str_strict(&message_create.channel).map_err(|_| {
|
||||
crate::Error::BadRequest {
|
||||
expected: String::from("Error while parsing channel"),
|
||||
}
|
||||
})?;
|
||||
|
||||
let member_groups = if message_create.member_groups.is_empty() {
|
||||
Ok(Groups::all())
|
||||
} else {
|
||||
bitflags::parser::from_str_strict(&message_create.member_groups).map_err(|_| {
|
||||
crate::Error::BadRequest {
|
||||
expected: "Error while parsing groups".to_string(),
|
||||
}
|
||||
})
|
||||
}?;
|
||||
|
||||
let member_roles = if message_create.member_roles.is_empty() {
|
||||
Ok(Roles::all())
|
||||
} else {
|
||||
bitflags::parser::from_str_strict(&message_create.member_roles).map_err(|_| {
|
||||
crate::Error::BadRequest {
|
||||
expected: "Error while parsing groups".to_string(),
|
||||
}
|
||||
})
|
||||
}?;
|
||||
|
||||
Ok(Self {
|
||||
message_id,
|
||||
created_at,
|
||||
scheduled_at: message_create.scheduled_at,
|
||||
title: message_create.title,
|
||||
content: message_create.content,
|
||||
channel: message_create.channel,
|
||||
channel,
|
||||
thumbnail_url: message_create.thumbnail_url,
|
||||
member_groups: message_create.member_groups,
|
||||
member_roles: message_create.member_roles,
|
||||
member_groups,
|
||||
member_roles,
|
||||
status: MessageStatus::Pending,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,8 +110,8 @@ impl From<DbMessage> for Message {
|
||||
title: value.title,
|
||||
content: value.content,
|
||||
channel: value.channel,
|
||||
member_groups: value.member_groups.into(),
|
||||
member_roles: value.member_roles.into(),
|
||||
member_groups: value.member_groups,
|
||||
member_roles: value.member_roles,
|
||||
thumbnail_url: value.thumbnail_url,
|
||||
}
|
||||
}
|
||||
@ -100,8 +127,8 @@ impl From<Message> for DbMessage {
|
||||
title: value.title,
|
||||
content: value.content,
|
||||
channel: value.channel,
|
||||
member_groups: value.member_groups.into(),
|
||||
member_roles: value.member_roles.into(),
|
||||
member_groups: value.member_groups,
|
||||
member_roles: value.member_roles,
|
||||
thumbnail_url: value.thumbnail_url,
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use crate::database::model::User as DbUser;
|
||||
use crate::database::model::UserMember as DbUserMember;
|
||||
use crate::util::convert_vec;
|
||||
|
||||
use super::member::Groups;
|
||||
use super::member::Roles;
|
||||
use super::Member;
|
||||
impl From<DbUser> for User {
|
||||
@ -72,4 +73,8 @@ impl User {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_roles_groups(&self, pool: &PgPool) -> Result<(Roles, Groups), sqlx::Error> {
|
||||
DbUserMember::get_roles_groups(pool, &self.id).await
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::HeaderMap,
|
||||
routing::post,
|
||||
Json, Router,
|
||||
};
|
||||
use axum::{extract::State, http::HeaderMap, routing::post, Json, Router};
|
||||
use bitflags::Flags;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{
|
||||
@ -26,8 +22,8 @@ pub struct MessageCreateRequest {
|
||||
title: String,
|
||||
content: String,
|
||||
channel: String,
|
||||
member_groups: Option<String>,
|
||||
member_roles: Option<String>,
|
||||
member_groups: String,
|
||||
member_roles: String,
|
||||
}
|
||||
|
||||
pub async fn message_create(
|
||||
@ -40,39 +36,15 @@ pub async fn message_create(
|
||||
user.authorize(&state.pool, Some(Roles::ADMIN | Roles::MESSAGES), None)
|
||||
.await?;
|
||||
|
||||
let channel: Channel = bitflags::parser::from_str_strict(&request.channel).map_err(|_| {
|
||||
crate::Error::BadRequest {
|
||||
expected: String::from("Error while parsing channel"),
|
||||
}
|
||||
})?;
|
||||
|
||||
let member_groups: Option<Groups> = request
|
||||
.member_groups
|
||||
.map(|groups| {
|
||||
bitflags::parser::from_str_strict(&groups).map_err(|_| crate::Error::BadRequest {
|
||||
expected: String::from("Error while parsing member groups"),
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let member_roles: Option<Roles> = request
|
||||
.member_roles
|
||||
.map(|roles| {
|
||||
bitflags::parser::from_str_strict(&roles).map_err(|_| crate::Error::BadRequest {
|
||||
expected: String::from("Error while parsing member roles"),
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let db_message: DbMessage = Message::new(MessageCreate {
|
||||
title: request.title,
|
||||
content: request.content,
|
||||
channel,
|
||||
member_groups,
|
||||
member_roles,
|
||||
channel: request.channel,
|
||||
member_groups: request.member_groups,
|
||||
member_roles: request.member_roles,
|
||||
scheduled_at: None,
|
||||
thumbnail_url: None,
|
||||
})
|
||||
})?
|
||||
.into();
|
||||
|
||||
let mut transaction = state.pool.begin().await?;
|
||||
|
@ -83,7 +83,9 @@ pub async fn get_messages(
|
||||
let user = get_user_from_header(&state.pool, &headers).await?;
|
||||
user.authorize(&state.pool, None, Some(user_id)).await?;
|
||||
|
||||
let messages = DbMessage::get(&state.pool, Channel::ALGEMEEN).await?;
|
||||
let (roles, groups) = user.get_roles_groups(&state.pool).await?;
|
||||
|
||||
let messages = DbMessage::get(&state.pool, Channel::ALGEMEEN, roles, groups).await?;
|
||||
|
||||
Ok(Json(convert_vec(messages)))
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use sqlx::{Acquire, PgPool};
|
||||
|
||||
use crate::model::{
|
||||
member::{Groups, Roles},
|
||||
Member,
|
||||
};
|
||||
use crate::model::member::{Groups, Roles};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(version, about, long_about = None)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user