gc-guide-api/src/main/java/com/gcsc/guide/service/RoleService.java
htlee ce6e88e221 feat(settings): 관리자 설정 기반 신규 사용자 자동승인 + 기본 롤 부여
- AppSetting 엔티티 + Repository (key-value 설정 저장소)
- SettingsService (자동승인 조회/수정)
- AdminSettingsController (GET/PUT /api/admin/settings/registration)
- Role.defaultGrant 컬럼 + AdminRoleController default-grant 토글
- AuthController: 신규 사용자 생성 시 자동승인 + 기본롤 부여 로직
- data.sql: WING_PERMIT 롤 시드 + auto-approve 설정 시드

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 23:19:50 +09:00

97 lines
3.5 KiB
Java

package com.gcsc.guide.service;
import com.gcsc.guide.dto.RoleResponse;
import com.gcsc.guide.entity.Role;
import com.gcsc.guide.entity.RoleUrlPattern;
import com.gcsc.guide.exception.BusinessException;
import com.gcsc.guide.exception.ResourceNotFoundException;
import com.gcsc.guide.repository.RoleRepository;
import com.gcsc.guide.repository.RoleUrlPatternRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@RequiredArgsConstructor
public class RoleService {
private final RoleRepository roleRepository;
private final RoleUrlPatternRepository roleUrlPatternRepository;
@Transactional(readOnly = true)
public List<RoleResponse> getRoles() {
return roleRepository.findAllWithUrlPatterns().stream()
.map(RoleResponse::from)
.toList();
}
@Transactional
public RoleResponse createRole(String name, String description) {
roleRepository.findByName(name).ifPresent(r -> {
throw new BusinessException("이미 존재하는 롤 이름입니다: " + name);
});
Role role = new Role(name, description);
return RoleResponse.from(roleRepository.save(role));
}
@Transactional
public RoleResponse updateRole(Long roleId, String name, String description) {
Role role = findRoleById(roleId);
roleRepository.findByName(name)
.filter(r -> !r.getId().equals(roleId))
.ifPresent(r -> {
throw new BusinessException("이미 존재하는 롤 이름입니다: " + name);
});
role.update(name, description);
return RoleResponse.from(roleRepository.save(role));
}
@Transactional
public void deleteRole(Long roleId) {
if (!roleRepository.existsById(roleId)) {
throw new ResourceNotFoundException("", roleId);
}
roleRepository.deleteById(roleId);
}
@Transactional(readOnly = true)
public List<String> getPermissions(Long roleId) {
Role role = roleRepository.findByIdWithUrlPatterns(roleId)
.orElseThrow(() -> new ResourceNotFoundException("", roleId));
return role.getUrlPatterns().stream()
.map(RoleUrlPattern::getUrlPattern)
.toList();
}
@Transactional
public RoleResponse addPermission(Long roleId, String urlPattern) {
Role role = roleRepository.findByIdWithUrlPatterns(roleId)
.orElseThrow(() -> new ResourceNotFoundException("", roleId));
role.getUrlPatterns().add(new RoleUrlPattern(role, urlPattern));
return RoleResponse.from(roleRepository.save(role));
}
@Transactional
public void deletePermission(Long permissionId) {
if (!roleUrlPatternRepository.existsById(permissionId)) {
throw new ResourceNotFoundException("권한", permissionId);
}
roleUrlPatternRepository.deleteById(permissionId);
}
@Transactional
public RoleResponse updateDefaultGrant(Long roleId, boolean defaultGrant) {
Role role = roleRepository.findByIdWithUrlPatterns(roleId)
.orElseThrow(() -> new ResourceNotFoundException("", roleId));
role.updateDefaultGrant(defaultGrant);
return RoleResponse.from(roleRepository.save(role));
}
private Role findRoleById(Long roleId) {
return roleRepository.findById(roleId)
.orElseThrow(() -> new ResourceNotFoundException("", roleId));
}
}