use crate::AppService; use crate::error::AppError; use models::projects::{MemberRole, project, project_history_name, project_members}; use models::repos::repo; use sea_orm::*; use session::Session; use std::str::FromStr; use uuid::Uuid; impl AppService { pub async fn utils_find_project_by_name( &self, name: String, ) -> Result { match project::Entity::find() .filter(project::Column::Name.eq(name.clone())) .one(&self.db) .await .ok() .flatten() { Some(project) => Ok(project), None => match project_history_name::Entity::find() .filter(project_history_name::Column::HistoryName.eq(name)) .one(&self.db) .await .ok() .flatten() { Some(project) => self.utils_find_project_by_uid(project.project_uid).await, None => Err(AppError::ProjectNotFound), }, } } pub async fn utils_find_project_by_uid(&self, uid: Uuid) -> Result { project::Entity::find_by_id(uid) .one(&self.db) .await .ok() .flatten() .ok_or(AppError::ProjectNotFound) } pub async fn utils_check_project_permission( &self, project_id: &Uuid, user_id: Uuid, required_scopes: &[MemberRole], ) -> Result<(), AppError> { let member = project_members::Entity::find() .filter(project_members::Column::Project.eq(*project_id)) .filter(project_members::Column::User.eq(user_id)) .one(&self.db) .await?; if let Some(member) = member { for scope in required_scopes { if member.scope_role().ok() == Some(scope.clone()) { return Ok(()); } } } Err(AppError::NoPower) } pub async fn utils_project_context_role( &self, context: &Session, project_name: String, ) -> Result { let user_uid = context.user().ok_or(AppError::Unauthorized)?; let project = self.utils_find_project_by_name(project_name).await?; let members = project_members::Entity::find() .filter(project_members::Column::Project.eq(project.id)) .filter(project_members::Column::User.eq(user_uid)) .one(&self.db) .await .map_err(|_| AppError::InternalError)? .map(|m| m.scope); MemberRole::from_str(&members.ok_or(AppError::Unauthorized)?) .map_err(|_| AppError::RoleParseError) } pub async fn utils_find_repo_by_name( &self, project_uid: Uuid, repo_name: &str, ) -> Result { repo::Entity::find() .filter(repo::Column::Project.eq(project_uid)) .filter(repo::Column::RepoName.eq(repo_name)) .one(&self.db) .await? .ok_or(AppError::NotFound(format!( "Repository '{}' not found", repo_name ))) } pub async fn check_project_access( &self, project_uid: Uuid, user_uid: Uuid, ) -> Result<(), AppError> { let project = project::Entity::find_by_id(project_uid) .one(&self.db) .await .ok() .flatten() .ok_or(AppError::ProjectNotFound)?; // Public project - allow access if project.is_public { return Ok(()); } // Private project - check membership let member = project_members::Entity::find() .filter(project_members::Column::Project.eq(project_uid)) .filter(project_members::Column::User.eq(user_uid)) .one(&self.db) .await?; if member.is_some() { Ok(()) } else { Err(AppError::NoPower) } } }