diff --git a/src/lib/auth/check-permission.ts b/src/lib/auth/check-permission.ts new file mode 100644 index 0000000..344e5ca --- /dev/null +++ b/src/lib/auth/check-permission.ts @@ -0,0 +1,39 @@ +import { getServerSession } from 'next-auth'; +import { authOptions } from '../auth'; +import { hasPermission, Role, Resource, Action } from './permissions'; + +export async function checkPermission( + resource: Resource, + action: Action +): Promise<{ allowed: boolean; userId?: string; role?: Role }> { + const session = await getServerSession(authOptions); + + if (!session || !session.user) { + return { allowed: false }; + } + + const userRole = session.user.role as Role; + const allowed = hasPermission(userRole, resource, action); + + return { + allowed, + userId: session.user.id, + role: userRole, + }; +} + +export async function requirePermission( + resource: Resource, + action: Action +): Promise<{ userId: string; role: Role }> { + const result = await checkPermission(resource, action); + + if (!result.allowed) { + throw new Error('无权限执行此操作'); + } + + return { + userId: result.userId!, + role: result.role!, + }; +} diff --git a/src/lib/auth/permissions.ts b/src/lib/auth/permissions.ts new file mode 100644 index 0000000..712e403 --- /dev/null +++ b/src/lib/auth/permissions.ts @@ -0,0 +1,38 @@ +export const PERMISSIONS = { + admin: { + content: ['create', 'read', 'update', 'delete', 'publish'], + config: ['read', 'update'], + users: ['create', 'read', 'update', 'delete'], + logs: ['read'], + }, + editor: { + content: ['create', 'read', 'update', 'publish'], + config: ['read'], + users: [], + logs: ['read'], + }, + viewer: { + content: ['read'], + config: ['read'], + users: [], + logs: [], + }, +} as const; + +export type Role = keyof typeof PERMISSIONS; +export type Resource = keyof typeof PERMISSIONS.admin; +export type Action = 'create' | 'read' | 'update' | 'delete' | 'publish'; + +export function hasPermission( + role: Role, + resource: Resource, + action: Action +): boolean { + const permissions = PERMISSIONS[role]; + if (!permissions) return false; + + const resourcePermissions = permissions[resource]; + if (!resourcePermissions) return false; + + return resourcePermissions.includes(action as never); +}