diff --git a/src/routes/v3/project_creation.rs b/src/routes/v3/project_creation.rs index 0c999ad9..fe89b195 100644 --- a/src/routes/v3/project_creation.rs +++ b/src/routes/v3/project_creation.rs @@ -612,11 +612,14 @@ async fn project_create_inner( additional_categories.extend(ids.values()); } + // Should only be owner if not attached to an organization + let is_owner = project_create_data.organization_id.is_none(); + let team = models::team_item::TeamBuilder { members: vec![models::team_item::TeamMemberBuilder { user_id: current_user.id.into(), role: crate::models::teams::OWNER_ROLE.to_owned(), - is_owner: true, + is_owner, // Allow all permissions for project creator, even if attached to a project permissions: ProjectPermissions::all(), organization_permissions: None, diff --git a/src/routes/v3/projects.rs b/src/routes/v3/projects.rs index bcf26500..fb9b7188 100644 --- a/src/routes/v3/projects.rs +++ b/src/routes/v3/projects.rs @@ -54,6 +54,7 @@ pub fn config(cfg: &mut web::ServiceConfig) { .route("{id}/gallery", web::delete().to(delete_gallery_item)) .route("{id}/follow", web::post().to(project_follow)) .route("{id}/follow", web::delete().to(project_unfollow)) + .route("{id}/organization", web::get().to(project_get_organization)) .service( web::scope("{project_id}") .route( @@ -2184,3 +2185,38 @@ pub async fn project_unfollow( )) } } + +pub async fn project_get_organization( + req: HttpRequest, + info: web::Path<(String,)>, + pool: web::Data, + redis: web::Data, + session_queue: web::Data, +) -> Result { + let user = get_user_from_headers(&req, &**pool, &redis, &session_queue, None) + .await? + .1; + let string = info.into_inner().0; + + let result = db_models::Project::get(&string, &**pool, &redis) + .await? + .ok_or_else(|| { + ApiError::InvalidInput("The specified project does not exist!".to_string()) + })?; + + if is_authorized(&result.inner, &Some(user), &pool).await? { + Err(ApiError::InvalidInput( + "The specified project does not exist!".to_string(), + )) + } else if let Some(organization_id) = result.inner.organization_id { + let organization = db_models::Organization::get_id(organization_id, &**pool, &redis) + .await? + .ok_or_else(|| { + ApiError::InvalidInput("The specified organization does not exist!".to_string()) + })?; + + Ok(HttpResponse::Ok().json(organization)) + } else { + Err(ApiError::NotFound) + } +} diff --git a/src/routes/v3/teams.rs b/src/routes/v3/teams.rs index 6fdf0934..d962152e 100644 --- a/src/routes/v3/teams.rs +++ b/src/routes/v3/teams.rs @@ -62,28 +62,14 @@ pub async fn team_members_get_project( if !is_authorized(&project.inner, ¤t_user, &pool).await? { return Err(ApiError::NotFound); } - let mut members_data = + let members_data = TeamMember::get_from_team_full(project.inner.team_id, &**pool, &redis).await?; - let mut member_user_ids = members_data.iter().map(|x| x.user_id).collect::>(); - - // Adds the organization's team members to the list of members, if the project is associated with an organization - if let Some(oid) = project.inner.organization_id { - let organization_data = Organization::get_id(oid, &**pool, &redis).await?; - if let Some(organization_data) = organization_data { - let org_team = - TeamMember::get_from_team_full(organization_data.team_id, &**pool, &redis) - .await?; - for member in org_team { - if !member_user_ids.contains(&member.user_id) { - member_user_ids.push(member.user_id); - members_data.push(member); - } - } - } - } - - let users = - crate::database::models::User::get_many_ids(&member_user_ids, &**pool, &redis).await?; + let users = crate::database::models::User::get_many_ids( + &members_data.iter().map(|x| x.user_id).collect::>(), + &**pool, + &redis, + ) + .await?; let user_id = current_user.as_ref().map(|x| x.id.into()); @@ -94,6 +80,7 @@ pub async fn team_members_get_project( .find(|x| x.user_id == user.id.into() && x.accepted) }) .is_some(); + let team_members: Vec<_> = members_data .into_iter() .filter(|x| { @@ -109,6 +96,7 @@ pub async fn team_members_get_project( }) }) .collect(); + Ok(HttpResponse::Ok().json(team_members)) } else { Err(ApiError::NotFound) diff --git a/tests/common/permissions.rs b/tests/common/permissions.rs index 435456ca..2a645557 100644 --- a/tests/common/permissions.rs +++ b/tests/common/permissions.rs @@ -1093,21 +1093,44 @@ async fn get_project_permissions( project_id: &str, setup_api: &ApiV3, ) -> ProjectPermissions { - let resp = setup_api.get_project_members(project_id, user_pat).await; - let permissions = if resp.status().as_u16() == 200 { - let value: serde_json::Value = test::read_body_json(resp).await; - value - .as_array() - .unwrap() + let project = setup_api + .get_project_deserialized(project_id, user_pat) + .await; + let project_team_id = project.team_id.to_string(); + let organization_id = project.organization.map(|id| id.to_string()); + + let organization = match organization_id { + Some(id) => Some(setup_api.get_organization_deserialized(&id, user_pat).await), + None => None, + }; + + let members = setup_api + .get_team_members_deserialized(&project_team_id, user_pat) + .await; + let permissions = members + .iter() + .find(|member| &member.user.id.to_string() == user_id) + .and_then(|member| member.permissions); + + let organization_members = match organization { + Some(org) => Some( + setup_api + .get_team_members_deserialized(&org.team_id.to_string(), user_pat) + .await, + ), + None => None, + }; + let organization_default_project_permissions = match organization_members { + Some(members) => members .iter() - .find(|member| member["user"]["id"].as_str().unwrap() == user_id) - .map(|member| member["permissions"].as_u64().unwrap()) - .unwrap_or_default() - } else { - 0 + .find(|member| &member.user.id.to_string() == user_id) + .and_then(|member| member.permissions), + None => None, }; - ProjectPermissions::from_bits_truncate(permissions) + permissions + .or(organization_default_project_permissions) + .unwrap_or_default() } async fn get_organization_permissions( diff --git a/tests/teams.rs b/tests/teams.rs index 89b66884..b3e267d8 100644 --- a/tests/teams.rs +++ b/tests/teams.rs @@ -294,13 +294,12 @@ async fn test_get_team_project_orgs() { .await; assert_eq!(members.len(), 0); - // The team members route from project should show: - // - the members of the project team including the ones from the organization + // The team members route from project should show the same! let members = test_env .api .get_project_members_deserialized_common(alpha_project_id, FRIEND_USER_PAT) .await; - assert_eq!(members.len(), 2); + assert_eq!(members.len(), 0); }) .await; }