Files
tk-factory-services/user-management/api/controllers/permissionController.js
Hyungi Ahn 733bb0cb35 feat: tkuser 통합 관리 서비스 + 전체 시스템 SSO 쿠키 인증 통합
- tkuser 서비스 신규 추가 (API + Web)
  - 사용자/권한/프로젝트/부서/작업자/작업장/설비/작업/휴가 통합 관리
  - 작업장 탭: 공장→작업장 드릴다운 네비게이션 + 구역지도 클릭 연동
  - 작업 탭: 공정(work_types)→작업(tasks) 계층 관리
  - 휴가 탭: 유형 관리 + 연차 배정(근로기준법 자동계산)
- 전 시스템 SSO 쿠키 인증으로 통합 (.technicalkorea.net 공유)
- System 2: 작업 이슈 리포트 기능 강화
- System 3: tkuser API 연동, 페이지 권한 체계 적용
- docker-compose에 tkuser-api, tkuser-web 서비스 추가
- ARCHITECTURE.md, DEPLOYMENT.md 문서 작성

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:45:52 +09:00

160 lines
4.2 KiB
JavaScript

/**
* Permission Controller
*
* 페이지 권한 관리 (system3 page_permissions.py 포팅)
*/
const permissionModel = require('../models/permissionModel');
const userModel = require('../models/userModel');
/**
* GET /api/users/:id/page-permissions - 사용자 권한 조회
*/
async function getUserPermissions(req, res, next) {
try {
const userId = parseInt(req.params.id);
const requesterId = req.user.user_id || req.user.id;
// 관리자이거나 본인만 조회 가능
if (req.user.role !== 'admin' && requesterId !== userId) {
return res.status(403).json({ success: false, error: '권한이 없습니다' });
}
const user = await userModel.findById(userId);
if (!user) {
return res.status(404).json({ success: false, error: '사용자를 찾을 수 없습니다' });
}
const permissions = await permissionModel.getUserPermissions(userId);
res.json(permissions);
} catch (err) {
next(err);
}
}
/**
* POST /api/permissions/grant - 단건 권한 부여
*/
async function grantPermission(req, res, next) {
try {
const { user_id, page_name, can_access, notes } = req.body;
const grantedById = req.user.user_id || req.user.id;
// 대상 사용자 확인
const targetUser = await userModel.findById(user_id);
if (!targetUser) {
return res.status(404).json({ success: false, error: '사용자를 찾을 수 없습니다' });
}
// 유효한 페이지명 확인
if (!permissionModel.DEFAULT_PAGES[page_name]) {
return res.status(400).json({ success: false, error: '유효하지 않은 페이지명입니다' });
}
const result = await permissionModel.grantPermission({
user_id,
page_name,
can_access,
granted_by_id: grantedById,
notes
});
res.json({ success: true, message: '권한이 설정되었습니다', data: result });
} catch (err) {
next(err);
}
}
/**
* POST /api/permissions/bulk-grant - 일괄 권한 부여
*/
async function bulkGrant(req, res, next) {
try {
const { user_id, permissions } = req.body;
const grantedById = req.user.user_id || req.user.id;
// 대상 사용자 확인
const targetUser = await userModel.findById(user_id);
if (!targetUser) {
return res.status(404).json({ success: false, error: '사용자를 찾을 수 없습니다' });
}
const result = await permissionModel.bulkGrant({
user_id,
permissions,
granted_by_id: grantedById
});
res.json({
success: true,
message: `${result.updated_count}개의 권한이 설정되었습니다`,
updated_count: result.updated_count
});
} catch (err) {
next(err);
}
}
/**
* GET /api/permissions/check/:uid/:page - 접근 권한 확인
*/
async function checkAccess(req, res, next) {
try {
const userId = parseInt(req.params.uid);
const pageName = req.params.page;
// 사용자 확인
const user = await userModel.findById(userId);
if (!user) {
return res.status(404).json({ success: false, error: '사용자를 찾을 수 없습니다' });
}
// admin은 모든 페이지 접근 가능
if (user.role === 'admin') {
return res.json({ can_access: true, reason: 'admin_role' });
}
const result = await permissionModel.checkAccess(userId, pageName);
res.json(result);
} catch (err) {
next(err);
}
}
/**
* GET /api/permissions/available-pages - 설정 가능 페이지 목록
*/
async function getAvailablePages(req, res) {
res.json({
pages: permissionModel.DEFAULT_PAGES,
total_count: Object.keys(permissionModel.DEFAULT_PAGES).length
});
}
/**
* DELETE /api/permissions/:id - 권한 삭제
*/
async function deletePermission(req, res, next) {
try {
const permissionId = parseInt(req.params.id);
const deleted = await permissionModel.deletePermission(permissionId);
if (!deleted) {
return res.status(404).json({ success: false, error: '권한을 찾을 수 없습니다' });
}
res.json({ success: true, message: '권한이 삭제되었습니다. 기본값이 적용됩니다.' });
} catch (err) {
next(err);
}
}
module.exports = {
getUserPermissions,
grantPermission,
bulkGrant,
checkAccess,
getAvailablePages,
deletePermission
};