1
0
forked from baron/baron-sso

3단계 권한 모델 확장, keto 권한 정책

This commit is contained in:
2026-02-03 14:21:37 +09:00
parent 6dbdd5d483
commit d09abab5a2
24 changed files with 1071 additions and 141 deletions

View File

@@ -12,6 +12,7 @@ import {
} from "lucide-react";
import { useEffect, useState } from "react";
import { NavLink, Outlet } from "react-router-dom";
import RoleSwitcher from "./RoleSwitcher";
const navItems = [
{ label: "Overview", to: "/", icon: LayoutDashboard },
@@ -132,6 +133,7 @@ function AppLayout() {
<main className="px-5 py-6 md:px-10 md:py-10">
<Outlet />
</main>
<RoleSwitcher />
</div>
</div>
);

View File

@@ -0,0 +1,68 @@
import React, { useState, useEffect } from 'react';
const RoleSwitcher: React.FC = () => {
const [currentRole, setCurrentRole] = useState<string>('super_admin');
useEffect(() => {
// localStorage에서 역할 읽기
const savedRole = window.localStorage.getItem('X-Mock-Role');
if (savedRole) {
setCurrentRole(savedRole);
} else {
// 기본값 설정
window.localStorage.setItem('X-Mock-Role', 'super_admin');
}
}, []);
const switchRole = (role: string) => {
// localStorage 설정
window.localStorage.setItem('X-Mock-Role', role);
setCurrentRole(role);
// 페이지 새로고침하여 권한 적용
window.location.reload();
};
if (process.env.NODE_ENV === 'production') return null;
return (
<div style={{
position: 'fixed',
bottom: '20px',
right: '20px',
zIndex: 9999,
background: '#1A1F2C',
color: 'white',
padding: '10px',
borderRadius: '8px',
boxShadow: '0 4px 12px rgba(0,0,0,0.3)',
display: 'flex',
flexDirection: 'column',
gap: '8px',
fontSize: '12px'
}}>
<div style={{ fontWeight: 'bold', borderBottom: '1px solid #444', paddingBottom: '4px', marginBottom: '4px' }}>
🛠 DEV Role Switcher
</div>
{(['super_admin', 'tenant_admin', 'user'] as const).map(role => (
<button
key={role}
onClick={() => switchRole(role)}
style={{
background: currentRole === role ? '#3b82f6' : '#333',
color: 'white',
border: 'none',
padding: '4px 8px',
borderRadius: '4px',
cursor: 'pointer',
textAlign: 'left',
transition: 'background 0.2s'
}}
>
{role.toUpperCase()} {currentRole === role ? '✅' : ''}
</button>
))}
</div>
);
};
export default RoleSwitcher;