Merge remote-tracking branch 'origin/main' into hjjeong
This commit is contained in:
@@ -295,7 +295,8 @@ public class AdminController {
|
||||
@PostMapping("/users/reset-password")
|
||||
public ResponseEntity<ApiResponse<Void>> resetUserPassword(@RequestBody Map<String, Object> body) {
|
||||
String userId = (String) body.get("user_id");
|
||||
adminService.resetUserPassword(userId);
|
||||
String newPassword = (String) body.get("new_password");
|
||||
adminService.resetUserPassword(userId, newPassword);
|
||||
return ResponseEntity.ok(ApiResponse.success(null, "비밀번호 초기화 성공"));
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public class SubstituteController {
|
||||
@PathVariable("id") Long substituteId,
|
||||
@RequestAttribute("company_code") String companyCode,
|
||||
@RequestAttribute("role") String role) {
|
||||
if (!"ADMIN".equals(role) && !"SUPER_ADMIN".equals(role)) {
|
||||
if (!"ADMIN".equals(role) && !"COMPANY_ADMIN".equals(role) && !"SUPER_ADMIN".equals(role)) {
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN)
|
||||
.body(ApiResponse.error("관리자만 조회할 수 있습니다."));
|
||||
}
|
||||
|
||||
@@ -208,10 +208,17 @@ public class AdminService extends BaseService {
|
||||
}
|
||||
|
||||
public void resetUserPassword(String userId) {
|
||||
String defaultPw = passwordEncoder.encode("Welcome1!");
|
||||
resetUserPassword(userId, null);
|
||||
}
|
||||
|
||||
public void resetUserPassword(String userId, String newPassword) {
|
||||
if (userId == null || userId.isBlank()) {
|
||||
throw new IllegalArgumentException("user_id 는 필수입니다");
|
||||
}
|
||||
String rawPw = (newPassword != null && !newPassword.isBlank()) ? newPassword : "Welcome1!";
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("user_id", userId);
|
||||
params.put("user_password", defaultPw);
|
||||
params.put("user_password", passwordEncoder.encode(rawPw));
|
||||
sqlSession.update("admin.updateUserPassword", params);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,12 @@ public class DdlService extends BaseService {
|
||||
"id", "created_date", "updated_date", "company_code"
|
||||
);
|
||||
|
||||
/** 사용자가 신규 추가하는 컬럼에 허용되는 INPUT_TYPE 8종 (백엔드 백스톱) */
|
||||
private static final Set<String> USER_SELECTABLE_INPUT_TYPES = Set.of(
|
||||
"text", "number", "date", "code", "entity",
|
||||
"numbering", "file", "image"
|
||||
);
|
||||
|
||||
public DdlService(JdbcTemplate jdbcTemplate, PlatformTransactionManager transactionManager) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
@@ -140,6 +146,12 @@ public class DdlService extends BaseService {
|
||||
transactionTemplate.execute(status -> {
|
||||
jdbcTemplate.execute(ddlQuery);
|
||||
String inputType = convertToInputType(column);
|
||||
if (!USER_SELECTABLE_INPUT_TYPES.contains(inputType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES
|
||||
+ " (받은 값: " + inputType + ")"
|
||||
);
|
||||
}
|
||||
String detailSettings = column.containsKey("detail_settings")
|
||||
? column.get("detail_settings").toString() : "{}";
|
||||
Integer maxOrder = jdbcTemplate.queryForObject(
|
||||
@@ -408,10 +420,17 @@ public class DdlService extends BaseService {
|
||||
// 사용자 정의 컬럼
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
Map<String, Object> col = columns.get(i);
|
||||
String inputType = convertToInputType(col);
|
||||
if (!USER_SELECTABLE_INPUT_TYPES.contains(inputType)) {
|
||||
throw new IllegalArgumentException(
|
||||
"INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES
|
||||
+ " (받은 값: " + inputType + ")"
|
||||
);
|
||||
}
|
||||
String detailSettings = col.containsKey("detail_settings")
|
||||
? col.get("detail_settings").toString() : "{}";
|
||||
saveColumnMeta(tableName, (String) col.get("name"), companyCode,
|
||||
convertToInputType(col), detailSettings, i);
|
||||
inputType, detailSettings, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ public class SubstituteService extends BaseService {
|
||||
|
||||
private void requireAdmin(Map<String, Object> params) {
|
||||
String role = (String) params.get("role");
|
||||
if (!"ADMIN".equals(role) && !"SUPER_ADMIN".equals(role)) {
|
||||
if (!"ADMIN".equals(role) && !"COMPANY_ADMIN".equals(role) && !"SUPER_ADMIN".equals(role)) {
|
||||
throw new AccessDeniedException("관리자만 대무자를 지정/수정/해지할 수 있습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ public class TableManagementService extends BaseService {
|
||||
|
||||
private static final String NS = "tableManagement.";
|
||||
|
||||
/** 사용자가 직접 선택 가능한 INPUT_TYPE 8종 (INSERT/UPDATE-type 검증용) */
|
||||
private static final Set<String> USER_SELECTABLE_INPUT_TYPES = Set.of(
|
||||
"text", "number", "date", "code", "entity",
|
||||
"numbering", "file", "image"
|
||||
);
|
||||
|
||||
// ──────────────────────────────────────────────────
|
||||
// 테이블 목록
|
||||
// ──────────────────────────────────────────────────
|
||||
@@ -145,7 +151,9 @@ public class TableManagementService extends BaseService {
|
||||
Map<String, Object> settings, String companyCode) {
|
||||
ensureTableInLabels(tableName);
|
||||
|
||||
String inputType = normalizeInputType((String) settings.get("input_type"));
|
||||
boolean inputTypeChanged = settings.containsKey("input_type");
|
||||
String ctx = inputTypeChanged ? "user-update-type" : "user-update-other";
|
||||
String inputType = normalizeInputType((String) settings.get("input_type"), ctx);
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("table_name", tableName);
|
||||
params.put("column_name", columnName);
|
||||
@@ -202,7 +210,7 @@ public class TableManagementService extends BaseService {
|
||||
public void updateColumnInputType(String tableName, String columnName,
|
||||
String inputType, String companyCode,
|
||||
Map<String, Object> detailSettings) {
|
||||
String finalType = normalizeInputType(inputType);
|
||||
String finalType = normalizeInputType(inputType, "user-update-type");
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("table_name", tableName);
|
||||
params.put("column_name", columnName);
|
||||
@@ -853,7 +861,7 @@ public class TableManagementService extends BaseService {
|
||||
return name.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
}
|
||||
|
||||
/** "direct" / "auto" → "text" 변환 */
|
||||
/** "direct" / "auto" → "text" 변환 (legacy 호출처 보호 — system-normalize 동작) */
|
||||
private String normalizeInputType(String inputType) {
|
||||
if ("direct".equals(inputType) || "auto".equals(inputType)) {
|
||||
log.warn("잘못된 inputType 값 감지: {} → 'text'로 변환", inputType);
|
||||
@@ -862,6 +870,24 @@ public class TableManagementService extends BaseService {
|
||||
return inputType != null ? inputType : "text";
|
||||
}
|
||||
|
||||
/**
|
||||
* context 에 따라 INPUT_TYPE 정규화 및 검증.
|
||||
* @param context "user-insert" | "user-update-type" | "user-update-other" | "system-normalize"
|
||||
*/
|
||||
private String normalizeInputType(String value, String context) {
|
||||
if ("user-insert".equals(context) || "user-update-type".equals(context)) {
|
||||
if (value == null || !USER_SELECTABLE_INPUT_TYPES.contains(value)) {
|
||||
throw new IllegalArgumentException(
|
||||
"INPUT_TYPE 은 다음 8개 중 하나여야 합니다: " + USER_SELECTABLE_INPUT_TYPES
|
||||
+ " (받은 값: " + value + ")"
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
// user-update-other / system-normalize: 기존 동작 그대로
|
||||
return normalizeInputType(value);
|
||||
}
|
||||
|
||||
private String toJsonString(Object obj) {
|
||||
if (obj == null) return "{}";
|
||||
if (obj instanceof String s) return s.isBlank() ? "{}" : s;
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
AND L.COMPANY_CODE = R.COMPANY_CODE
|
||||
)
|
||||
</if>
|
||||
ORDER BY R.CREATED_DATE DESC
|
||||
ORDER BY R.CREATED_AT DESC
|
||||
<if test="page_limit != null">
|
||||
LIMIT #{page_limit} OFFSET #{page_offset}
|
||||
</if>
|
||||
@@ -465,7 +465,7 @@
|
||||
SELECT L.*,
|
||||
R.TITLE, R.TARGET_TABLE, R.TARGET_RECORD_ID,
|
||||
R.REQUESTER_NAME, R.REQUESTER_DEPT,
|
||||
R.CREATED_DATE AS REQUEST_CREATED_DATE
|
||||
R.CREATED_AT AS REQUEST_CREATED_DATE
|
||||
FROM APPROVAL_LINES L
|
||||
JOIN APPROVAL_REQUESTS R
|
||||
ON L.REQUEST_ID = R.REQUEST_ID AND L.COMPANY_CODE = R.COMPANY_CODE
|
||||
@@ -475,7 +475,7 @@
|
||||
</foreach>
|
||||
AND L.STATUS = 'pending'
|
||||
AND (L.COMPANY_CODE = #{company_code} OR L.COMPANY_CODE = '*')
|
||||
ORDER BY R.CREATED_DATE ASC
|
||||
ORDER BY R.CREATED_AT ASC
|
||||
</select>
|
||||
|
||||
<!-- ================================================================
|
||||
|
||||
@@ -246,8 +246,8 @@
|
||||
#{company_code}
|
||||
, #{original_user_id}
|
||||
, #{proxy_user_id}
|
||||
, #{start_date}
|
||||
, #{end_date}
|
||||
, CAST(#{start_date} AS DATE)
|
||||
, CAST(#{end_date} AS DATE)
|
||||
, #{reason}
|
||||
, COALESCE(#{is_active}, TRUE)
|
||||
, #{created_by}
|
||||
|
||||
Reference in New Issue
Block a user