Skip to content
Snippets Groups Projects
Commit de87acd2 authored by nahyun's avatar nahyun
Browse files

Merge branch 'feat/auth' into 'dev'

Feat/auth 프로젝트 role 조회 api 추가

See merge request !3
parents 0b638ed2 cf23a243
No related branches found
No related tags found
3 merge requests!15Feat/certificate,!6Feat/forwarding 포트포워딩 CRUD,!3Feat/auth 프로젝트 role 조회 api 추가
...@@ -6,10 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; ...@@ -6,10 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/auth") @RequestMapping("/api/auth")
...@@ -24,4 +21,11 @@ public class AuthController { ...@@ -24,4 +21,11 @@ public class AuthController {
return ResponseEntity.ok(authService.userLogin(response, loginRequestDTO)); 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));
}
} }
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;
}
...@@ -9,7 +9,10 @@ import org.springframework.http.HttpStatus; ...@@ -9,7 +9,10 @@ import org.springframework.http.HttpStatus;
public enum ErrorCode { public enum ErrorCode {
// User // 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 HttpStatus status;
private final String message; private final String message;
......
...@@ -3,7 +3,6 @@ package com.aolda.itda.service; ...@@ -3,7 +3,6 @@ package com.aolda.itda.service;
import com.aolda.itda.dto.auth.LoginRequestDTO; import com.aolda.itda.dto.auth.LoginRequestDTO;
import com.aolda.itda.dto.auth.LoginResponseDTO; import com.aolda.itda.dto.auth.LoginResponseDTO;
import com.aolda.itda.dto.auth.ProjectIdAndNameDTO; 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.CustomException;
import com.aolda.itda.exception.ErrorCode; import com.aolda.itda.exception.ErrorCode;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
...@@ -15,6 +14,7 @@ import lombok.RequiredArgsConstructor; ...@@ -15,6 +14,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*; import org.springframework.http.*;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.util.*; import java.util.*;
...@@ -88,8 +88,15 @@ public class AuthService { ...@@ -88,8 +88,15 @@ public class AuthService {
"token", token); "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 userId = user.get("id");
String token = user.get("token"); String token = user.get("token");
...@@ -97,7 +104,7 @@ public class AuthService { ...@@ -97,7 +104,7 @@ public class AuthService {
throw new CustomException(ErrorCode.INVALID_USER_INFO); 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(); HttpHeaders headers = new HttpHeaders();
headers.set("X-Auth-Token", getAdminToken()); headers.set("X-Auth-Token", getAdminToken());
...@@ -108,19 +115,23 @@ public class AuthService { ...@@ -108,19 +115,23 @@ public class AuthService {
JsonNode node = objectMapper.readTree(res.getBody()); JsonNode node = objectMapper.readTree(res.getBody());
ArrayNode arrayNode = (ArrayNode) node.get("role_assignments"); ArrayNode arrayNode = (ArrayNode) node.get("role_assignments");
List<ProjectRoleDTO> lists = new ArrayList<>(); String bestRole = "reader";
for (JsonNode assignment : arrayNode) { for (JsonNode assignment : arrayNode) {
String projectName = assignment.path("scope").path("project").path("name").asText();
String roleName = assignment.path("role").path("name").asText(); String roleName = assignment.path("role").path("name").asText();
ProjectRoleDTO projectRoleDTO = new ProjectRoleDTO(projectName, roleName); if (roleName.equals("admin")) { // admin인 경우
lists.add(projectRoleDTO); 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 { ...@@ -129,6 +140,7 @@ public class AuthService {
return user.get("token"); return user.get("token");
} }
// 특정 사용자의 참여 프로젝트 반환
private List<ProjectIdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException { private List<ProjectIdAndNameDTO> getProjectsWithUser(Map<String, String> user) throws JsonProcessingException {
String userId = user.get("id"); String userId = user.get("id");
String token = user.get("token"); String token = user.get("token");
...@@ -156,4 +168,20 @@ public class AuthService { ...@@ -156,4 +168,20 @@ public class AuthService {
} }
return lists; 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();
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment