able to query for UserGroup permissions

This commit is contained in:
mbecker20
2024-04-21 14:36:32 -07:00
parent c676b5168a
commit 577b93e2dc
9 changed files with 79 additions and 47 deletions

View File

@@ -45,7 +45,7 @@ enum ReadRequest {
ListApiKeys(ListApiKeys),
ListPermissions(ListPermissions),
GetPermissionLevel(GetPermissionLevel),
ListUserPermissions(ListUserPermissions),
ListUserTargetPermissions(ListUserTargetPermissions),
// ==== USER GROUP ====
GetUserGroup(GetUserGroup),

View File

@@ -3,8 +3,8 @@ use axum::async_trait;
use monitor_client::{
api::read::{
GetPermissionLevel, GetPermissionLevelResponse, ListPermissions,
ListPermissionsResponse, ListUserPermissions,
ListUserPermissionsResponse,
ListPermissionsResponse, ListUserTargetPermissions,
ListUserTargetPermissionsResponse,
},
entities::{permission::PermissionLevel, user::User},
};
@@ -52,20 +52,21 @@ impl Resolve<GetPermissionLevel, User> for State {
}
#[async_trait]
impl Resolve<ListUserPermissions, User> for State {
impl Resolve<ListUserTargetPermissions, User> for State {
async fn resolve(
&self,
ListUserPermissions { user_id }: ListUserPermissions,
ListUserTargetPermissions { user_target }: ListUserTargetPermissions,
user: User,
) -> anyhow::Result<ListUserPermissionsResponse> {
) -> anyhow::Result<ListUserTargetPermissionsResponse> {
if !user.admin {
return Err(anyhow!("this method is admin only"));
}
let (variant, id) = user_target.extract_variant_id();
find_collect(
&db_client().await.permissions,
doc! {
"user_target.type": "User",
"user_target.id": user_id
"user_target.type": variant.as_ref(),
"user_target.id": id
},
None,
)

View File

@@ -23,6 +23,9 @@ pub struct RunBuild {
//
/// Cancels the target build.
/// Only does anything if the build is `building` when called.
/// Response: [Update]
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Request, EmptyTraits,

View File

@@ -4,13 +4,15 @@ use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use crate::entities::{
permission::{Permission, PermissionLevel},
permission::{Permission, PermissionLevel, UserTarget},
update::ResourceTarget,
};
use super::MonitorReadRequest;
/// List permissions for the calling user. Response: [ListPermissionsResponse]
/// List permissions for the calling user.
/// Does not include any permissions on UserGroups they may be a part of.
/// Response: [ListPermissionsResponse]
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Request, EmptyTraits,
@@ -24,7 +26,9 @@ pub type ListPermissionsResponse = Vec<Permission>;
//
/// Gets the calling user's permission level on a specific resource. Response: [PermissionLevel]
/// Gets the calling user's permission level on a specific resource.
/// Factors in any UserGroup's permissions they may be a part of.
/// Response: [PermissionLevel]
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Request, EmptyTraits,
@@ -40,16 +44,17 @@ pub type GetPermissionLevelResponse = PermissionLevel;
//
/// List permissions for a specific user. Admin only. Response: [ListUserPermissionsResponse]
/// List permissions for a specific user. **Admin only**.
/// Response: [ListUserTargetPermissionsResponse]
#[typeshare]
#[derive(
Serialize, Deserialize, Debug, Clone, Request, EmptyTraits,
)]
#[empty_traits(MonitorReadRequest)]
#[response(ListUserPermissionsResponse)]
pub struct ListUserPermissions {
pub user_id: String,
#[response(ListUserTargetPermissionsResponse)]
pub struct ListUserTargetPermissions {
pub user_target: UserTarget,
}
#[typeshare]
pub type ListUserPermissionsResponse = Vec<Permission>;
pub type ListUserTargetPermissionsResponse = Vec<Permission>;

View File

@@ -18,7 +18,7 @@ export type ReadResponses = {
ListApiKeys: Types.ListApiKeysResponse;
ListPermissions: Types.ListPermissionsResponse;
GetPermissionLevel: Types.GetPermissionLevelResponse;
ListUserPermissions: Types.ListUserPermissionsResponse;
ListUserTargetPermissions: Types.ListUserTargetPermissionsResponse;
// ==== USER GROUP ====
GetUserGroup: Types.GetUserGroupResponse;

View File

@@ -553,7 +553,7 @@ export type ListPermissionsResponse = Permission[];
export type GetPermissionLevelResponse = PermissionLevel;
export type ListUserPermissionsResponse = Permission[];
export type ListUserTargetPermissionsResponse = Permission[];
export enum ProcedureType {
/** Run the executions one after the other, in order of increasing index. */
@@ -1187,6 +1187,11 @@ export interface RunBuild {
build: string;
}
/**
* Cancels the target build.
* Only does anything if the build is `building` when called.
* Response: [Update]
*/
export interface CancelBuild {
/** Can be id or name */
build: string;
@@ -1461,18 +1466,29 @@ export interface GetCoreInfoResponse {
github_webhook_base_url: string;
}
/** List permissions for the calling user. Response: [ListPermissionsResponse] */
/**
* List permissions for the calling user.
* Does not include any permissions on UserGroups they may be a part of.
* Response: [ListPermissionsResponse]
*/
export interface ListPermissions {
}
/** Gets the calling user's permission level on a specific resource. Response: [PermissionLevel] */
/**
* Gets the calling user's permission level on a specific resource.
* Factors in any UserGroup's permissions they may be a part of.
* Response: [PermissionLevel]
*/
export interface GetPermissionLevel {
target: ResourceTarget;
}
/** List permissions for a specific user. Admin only. Response: [ListUserPermissionsResponse] */
export interface ListUserPermissions {
user_id: string;
/**
* List permissions for a specific user. **Admin only**.
* Response: [ListUserTargetPermissionsResponse]
*/
export interface ListUserTargetPermissions {
user_target: UserTarget;
}
export interface GetProcedure {
@@ -2124,7 +2140,7 @@ export type ReadRequest =
| { type: "ListApiKeys", params: ListApiKeys }
| { type: "ListPermissions", params: ListPermissions }
| { type: "GetPermissionLevel", params: GetPermissionLevel }
| { type: "ListUserPermissions", params: ListUserPermissions }
| { type: "ListUserTargetPermissions", params: ListUserTargetPermissions }
| { type: "GetUserGroup", params: GetUserGroup }
| { type: "ListUserGroups", params: ListUserGroups }
| { type: "FindResources", params: FindResources }

View File

@@ -55,7 +55,7 @@
"postcss": "8.4.38",
"tailwindcss": "3.4.3",
"typescript": "5.4.5",
"vite": "5.2.9",
"vite": "5.2.10",
"vite-tsconfig-paths": "4.3.2"
}
}

View File

@@ -133,14 +133,18 @@ export const UserPage = () => {
)
}
>
{!user.admin && <PermissionsTable />}
{!user.admin && (
<PermissionsTable user_target={{ type: "User", id: user_id }} />
)}
</Page>
)
);
};
const useUserPermissions = (user_id: string) => {
const permissions = useRead("ListUserPermissions", { user_id }).data;
const useUserTargetPermissions = (user_target: Types.UserTarget) => {
const permissions = useRead("ListUserTargetPermissions", {
user_target,
}).data;
const servers = useRead("ListServers", {}).data;
const deployments = useRead("ListDeployments", {}).data;
const builds = useRead("ListBuilds", {}).data;
@@ -149,18 +153,18 @@ const useUserPermissions = (user_id: string) => {
const builders = useRead("ListBuilders", {}).data;
const alerters = useRead("ListAlerters", {}).data;
const perms: (Types.Permission & { name: string })[] = [];
addPerms(user_id, permissions, "Server", servers, perms);
addPerms(user_id, permissions, "Deployment", deployments, perms);
addPerms(user_id, permissions, "Build", builds, perms);
addPerms(user_id, permissions, "Repo", repos, perms);
addPerms(user_id, permissions, "Procedure", procedures, perms);
addPerms(user_id, permissions, "Builder", builders, perms);
addPerms(user_id, permissions, "Alerter", alerters, perms);
addPerms(user_target, permissions, "Server", servers, perms);
addPerms(user_target, permissions, "Deployment", deployments, perms);
addPerms(user_target, permissions, "Build", builds, perms);
addPerms(user_target, permissions, "Repo", repos, perms);
addPerms(user_target, permissions, "Procedure", procedures, perms);
addPerms(user_target, permissions, "Builder", builders, perms);
addPerms(user_target, permissions, "Alerter", alerters, perms);
return perms;
};
function addPerms<I>(
user_id: string,
user_target: Types.UserTarget,
permissions: Types.Permission[] | undefined,
resource_type: UsableResource,
resources: Types.ResourceListItem<I>[] | undefined,
@@ -176,7 +180,7 @@ function addPerms<I>(
perms.push({ ...perm, name: resource.name });
} else {
perms.push({
user_target: { type: "User", id: user_id },
user_target,
name: resource.name,
level: Types.PermissionLevel.None,
resource_target: { type: resource_type, id: resource.id },
@@ -185,7 +189,11 @@ function addPerms<I>(
});
}
const PermissionsTable = () => {
const PermissionsTable = ({
user_target,
}: {
user_target: Types.UserTarget;
}) => {
const { toast } = useToast();
const [showNone, setShowNone] = useState(false);
const [resourceType, setResourceType] = useState<UsableResource | "All">(
@@ -194,12 +202,11 @@ const PermissionsTable = () => {
const [search, setSearch] = useState("");
const searchSplit = search.toLowerCase().split(" ");
const inv = useInvalidate();
const user_id = useParams().id as string;
const permissions = useUserPermissions(user_id);
const permissions = useUserTargetPermissions(user_target);
const { mutate } = useWrite("UpdatePermissionOnTarget", {
onSuccess: () => {
toast({ title: "Updated user permission" });
inv(["ListUserPermissions"]);
toast({ title: "Updated permission" });
inv(["ListUserTargetPermissions"]);
},
});
return (
@@ -330,7 +337,7 @@ const PermissionsTable = () => {
onValueChange={(value) =>
mutate({
...permission,
user_target: { type: "User", id: user_id },
user_target,
permission: value as Types.PermissionLevel,
})
}

View File

@@ -2805,10 +2805,10 @@ vite-tsconfig-paths@4.3.2:
globrex "^0.1.2"
tsconfck "^3.0.3"
vite@5.2.9:
version "5.2.9"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.9.tgz#cd9a356c6ff5f7456c09c5ce74068ffa8df743d9"
integrity sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==
vite@5.2.10:
version "5.2.10"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.2.10.tgz#2ac927c91e99d51b376a5c73c0e4b059705f5bd7"
integrity sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==
dependencies:
esbuild "^0.20.1"
postcss "^8.4.38"