[Developer] #424 hide orphan protected objects in permission picker
This commit is contained in:
@@ -29,6 +29,10 @@ public interface PermissionMapper {
|
||||
|
||||
Long findPermissionId(@Param("roleId") long roleId, @Param("objectId") long objectId);
|
||||
|
||||
Long findObjectIdByPermissionId(@Param("permissionId") long permissionId);
|
||||
|
||||
int countPermissionsByObjectId(@Param("objectId") long objectId);
|
||||
|
||||
void insertPermission(@Param("permissionId") long permissionId,
|
||||
@Param("roleId") long roleId,
|
||||
@Param("objectId") long objectId,
|
||||
|
||||
@@ -13,6 +13,8 @@ public interface ProtectedObjectMapper {
|
||||
|
||||
List<ProtectedObject> findEnabled();
|
||||
|
||||
List<ProtectedObject> findEnabledWithPermissions();
|
||||
|
||||
ProtectedObject findById(@Param("objectId") long objectId);
|
||||
|
||||
ProtectedObject findByOwnerAndName(@Param("owner") String owner, @Param("objectName") String objectName);
|
||||
|
||||
@@ -110,12 +110,16 @@ public class PermissionService {
|
||||
|
||||
@Transactional
|
||||
public void deletePermission(long permissionId) {
|
||||
Long objectId = permissionMapper.findObjectIdByPermissionId(permissionId);
|
||||
permissionMapper.deleteRules(permissionId);
|
||||
permissionMapper.deleteVisibleColumns(permissionId);
|
||||
int deleted = permissionMapper.deletePermission(permissionId);
|
||||
if (deleted == 0) {
|
||||
throw new AppException("삭제할 권한을 찾을 수 없습니다.");
|
||||
}
|
||||
if (objectId != null && permissionMapper.countPermissionsByObjectId(objectId) == 0) {
|
||||
protectedObjectService.disableObject(objectId);
|
||||
}
|
||||
auditService.record(new AuditEvent("PERMISSION_DELETED", null, null, "SUCCESS", null, null,
|
||||
"permissionId=" + permissionId));
|
||||
}
|
||||
|
||||
@@ -35,6 +35,10 @@ public class ProtectedObjectService {
|
||||
return mapper.findEnabled();
|
||||
}
|
||||
|
||||
public List<ProtectedObject> findEnabledWithPermissions() {
|
||||
return mapper.findEnabledWithPermissions();
|
||||
}
|
||||
|
||||
public List<DatabaseObjectOption> findDatabaseObjects() {
|
||||
CacheEntry<List<DatabaseObjectOption>> cached = databaseObjectsCache;
|
||||
if (cached != null && !cached.expired()) {
|
||||
@@ -83,6 +87,7 @@ public class ProtectedObjectService {
|
||||
for (String column : splitCsv(normalized.columns())) {
|
||||
mapper.insertColumn(mapper.nextColumnId(), objectId, column, sensitive.contains(column) ? "Y" : "N");
|
||||
}
|
||||
databaseObjectsCache = null;
|
||||
protectedColumnsCache.remove(objectId);
|
||||
auditService.record(new AuditEvent("PROTECTED_OBJECT_CREATED", null, objectId, "SUCCESS", null, null,
|
||||
normalized.objectName()));
|
||||
@@ -96,6 +101,8 @@ public class ProtectedObjectService {
|
||||
if (existing != null) {
|
||||
if (!existing.enabled()) {
|
||||
mapper.enableObject(existing.objectId());
|
||||
databaseObjectsCache = null;
|
||||
protectedColumnsCache.remove(existing.objectId());
|
||||
auditService.record(new AuditEvent("PROTECTED_OBJECT_RE_ENABLED", null, existing.objectId(), "SUCCESS", null,
|
||||
null, existing.displayName()));
|
||||
return mapper.findById(existing.objectId());
|
||||
@@ -119,6 +126,7 @@ public class ProtectedObjectService {
|
||||
for (String column : columns) {
|
||||
mapper.insertColumn(mapper.nextColumnId(), objectId, column, "N");
|
||||
}
|
||||
databaseObjectsCache = null;
|
||||
protectedColumnsCache.remove(objectId);
|
||||
auditService.record(new AuditEvent("PROTECTED_OBJECT_AUTO_CREATED", null, objectId, "SUCCESS", null, null,
|
||||
command.objectName()));
|
||||
@@ -162,6 +170,8 @@ public class ProtectedObjectService {
|
||||
if (updated == 0) {
|
||||
throw new AppException("보호 객체를 찾을 수 없습니다.");
|
||||
}
|
||||
databaseObjectsCache = null;
|
||||
protectedColumnsCache.remove(objectId);
|
||||
auditService.record(new AuditEvent("PROTECTED_OBJECT_DISABLED", null, objectId, "SUCCESS", null, null, null));
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class PermissionController {
|
||||
@GetMapping("/permissions")
|
||||
public String permissions(Model model) {
|
||||
long started = System.nanoTime();
|
||||
var objects = protectedObjectService.findEnabled();
|
||||
var objects = protectedObjectService.findEnabledWithPermissions();
|
||||
long objectsAt = System.nanoTime();
|
||||
var roles = permissionService.findRoles();
|
||||
long rolesAt = System.nanoTime();
|
||||
|
||||
@@ -84,6 +84,20 @@
|
||||
AND o.object_id = #{objectId}
|
||||
</select>
|
||||
|
||||
<select id="findObjectIdByPermissionId" resultType="long">
|
||||
SELECT o.object_id
|
||||
FROM cb_permission p
|
||||
JOIN cb_protected_object o ON o.object_name = p.target_name
|
||||
WHERE p.perm_id = #{permissionId}
|
||||
</select>
|
||||
|
||||
<select id="countPermissionsByObjectId" resultType="int">
|
||||
SELECT COUNT(*)
|
||||
FROM cb_permission p
|
||||
JOIN cb_protected_object o ON o.object_name = p.target_name
|
||||
WHERE o.object_id = #{objectId}
|
||||
</select>
|
||||
|
||||
<select id="findPermissionSet" resultType="com.cloudhandson.vpdbackoffice.domain.permission.PermissionSet">
|
||||
SELECT p.perm_id AS permission_id,
|
||||
p.role_id,
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
ORDER BY owner, object_name
|
||||
</select>
|
||||
|
||||
<select id="findEnabledWithPermissions" resultType="com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObject">
|
||||
SELECT DISTINCT po.object_id, po.owner, po.object_name, po.ords_path, po.enabled_yn
|
||||
FROM cb_protected_object po
|
||||
JOIN cb_permission p ON p.target_name = po.object_name
|
||||
WHERE po.enabled_yn = 'Y'
|
||||
ORDER BY po.owner, po.object_name
|
||||
</select>
|
||||
|
||||
<select id="findById" resultType="com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObject">
|
||||
SELECT object_id, owner, object_name, ords_path, enabled_yn
|
||||
FROM cb_protected_object
|
||||
@@ -31,6 +39,7 @@
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM cb_protected_object po
|
||||
JOIN cb_permission p ON p.target_name = po.object_name
|
||||
WHERE po.owner = all_objects.owner
|
||||
AND po.object_name = all_objects.object_name
|
||||
AND po.enabled_yn = 'Y'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.cloudhandson.vpdbackoffice.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.cloudhandson.vpdbackoffice.domain.audit.AuditEvent;
|
||||
@@ -74,6 +75,24 @@ class PermissionServiceTest {
|
||||
.hasMessageContaining("허용되지 않은");
|
||||
}
|
||||
|
||||
@Test
|
||||
void disablesProtectedObjectWhenLastPermissionIsDeleted() {
|
||||
var mapper = new FakePermissionMapper();
|
||||
boolean[] disabled = {false};
|
||||
AuditService auditService = new AuditService(new NoopAuditMapper());
|
||||
ProtectedObjectService objectService = new ProtectedObjectService(null, auditService) {
|
||||
@Override
|
||||
public void disableObject(long objectId) {
|
||||
disabled[0] = objectId == 1L;
|
||||
}
|
||||
};
|
||||
PermissionService service = new PermissionService(mapper, objectService, auditService);
|
||||
|
||||
service.deletePermission(1000L);
|
||||
|
||||
assertThat(disabled[0]).isTrue();
|
||||
}
|
||||
|
||||
private static class NoopAuditMapper implements AuditMapper {
|
||||
@Override
|
||||
public void insert(AuditEvent event) {
|
||||
@@ -120,6 +139,16 @@ class PermissionServiceTest {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long findObjectIdByPermissionId(long permissionId) {
|
||||
return permissionId == 1000L ? 1L : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countPermissionsByObjectId(long objectId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertPermission(long permissionId, long roleId, long objectId, String action) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user