Skip to content

Commit

Permalink
add permission checks for backend related buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
dafengzhen committed Mar 17, 2024
1 parent 06e671b commit 3413588
Show file tree
Hide file tree
Showing 66 changed files with 664 additions and 160 deletions.
83 changes: 43 additions & 40 deletions src/main/java/com/youdeyiwu/service/user/impl/UserServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.youdeyiwu.model.dto.user.UsersCountByDateDto;
import com.youdeyiwu.model.entity.forum.PostEntity;
import com.youdeyiwu.model.entity.user.ActionEntity;
import com.youdeyiwu.model.entity.user.MenuEntity;
import com.youdeyiwu.model.entity.user.SubmenuEntity;
import com.youdeyiwu.model.entity.user.UserEntity;
import com.youdeyiwu.model.vo.PageVo;
Expand Down Expand Up @@ -592,48 +593,50 @@ private List<MenuEntityVo> getAuthenticatedUserMenus() {
.filter(roleEntity -> !roleEntity.getMenus().isEmpty())
.flatMap(roleEntity -> roleEntity.getMenus()
.stream()
.sorted(
Comparator.comparing(MenuEntity::getSort)
.thenComparing(MenuEntity::getId).reversed()
)
.map(menuEntity -> {
MenuEntityVo vo = menuMapper.entityToVo(menuEntity);
if (menuEntity.getSubmenus().isEmpty()) {
vo.setActions(
menuEntity.getActions()
.stream()
.filter(actionEntity -> actionEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(ActionEntity::getSort)
.thenComparing(ActionEntity::getId).reversed()
)
.map(actionMapper::entityToVo)
.collect(Collectors.toCollection(LinkedHashSet::new))
);
vo.setSubmenus(new HashSet<>());
} else {
Set<SubmenuEntityVo> submenuEntityVos = menuEntity.getSubmenus()
.stream()
.filter(submenuEntity -> submenuEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(SubmenuEntity::getSort)
.thenComparing(SubmenuEntity::getId).reversed()
)
.map(submenuEntity -> {
SubmenuEntityVo submenuEntityVo = submenuMapper.entityToVo(submenuEntity);
submenuEntityVo.setActions(
submenuEntity.getActions()
.stream()
.filter(actionEntity -> actionEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(ActionEntity::getSort)
.thenComparing(ActionEntity::getId).reversed()
)
.map(actionMapper::entityToVo)
.collect(Collectors.toCollection(LinkedHashSet::new))
);
return submenuEntityVo;
})
.collect(Collectors.toCollection(LinkedHashSet::new));
vo.setActions(new HashSet<>());
vo.setSubmenus(submenuEntityVos);
}
vo.setActions(
menuEntity.getActions()
.stream()
.filter(actionEntity -> actionEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(ActionEntity::getSort)
.thenComparing(ActionEntity::getId).reversed()
)
.map(actionMapper::entityToVo)
.collect(Collectors.toCollection(LinkedHashSet::new))
);

vo.setSubmenus(
menuEntity.getSubmenus()
.stream()
.filter(submenuEntity -> submenuEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(SubmenuEntity::getSort)
.thenComparing(SubmenuEntity::getId).reversed()
)
.map(submenuEntity -> {
SubmenuEntityVo submenuEntityVo = submenuMapper.entityToVo(submenuEntity);
submenuEntityVo.setActions(
submenuEntity.getActions()
.stream()
.filter(actionEntity -> actionEntity.getRoles().contains(roleEntity))
.sorted(
Comparator.comparing(ActionEntity::getSort)
.thenComparing(ActionEntity::getId).reversed()
)
.map(actionMapper::entityToVo)
.collect(Collectors.toCollection(LinkedHashSet::new))
);
return submenuEntityVo;
})
.collect(Collectors.toCollection(LinkedHashSet::new))
);

return vo;
})
)
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/db/migration/V1_5__init_action.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ VALUES (1, null, now(), false, null, now(), 0, 'Section Create', 'Sections#Creat
(50, null, now(), false, null, now(), 0, 'Actions Update Roles', 'Actions#Update Roles', 0, 17, null),
(51, null, now(), false, null, now(), 0, 'Actions Delete', 'Actions#Delete', 0, 17, null),
(52, null, now(), false, null, now(), 0, 'JwtConfigs Update', 'JwtConfigs#Update', 0, 18, null),
(53, null, now(), false, null, now(), 0, 'PointConfigs Update', 'PointConfigs#Update', 0, 18, null);
(53, null, now(), false, null, now(), 0, 'PointConfigs Update', 'PointConfigs#Update', 0, 18, null),
(54, null, now(), false, null, now(), 0, 'Post Delete', 'Posts#Delete', 0, 6, null),
(55, null, now(), false, null, now(), 0, 'Section Update', 'Sections#Delete', 0, 2, null),
(56, null, now(), false, null, now(), 0, 'Section Groups Delete', 'Section Groups#Delete', 0, 3, null),
(57, null, now(), false, null, now(), 0, 'Comments Update State', 'Comments#Update State', 0, 8, null);

6 changes: 5 additions & 1 deletion src/main/resources/db/migration/V1_8__init_role_action.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ VALUES (1, 1),
(50, 1),
(51, 1),
(52, 1),
(53, 1);
(53, 1),
(54, 1),
(55, 1),
(56, 1),
(57, 1);
8 changes: 7 additions & 1 deletion web/app/[locale]/admin/actions/[id]/delete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ import { GlobalContext } from '@/app/[locale]/contexts';
import RefreshAction from '@/app/[locale]/actions/refresh-action';
import type { IAction } from '@/app/[locale]/interfaces/menus';
import DeleteActionAction from '@/app/[locale]/actions/actions/delete-action-action';
import useMenuActionPermission from '@/app/[locale]/hooks/useMenuActionPermission';

export default function Delete({ action }: { action: IAction }) {
const { toast } = useContext(GlobalContext);
const { isActionDisabled, AccessDeniedAlert } = useMenuActionPermission(
'/admin/actions',
'Actions#Delete',
);

const deleteActionActionMutation = useMutation({
mutationFn: async (variables: { id: number }) => {
Expand Down Expand Up @@ -79,12 +84,13 @@ export default function Delete({ action }: { action: IAction }) {
<div className="mt-4">
<button
onClick={onClickDelete}
disabled={deleteActionActionMutation.isPending}
disabled={isActionDisabled || deleteActionActionMutation.isPending}
type="button"
className="btn btn-sm btn-danger"
>
{deleteActionActionMutation.isPending ? 'Deleting' : 'Delete'}
</button>
<AccessDeniedAlert />
</div>
</div>
</Box>
Expand Down
10 changes: 9 additions & 1 deletion web/app/[locale]/admin/actions/[id]/update-roles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,17 @@ import UpdateRolesActionAction, {
} from '@/app/[locale]/actions/actions/update-roles-action-action';
import { nonNum } from '@/app/[locale]/common/client';
import SimpleDynamicInput from '@/app/[locale]/common/simple-dynamic-input';
import useMenuActionPermission from '@/app/[locale]/hooks/useMenuActionPermission';

export default function UpdateRoles({ action }: { action: IAction }) {
const { toast } = useContext(GlobalContext);
const [roles, setRoles] = useState<string[]>(
action.roles.map((item) => item.id + ''),
);
const { isActionDisabled, AccessDeniedAlert } = useMenuActionPermission(
'/admin/actions',
'Actions#Update Roles',
);

const updateRolesActionActionMutation = useMutation({
mutationFn: async (variables: {
Expand Down Expand Up @@ -81,14 +86,17 @@ export default function UpdateRoles({ action }: { action: IAction }) {

<div>
<button
disabled={updateRolesActionActionMutation.isPending}
disabled={
isActionDisabled || updateRolesActionActionMutation.isPending
}
type="submit"
className="btn btn-success"
>
{updateRolesActionActionMutation.isPending
? 'Updating'
: 'Update Action Role'}
</button>
<AccessDeniedAlert />
</div>
</form>
</Box>
Expand Down
7 changes: 7 additions & 0 deletions web/app/[locale]/admin/actions/[id]/update.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UpdateActionAction, {
type IUpdateActionActionVariables,
} from '@/app/[locale]/actions/actions/update-action-action';
import { ACTION_PAGES_DATA } from '@/app/[locale]/constants';
import useMenuActionPermission from '@/app/[locale]/hooks/useMenuActionPermission';

const ACTION_PAGES = Object.keys(ACTION_PAGES_DATA);

Expand All @@ -32,6 +33,10 @@ export default function Update({ action }: { action: IAction }) {
menu: (action.menu?.id ?? '') + '' ?? '',
submenu: (action.submenu?.id ?? '') + '' ?? '',
});
const { isActionDisabled, AccessDeniedAlert } = useMenuActionPermission(
'/admin/actions',
'Actions#Update',
);

const updateActionActionMutation = useMutation({
mutationFn: async (variables: {
Expand Down Expand Up @@ -230,6 +235,7 @@ export default function Update({ action }: { action: IAction }) {
<div>
<button
disabled={
isActionDisabled ||
(ACTION_PAGES_DATA as any)[form.page].length === 0 ||
updateActionActionMutation.isPending
}
Expand All @@ -240,6 +246,7 @@ export default function Update({ action }: { action: IAction }) {
? 'Updating'
: 'Update Action'}
</button>
<AccessDeniedAlert />
</div>
</form>
</Box>
Expand Down
7 changes: 7 additions & 0 deletions web/app/[locale]/admin/actions/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import CreateActionAction, {
type ICreateActionActionVariables,
} from '@/app/[locale]/actions/actions/create-action-action';
import { ACTION_PAGES_DATA } from '@/app/[locale]/constants';
import useMenuActionPermission from '@/app/[locale]/hooks/useMenuActionPermission';

const ACTION_PAGES = Object.keys(ACTION_PAGES_DATA);

Expand All @@ -27,6 +28,10 @@ export default function Create() {
alias: '',
sort: 0,
});
const { isActionDisabled, AccessDeniedAlert } = useMenuActionPermission(
'/admin/actions',
'Actions#Create',
);

const createActionActionMutation = useMutation({
mutationFn: async (variables: ICreateActionActionVariables) => {
Expand Down Expand Up @@ -182,6 +187,7 @@ export default function Create() {
<div>
<button
disabled={
isActionDisabled ||
(ACTION_PAGES_DATA as any)[form.page].length === 0 ||
createActionActionMutation.isPending
}
Expand All @@ -192,6 +198,7 @@ export default function Create() {
? 'Creating'
: 'Create Action'}
</button>
<AccessDeniedAlert />
</div>
</form>
</Box>
Expand Down
6 changes: 4 additions & 2 deletions web/app/[locale]/admin/admin.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client';

import { TUsersCountByDate } from '@/app/[locale]/interfaces/users';
import type { TUsersCountByDate } from '@/app/[locale]/interfaces/users';
import { useEffect, useRef } from 'react';
import Chart from '@/app/[locale]/common/chart';
import type { ChartData, ChartOptions } from 'chart.js';
import { useTranslations } from 'next-intl';

export default function Admin({
usersCountByDate,
Expand All @@ -12,6 +13,7 @@ export default function Admin({
}) {
const canvas = useRef<HTMLCanvasElement>(null);
const chartRef = useRef<Chart<'line', any, any>>();
const t = useTranslations();

useEffect(() => {
const current = canvas.current;
Expand Down Expand Up @@ -76,7 +78,7 @@ export default function Admin({
<div className="card rounded-2">
<div className="card-header bg-transparent border-bottom-0">
<div className="fw-bold">
Statistics of User Registrations in the Past 15 Days
{t('common.userRegistrationStatisticsForTheLast15Days')}
</div>
</div>
<div className="card-body">
Expand Down
Loading

0 comments on commit 3413588

Please sign in to comment.