fix: complete acl management
This commit is contained in:
1 parent
667ec9af4c
commit
4b596226e0
6 files changed
+189
-77
No files matched your search
@@ -0,0 +1,35 @@
|
||||
UPDATE `acl_model_permissions` SET `model_type` = 'Role' WHERE LOWER(`model_type`) = 'role';
|
||||
UPDATE `acl_model_roles` SET `model_type` = 'User' WHERE LOWER(`model_type`) = 'user';
|
||||
|
||||
INSERT INTO `acl_permissions` (`slug`, `title`) VALUES
|
||||
('admin.assets.import', 'Import assets'),
|
||||
('admin.permissions.manage', 'Manage permissions')
|
||||
ON DUPLICATE KEY UPDATE `title` = VALUES(`title`);
|
||||
|
||||
INSERT INTO `acl_roles` (`slug`, `title`, `description`)
|
||||
SELECT CONCAT('rank_', pr.id), COALESCE(NULLIF(pr.rank_name, ''), CONCAT('Rank ', pr.id)), 'CMS role synchronized from permission_ranks'
|
||||
FROM `permission_ranks` pr
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `acl_roles` ar WHERE ar.slug = CONCAT('rank_', pr.id));
|
||||
|
||||
INSERT INTO `acl_model_permissions` (`model_type`, `model_id`, `permission_id`)
|
||||
SELECT 'Role', ar.id, ap.id
|
||||
FROM `permission_ranks` pr
|
||||
JOIN `acl_roles` ar ON ar.slug = CONCAT('rank_', pr.id)
|
||||
CROSS JOIN `acl_permissions` ap
|
||||
WHERE pr.id = (SELECT MAX(id) FROM `permission_ranks`)
|
||||
AND ap.slug IN ('admin.permissions.manage', 'admin.assets.import')
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM `acl_model_permissions` amp
|
||||
WHERE amp.model_type = 'Role' AND amp.model_id = ar.id AND amp.permission_id = ap.id
|
||||
);
|
||||
|
||||
INSERT INTO `acl_model_permissions` (`model_type`, `model_id`, `permission_id`)
|
||||
SELECT 'Role', ar.id, ap.id
|
||||
FROM `website_housekeeping_permissions` whp
|
||||
JOIN `acl_permissions` ap ON ap.slug = whp.permission
|
||||
JOIN `permission_ranks` pr ON pr.id >= whp.min_rank
|
||||
JOIN `acl_roles` ar ON ar.slug = CONCAT('rank_', pr.id)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM `acl_model_permissions` amp
|
||||
WHERE amp.model_type = 'Role' AND amp.model_id = ar.id AND amp.permission_id = ap.id
|
||||
);
|
||||
+97
-66
File diff suppressed because it is too large.
Load diff
@@ -20,17 +20,6 @@ export default async function PermissionsPage(_props: { params: Promise<{ locale
|
||||
countMap[Number(row.rank)] = Number(row.cnt)
|
||||
}
|
||||
|
||||
// Auto-create CMS roles for ranks >= 4
|
||||
for (const rank of ranks) {
|
||||
if (rank.id >= 4) {
|
||||
await prisma.aclRole.upsert({
|
||||
where: { slug: `rank_${rank.id}` },
|
||||
create: { slug: `rank_${rank.id}`, title: rank.rank_name || `Rank ${rank.id}` },
|
||||
update: {},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const ranksWithCounts = ranks.map((rank) => ({
|
||||
...rank,
|
||||
userCount: countMap[rank.id] ?? 0,
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { revalidateTag } from 'next/cache'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { withAdmin } from '@/lib/api-handler'
|
||||
import { apiError } from '@/lib/api-response'
|
||||
import { PERMS } from '@/lib/permissions'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
|
||||
export const POST = withAdmin({ permission: PERMS.PERMISSIONS_MANAGE }, async (request) => {
|
||||
const body = await request.json()
|
||||
const userId = Number(body.userId)
|
||||
const roleId = Number(body.roleId)
|
||||
if (!Number.isInteger(userId) || userId <= 0 || !Number.isInteger(roleId) || roleId <= 0) {
|
||||
return apiError('Valid userId and roleId required', 400)
|
||||
}
|
||||
if (body.action === 'remove') {
|
||||
await prisma.aclModelRole.deleteMany({ where: { modelType: 'User', modelId: userId, roleId } })
|
||||
} else {
|
||||
const existing = await prisma.aclModelRole.findFirst({ where: { modelType: 'User', modelId: userId, roleId } })
|
||||
if (!existing) await prisma.aclModelRole.create({ data: { modelType: 'User', modelId: userId, roleId } })
|
||||
}
|
||||
revalidateTag('permissions', { expire: 0 })
|
||||
return NextResponse.json({ success: true })
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
import { revalidateTag } from 'next/cache'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { withAdmin } from '@/lib/api-handler'
|
||||
import { apiError } from '@/lib/api-response'
|
||||
import { PERMS } from '@/lib/permissions'
|
||||
import { prisma } from '@/lib/prisma'
|
||||
|
||||
export const POST = withAdmin({ permission: PERMS.PERMISSIONS_MANAGE }, async (request) => {
|
||||
const body = await request.json()
|
||||
const slug = String(body.slug ?? '').trim().toLowerCase()
|
||||
const title = String(body.title ?? '').trim()
|
||||
if (!/^[a-z0-9._-]{2,64}$/.test(slug) || !title) return apiError('Valid slug and title required', 400)
|
||||
const role = await prisma.aclRole.create({ data: { slug, title } })
|
||||
revalidateTag('permissions', { expire: 0 })
|
||||
return NextResponse.json({ role })
|
||||
})
|
||||
|
||||
export const DELETE = withAdmin({ permission: PERMS.PERMISSIONS_MANAGE }, async (request) => {
|
||||
const id = Number(request.nextUrl.searchParams.get('id'))
|
||||
if (!Number.isInteger(id) || id <= 0) return apiError('Valid ID required', 400)
|
||||
const role = await prisma.aclRole.findUnique({ where: { id }, select: { slug: true } })
|
||||
if (!role) return apiError('Role not found', 404)
|
||||
if (role.slug.startsWith('rank_')) return apiError('Rank roles must be managed through emulator ranks', 409)
|
||||
await prisma.$transaction([
|
||||
prisma.aclModelPermission.deleteMany({ where: { modelType: 'Role', modelId: id } }),
|
||||
prisma.aclModelRole.deleteMany({ where: { roleId: id } }),
|
||||
prisma.aclRole.delete({ where: { id } }),
|
||||
])
|
||||
revalidateTag('permissions', { expire: 0 })
|
||||
return NextResponse.json({ success: true })
|
||||
})
|
||||
@@ -110,6 +110,9 @@ export class RconClient {
|
||||
updateCatalog() {
|
||||
return this.send("updatecatalog");
|
||||
}
|
||||
updateItems() {
|
||||
return this.send("updateitems");
|
||||
}
|
||||
updateConfig() {
|
||||
return this.send("updateconfig");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user