Skip to content

Commit

Permalink
🛂invitation privilege verification
Browse files Browse the repository at this point in the history
~ first commit with that gitmoji
  • Loading branch information
HubertK05 committed Jan 27, 2023
1 parent d5e730c commit 0f4f138
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 11 deletions.
34 changes: 30 additions & 4 deletions backend/src/routes/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::utils::chat::socket::{
use crate::utils::chat::*;
use crate::utils::groups::*;
use crate::utils::roles::models::{SocketGroupRolePrivileges, Gate, Role};
use crate::utils::roles::privileges::{Privilege, CanInvite, CanSendMessages};
use crate::utils::roles::{get_group_role_privileges, get_user_role, single_set_group_role_privileges, single_set_group_user_role};
use axum::http::HeaderMap;
use axum::{
Expand All @@ -16,6 +17,7 @@ use axum::{
Extension, Router,
};
use sqlx::PgPool;
use std::cmp::Ordering;
use std::sync::Arc;
use tracing::{debug, error, info};
use uuid::Uuid;
Expand Down Expand Up @@ -159,6 +161,18 @@ pub async fn chat_socket(
}
// todo: send group invites in chat
ClientAction::GroupInvite { group_id } => {
match controller.verify_with_privilege(claims.user_id, Privilege::CanInvite(CanInvite::Yes)).await {
Ok(false) => {
info!("User does not have privileges to invite other users");
continue;
},
Err(e) => {
error!("Failed to verify with privilege: {:?}", e);
continue;
},
_ => (),
}

let Ok(_is_member) = check_if_group_member(&pool, &claims.user_id, &group_id).await else {
error!("Failed to check whether a user {} ({}) is a group {} member (during sending a group invite)", &claims.user_id, &claims.login, &group_id);
continue;
Expand All @@ -180,12 +194,24 @@ pub async fn chat_socket(
_ => (),
};

// todo: check for user priviliges
let role_verified = gate.verify(Role::Admin, Role::Member, (Uuid::new_v4(), Uuid::new_v4()));
let Some(user_role) = controller.get_role(claims.user_id).await else {
error!("Failed to get the controller's role");
continue;
};

let Some(target_user_role) = controller.get_role(user_id).await else {
error!("Failed to get the target user's role");
continue;
};

if !gate.verify(user_role, target_user_role, (claims.user_id, user_id)) {
info!("User does not have privileges to kick another user");
continue;
}

// Remove user from group
let Ok(_) = try_remove_user_from_group(&pool, user_id, group_id).await else {
error!("ws closed: Failed to remove user {} from a group {}", &user_id, &group_id);
error!("Failed to remove user {} from a group {}", &user_id, &group_id);
continue;
};

Expand All @@ -195,7 +221,7 @@ pub async fn chat_socket(
// todo: disconnect group controllers
}
ClientAction::SingleChangePrivileges { mut data } => {
let Some(socket_privileges) = controller.get_privileges() else {
let Some(socket_privileges) = controller.get_group_privileges() else {
debug!("User trying to change privileges not in group");
continue
};
Expand Down
23 changes: 16 additions & 7 deletions backend/src/utils/chat/socket.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::utils::roles::errors::RoleError;
use crate::utils::roles::models::{Role, SocketGroupRolePrivileges, PrivilegeChangeData, UserRoleChangeData};
use crate::utils::roles::privileges::Privileges;
use crate::utils::roles::privileges::{Privileges, Privilege};

use super::models::{GroupUserMessage, KickMessage};
use anyhow::anyhow;
Expand Down Expand Up @@ -246,21 +246,30 @@ impl UserController {
Ok(user.connections.send_across_all(&ServerAction::SetPrivileges(privileges)).await)
}

pub async fn get_role(&self) -> Option<Role> {
pub async fn get_role(&self, user_id: Uuid) -> Option<Role> {
let Some(conn) = &self.group_conn else {
return None
};

match conn.controller.users.0.read().await.get(&self.user_id) {
Some(user_data) => Some(user_data.role),
None => None,
}
conn.controller.users.0.read().await.get(&user_id)
.and_then(|x| Some(x.role))
}

pub fn get_privileges(&self) -> Option<&SocketGroupRolePrivileges> {
pub fn get_group_privileges(&self) -> Option<&SocketGroupRolePrivileges> {
let connection = self.group_conn.as_ref()?;
Some(&connection.controller.privileges)
}

pub async fn get_user_privilege(&self, user_id: Uuid, val: Privilege) -> Option<Privilege> {
let role = self.get_role(user_id).await?;
self.get_group_privileges()?.get_privilege(role, val).await
}

pub async fn verify_with_privilege(&self, user_id: Uuid, min_val: Privilege) -> Result<bool, RoleError> {
let role = self.get_role(user_id).await.ok_or(RoleError::Unexpected(anyhow!("No role found for user_id")))?;
let privileges = self.get_group_privileges().ok_or(RoleError::Unexpected(anyhow!("No socket privileges found")))?;
privileges.verify_with_privilege(role, min_val).await
}
}

pub struct UserChannelListener {
Expand Down
13 changes: 13 additions & 0 deletions backend/src/utils/roles/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,19 @@ impl SocketGroupRolePrivileges {
Some(self.0.get(&role)?.read().await.clone())
}
}