Files
goldenChart/backend/src/main/java/com/goldenchart/service/RolePermissionService.java
T
2026-05-23 15:11:48 +09:00

96 lines
3.8 KiB
Java

package com.goldenchart.service;
import com.goldenchart.auth.MenuIds;
import com.goldenchart.auth.UserRole;
import com.goldenchart.dto.MenuPermissionsResponse;
import com.goldenchart.dto.RolePermissionsUpdateRequest;
import com.goldenchart.entity.GcRoleMenuPermission;
import com.goldenchart.entity.GcUser;
import com.goldenchart.repository.GcRoleMenuPermissionRepository;
import com.goldenchart.repository.GcUserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class RolePermissionService {
private final GcRoleMenuPermissionRepository permRepo;
private final GcUserRepository userRepo;
@Transactional(readOnly = true)
public MenuPermissionsResponse resolveForUserId(Long userId) {
if (userId == null) {
return buildForRole(UserRole.GUEST.name());
}
GcUser user = userRepo.findById(userId)
.filter(u -> Boolean.TRUE.equals(u.getEnabled()))
.orElse(null);
if (user == null) {
return buildForRole(UserRole.GUEST.name());
}
String role = user.getRole() != null ? user.getRole() : UserRole.USER.name();
return buildForRole(role);
}
@Transactional(readOnly = true)
public MenuPermissionsResponse buildForRole(String role) {
String r = UserRole.fromString(role).name();
Map<String, Boolean> map = defaultMap();
for (GcRoleMenuPermission p : permRepo.findByRole(r)) {
map.put(p.getMenuId(), Boolean.TRUE.equals(p.getAllowed()));
}
return MenuPermissionsResponse.builder().role(r).permissions(map).build();
}
@Transactional(readOnly = true)
public Map<String, Map<String, Boolean>> listAllRolePermissions() {
Map<String, Map<String, Boolean>> out = new LinkedHashMap<>();
for (UserRole role : UserRole.values()) {
out.put(role.name(), buildForRole(role.name()).getPermissions());
}
return out;
}
@Transactional
public void updateRolePermissions(RolePermissionsUpdateRequest req) {
if (req == null || req.getRole() == null || req.getPermissions() == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "role과 permissions가 필요합니다.");
}
String role = UserRole.fromString(req.getRole()).name();
permRepo.deleteByRole(role);
List<GcRoleMenuPermission> rows = new ArrayList<>();
for (String menuId : MenuIds.ALL) {
Boolean allowed = req.getPermissions().getOrDefault(menuId, false);
rows.add(GcRoleMenuPermission.builder()
.role(role)
.menuId(menuId)
.allowed(allowed)
.build());
}
permRepo.saveAll(rows);
}
@Transactional(readOnly = true)
public void requireAdmin(Long userId) {
GcUser user = userRepo.findById(userId)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.UNAUTHORIZED, "로그인이 필요합니다."));
if (!UserRole.ADMIN.name().equalsIgnoreCase(user.getRole())) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "관리자 권한이 필요합니다.");
}
if (!Boolean.TRUE.equals(user.getEnabled())) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "비활성화된 계정입니다.");
}
}
private static Map<String, Boolean> defaultMap() {
return MenuIds.ALL.stream().collect(Collectors.toMap(id -> id, id -> false, (a, b) -> b, LinkedHashMap::new));
}
}