diff --git a/src/main/java/org/poolc/api/auth/configurations/WebSecurityConfig.java b/src/main/java/org/poolc/api/auth/configurations/WebSecurityConfig.java index 80c0195..399e519 100644 --- a/src/main/java/org/poolc/api/auth/configurations/WebSecurityConfig.java +++ b/src/main/java/org/poolc/api/auth/configurations/WebSecurityConfig.java @@ -152,6 +152,9 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers(HttpMethod.PUT, "/interview/slots/*").hasAuthority(MemberRole.ADMIN.name()) .antMatchers(HttpMethod.DELETE, "/interview/slots/*").hasAuthority(MemberRole.ADMIN.name()) .antMatchers(HttpMethod.PUT, "/interview/slots").hasAuthority(MemberRole.ADMIN.name()) + + .antMatchers(HttpMethod.GET, "/kubernetes/").permitAll() + .antMatchers(HttpMethod.POST, "/kubernetes/").permitAll() .antMatchers("/**").permitAll() .anyRequest().authenticated().and() diff --git a/src/main/java/org/poolc/api/kubernetes/controller/KubernetesController.java b/src/main/java/org/poolc/api/kubernetes/controller/KubernetesController.java new file mode 100644 index 0000000..039de3e --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/controller/KubernetesController.java @@ -0,0 +1,34 @@ +package org.poolc.api.kubernetes.controller; + +import lombok.RequiredArgsConstructor; +import org.poolc.api.kubernetes.dto.GetKubernetesResponseDto; +import org.poolc.api.kubernetes.service.KubernetesService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + +@RestController +@RequestMapping("/kubernetes") +@RequiredArgsConstructor +public class KubernetesController { + + private final KubernetesService kubernetesService; + + @GetMapping(value="/") + public ResponseEntity getAllActiveMembers(@RequestHeader("X-API-KEY") String apiKey){ + + GetKubernetesResponseDto response = new GetKubernetesResponseDto( + kubernetesService.getAllActiveMembers(apiKey) + ); + return ResponseEntity.ok().body(response); + } + + @PostMapping(value="/") + public ResponseEntity refreshMamberKeys(@RequestHeader("X-API-KEY") String apiKey, @RequestBody Map requestBody) { + + kubernetesService.refreshMemberKey(requestBody, apiKey); + return ResponseEntity.ok().build(); + } + +} diff --git a/src/main/java/org/poolc/api/kubernetes/domain/KubernetesMapping.java b/src/main/java/org/poolc/api/kubernetes/domain/KubernetesMapping.java new file mode 100644 index 0000000..443ab75 --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/domain/KubernetesMapping.java @@ -0,0 +1,34 @@ +package org.poolc.api.kubernetes.domain; + +import lombok.Builder; +import lombok.Getter; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +@Getter +@Entity(name = "kubernetes_mappings") +public class KubernetesMapping { + + @Id + @GeneratedValue + private Long id; + + @Column(name = "user_uuid",nullable = false) + private String UUID; + + @Column(name = "kubernetes_key", nullable = false, columnDefinition = "TEXT") + private String kubernetesKey; + + @Builder + public KubernetesMapping(String UUID, String kubernetesKey) { + this.UUID = UUID; + this.kubernetesKey = kubernetesKey; + } + + protected KubernetesMapping() { + + } +} diff --git a/src/main/java/org/poolc/api/kubernetes/dto/GetKubernetesResponseDto.java b/src/main/java/org/poolc/api/kubernetes/dto/GetKubernetesResponseDto.java new file mode 100644 index 0000000..40c512e --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/dto/GetKubernetesResponseDto.java @@ -0,0 +1,16 @@ +package org.poolc.api.kubernetes.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import lombok.Getter; + +import java.util.List; + +@Getter +public class GetKubernetesResponseDto { + private final List activeMembers; + + @JsonCreator + public GetKubernetesResponseDto(List activeMembers) { + this.activeMembers = activeMembers; + } +} diff --git a/src/main/java/org/poolc/api/kubernetes/dto/PostKubernetesRequestDto.java b/src/main/java/org/poolc/api/kubernetes/dto/PostKubernetesRequestDto.java new file mode 100644 index 0000000..fb439a6 --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/dto/PostKubernetesRequestDto.java @@ -0,0 +1,15 @@ +package org.poolc.api.kubernetes.dto; + +import lombok.Getter; + +import java.util.List; +import java.util.Map; + +@Getter +public class PostKubernetesRequestDto { + private final Map activeMembersMap; + + public PostKubernetesRequestDto(Map activeMembersMap) { + this.activeMembersMap = activeMembersMap; + } +} diff --git a/src/main/java/org/poolc/api/kubernetes/repository/KubernetesRepository.java b/src/main/java/org/poolc/api/kubernetes/repository/KubernetesRepository.java new file mode 100644 index 0000000..89edfbc --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/repository/KubernetesRepository.java @@ -0,0 +1,36 @@ +package org.poolc.api.kubernetes.repository; + +import org.poolc.api.kubernetes.domain.KubernetesMapping; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Optional; + +public interface KubernetesRepository extends JpaRepository { + + + @Query(value = "SELECT DISTINCT MEMBER_UUID\n" + + "FROM ROLES\n" + + "WHERE MEMBER_UUID IN (\n" + + " SELECT MEMBER_UUID\n" + + " FROM ROLES\n" + + " WHERE ROLES = 'MEMBER'\n" + + ")\n" + + "AND MEMBER_UUID NOT IN (\n" + + " SELECT MEMBER_UUID\n" + + " FROM ROLES\n" + + " WHERE ROLES = 'INACTIVE'\n" + + ")", nativeQuery = true) + List findAllActiveMembers(); + + @Modifying + @Transactional + @Query(value = "TRUNCATE TABLE KUBERNETES_MAPPINGS", nativeQuery = true) + void truncateKubernetesMappingTable(); + + @Query(value = "SELECT kubernetesKey FROM kubernetes_mappings WHERE UUID IN (SELECT UUID FROM Member WHERE loginID = :userId)") + Optional findKubernetesKeyByUserId(String userId); +} diff --git a/src/main/java/org/poolc/api/kubernetes/service/KubernetesService.java b/src/main/java/org/poolc/api/kubernetes/service/KubernetesService.java new file mode 100644 index 0000000..a37ae73 --- /dev/null +++ b/src/main/java/org/poolc/api/kubernetes/service/KubernetesService.java @@ -0,0 +1,54 @@ +package org.poolc.api.kubernetes.service; + +import lombok.RequiredArgsConstructor; +import org.poolc.api.kubernetes.domain.KubernetesMapping; +import org.poolc.api.kubernetes.repository.KubernetesRepository; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class KubernetesService { + private final KubernetesRepository kubernetesRepository; + + @Value("${kubernetes.api.key}") + private String API_KEY; + + public List getAllActiveMembers(String apiKey) { + if(!isValidApiKey(apiKey)) { + throw new IllegalArgumentException("Invalid API key"); + } + return kubernetesRepository.findAllActiveMembers(); + } + + @Transactional + public void refreshMemberKey(Map requestBody, String apiKey) { + if(!isValidApiKey(apiKey)) { + throw new IllegalArgumentException("Invalid API key"); + } + + kubernetesRepository.truncateKubernetesMappingTable(); + + List mappings = requestBody.entrySet().stream() + .map(entry -> KubernetesMapping.builder() + .UUID(entry.getKey()) + .kubernetesKey(entry.getValue()) + .build()) + .collect(Collectors.toList()); + kubernetesRepository.saveAll(mappings); + } + + public String getKubernetesKeyByUserId(String userId) { + return kubernetesRepository.findKubernetesKeyByUserId(userId) + .orElseThrow(() -> new IllegalArgumentException("No Kubernetes key found for user: " + userId)); + } + + private boolean isValidApiKey(String apiKey) { + return API_KEY.equals(apiKey); + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 72a1ca6..8a92411 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -38,3 +38,6 @@ book: id: ${NAVER_BOOK_CLIENT_ID} secret: ${NAVER_BOOK_CLIENT_SECRET} +kubernetes: + api: + key: ${KUBERNETES_API_KEY} \ No newline at end of file