diff --git a/src/main/java/com/aolda/itda/controller/AuthController.java b/src/main/java/com/aolda/itda/controller/AuthController.java index 274ad8fe399c07e460c495151160a017cd8f1b52..79046d2d2459cde40b302cc0e190d3240280257e 100644 --- a/src/main/java/com/aolda/itda/controller/AuthController.java +++ b/src/main/java/com/aolda/itda/controller/AuthController.java @@ -6,10 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/auth") @@ -24,4 +21,11 @@ public class AuthController { return ResponseEntity.ok(authService.userLogin(response, loginRequestDTO)); } + + @GetMapping("/role") + public ResponseEntity<Object> roleWithinProject(@RequestHeader("X-Subject-Token") String token, + @RequestParam String projectId) throws JsonProcessingException { + + return ResponseEntity.ok(authService.getBestRoleWithinProject(token, projectId)); + } } diff --git a/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java b/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java deleted file mode 100644 index d3b9b8ecdc53343703a4f8b8cebbe6bbd6de4228..0000000000000000000000000000000000000000 --- a/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.aolda.itda.dto.auth; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.util.List; - -@Getter -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class ProjectRoleDTO { - private String projectName; - private String roleName; -} diff --git a/src/main/java/com/aolda/itda/exception/ErrorCode.java b/src/main/java/com/aolda/itda/exception/ErrorCode.java index 6bcb6431ef8ff826b318abd9d72cc5d2255aadcd..0916e71a1ef9a0824f3541ae257d490236c42cb3 100644 --- a/src/main/java/com/aolda/itda/exception/ErrorCode.java +++ b/src/main/java/com/aolda/itda/exception/ErrorCode.java @@ -9,7 +9,10 @@ import org.springframework.http.HttpStatus; public enum ErrorCode { // User - INVALID_USER_INFO(HttpStatus.BAD_REQUEST, "잘못된 회원 정보입니다"); + INVALID_USER_INFO(HttpStatus.BAD_REQUEST, "잘못된 회원 정보입니다"), + + // Token + INVALID_TOKEN(HttpStatus.BAD_REQUEST, "잘못된 토큰입니다"); private final HttpStatus status; private final String message; diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index 5f071eef2e680b74779350994fb6c355e2333b66..88062f7e508d645f8e6d025ae346012e972b37f6 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -3,7 +3,6 @@ package com.aolda.itda.service; import com.aolda.itda.dto.auth.LoginRequestDTO; import com.aolda.itda.dto.auth.LoginResponseDTO; import com.aolda.itda.dto.auth.ProjectIdAndNameDTO; -import com.aolda.itda.dto.auth.ProjectRoleDTO; import com.aolda.itda.exception.CustomException; import com.aolda.itda.exception.ErrorCode; import com.fasterxml.jackson.core.JsonProcessingException; @@ -15,6 +14,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import java.util.*; @@ -88,8 +88,15 @@ public class AuthService { "token", token); } - // 특정 사용자의 프로젝트별 Role 반환 - private List<ProjectRoleDTO> getRolesWithProjects(Map<String, String> user) throws JsonProcessingException { + // 특정 사용자의 특정 프로젝트 내 최고 권한 반환 + public Map<String, String> getBestRoleWithinProject(String token, String projectId) throws JsonProcessingException { + return getBestRoleWithinProject(Map.of( + "id", validateTokenAndGetUserId(token), + "token", token), + projectId); + } + + private Map<String, String> getBestRoleWithinProject(Map<String, String> user, String projectId) throws JsonProcessingException { String userId = user.get("id"); String token = user.get("token"); @@ -97,7 +104,7 @@ public class AuthService { throw new CustomException(ErrorCode.INVALID_USER_INFO); } - String url = keystone + "/role_assignments?user.id=" + userId + "&effective&include_names=true"; + String url = keystone + "/role_assignments?user.id=" + userId + "&effective&include_names=true&scope.project.id=" + projectId; HttpHeaders headers = new HttpHeaders(); headers.set("X-Auth-Token", getAdminToken()); @@ -108,19 +115,23 @@ public class AuthService { JsonNode node = objectMapper.readTree(res.getBody()); ArrayNode arrayNode = (ArrayNode) node.get("role_assignments"); - List<ProjectRoleDTO> lists = new ArrayList<>(); + String bestRole = "reader"; for (JsonNode assignment : arrayNode) { - String projectName = assignment.path("scope").path("project").path("name").asText(); String roleName = assignment.path("role").path("name").asText(); - ProjectRoleDTO projectRoleDTO = new ProjectRoleDTO(projectName, roleName); - lists.add(projectRoleDTO); + if (roleName.equals("admin")) { // admin인 경우 + bestRole = roleName; + } else if (roleName.equals("manager") && !bestRole.equals("admin")) { // 최고 권한이 admin이 아닌 경우 + bestRole = roleName; + } else if (roleName.equals("member") && bestRole.equals("reader")) { // 최고 권한이 reader인 경우 + bestRole = roleName; + } } - return lists; + return Map.of("role", bestRole); } // 관리자용 토큰 발행 @@ -129,6 +140,7 @@ public class AuthService { return user.get("token"); } + // 특정 사용자의 참여 프로젝트 반환 private List<ProjectIdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException { String userId = user.get("id"); String token = user.get("token"); @@ -156,4 +168,20 @@ public class AuthService { } return lists; } + + private String validateTokenAndGetUserId(String token) throws JsonProcessingException { + String url = keystone + "/auth/tokens"; + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Auth-Token", getAdminToken()); + headers.set("X-Subject-Token", token); + HttpEntity<String> requestEntity = new HttpEntity<>(headers); + ResponseEntity<String> res; + try { + res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + } catch (HttpClientErrorException.NotFound e) { + throw new CustomException(ErrorCode.INVALID_TOKEN); + } + return objectMapper.readTree(res.getBody()).path("token").path("user").path("id").asText(); + + } }