use askama::Template; use axum::{ debug_handler, extract::{Path, State}, response::{Html, IntoResponse}, }; use interim_models::{ workspace::Workspace, workspace_user_perm::{self, WorkspaceUserPerm}, }; use serde::Deserialize; use uuid::Uuid; use crate::{ app_error::{AppError, forbidden}, app_state::{App, AppDbConn}, base_pooler::{RoleAssignment, WorkspacePooler}, navbar::WorkspaceNav, navigator::Navigator, settings::Settings, user::CurrentUser, }; #[derive(Debug, Deserialize)] pub(super) struct PathParams { workspace_id: Uuid, } #[debug_handler(state = App)] pub(super) async fn get( State(settings): State, CurrentUser(user): CurrentUser, AppDbConn(mut app_db): AppDbConn, Path(PathParams { workspace_id }): Path, navigator: Navigator, State(mut pooler): State, ) -> Result { // Check workspace authorization. let workspace_perms = WorkspaceUserPerm::belonging_to_user(user.id) .fetch_all(&mut app_db) .await?; if workspace_perms.iter().all(|p| { p.workspace_id != workspace_id || p.perm != workspace_user_perm::PermissionValue::Connect }) { return Err(forbidden!("access denied to workspace")); } let workspace = Workspace::with_id(workspace_id) .fetch_one(&mut app_db) .await?; let mut workspace_client = pooler .acquire_for(workspace_id, RoleAssignment::User(user.id)) .await?; #[derive(Template)] #[template(path = "workspaces_single/nav.html")] struct ResponseTemplate { settings: Settings, workspace: Workspace, workspace_nav: WorkspaceNav, } Ok(Html( ResponseTemplate { workspace_nav: WorkspaceNav::builder() .navigator(navigator) .workspace(workspace.clone()) .populate_rels(&mut app_db, &mut workspace_client) .await? .build()?, settings, workspace, } .render()?, )) }