feat: add /guilds/{uuid}members
Also makes it return user object with the query
This commit is contained in:
parent
746285e0fb
commit
c9a3e8c6c4
13 changed files with 141 additions and 42 deletions
|
@ -64,7 +64,7 @@ pub async fn get(
|
|||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
let messages = channel
|
||||
.fetch_messages(&data, message_request.amount, message_request.offset)
|
||||
|
|
|
@ -27,7 +27,7 @@ pub async fn get(
|
|||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(channel))
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub async fn delete(
|
|||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
channel.delete(&data).await?;
|
||||
|
||||
|
|
|
@ -36,8 +36,7 @@ pub async fn ws(
|
|||
|
||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||
|
||||
// Get server member from psql
|
||||
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||
|
||||
let (mut res, mut session_1, stream) = actix_ws::handle(&req, stream)?;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ pub async fn get(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}_channels", guild_uuid)).await {
|
||||
return Ok(HttpResponse::Ok()
|
||||
|
@ -70,7 +70,7 @@ pub async fn create(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
// FIXME: Logic to check permissions, should probably be done in utils.rs
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ pub async fn upload(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
let mut guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ pub async fn get(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
let guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||
|
||||
|
@ -57,13 +57,13 @@ pub async fn create(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
let member = Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
let guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||
|
||||
let custom_id = invite_request.as_ref().map(|ir| ir.custom_id.clone());
|
||||
|
||||
let invite = guild.create_invite(&mut conn, &member, custom_id).await?;
|
||||
let invite = guild.create_invite(&mut conn, uuid, custom_id).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(invite))
|
||||
}
|
||||
|
|
30
src/api/v1/guilds/uuid/members.rs
Normal file
30
src/api/v1/guilds/uuid/members.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::{
|
||||
api::v1::auth::check_access_token, error::Error, structs::Member, utils::{get_auth_header, global_checks}, Data
|
||||
};
|
||||
use ::uuid::Uuid;
|
||||
use actix_web::{HttpRequest, HttpResponse, get, web};
|
||||
|
||||
#[get("{uuid}/members")]
|
||||
pub async fn get(
|
||||
req: HttpRequest,
|
||||
path: web::Path<(Uuid,)>,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let headers = req.headers();
|
||||
|
||||
let auth_header = get_auth_header(headers)?;
|
||||
|
||||
let guild_uuid = path.into_inner().0;
|
||||
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
let members = Member::fetch_all(&data, guild_uuid).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(members))
|
||||
}
|
|
@ -7,6 +7,7 @@ mod channels;
|
|||
mod icon;
|
||||
mod invites;
|
||||
mod roles;
|
||||
mod members;
|
||||
|
||||
use crate::{
|
||||
api::v1::auth::check_access_token, error::Error, structs::{Guild, Member}, utils::{get_auth_header, global_checks}, Data
|
||||
|
@ -28,6 +29,8 @@ pub fn web() -> Scope {
|
|||
.service(invites::create)
|
||||
// Icon
|
||||
.service(icon::upload)
|
||||
// Members
|
||||
.service(members::get)
|
||||
}
|
||||
|
||||
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
||||
|
@ -81,7 +84,7 @@ pub async fn get(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
let guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ pub async fn get(
|
|||
|
||||
let uuid = check_access_token(auth_header, &mut conn).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}_roles", guild_uuid)).await {
|
||||
return Ok(HttpResponse::Ok()
|
||||
|
@ -66,7 +66,7 @@ pub async fn create(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
// FIXME: Logic to check permissions, should probably be done in utils.rs
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ pub async fn get(
|
|||
|
||||
global_checks(&data, uuid).await?;
|
||||
|
||||
Member::fetch_one(&mut conn, uuid, guild_uuid).await?;
|
||||
Member::check_membership(&mut conn, uuid, guild_uuid).await?;
|
||||
|
||||
if let Ok(cache_hit) = data.get_cache_key(format!("{}", role_uuid)).await {
|
||||
return Ok(HttpResponse::Ok()
|
||||
|
|
|
@ -42,7 +42,7 @@ pub async fn join(
|
|||
|
||||
let guild = Guild::fetch_one(&mut conn, invite.guild_uuid).await?;
|
||||
|
||||
Member::new(&mut conn, uuid, guild.uuid).await?;
|
||||
Member::new(&data, uuid, guild.uuid).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(guild))
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ pub async fn get(req: HttpRequest, data: web::Data<Data>) -> Result<HttpResponse
|
|||
|
||||
let me = Me::get(&mut conn, uuid).await?;
|
||||
|
||||
let memberships = me.fetch_memberships(&mut conn).await?;
|
||||
let memberships = me.fetch_memberships(&data).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(memberships))
|
||||
}
|
117
src/structs.rs
117
src/structs.rs
|
@ -473,7 +473,7 @@ impl Guild {
|
|||
|
||||
let member_uuid = Uuid::now_v7();
|
||||
|
||||
let member = Member {
|
||||
let member = MemberBuilder {
|
||||
uuid: member_uuid,
|
||||
nickname: None,
|
||||
user_uuid: owner_uuid,
|
||||
|
@ -512,7 +512,7 @@ impl Guild {
|
|||
pub async fn create_invite(
|
||||
&self,
|
||||
conn: &mut Conn,
|
||||
member: &Member,
|
||||
user_uuid: Uuid,
|
||||
custom_id: Option<String>,
|
||||
) -> Result<Invite, Error> {
|
||||
let invite_id;
|
||||
|
@ -530,7 +530,7 @@ impl Guild {
|
|||
|
||||
let invite = Invite {
|
||||
id: invite_id,
|
||||
user_uuid: member.user_uuid,
|
||||
user_uuid,
|
||||
guild_uuid: self.uuid,
|
||||
};
|
||||
|
||||
|
@ -666,11 +666,34 @@ impl Role {
|
|||
#[derive(Serialize, Queryable, Selectable, Insertable)]
|
||||
#[diesel(table_name = guild_members)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct MemberBuilder {
|
||||
pub uuid: Uuid,
|
||||
pub nickname: Option<String>,
|
||||
pub user_uuid: Uuid,
|
||||
pub guild_uuid: Uuid,
|
||||
}
|
||||
|
||||
impl MemberBuilder {
|
||||
async fn build(&self, data: &Data) -> Result<Member, Error> {
|
||||
let user = User::fetch_one(data, self.user_uuid).await?;
|
||||
|
||||
Ok(Member {
|
||||
uuid: self.uuid,
|
||||
nickname: self.nickname.clone(),
|
||||
user_uuid: self.user_uuid,
|
||||
guild_uuid: self.guild_uuid,
|
||||
user,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Member {
|
||||
pub uuid: Uuid,
|
||||
pub nickname: Option<String>,
|
||||
pub user_uuid: Uuid,
|
||||
pub guild_uuid: Uuid,
|
||||
user: User,
|
||||
}
|
||||
|
||||
impl Member {
|
||||
|
@ -685,26 +708,61 @@ impl Member {
|
|||
Ok(count)
|
||||
}
|
||||
|
||||
pub async fn fetch_one(
|
||||
conn: &mut Conn,
|
||||
user_uuid: Uuid,
|
||||
guild_uuid: Uuid,
|
||||
) -> Result<Self, Error> {
|
||||
pub async fn check_membership(conn: &mut Conn, user_uuid: Uuid, guild_uuid: Uuid) -> Result<(), Error> {
|
||||
use guild_members::dsl;
|
||||
let member: Member = dsl::guild_members
|
||||
dsl::guild_members
|
||||
.filter(dsl::user_uuid.eq(user_uuid))
|
||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||
.select(Member::as_select())
|
||||
.select(MemberBuilder::as_select())
|
||||
.get_result(conn)
|
||||
.await?;
|
||||
|
||||
Ok(member)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn new(conn: &mut Conn, user_uuid: Uuid, guild_uuid: Uuid) -> Result<Self, Error> {
|
||||
pub async fn fetch_one(
|
||||
data: &Data,
|
||||
user_uuid: Uuid,
|
||||
guild_uuid: Uuid,
|
||||
) -> Result<Self, Error> {
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
use guild_members::dsl;
|
||||
let member: MemberBuilder = dsl::guild_members
|
||||
.filter(dsl::user_uuid.eq(user_uuid))
|
||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||
.select(MemberBuilder::as_select())
|
||||
.get_result(&mut conn)
|
||||
.await?;
|
||||
|
||||
member.build(data).await
|
||||
}
|
||||
|
||||
pub async fn fetch_all(data: &Data, guild_uuid: Uuid) -> Result<Vec<Self>, Error> {
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
use guild_members::dsl;
|
||||
let member_builders: Vec<MemberBuilder> = load_or_empty(
|
||||
dsl::guild_members
|
||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||
.select(MemberBuilder::as_select())
|
||||
.load(&mut conn)
|
||||
.await
|
||||
)?;
|
||||
|
||||
let member_futures = member_builders.iter().map(async move |m| {
|
||||
m.build(data).await
|
||||
});
|
||||
|
||||
futures::future::try_join_all(member_futures).await
|
||||
}
|
||||
|
||||
pub async fn new(data: &Data, user_uuid: Uuid, guild_uuid: Uuid) -> Result<Self, Error> {
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
let member_uuid = Uuid::now_v7();
|
||||
|
||||
let member = Member {
|
||||
let member = MemberBuilder {
|
||||
uuid: member_uuid,
|
||||
guild_uuid,
|
||||
user_uuid,
|
||||
|
@ -712,16 +770,11 @@ impl Member {
|
|||
};
|
||||
|
||||
insert_into(guild_members::table)
|
||||
.values(member)
|
||||
.execute(conn)
|
||||
.values(&member)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
|
||||
Ok(Self {
|
||||
uuid: member_uuid,
|
||||
nickname: None,
|
||||
user_uuid,
|
||||
guild_uuid,
|
||||
})
|
||||
member.build(data).await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,14 +909,28 @@ impl Me {
|
|||
Ok(me)
|
||||
}
|
||||
|
||||
pub async fn fetch_memberships(&self, conn: &mut Conn) -> Result<Vec<Member>, Error> {
|
||||
pub async fn fetch_memberships(&self, data: &Data) -> Result<Vec<Member>, Error> {
|
||||
let mut conn = data.pool.get().await?;
|
||||
|
||||
use guild_members::dsl;
|
||||
let memberships: Vec<Member> = dsl::guild_members
|
||||
let member_builders: Vec<MemberBuilder> = dsl::guild_members
|
||||
.filter(dsl::user_uuid.eq(self.uuid))
|
||||
.select(Member::as_select())
|
||||
.load(conn)
|
||||
.select(MemberBuilder::as_select())
|
||||
.load(&mut conn)
|
||||
.await?;
|
||||
|
||||
let user = User::fetch_one(data, self.uuid).await?;
|
||||
|
||||
let memberships = member_builders.iter().map(|m| {
|
||||
Member {
|
||||
uuid: m.uuid,
|
||||
nickname: m.nickname.clone(),
|
||||
user_uuid: m.user_uuid,
|
||||
guild_uuid: m.guild_uuid,
|
||||
user: user.clone(),
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Ok(memberships)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue