Skip to content

Commit

Permalink
feat(core/room): remove validation of optional arguments and join/arc…
Browse files Browse the repository at this point in the history
…hive/leave handlers
  • Loading branch information
avdb13 committed Feb 10, 2024
1 parent 553a8f2 commit bc8bb66
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 24 deletions.
1 change: 1 addition & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ serde_json = { workspace = true }
tracing = { workspace = true }
uuid = { workspace = true, features= ["serde"] }
url = { workspace = true, features = ["serde"] }
tokio = { workspace = true, features = ["full"] }

# Local Dependencies
matrix = { path = "../matrix" }
7 changes: 5 additions & 2 deletions crates/core/src/room/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ use crate::error::HttpStatusCode;

#[derive(Debug, Error)]
pub enum RoomErrorCode {
#[error("Vaildation error. {0}")]
#[error("Failed to parse RoomId")]
MalformedRoomId,
#[error("Validation error. {0}")]
ValidationError(#[from] ValidationErrors),
}

impl HttpStatusCode for RoomErrorCode {
fn status_code(&self) -> StatusCode {
match self {
RoomErrorCode::ValidationError(_) => StatusCode::BAD_REQUEST,
RoomErrorCode::MalformedRoomId | RoomErrorCode::ValidationError(_) => StatusCode::BAD_REQUEST,
}
}

fn error_code(&self) -> &'static str {
match self {
RoomErrorCode::MalformedRoomId => "BAD_REQUEST",
RoomErrorCode::ValidationError(_) => "CREATION_DETAIL_INVALID",
}
}
Expand Down
194 changes: 172 additions & 22 deletions crates/core/src/room/service.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
use std::sync::Arc;

use tracing::instrument;
use validator::Validate;

use matrix::client::resources::room::{
CreateRoomCreationContent, CreateRoomRequestBody, Room as MatrixRoom, RoomPreset,
use matrix::{
client::resources::room::{
CreateRoomBody, JoinRoomBody, Room as MatrixRoom, RoomCreationContent, RoomPreset, ForgetRoomBody, LeaveRoomBody,
},
ruma_common::{OwnedUserId, OwnedRoomId, OwnedRoomOrAliasId},
Client as MatrixAdminClient,
};
use matrix::Client as MatrixAdminClient;

use crate::util::secret::Secret;
use crate::{Error, Result};
use crate::{util::secret::Secret, Error, Result};

use super::error::RoomErrorCode;
use super::model::Room;

#[derive(Debug, Clone, Validate)]
#[derive(Debug, Default, Clone)]
pub struct CreateRoomDto {
#[validate(length(min = 3, max = 255))]
pub name: String,
#[validate(length(min = 3, max = 255))]
pub topic: String,
#[validate(length(min = 3, max = 255))]
pub alias: String,
pub name: Option<String>,
pub topic: Option<String>,
pub alias: Option<String>,
}

#[derive(Debug, Clone)]
pub struct CreateDirectRoomDto {
pub invitee: OwnedUserId,
}

#[derive(Debug, Clone)]
pub struct JoinRoomDto {
pub alias_or_id: OwnedRoomOrAliasId,
pub reason: Option<String>,
}

#[derive(Debug, Clone)]
pub struct ArchiveRoomDto {
pub room_id: OwnedRoomId,
pub reason: Option<String>,
}

#[derive(Debug, Clone)]
pub struct LeaveRoomDto {
pub room_id: OwnedRoomId,
pub reason: Option<String>,
}

pub struct RoomService {
Expand All @@ -40,18 +60,77 @@ impl RoomService {
access_token: &Secret,
dto: CreateRoomDto,
) -> Result<Room> {
dto.validate()
.map_err(|err| Error::Room(RoomErrorCode::from(err)))?;
match MatrixRoom::create(
&self.admin,
access_token.to_string(),
CreateRoomBody {
creation_content: Some(RoomCreationContent { federate: false }),
preset: Some(RoomPreset::PublicChat),
name: dto.name.unwrap_or_default(),
room_alias_name: dto.alias.unwrap_or_default(),
topic: dto.topic.unwrap_or_default(),
..Default::default()
},
)
.await
{
Ok(room) => Ok(Room {
room_id: room.room_id,
}),
Err(err) => {
tracing::error!("Failed to create room: {}", err);
Err(Error::Unknown)
}
}
}

/// Creates a Hidden Chat Room
#[instrument(skip(self, dto))]
pub async fn create_hidden_room(
&self,
access_token: &Secret,
dto: CreateRoomDto,
) -> Result<Room> {
match MatrixRoom::create(
&self.admin,
access_token.to_string(),
CreateRoomBody {
creation_content: Some(RoomCreationContent { federate: false }),
preset: Some(RoomPreset::PrivateChat),
name: dto.name.unwrap_or_default(),
room_alias_name: dto.alias.unwrap_or_default(),
topic: dto.topic.unwrap_or_default(),
..Default::default()
},
)
.await
{
Ok(room) => Ok(Room {
room_id: room.room_id,
}),
Err(err) => {
tracing::error!("Failed to create room: {}", err);
Err(Error::Unknown)
}
}
}

/// Creates a Direct Chat Room
#[instrument(skip(self, dto))]
pub async fn create_direct_room(
&self,
access_token: &Secret,
dto: CreateDirectRoomDto,
) -> Result<Room> {
match MatrixRoom::create(
&self.admin,
access_token.to_string(),
CreateRoomRequestBody {
creation_content: CreateRoomCreationContent { m_federate: false },
name: dto.name,
preset: RoomPreset::PublicChat,
room_alias_name: dto.alias,
topic: dto.topic,
CreateRoomBody {
creation_content: Some(RoomCreationContent { federate: false }),
preset: Some(RoomPreset::TrustedPrivateChat),
is_direct: true,
invite: vec![dto.invitee],
..Default::default()
},
)
.await
Expand All @@ -65,4 +144,75 @@ impl RoomService {
}
}
}

/// Joins a Chat Room
#[instrument(skip(self, dto))]
pub async fn join_room(
&self,
access_token: &Secret,
dto: JoinRoomDto,
) -> Result<Room> {
match MatrixRoom::join(
&self.admin,
access_token.to_string(),
&dto.alias_or_id,
JoinRoomBody { reason: dto.reason.unwrap_or_default() },
)
.await
{
Ok(room) => Ok(Room {
room_id: room.room_id,
}),
Err(err) => {
tracing::error!("Failed to join room: {}", err);
Err(Error::Unknown)
}
}
}

/// Archives a Chat Room
#[instrument(skip(self, dto))]
pub async fn archive_room(
&self,
access_token: &Secret,
dto: ArchiveRoomDto,
) -> Result<()> {
match MatrixRoom::forget(
&self.admin,
access_token.to_string(),
&dto.room_id,
ForgetRoomBody { reason: dto.reason.unwrap_or_default() },
)
.await
{
Ok(_) => Ok(()),
Err(err) => {
tracing::error!("Failed to archive room: {}", err);
Err(Error::Unknown)
}
}
}

/// Leaves a Chat Room
#[instrument(skip(self, dto))]
pub async fn leave_room(
&self,
access_token: &Secret,
dto: LeaveRoomDto,
) -> Result<()> {
match MatrixRoom::leave(
&self.admin,
access_token.to_string(),
&dto.room_id,
LeaveRoomBody { reason: dto.reason.unwrap_or_default() },
)
.await
{
Ok(_) => Ok(()),
Err(err) => {
tracing::error!("Failed to leave room: {}", err);
Err(Error::Unknown)
}
}
}
}
3 changes: 3 additions & 0 deletions crates/matrix/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ pub mod admin;
/// Different to the Matrix SDK, no user state is kept in the Client instance,
/// this is equivalent to making cURL requests to the Matrix server.
pub mod client;

/// Ruma re-exports
pub use ruma_common;

0 comments on commit bc8bb66

Please sign in to comment.