From 1ed96c15d2cd0ca43360f779a39c4863e55e2034 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Wed, 10 Nov 2021 02:10:18 +0000 Subject: [PATCH] Implement implied permissions (selecting CREATE_CRATE automatically selects PUBLISH_VERSION) Fixes #21 --- chartered-db/src/permissions.rs | 11 +++++++++++ chartered-frontend/src/pages/crate/CrateView.tsx | 6 ++++-- chartered-frontend/src/pages/crate/Members.tsx | 15 +++++++++++++++ chartered-frontend/src/pages/crate/OrganisationView.tsx | 7 +++++++ chartered-web/src/endpoints/web_api/crates/members.rs | 6 ++++-- chartered-web/src/endpoints/web_api/organisations/info.rs | 2 ++ 6 files changed, 43 insertions(+), 4 deletions(-) diff --git a/chartered-db/src/permissions.rs b/chartered-db/src/permissions.rs index 0b3e282..53a4906 100644 --- a/chartered-db/src/permissions.rs +++ a/chartered-db/src/permissions.rs @@ -17,6 +17,17 @@ pub fn names() -> &'static [&'static str] { Self::NAMES } + + /// Returns a list of permissions that implied by setting other permissions, + /// those these can be overridden if the user adding the permssion explicitly + /// removes the permission. + #[must_use] + pub fn implications() -> &'static [[UserPermission; 2]] { + &[ + // original => implied + [Self::CREATE_CRATE, Self::PUBLISH_VERSION], + ] + } } impl diesel::deserialize::FromSql diff --git a/chartered-frontend/src/pages/crate/CrateView.tsx b/chartered-frontend/src/pages/crate/CrateView.tsx index e190ae7..331a4a8 100644 --- a/chartered-frontend/src/pages/crate/CrateView.tsx +++ a/chartered-frontend/src/pages/crate/CrateView.tsx @@ -270,7 +270,8 @@ } interface CratesMembersResponse { - allowed_permissions: string[]; + possible_permissions: string[]; + implied_permissions: string[]; members: Member[]; } @@ -405,7 +406,8 @@ return ( diff --git a/chartered-frontend/src/pages/crate/Members.tsx b/chartered-frontend/src/pages/crate/Members.tsx index a671ede..8dd5a9f 100644 --- a/chartered-frontend/src/pages/crate/Members.tsx +++ a/chartered-frontend/src/pages/crate/Members.tsx @@ -16,11 +16,13 @@ export default function Members({ members, possiblePermissions, + impliedPermissions, saveMemberPermissions, deleteMember, }: { members: Member[]; possiblePermissions?: string[]; + impliedPermissions?: string[][][]; saveMemberPermissions: ( prospectiveMember: boolean, uuid: string, @@ -53,6 +55,7 @@ member={member} prospectiveMember={false} possiblePermissions={possiblePermissions} + impliedPermissions={impliedPermissions} saveMemberPermissions={saveMemberPermissions} deleteMember={deleteMember} /> @@ -64,6 +67,7 @@ member={member} prospectiveMember={true} possiblePermissions={possiblePermissions} + impliedPermissions={impliedPermissions} saveMemberPermissions={saveMemberPermissions} deleteMember={deleteMember} /> @@ -96,12 +100,14 @@ member, prospectiveMember, possiblePermissions, + impliedPermissions, saveMemberPermissions, deleteMember, }: { member: Member; prospectiveMember: boolean; possiblePermissions?: string[]; + impliedPermissions?: string[][][]; saveMemberPermissions: ( prospectiveMember: boolean, uuid: string, @@ -225,6 +231,7 @@ any; }) { @@ -394,6 +403,12 @@ if (e.target.checked) { newUserPermissions.add(permission); + + for (const [a, b] of impliedPermissions) { + if (a[0] === permission) { + newUserPermissions.add(b[0]); + } + } } else { newUserPermissions.delete(permission); } diff --git a/chartered-frontend/src/pages/crate/OrganisationView.tsx b/chartered-frontend/src/pages/crate/OrganisationView.tsx index e3f1909..ed99dd1 100644 --- a/chartered-frontend/src/pages/crate/OrganisationView.tsx +++ a/chartered-frontend/src/pages/crate/OrganisationView.tsx @@ -16,6 +16,7 @@ interface OrganisationDetails { possible_permissions?: string[]; + implied_permissions?: string[][][]; crates: Crate[]; members: Member[]; description: string; @@ -153,6 +154,9 @@ possiblePermissions={ organisationDetails.possible_permissions } + impliedPermissions={ + organisationDetails.implied_permissions + } reload={() => setReload(reload + 1)} /> ) : ( @@ -219,6 +223,7 @@ organisation: string; members: Member[]; possiblePermissions?: string[]; + impliedPermissions?: string[][][]; reload: () => any; } @@ -226,6 +231,7 @@ organisation, members, possiblePermissions, + impliedPermissions, reload, }: ListMemberParams) { const auth = useAuth(); @@ -289,6 +295,7 @@ diff --git a/chartered-web/src/endpoints/web_api/crates/members.rs b/chartered-web/src/endpoints/web_api/crates/members.rs index 3f3dc09..f84969a 100644 --- a/chartered-web/src/endpoints/web_api/crates/members.rs +++ a/chartered-web/src/endpoints/web_api/crates/members.rs @@ -36,7 +36,8 @@ .collect(); Ok(Json(GetResponse { - allowed_permissions: UserPermission::names(), + possible_permissions: UserPermission::names(), + implied_permissions: UserPermission::implications(), members, })) } @@ -109,7 +110,8 @@ #[derive(Serialize)] pub struct GetResponse { - allowed_permissions: &'static [&'static str], + possible_permissions: &'static [&'static str], + implied_permissions: &'static [[UserPermission; 2]], members: Vec, } diff --git a/chartered-web/src/endpoints/web_api/organisations/info.rs b/chartered-web/src/endpoints/web_api/organisations/info.rs index 8cc54a6..828557f 100644 --- a/chartered-web/src/endpoints/web_api/organisations/info.rs +++ a/chartered-web/src/endpoints/web_api/organisations/info.rs @@ -34,6 +34,7 @@ description: organisation.organisation().description.to_string(), // all the permissions the requesting user can give out for this organisation possible_permissions: can_manage_users.then(UserPermission::all), + implied_permissions: can_manage_users.then(UserPermission::implications), crates: crates .into_iter() .map(|v| ResponseCrate { @@ -57,6 +58,7 @@ pub struct Response { description: String, possible_permissions: Option, + implied_permissions: Option<&'static [[UserPermission; 2]]>, crates: Vec, members: Vec, } -- rgit 0.1.3