diff --git a/thoth-api/src/graphql/model.rs b/thoth-api/src/graphql/model.rs index 194da909..25360680 100644 --- a/thoth-api/src/graphql/model.rs +++ b/thoth-api/src/graphql/model.rs @@ -1975,18 +1975,37 @@ impl MutationRoot { #[graphql(description = "Values to apply to existing location")] data: PatchLocation, ) -> FieldResult { context.token.jwt.as_ref().ok_or(ThothError::Unauthorised)?; - let location = Location::from_id(&context.db, &data.location_id).unwrap(); + let current_location = Location::from_id(&context.db, &data.location_id).unwrap(); + let publication = Publication::from_id(&context.db, &data.publication_id).unwrap(); + let thoth_location = publication.locations( + context, + Some(100), + Some(0), + Some(LocationOrderBy::default()), + Some(vec![LocationPlatform::Thoth]), + ); + + let locations = thoth_location?; + + let has_canonical_thoth_location = locations.iter().any(|location| { + location.location_platform == LocationPlatform::Thoth && location.canonical + }); + // Only superusers can update the canonical location when a Thoth Location Platform canonical location already exists + if has_canonical_thoth_location && data.canonical && !context.account_access.is_superuser { + return Err(ThothError::ThothUpdateCanonicalError.into()); + } + // Only superusers can edit locations where Location Platform is Thoth if !context.account_access.is_superuser - && location.location_platform == LocationPlatform::Thoth + && current_location.location_platform == LocationPlatform::Thoth { return Err(ThothError::ThothLocationError.into()); } context .account_access - .can_edit(location.publisher_id(&context.db)?)?; + .can_edit(current_location.publisher_id(&context.db)?)?; - if data.publication_id != location.publication_id { + if data.publication_id != current_location.publication_id { context .account_access .can_edit(publisher_id_from_publication_id( @@ -2000,7 +2019,7 @@ impl MutationRoot { } let account_id = context.token.jwt.as_ref().unwrap().account_id(&context.db); - location + current_location .update(&context.db, &data, &account_id) .map_err(|e| e.into()) } diff --git a/thoth-app/src/component/locations_form.rs b/thoth-app/src/component/locations_form.rs index e9cf4315..028ff02f 100644 --- a/thoth-app/src/component/locations_form.rs +++ b/thoth-app/src/component/locations_form.rs @@ -157,12 +157,7 @@ impl Component for LocationsFormComponent { .enum_values .clone() .into_iter() - .filter(|platform| { - *platform - != LocationPlatformValues { - name: LocationPlatform::Thoth, - } - }) + .filter(|platform| platform.name != LocationPlatform::Thoth) .collect() } } diff --git a/thoth-errors/src/lib.rs b/thoth-errors/src/lib.rs index 9244de18..26445d53 100644 --- a/thoth-errors/src/lib.rs +++ b/thoth-errors/src/lib.rs @@ -99,6 +99,8 @@ pub enum ThothError { NoWithdrawnDateError, #[error("Only superusers can create, edit, or delete Locations where the Location Platform is Thoth.")] ThothLocationError, + #[error("Only superusers can update the canonical location when Thoth Location Platform is already set as canonical.")] + ThothUpdateCanonicalError, } #[cfg(not(target_arch = "wasm32"))]