공통코드,REST API 회사별 분리
This commit is contained in:
@@ -17,7 +17,8 @@ export class ExternalDbConnectionService {
|
||||
* 외부 DB 연결 목록 조회
|
||||
*/
|
||||
static async getConnections(
|
||||
filter: ExternalDbConnectionFilter
|
||||
filter: ExternalDbConnectionFilter,
|
||||
userCompanyCode?: string
|
||||
): Promise<ApiResponse<ExternalDbConnection[]>> {
|
||||
try {
|
||||
// WHERE 조건 동적 생성
|
||||
@@ -25,6 +26,26 @@ export class ExternalDbConnectionService {
|
||||
const params: any[] = [];
|
||||
let paramIndex = 1;
|
||||
|
||||
// 회사별 필터링 (최고 관리자가 아닌 경우 필수)
|
||||
if (userCompanyCode && userCompanyCode !== "*") {
|
||||
whereConditions.push(`company_code = $${paramIndex++}`);
|
||||
params.push(userCompanyCode);
|
||||
logger.info(`회사별 외부 DB 연결 필터링: ${userCompanyCode}`);
|
||||
} else if (userCompanyCode === "*") {
|
||||
logger.info(`최고 관리자: 모든 외부 DB 연결 조회`);
|
||||
// 필터가 있으면 적용
|
||||
if (filter.company_code) {
|
||||
whereConditions.push(`company_code = $${paramIndex++}`);
|
||||
params.push(filter.company_code);
|
||||
}
|
||||
} else {
|
||||
// userCompanyCode가 없는 경우 (하위 호환성)
|
||||
if (filter.company_code) {
|
||||
whereConditions.push(`company_code = $${paramIndex++}`);
|
||||
params.push(filter.company_code);
|
||||
}
|
||||
}
|
||||
|
||||
// 필터 조건 적용
|
||||
if (filter.db_type) {
|
||||
whereConditions.push(`db_type = $${paramIndex++}`);
|
||||
@@ -36,11 +57,6 @@ export class ExternalDbConnectionService {
|
||||
params.push(filter.is_active);
|
||||
}
|
||||
|
||||
if (filter.company_code) {
|
||||
whereConditions.push(`company_code = $${paramIndex++}`);
|
||||
params.push(filter.company_code);
|
||||
}
|
||||
|
||||
// 검색 조건 적용 (연결명 또는 설명에서 검색)
|
||||
if (filter.search && filter.search.trim()) {
|
||||
whereConditions.push(
|
||||
@@ -496,23 +512,36 @@ export class ExternalDbConnectionService {
|
||||
/**
|
||||
* 외부 DB 연결 삭제 (물리 삭제)
|
||||
*/
|
||||
static async deleteConnection(id: number): Promise<ApiResponse<void>> {
|
||||
static async deleteConnection(
|
||||
id: number,
|
||||
userCompanyCode?: string
|
||||
): Promise<ApiResponse<void>> {
|
||||
try {
|
||||
const existingConnection = await queryOne(
|
||||
`SELECT id FROM external_db_connections WHERE id = $1`,
|
||||
[id]
|
||||
);
|
||||
let selectQuery = `SELECT id FROM external_db_connections WHERE id = $1`;
|
||||
const selectParams: any[] = [id];
|
||||
|
||||
// 회사별 필터링 (최고 관리자가 아닌 경우)
|
||||
if (userCompanyCode && userCompanyCode !== "*") {
|
||||
selectQuery += ` AND company_code = $2`;
|
||||
selectParams.push(userCompanyCode);
|
||||
}
|
||||
|
||||
const existingConnection = await queryOne(selectQuery, selectParams);
|
||||
|
||||
if (!existingConnection) {
|
||||
return {
|
||||
success: false,
|
||||
message: "해당 연결 설정을 찾을 수 없습니다.",
|
||||
message: "해당 연결 설정을 찾을 수 없거나 권한이 없습니다.",
|
||||
};
|
||||
}
|
||||
|
||||
// 물리 삭제 (실제 데이터 삭제)
|
||||
await query(`DELETE FROM external_db_connections WHERE id = $1`, [id]);
|
||||
|
||||
logger.info(
|
||||
`외부 DB 연결 삭제: ID ${id} (회사: ${userCompanyCode || "전체"})`
|
||||
);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: "연결 설정이 삭제되었습니다.",
|
||||
@@ -747,8 +776,11 @@ export class ExternalDbConnectionService {
|
||||
try {
|
||||
// 보안 검증: SELECT 쿼리만 허용
|
||||
const trimmedQuery = query.trim().toUpperCase();
|
||||
if (!trimmedQuery.startsWith('SELECT')) {
|
||||
console.log("보안 오류: SELECT가 아닌 쿼리 시도:", { id, query: query.substring(0, 100) });
|
||||
if (!trimmedQuery.startsWith("SELECT")) {
|
||||
console.log("보안 오류: SELECT가 아닌 쿼리 시도:", {
|
||||
id,
|
||||
query: query.substring(0, 100),
|
||||
});
|
||||
return {
|
||||
success: false,
|
||||
message: "외부 데이터베이스에서는 SELECT 쿼리만 실행할 수 있습니다.",
|
||||
@@ -756,16 +788,32 @@ export class ExternalDbConnectionService {
|
||||
}
|
||||
|
||||
// 위험한 키워드 검사
|
||||
const dangerousKeywords = ['INSERT', 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER', 'TRUNCATE', 'EXEC', 'EXECUTE', 'CALL', 'MERGE'];
|
||||
const hasDangerousKeyword = dangerousKeywords.some(keyword =>
|
||||
const dangerousKeywords = [
|
||||
"INSERT",
|
||||
"UPDATE",
|
||||
"DELETE",
|
||||
"DROP",
|
||||
"CREATE",
|
||||
"ALTER",
|
||||
"TRUNCATE",
|
||||
"EXEC",
|
||||
"EXECUTE",
|
||||
"CALL",
|
||||
"MERGE",
|
||||
];
|
||||
const hasDangerousKeyword = dangerousKeywords.some((keyword) =>
|
||||
trimmedQuery.includes(keyword)
|
||||
);
|
||||
|
||||
|
||||
if (hasDangerousKeyword) {
|
||||
console.log("보안 오류: 위험한 키워드 포함 쿼리 시도:", { id, query: query.substring(0, 100) });
|
||||
console.log("보안 오류: 위험한 키워드 포함 쿼리 시도:", {
|
||||
id,
|
||||
query: query.substring(0, 100),
|
||||
});
|
||||
return {
|
||||
success: false,
|
||||
message: "데이터를 변경하거나 삭제하는 쿼리는 허용되지 않습니다. SELECT 쿼리만 사용해주세요.",
|
||||
message:
|
||||
"데이터를 변경하거나 삭제하는 쿼리는 허용되지 않습니다. SELECT 쿼리만 사용해주세요.",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user