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?;
|
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
|
let messages = channel
|
||||||
.fetch_messages(&data, message_request.amount, message_request.offset)
|
.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?;
|
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))
|
Ok(HttpResponse::Ok().json(channel))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ pub async fn delete(
|
||||||
|
|
||||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
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?;
|
channel.delete(&data).await?;
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,7 @@ pub async fn ws(
|
||||||
|
|
||||||
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
let channel = Channel::fetch_one(&data, channel_uuid).await?;
|
||||||
|
|
||||||
// Get server member from psql
|
Member::check_membership(&mut conn, uuid, channel.guild_uuid).await?;
|
||||||
Member::fetch_one(&mut conn, uuid, channel.guild_uuid).await?;
|
|
||||||
|
|
||||||
let (mut res, mut session_1, stream) = actix_ws::handle(&req, stream)?;
|
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?;
|
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 {
|
if let Ok(cache_hit) = data.get_cache_key(format!("{}_channels", guild_uuid)).await {
|
||||||
return Ok(HttpResponse::Ok()
|
return Ok(HttpResponse::Ok()
|
||||||
|
@ -70,7 +70,7 @@ pub async fn create(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
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
|
// 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?;
|
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?;
|
let mut guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub async fn get(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
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?;
|
let guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||||
|
|
||||||
|
@ -57,13 +57,13 @@ pub async fn create(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
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 guild = Guild::fetch_one(&mut conn, guild_uuid).await?;
|
||||||
|
|
||||||
let custom_id = invite_request.as_ref().map(|ir| ir.custom_id.clone());
|
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))
|
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 icon;
|
||||||
mod invites;
|
mod invites;
|
||||||
mod roles;
|
mod roles;
|
||||||
|
mod members;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
api::v1::auth::check_access_token, error::Error, structs::{Guild, Member}, utils::{get_auth_header, global_checks}, Data
|
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)
|
.service(invites::create)
|
||||||
// Icon
|
// Icon
|
||||||
.service(icon::upload)
|
.service(icon::upload)
|
||||||
|
// Members
|
||||||
|
.service(members::get)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
/// `GET /api/v1/guilds/{uuid}` DESCRIPTION
|
||||||
|
@ -81,7 +84,7 @@ pub async fn get(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
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?;
|
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?;
|
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 {
|
if let Ok(cache_hit) = data.get_cache_key(format!("{}_roles", guild_uuid)).await {
|
||||||
return Ok(HttpResponse::Ok()
|
return Ok(HttpResponse::Ok()
|
||||||
|
@ -66,7 +66,7 @@ pub async fn create(
|
||||||
|
|
||||||
global_checks(&data, uuid).await?;
|
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
|
// 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?;
|
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 {
|
if let Ok(cache_hit) = data.get_cache_key(format!("{}", role_uuid)).await {
|
||||||
return Ok(HttpResponse::Ok()
|
return Ok(HttpResponse::Ok()
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub async fn join(
|
||||||
|
|
||||||
let guild = Guild::fetch_one(&mut conn, invite.guild_uuid).await?;
|
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))
|
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 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))
|
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_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let member = Member {
|
let member = MemberBuilder {
|
||||||
uuid: member_uuid,
|
uuid: member_uuid,
|
||||||
nickname: None,
|
nickname: None,
|
||||||
user_uuid: owner_uuid,
|
user_uuid: owner_uuid,
|
||||||
|
@ -512,7 +512,7 @@ impl Guild {
|
||||||
pub async fn create_invite(
|
pub async fn create_invite(
|
||||||
&self,
|
&self,
|
||||||
conn: &mut Conn,
|
conn: &mut Conn,
|
||||||
member: &Member,
|
user_uuid: Uuid,
|
||||||
custom_id: Option<String>,
|
custom_id: Option<String>,
|
||||||
) -> Result<Invite, Error> {
|
) -> Result<Invite, Error> {
|
||||||
let invite_id;
|
let invite_id;
|
||||||
|
@ -530,7 +530,7 @@ impl Guild {
|
||||||
|
|
||||||
let invite = Invite {
|
let invite = Invite {
|
||||||
id: invite_id,
|
id: invite_id,
|
||||||
user_uuid: member.user_uuid,
|
user_uuid,
|
||||||
guild_uuid: self.uuid,
|
guild_uuid: self.uuid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -666,11 +666,34 @@ impl Role {
|
||||||
#[derive(Serialize, Queryable, Selectable, Insertable)]
|
#[derive(Serialize, Queryable, Selectable, Insertable)]
|
||||||
#[diesel(table_name = guild_members)]
|
#[diesel(table_name = guild_members)]
|
||||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
#[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 struct Member {
|
||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
pub nickname: Option<String>,
|
pub nickname: Option<String>,
|
||||||
pub user_uuid: Uuid,
|
pub user_uuid: Uuid,
|
||||||
pub guild_uuid: Uuid,
|
pub guild_uuid: Uuid,
|
||||||
|
user: User,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Member {
|
impl Member {
|
||||||
|
@ -685,26 +708,61 @@ impl Member {
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_one(
|
pub async fn check_membership(conn: &mut Conn, user_uuid: Uuid, guild_uuid: Uuid) -> Result<(), Error> {
|
||||||
conn: &mut Conn,
|
|
||||||
user_uuid: Uuid,
|
|
||||||
guild_uuid: Uuid,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
use guild_members::dsl;
|
use guild_members::dsl;
|
||||||
let member: Member = dsl::guild_members
|
dsl::guild_members
|
||||||
.filter(dsl::user_uuid.eq(user_uuid))
|
.filter(dsl::user_uuid.eq(user_uuid))
|
||||||
.filter(dsl::guild_uuid.eq(guild_uuid))
|
.filter(dsl::guild_uuid.eq(guild_uuid))
|
||||||
.select(Member::as_select())
|
.select(MemberBuilder::as_select())
|
||||||
.get_result(conn)
|
.get_result(conn)
|
||||||
.await?;
|
.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_uuid = Uuid::now_v7();
|
||||||
|
|
||||||
let member = Member {
|
let member = MemberBuilder {
|
||||||
uuid: member_uuid,
|
uuid: member_uuid,
|
||||||
guild_uuid,
|
guild_uuid,
|
||||||
user_uuid,
|
user_uuid,
|
||||||
|
@ -712,16 +770,11 @@ impl Member {
|
||||||
};
|
};
|
||||||
|
|
||||||
insert_into(guild_members::table)
|
insert_into(guild_members::table)
|
||||||
.values(member)
|
.values(&member)
|
||||||
.execute(conn)
|
.execute(&mut conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(Self {
|
member.build(data).await
|
||||||
uuid: member_uuid,
|
|
||||||
nickname: None,
|
|
||||||
user_uuid,
|
|
||||||
guild_uuid,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -856,14 +909,28 @@ impl Me {
|
||||||
Ok(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;
|
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))
|
.filter(dsl::user_uuid.eq(self.uuid))
|
||||||
.select(Member::as_select())
|
.select(MemberBuilder::as_select())
|
||||||
.load(conn)
|
.load(&mut conn)
|
||||||
.await?;
|
.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)
|
Ok(memberships)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue