From 48c035a255f332151a82220f9318f5a2aead787b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Fri, 28 Feb 2025 14:47:36 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EC=9A=A9=20=ED=95=B8=EB=93=A4=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../itda/exception/ApiExceptionHandler.java | 17 +++++++++++ .../aolda/itda/exception/CustomException.java | 19 ++++++++++++ .../com/aolda/itda/exception/ErrorCode.java | 16 ++++++++++ .../aolda/itda/exception/ErrorResponse.java | 29 +++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 src/main/java/com/aolda/itda/exception/ApiExceptionHandler.java create mode 100644 src/main/java/com/aolda/itda/exception/CustomException.java create mode 100644 src/main/java/com/aolda/itda/exception/ErrorCode.java create mode 100644 src/main/java/com/aolda/itda/exception/ErrorResponse.java diff --git a/build.gradle b/build.gradle index 9305e70..8b2abc8 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' + runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/main/java/com/aolda/itda/exception/ApiExceptionHandler.java b/src/main/java/com/aolda/itda/exception/ApiExceptionHandler.java new file mode 100644 index 0000000..4d1f360 --- /dev/null +++ b/src/main/java/com/aolda/itda/exception/ApiExceptionHandler.java @@ -0,0 +1,17 @@ +package com.aolda.itda.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@Slf4j +@RestControllerAdvice +public class ApiExceptionHandler { + + @ExceptionHandler(value = CustomException.class) + public ResponseEntity<ErrorResponse> handleCustomException(CustomException e) { + log.error("[handleCustomException] {} : {}", e.getErrorCode().name(), e.getErrorCode().getMessage()); + return ErrorResponse.fromException(e); + } +} diff --git a/src/main/java/com/aolda/itda/exception/CustomException.java b/src/main/java/com/aolda/itda/exception/CustomException.java new file mode 100644 index 0000000..d110063 --- /dev/null +++ b/src/main/java/com/aolda/itda/exception/CustomException.java @@ -0,0 +1,19 @@ +package com.aolda.itda.exception; + +import lombok.Getter; + +@Getter +public class CustomException extends RuntimeException{ + private ErrorCode errorCode; + + private String info; + + public CustomException(ErrorCode errorCode) { + this.errorCode = errorCode; + } + + public CustomException(ErrorCode errorCode, String info){ + this.errorCode = errorCode; + this.info = info; + } +} diff --git a/src/main/java/com/aolda/itda/exception/ErrorCode.java b/src/main/java/com/aolda/itda/exception/ErrorCode.java new file mode 100644 index 0000000..6bcb643 --- /dev/null +++ b/src/main/java/com/aolda/itda/exception/ErrorCode.java @@ -0,0 +1,16 @@ +package com.aolda.itda.exception; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@RequiredArgsConstructor +public enum ErrorCode { + + // User + INVALID_USER_INFO(HttpStatus.BAD_REQUEST, "잘못된 회원 정보입니다"); + + private final HttpStatus status; + private final String message; +} diff --git a/src/main/java/com/aolda/itda/exception/ErrorResponse.java b/src/main/java/com/aolda/itda/exception/ErrorResponse.java new file mode 100644 index 0000000..1bec060 --- /dev/null +++ b/src/main/java/com/aolda/itda/exception/ErrorResponse.java @@ -0,0 +1,29 @@ +package com.aolda.itda.exception; + +import lombok.Builder; +import lombok.Getter; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +@Getter +@Builder +public class ErrorResponse { + + private final HttpStatus status; // HTTP 상태 코드 + private final String code; // 에러 코드 + private final String message; // 에러 메시지 + + public static ResponseEntity<ErrorResponse> fromException(CustomException e) { + String message = e.getErrorCode().getMessage(); + if (e.getInfo() != null) { + message += " " + e.getInfo(); // 추가 정보가 있는 경우 결합 + } + return ResponseEntity + .status(e.getErrorCode().getStatus()) + .body(ErrorResponse.builder() + .status(e.getErrorCode().getStatus()) + .code(e.getErrorCode().name()) + .message(message) + .build()); + } +} -- GitLab From de5c55e5fbb480d20a6bbf180b2caeae6a4bfde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Fri, 28 Feb 2025 22:27:45 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EB=B0=9C?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../java/com/aolda/itda/config/WebConfig.java | 19 ++++++ .../aolda/itda/controller/AuthController.java | 27 +++++++++ .../aolda/itda/dto/auth/LoginRequestDTO.java | 11 ++++ .../aolda/itda/dto/auth/LoginResponseDTO.java | 16 +++++ .../aolda/itda/dto/auth/ProjectRoleDTO.java | 17 ++++++ .../com/aolda/itda/service/AuthService.java | 60 +++++++++++++++++++ 7 files changed, 151 insertions(+) create mode 100644 src/main/java/com/aolda/itda/config/WebConfig.java create mode 100644 src/main/java/com/aolda/itda/controller/AuthController.java create mode 100644 src/main/java/com/aolda/itda/dto/auth/LoginRequestDTO.java create mode 100644 src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java create mode 100644 src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java create mode 100644 src/main/java/com/aolda/itda/service/AuthService.java diff --git a/build.gradle b/build.gradle index 8b2abc8..5cef9f6 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' runtimeOnly 'com.mysql:mysql-connector-j' + implementation 'org.pacesys:openstack4j:3.1.0' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' diff --git a/src/main/java/com/aolda/itda/config/WebConfig.java b/src/main/java/com/aolda/itda/config/WebConfig.java new file mode 100644 index 0000000..9eb992b --- /dev/null +++ b/src/main/java/com/aolda/itda/config/WebConfig.java @@ -0,0 +1,19 @@ +package com.aolda.itda.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + @Override + public void addCorsMappings(CorsRegistry registry) { // 스프링단에서 cors 설정 + registry.addMapping("/**") + .allowedOriginPatterns("*") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "FETCH") + .allowedHeaders("*") + .allowCredentials(true) + .exposedHeaders("Authorization", "X-Refresh-Token", "Access-Control-Allow-Origin") + ; + } +} diff --git a/src/main/java/com/aolda/itda/controller/AuthController.java b/src/main/java/com/aolda/itda/controller/AuthController.java new file mode 100644 index 0000000..7ffa41e --- /dev/null +++ b/src/main/java/com/aolda/itda/controller/AuthController.java @@ -0,0 +1,27 @@ +package com.aolda.itda.controller; + +import com.aolda.itda.dto.auth.LoginRequestDTO; +import com.aolda.itda.service.AuthService; +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; + +@RestController +@RequestMapping("/api/auth") +@RequiredArgsConstructor +public class AuthController { + + private final AuthService authService; + + @PostMapping("/login") + public ResponseEntity<Object> login(HttpServletResponse response, + @RequestBody LoginRequestDTO loginRequestDTO) { + + + return ResponseEntity.ok(authService.getToken(response, loginRequestDTO)); + } +} diff --git a/src/main/java/com/aolda/itda/dto/auth/LoginRequestDTO.java b/src/main/java/com/aolda/itda/dto/auth/LoginRequestDTO.java new file mode 100644 index 0000000..b91b3af --- /dev/null +++ b/src/main/java/com/aolda/itda/dto/auth/LoginRequestDTO.java @@ -0,0 +1,11 @@ +package com.aolda.itda.dto.auth; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class LoginRequestDTO { + private String id; + private String password; +} diff --git a/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java new file mode 100644 index 0000000..ecbcbd2 --- /dev/null +++ b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java @@ -0,0 +1,16 @@ +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 LoginResponseDTO { + private List<ProjectRoleDTO> lists; +} diff --git a/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java b/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java new file mode 100644 index 0000000..b08218b --- /dev/null +++ b/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java @@ -0,0 +1,17 @@ +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 List<String> roles; +} diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java new file mode 100644 index 0000000..6233da7 --- /dev/null +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -0,0 +1,60 @@ +package com.aolda.itda.service; + +import com.aolda.itda.dto.auth.LoginRequestDTO; +import com.aolda.itda.dto.auth.LoginResponseDTO; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.*; + +@Service +@RequiredArgsConstructor +public class AuthService { + + public LoginResponseDTO getToken(HttpServletResponse response, LoginRequestDTO loginRequestDTO) { + + RestTemplate restTemplate = new RestTemplate(); + String url = "http://10.16.0.2:5000/v3/auth/tokens"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + String requestBody = "{\n" + + " \"auth\": {\n" + + " \"identity\": {\n" + + " \"methods\": [\n" + + " \"password\"\n" + + " ],\n" + + " \"password\": {\n" + + " \"user\": {\n" + + " \"name\": \""+ loginRequestDTO.getId() + "\",\n" + + " \"domain\": {\n" + + " \"name\": \"Default\"\n" + + " },\n" + + " \"password\": \"" + loginRequestDTO.getPassword() + "\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); + ResponseEntity<Map> res = restTemplate.postForEntity(url, requestEntity, Map.class); + System.out.println(res.getBody()); + + Map<String, Object> resToken = (Map<String, Object>) res.getBody().get("token"); + Map<String, Object> resUser = (Map<String, Object>) resToken.get("user"); + String userId = (String) resUser.get("id"); + + System.out.println("User ID: " + userId); + response.addHeader("X-Subject-Token", res.getHeaders().getFirst("X-Subject-Token")); + return LoginResponseDTO.builder() + .lists(null) + .build(); + } +} -- GitLab From e033bfbf3beac297e1189d83dcbd08ddc6ac87bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Sun, 2 Mar 2025 23:35:40 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EB=B0=9C?= =?UTF-8?q?=ED=96=89=EC=8B=9C=20=ED=94=84=EB=A1=9C=EC=A0=9D=ED=8A=B8?= =?UTF-8?q?=EB=B3=84=20Role=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aolda/itda/controller/AuthController.java | 6 +- .../aolda/itda/dto/auth/ProjectRoleDTO.java | 2 +- .../com/aolda/itda/service/AuthService.java | 99 ++++++++++++++++--- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/aolda/itda/controller/AuthController.java b/src/main/java/com/aolda/itda/controller/AuthController.java index 7ffa41e..274ad8f 100644 --- a/src/main/java/com/aolda/itda/controller/AuthController.java +++ b/src/main/java/com/aolda/itda/controller/AuthController.java @@ -2,6 +2,7 @@ package com.aolda.itda.controller; import com.aolda.itda.dto.auth.LoginRequestDTO; import com.aolda.itda.service.AuthService; +import com.fasterxml.jackson.core.JsonProcessingException; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -19,9 +20,8 @@ public class AuthController { @PostMapping("/login") public ResponseEntity<Object> login(HttpServletResponse response, - @RequestBody LoginRequestDTO loginRequestDTO) { + @RequestBody LoginRequestDTO loginRequestDTO) throws JsonProcessingException { - - return ResponseEntity.ok(authService.getToken(response, loginRequestDTO)); + return ResponseEntity.ok(authService.userLogin(response, loginRequestDTO)); } } diff --git a/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java b/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java index b08218b..d3b9b8e 100644 --- a/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java +++ b/src/main/java/com/aolda/itda/dto/auth/ProjectRoleDTO.java @@ -13,5 +13,5 @@ import java.util.List; @Builder public class ProjectRoleDTO { private String projectName; - private List<String> roles; + private String roleName; } diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index 6233da7..cbd20a1 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -2,12 +2,17 @@ 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.ProjectRoleDTO; +import com.aolda.itda.exception.CustomException; +import com.aolda.itda.exception.ErrorCode; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -17,10 +22,36 @@ import java.util.*; @RequiredArgsConstructor public class AuthService { - public LoginResponseDTO getToken(HttpServletResponse response, LoginRequestDTO loginRequestDTO) { + @Value("${spring.server.keystone}") + private String keystone; + @Value("${spring.server.admin-id}") + private String adminId; + @Value("${spring.server.admin-password}") + private String adminPassword; + private final RestTemplate restTemplate = new RestTemplate(); + private final ObjectMapper objectMapper = new ObjectMapper(); - RestTemplate restTemplate = new RestTemplate(); - String url = "http://10.16.0.2:5000/v3/auth/tokens"; + // 사용자 로그인 후 토큰 발행 및 Role 반환 + public LoginResponseDTO userLogin(HttpServletResponse response, LoginRequestDTO loginRequestDTO) throws JsonProcessingException { + Map<String, String> user = getToken(loginRequestDTO.getId(), loginRequestDTO.getPassword()); + + String userId = user.get("id"); + String token = user.get("token"); + + if (userId == null || token == null) { + throw new CustomException(ErrorCode.INVALID_USER_INFO); + } + + response.addHeader("X-Subject-Token", token); + return LoginResponseDTO.builder() + .lists(getRolesWithProjects(user)) + .build(); + } + + // 특정 사용자의 토큰 발행 + private Map<String, String> getToken(String id, String password) { + + String url = keystone + "/auth/tokens"; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); @@ -32,11 +63,11 @@ public class AuthService { " ],\n" + " \"password\": {\n" + " \"user\": {\n" + - " \"name\": \""+ loginRequestDTO.getId() + "\",\n" + + " \"name\": \""+ id + "\",\n" + " \"domain\": {\n" + " \"name\": \"Default\"\n" + " },\n" + - " \"password\": \"" + loginRequestDTO.getPassword() + "\"\n" + + " \"password\": \"" + password + "\"\n" + " }\n" + " }\n" + " }\n" + @@ -45,16 +76,54 @@ public class AuthService { HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); ResponseEntity<Map> res = restTemplate.postForEntity(url, requestEntity, Map.class); - System.out.println(res.getBody()); Map<String, Object> resToken = (Map<String, Object>) res.getBody().get("token"); Map<String, Object> resUser = (Map<String, Object>) resToken.get("user"); String userId = (String) resUser.get("id"); + String token = res.getHeaders().getFirst("X-Subject-Token"); - System.out.println("User ID: " + userId); - response.addHeader("X-Subject-Token", res.getHeaders().getFirst("X-Subject-Token")); - return LoginResponseDTO.builder() - .lists(null) - .build(); + return Map.of("id", userId, + "token", token); + } + + // 특정 사용자의 프로젝트별 Role 반환 + private List<ProjectRoleDTO> getRolesWithProjects(Map<String, String> user) throws JsonProcessingException { + String userId = user.get("id"); + String token = user.get("token"); + + if (userId == null || token == null) { + throw new CustomException(ErrorCode.INVALID_USER_INFO); + } + + String url = keystone + "/role_assignments?user.id=" + userId + "&effective&include_names=true"; + + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Auth-Token", getAdminToken()); + + HttpEntity<String> requestEntity = new HttpEntity<>(headers); + ResponseEntity<String> res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + + JsonNode node = objectMapper.readTree(res.getBody()); + ArrayNode arrayNode = (ArrayNode) node.get("role_assignments"); + + List<ProjectRoleDTO> lists = new ArrayList<>(); + + 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); + + } + + return lists; + } + + // 관리자용 토큰 발행 + public String getAdminToken() { + Map<String, String> user = getToken(adminId, adminPassword); + return user.get("token"); } } -- GitLab From 9b5807576783d86fb0f3d449517066fa9c09ac47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B2=9C=20=EC=A7=84=EA=B0=95?= <jjjjjk12@ajou.ac.kr> Date: Mon, 3 Mar 2025 21:02:38 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=ED=86=A0=ED=81=B0=20=EB=B0=9C?= =?UTF-8?q?=ED=96=89=EC=8B=9C=20=EC=B0=B8=EC=97=AC=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=EB=A7=8C=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aolda/itda/dto/auth/LoginResponseDTO.java | 3 +- .../itda/dto/auth/ProjectIdAndNameDTO.java | 16 ++++++++++ .../com/aolda/itda/service/AuthService.java | 32 ++++++++++++++++++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java diff --git a/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java index ecbcbd2..a5aa14a 100644 --- a/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java +++ b/src/main/java/com/aolda/itda/dto/auth/LoginResponseDTO.java @@ -12,5 +12,6 @@ import java.util.List; @AllArgsConstructor @Builder public class LoginResponseDTO { - private List<ProjectRoleDTO> lists; + private Boolean isAdmin; + private List<ProjectIdAndNameDTO> lists; } diff --git a/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java b/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java new file mode 100644 index 0000000..1ca894d --- /dev/null +++ b/src/main/java/com/aolda/itda/dto/auth/ProjectIdAndNameDTO.java @@ -0,0 +1,16 @@ +package com.aolda.itda.dto.auth; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ProjectIdAndNameDTO { + + private String id; + private String name; +} diff --git a/src/main/java/com/aolda/itda/service/AuthService.java b/src/main/java/com/aolda/itda/service/AuthService.java index cbd20a1..5f071ee 100644 --- a/src/main/java/com/aolda/itda/service/AuthService.java +++ b/src/main/java/com/aolda/itda/service/AuthService.java @@ -2,6 +2,7 @@ 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; @@ -44,7 +45,8 @@ public class AuthService { response.addHeader("X-Subject-Token", token); return LoginResponseDTO.builder() - .lists(getRolesWithProjects(user)) + .isAdmin(false) + .lists(getProjectsWithUser(user)) .build(); } @@ -126,4 +128,32 @@ public class AuthService { Map<String, String> user = getToken(adminId, adminPassword); return user.get("token"); } + + private List<ProjectIdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException { + String userId = user.get("id"); + String token = user.get("token"); + if (userId == null || token == null) { + throw new CustomException(ErrorCode.INVALID_USER_INFO); + } + + String url = keystone + "/users/" + userId + "/projects"; + + HttpHeaders headers = new HttpHeaders(); + headers.set("X-Auth-Token", getAdminToken()); + + HttpEntity<String> requestEntity = new HttpEntity<>(headers); + ResponseEntity<String> res = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class); + + JsonNode node = objectMapper.readTree(res.getBody()); + ArrayNode arrayNode = (ArrayNode) node.get("projects"); + + List<ProjectIdAndNameDTO> lists = new ArrayList<>(); + + for (JsonNode assignment : arrayNode) { + String projectId = assignment.path("id").asText(); + String projectName = assignment.path("name").asText(); + lists.add(new ProjectIdAndNameDTO(projectId, projectName)); + } + return lists; + } } -- GitLab