96 lines
3.8 KiB
Java
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));
|
|
}
|
|
}
|