feat: 프로필별 플레이 감사 조회와 권한 검사 연결
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
/** Gateway capability resolver와 같은 명시적 전권·범위 규칙. 인게임 직책은 사용하지 않는다. */
|
||||
export const canReadPlayAudit = (roles: readonly string[], profileName: string): boolean =>
|
||||
roles.some(
|
||||
(role) =>
|
||||
role === 'superuser' ||
|
||||
role === 'admin.superuser' ||
|
||||
role === 'admin.playAudit.read' ||
|
||||
role === 'admin.playAudit.read:*' ||
|
||||
role === `admin.playAudit.read:${profileName}`
|
||||
);
|
||||
|
||||
export const canReadPlayAuditAccounts = (roles: readonly string[], profileName: string): boolean =>
|
||||
canReadPlayAudit(roles, profileName) &&
|
||||
roles.some((role) => role === 'superuser' || role === 'admin.superuser' || role === 'admin.playAudit.accounts');
|
||||
@@ -32,3 +32,4 @@ export * from './gateway/runtimeDiagnostics.js';
|
||||
export * from './game/accessPenalty.js';
|
||||
export * from './http/trpcTransport.js';
|
||||
export * from './webPush/types.js';
|
||||
export { canReadPlayAudit, canReadPlayAuditAccounts } from './auth/playAudit.js';
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { canReadPlayAudit, canReadPlayAuditAccounts } from '../src/auth/playAudit.js';
|
||||
|
||||
describe('play audit capability scope', () => {
|
||||
it.each([
|
||||
'superuser',
|
||||
'admin.superuser',
|
||||
'admin.playAudit.read',
|
||||
'admin.playAudit.read:*',
|
||||
'admin.playAudit.read:che:default',
|
||||
])('accepts explicit capability %s', (role) => expect(canReadPlayAudit([role], 'che:default')).toBe(true));
|
||||
it.each([
|
||||
'admin',
|
||||
'user',
|
||||
'admin.audit.read',
|
||||
'admin.profiles.runtime:che:default',
|
||||
'admin.playAudit.read:che',
|
||||
'admin.playAudit.read:hwe:default',
|
||||
'admin.playAudit.accounts',
|
||||
])('rejects unrelated role %s', (role) => expect(canReadPlayAudit([role], 'che:default')).toBe(false));
|
||||
it('requires both scoped game audit and global account audit', () => {
|
||||
expect(canReadPlayAuditAccounts(['admin.playAudit.read:che:default'], 'che:default')).toBe(false);
|
||||
expect(
|
||||
canReadPlayAuditAccounts(['admin.playAudit.read:che:default', 'admin.playAudit.accounts'], 'che:default')
|
||||
).toBe(true);
|
||||
expect(
|
||||
canReadPlayAuditAccounts(['admin.playAudit.read:che:default', 'admin.playAudit.accounts'], 'hwe:default')
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,10 @@ export interface DatabaseClient {
|
||||
diplomacy: GamePrisma.DiplomacyDelegate;
|
||||
diplomacyLetter: GamePrisma.DiplomacyLetterDelegate;
|
||||
yearbookHistory: GamePrisma.YearbookHistoryDelegate;
|
||||
playAuditMonth: GamePrisma.PlayAuditMonthDelegate;
|
||||
playAuditNation: GamePrisma.PlayAuditNationDelegate;
|
||||
playAuditCity: GamePrisma.PlayAuditCityDelegate;
|
||||
playAuditGeneral: GamePrisma.PlayAuditGeneralDelegate;
|
||||
rankData: GamePrisma.RankDataDelegate;
|
||||
hallOfFame: GamePrisma.HallOfFameDelegate;
|
||||
gameHistory: GamePrisma.GameHistoryDelegate;
|
||||
|
||||
Reference in New Issue
Block a user