Skip to content

Commit

Permalink
refactor: improve role dependency-related functions and i18n
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Wang <[email protected]>
  • Loading branch information
ruibaby committed Jan 22, 2024
1 parent 14580b9 commit d7f0a57
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
halo.run/role-template: "true"
annotations:
rbac.authorization.halo.run/dependencies: |
[ "role-template-view-posts", "role-template-manage-snapshots", "role-template-manage-tags", "role-template-manage-categories" ]
[ "role-template-view-posts", "role-template-manage-snapshots", "role-template-manage-tags", "role-template-manage-categories", "role-template-post-author" ]
rbac.authorization.halo.run/module: "Posts Management"
rbac.authorization.halo.run/display-name: "Post Manage"
rbac.authorization.halo.run/ui-permissions: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ metadata:
# Currently, yaml definition does not support i18n, please see https://github.com/halo-dev/halo/issues/3573
rbac.authorization.halo.run/display-name: "编辑者"
rbac.authorization.halo.run/dependencies: |
["role-template-post-editor"]
rules: [ ]
["role-template-manage-posts"]
rules: []

---
apiVersion: v1alpha1
kind: "Role"
metadata:
name: role-template-post-editor
# Deprecated, will be removed in the future
deletionTimestamp: 2023-12-01T03:36:25.875373Z
labels:
halo.run/role-template: "true"
annotations:
Expand All @@ -24,7 +26,7 @@ metadata:
rbac.authorization.halo.run/display-name: "Post Editor"
rbac.authorization.halo.run/dependencies: |
["role-template-manage-posts", "role-template-post-author"]
rules: [ ]
rules: []

---
apiVersion: v1alpha1
Expand All @@ -40,7 +42,7 @@ metadata:
rbac.authorization.halo.run/redirect-on-login: "/uc"
rbac.authorization.halo.run/dependencies: |
[ "role-template-post-author" ]
rules: [ ]
rules: []

---
apiVersion: v1alpha1
Expand All @@ -55,7 +57,7 @@ metadata:
rbac.authorization.halo.run/display-name: "Post Author"
rbac.authorization.halo.run/dependencies: |
[ "role-template-post-contributor", "role-template-post-publisher", "role-template-post-attachment-manager" ]
rules: [ ]
rules: []

---
apiVersion: v1alpha1
Expand All @@ -71,7 +73,7 @@ metadata:
rbac.authorization.halo.run/redirect-on-login: "/uc"
rbac.authorization.halo.run/dependencies: |
[ "role-template-post-contributor" ]
rules: [ ]
rules: []

---
apiVersion: v1alpha1
Expand All @@ -89,12 +91,12 @@ metadata:
rbac.authorization.halo.run/ui-permissions: |
[ "uc:posts:manage" ]
rules:
- apiGroups: [ "uc.api.content.halo.run" ]
resources: [ "posts" ]
verbs: [ "get", "list", "create", "update", "delete" ]
- apiGroups: [ "uc.api.content.halo.run" ]
resources: [ "posts/draft" ]
verbs: [ "update", "get" ]
- apiGroups: ["uc.api.content.halo.run"]
resources: ["posts"]
verbs: ["get", "list", "create", "update", "delete"]
- apiGroups: ["uc.api.content.halo.run"]
resources: ["posts/draft"]
verbs: ["update", "get"]

---
apiVersion: v1alpha1
Expand All @@ -109,9 +111,9 @@ metadata:
rbac.authorization.halo.run/ui-permissions: |
[ "uc:posts:publish" ]
rules:
- apiGroups: [ "uc.api.content.halo.run" ]
resources: [ "posts/publish", "posts/unpublish" ]
verbs: [ "update" ]
- apiGroups: ["uc.api.content.halo.run"]
resources: ["posts/publish", "posts/unpublish"]
verbs: ["update"]

---
apiVersion: v1alpha1
Expand All @@ -126,6 +128,6 @@ metadata:
rbac.authorization.halo.run/ui-permissions: |
[ "uc:attachments:manage" ]
rules:
- apiGroups: [ "uc.api.content.halo.run" ]
resources: [ "attachments" ]
verbs: [ "create", "update", "delete" ]
- apiGroups: ["uc.api.content.halo.run"]
resources: ["attachments"]
verbs: ["create", "update", "delete"]
46 changes: 23 additions & 23 deletions console/console-src/modules/system/roles/RoleDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
VDescriptionItem,
} from "@halo-dev/components";
import { useRoute } from "vue-router";
import { computed, onMounted, ref, watch } from "vue";
import { computed, ref, watch } from "vue";
import { apiClient } from "@/utils/api-client";
import { pluginLabels, roleLabels } from "@/constants/labels";
import { rbacAnnotations } from "@/constants/annotations";
Expand All @@ -20,6 +20,8 @@ import { SUPER_ROLE_NAME } from "@/constants/constants";
import { useI18n } from "vue-i18n";
import { formatDatetime } from "@/utils/date";
import { useQuery } from "@tanstack/vue-query";
import type { Role } from "packages/api-client/dist";
import { resolveDeepDependencies } from "@/utils/role";
const route = useRoute();
const { t } = useI18n();
Expand Down Expand Up @@ -58,12 +60,14 @@ const getRoleCountText = computed(() => {
return t("core.role.common.text.contains_all_permissions");
}
const dependenciesCount = JSON.parse(
formState.value.metadata.annotations?.[rbacAnnotations.DEPENDENCIES] || "[]"
).length;
const dependencies = new Set<string>(
resolveDeepDependencies(formState.value, roleTemplates.value || [])
);
console.log(dependencies);
return t("core.role.common.text.contains_n_permissions", {
count: dependenciesCount,
count: dependencies.size || 0,
});
});
Expand All @@ -77,31 +81,27 @@ watch(
}
);
const handleFetchRole = async () => {
try {
const response = await apiClient.extension.role.getv1alpha1Role({
const { refetch } = useQuery<Role>({
queryKey: ["role", route.params.name],
queryFn: async () => {
const { data } = await apiClient.extension.role.getv1alpha1Role({
name: route.params.name as string,
});
formState.value = response.data;
selectedRoleTemplates.value = new Set(
JSON.parse(
response.data.metadata.annotations?.[rbacAnnotations.DEPENDENCIES] ||
"[]"
)
return data;
},
onSuccess(data) {
formState.value = data;
selectedRoleTemplates.value = new Set<string>(
resolveDeepDependencies(data, roleTemplates.value || [])
);
} catch (error) {
console.error(error);
}
};
},
enabled: computed(() => !!roleTemplates.value),
});
const handleUpdateRole = async () => {
await handleCreateOrUpdate();
await handleFetchRole();
await refetch();
};
onMounted(() => {
handleFetchRole();
});
</script>
<template>
<VPageHeader :title="$t('core.role.detail.title')">
Expand Down
82 changes: 60 additions & 22 deletions console/console-src/modules/system/roles/RoleList.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
// core libs
import { computed, ref, watch } from "vue";
import type { Role } from "@halo-dev/api-client";
import { computed, ref } from "vue";
import type { Role, RoleList } from "@halo-dev/api-client";
// components
import {
Expand All @@ -25,43 +25,81 @@ import RoleEditingModal from "./components/RoleEditingModal.vue";
import { rbacAnnotations } from "@/constants/annotations";
import { formatDatetime } from "@/utils/date";
// hooks
import { useFetchRole } from "@/composables/use-role";
// libs
import { apiClient } from "@/utils/api-client";
import Fuse from "fuse.js";
import { usePermission } from "@/utils/permission";
import { roleLabels } from "@/constants/labels";
import { SUPER_ROLE_NAME } from "@/constants/constants";
import { useI18n } from "vue-i18n";
import { useQuery } from "@tanstack/vue-query";
import { resolveDeepDependencies } from "@/utils/role";
const { currentUserHasPermission } = usePermission();
const { t } = useI18n();
const editingModal = ref<boolean>(false);
const selectedRole = ref<Role>();
const { roles, handleFetchRoles, loading } = useFetchRole();
let fuse: Fuse<Role> | undefined = undefined;
watch(
() => roles.value,
(value) => {
fuse = new Fuse(value, {
keys: ["spec.displayName", "metadata.name"],
const { data: roleTemplates } = useQuery({
queryKey: ["role-templates"],
queryFn: async () => {
const { data } = await apiClient.extension.role.listv1alpha1Role({
page: 0,
size: 0,
labelSelector: [`${roleLabels.TEMPLATE}=true`, "!halo.run/hidden"],
});
return data.items;
},
});
const {
data: roles,
isLoading,
refetch,
} = useQuery<RoleList>({
queryKey: ["roles"],
queryFn: async () => {
const { data } = await apiClient.extension.role.listv1alpha1Role({
page: 0,
size: 0,
labelSelector: [`!${roleLabels.TEMPLATE}`],
});
return data;
},
refetchInterval(data) {
const hasDeletingRole = data?.items.some(
(item) => !!item.metadata.deletionTimestamp
);
return hasDeletingRole ? 1000 : false;
},
onSuccess(data) {
fuse = new Fuse(data.items, {
keys: [
{
name: "displayName",
getFn: (role) => {
return (
role.metadata.annotations?.[rbacAnnotations.DISPLAY_NAME] || ""
);
},
},
"metadata.name",
],
useExtendedSearch: true,
threshold: 0.2,
});
}
);
},
enabled: computed(() => !!roleTemplates.value),
});
const keyword = ref("");
const searchResults = computed(() => {
if (!fuse || !keyword.value) {
return roles.value;
return roles.value?.items || [];
}
return fuse?.search(keyword.value).map((item) => item.item);
Expand All @@ -76,12 +114,12 @@ const getRoleCountText = (role: Role) => {
return t("core.role.common.text.contains_all_permissions");
}
const dependenciesCount = JSON.parse(
role.metadata.annotations?.[rbacAnnotations.DEPENDENCIES] || "[]"
).length;
const dependencies = new Set<string>(
resolveDeepDependencies(role, roleTemplates.value || [])
);
return t("core.role.common.text.contains_n_permissions", {
count: dependenciesCount,
count: dependencies.size || 0,
});
};
Expand All @@ -92,7 +130,7 @@ const handleOpenEditingModal = (role: Role) => {
const onEditingModalClose = () => {
selectedRole.value = undefined;
handleFetchRoles();
refetch();
};
const handleCloneRole = async (role: Role) => {
Expand Down Expand Up @@ -152,7 +190,7 @@ const handleDelete = async (role: Role) => {
} catch (e) {
console.error("Failed to delete role", e);
} finally {
handleFetchRoles();
refetch();
}
},
});
Expand Down Expand Up @@ -200,7 +238,7 @@ const handleDelete = async (role: Role) => {
</div>
</div>
</template>
<VLoading v-if="loading" />
<VLoading v-if="isLoading" />
<Transition v-else appear name="fade">
<ul
class="box-border h-full w-full divide-y divide-gray-100"
Expand Down
17 changes: 9 additions & 8 deletions console/src/composables/use-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { rbacAnnotations } from "@/constants/annotations";
import { apiClient } from "@/utils/api-client";
import { Toast } from "@halo-dev/components";
import { useI18n } from "vue-i18n";
import { resolveDeepDependencies } from "@/utils/role";

interface RoleTemplateGroup {
module: string | null | undefined;
Expand Down Expand Up @@ -38,7 +39,7 @@ interface useRoleFormReturn {
initialFormState: Role;
saving: Ref<boolean>;
isUpdateMode: ComputedRef<boolean>;
handleCreateOrUpdate: () => void;
handleCreateOrUpdate: () => Promise<void>;
}

interface useRoleTemplateSelectionReturn {
Expand Down Expand Up @@ -271,15 +272,15 @@ export function useRoleTemplateSelection(
const role = roleTemplates.value?.find(
(role) => role.metadata.name === value
);
const dependencies =
role?.metadata.annotations?.[rbacAnnotations.DEPENDENCIES];
if (!dependencies) {

if (!role) {
return;
}
const dependenciesArray = JSON.parse(dependencies);
dependenciesArray.forEach((role) => {
selectedRoleTemplates.value.add(role);
});

selectedRoleTemplates.value = new Set([
role.metadata.name,
...resolveDeepDependencies(role, roleTemplates.value || []),
]);
};

return {
Expand Down
Loading

0 comments on commit d7f0a57

Please sign in to comment.