From edfeca916b19764867b64b146c4534818d73b157 Mon Sep 17 00:00:00 2001 From: suhaoh Date: Sun, 6 Oct 2024 17:01:34 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[36]=20partner=20=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=B8=94=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - auth id 추가, 패스워드 칼럼 삭제 --- .../db/migration/mysql/V1.6__update_partner_table.sql | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/resources/db/migration/mysql/V1.6__update_partner_table.sql diff --git a/src/main/resources/db/migration/mysql/V1.6__update_partner_table.sql b/src/main/resources/db/migration/mysql/V1.6__update_partner_table.sql new file mode 100644 index 0000000..c298202 --- /dev/null +++ b/src/main/resources/db/migration/mysql/V1.6__update_partner_table.sql @@ -0,0 +1,4 @@ +ALTER TABLE ecommerce_site.partners DROP COLUMN password; +ALTER TABLE ecommerce_site.partners + ADD auth_id varchar(255) NULL; +ALTER TABLE ecommerce_site.partners CHANGE auth_id auth_id varchar (255) NULL AFTER id; From 79c326e9e35d3475f0f2577336de723a4e743cff Mon Sep 17 00:00:00 2001 From: suhaoh Date: Sun, 6 Oct 2024 22:57:19 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[36]=20partner=20user=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/auth/KeycloakAuthService.java | 87 ++++++++++++++++++- .../application/partner/PartnerService.java | 27 ++++-- .../partner/dto/PartnerRequestDto.java | 20 ++++- .../partner/dto/PartnerResponseDto.java | 2 - .../commerce_site/attribute/UserRoles.java | 6 ++ .../commerce_site/config/OpenApiConfig.java | 4 +- .../commerce_site/config/SecurityConfig.java | 2 +- .../example/commerce_site/domain/Partner.java | 10 ++- .../partner/PartnerRepository.java | 3 + .../partner/PartnerController.java | 26 ++++-- .../partner/dto/PartnerRequest.java | 66 ++++++++++++++ .../partner/request/PartnerRequest.java | 34 -------- .../partner/response/PartnerResponse.java | 27 ------ .../representation/user/UserController.java | 1 + src/main/resources/application.yml | 2 + 15 files changed, 235 insertions(+), 82 deletions(-) create mode 100644 src/main/java/org/example/commerce_site/attribute/UserRoles.java create mode 100644 src/main/java/org/example/commerce_site/representation/partner/dto/PartnerRequest.java delete mode 100644 src/main/java/org/example/commerce_site/representation/partner/request/PartnerRequest.java delete mode 100644 src/main/java/org/example/commerce_site/representation/partner/response/PartnerResponse.java diff --git a/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java b/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java index f32640e..b31c339 100644 --- a/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java +++ b/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java @@ -1,7 +1,24 @@ package org.example.commerce_site.application.auth; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import org.example.commerce_site.application.auth.dto.OAuthAccessTokenResponse; +import org.example.commerce_site.application.partner.dto.PartnerRequestDto; +import org.example.commerce_site.attribute.UserRoles; +import org.example.commerce_site.common.exception.CustomException; +import org.example.commerce_site.common.exception.ErrorCode; import org.example.commerce_site.config.KeycloakProperties; +import org.keycloak.admin.client.Keycloak; +import org.keycloak.admin.client.resource.ClientsResource; +import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.admin.client.resource.UsersResource; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.CredentialRepresentation; +import org.keycloak.representations.idm.RoleRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -10,12 +27,15 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import jakarta.ws.rs.core.Response; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Service @RequiredArgsConstructor public class KeycloakAuthService { - private final RestTemplate restTemplate = new RestTemplate(); + private final Keycloak keycloak; private final KeycloakProperties keycloakProperties; public OAuthAccessTokenResponse.Keycloak getAccessToken(String code) { @@ -31,7 +51,72 @@ public OAuthAccessTokenResponse.Keycloak getAccessToken(String code) { final HttpEntity> httpEntity = new HttpEntity<>(info, headers); + RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForEntity(keycloakProperties.getUri().getToken(), httpEntity, OAuthAccessTokenResponse.Keycloak.class).getBody(); } + + public void createPartner(PartnerRequestDto.Create requestDto) { + UserRepresentation user = createUserRepresentation(requestDto); + UsersResource usersResource = keycloak.realm(keycloakProperties.getRealm()).users(); + String userId = null; + try (Response response = usersResource.create(user)) { + if (response.getStatus() == 201) { + userId = response.getLocation().getPath().replaceAll(".*/([^/]+)$", "$1"); + + resetUserPassword(userId, requestDto.getPassword()); + assignClientRoleToUser(userId, keycloakProperties.getCredentials().getClient(), + UserRoles.ROLE_PARTNER.name()); + } else { + throw new CustomException(ErrorCode.CREATE_KEYCLOAK_USER_ERROR); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new CustomException(ErrorCode.CREATE_KEYCLOAK_USER_ERROR); + } + } + + private UserRepresentation createUserRepresentation(PartnerRequestDto.Create partner) { + UserRepresentation user = new UserRepresentation(); + user.setUsername(partner.getEmail()); + user.setFirstName(partner.getFirstName()); + user.setLastName(partner.getLastName()); + user.setEmail(partner.getEmail()); + user.setEnabled(true); + + Map> resourceAccess = new HashMap<>(); + resourceAccess.put("bizId", Collections.singletonList(partner.getBusinessNumber())); + resourceAccess.put("shopName", Collections.singletonList(partner.getShopName())); + user.setAttributes(resourceAccess); + + return user; + } + + private void resetUserPassword(String userId, String password) { + CredentialRepresentation credential = new CredentialRepresentation(); + credential.setTemporary(false); + credential.setType(CredentialRepresentation.PASSWORD); + credential.setValue(password); + + UsersResource usersResource = keycloak.realm(keycloakProperties.getRealm()).users(); + usersResource.get(userId).resetPassword(credential); + } + + private void assignClientRoleToUser(String userId, String clientId, String roleName) { + ClientsResource clientsResource = keycloak.realm(keycloakProperties.getRealm()).clients(); + ClientRepresentation oauth2Client = clientsResource.findByClientId(clientId).getFirst(); + + if (oauth2Client == null) { + throw new CustomException(ErrorCode.CREATE_KEYCLOAK_USER_ERROR); + } + + RoleRepresentation userClientRole = keycloak.realm(keycloakProperties.getRealm()) + .clients().get(oauth2Client.getId()) + .roles().get(roleName).toRepresentation(); + + UserResource userResource = keycloak.realm(keycloakProperties.getRealm()).users().get(userId); + userResource.roles() + .clientLevel(oauth2Client.getId()) + .add(List.of(userClientRole)); + } } diff --git a/src/main/java/org/example/commerce_site/application/partner/PartnerService.java b/src/main/java/org/example/commerce_site/application/partner/PartnerService.java index 4d3d3d5..d337cd9 100644 --- a/src/main/java/org/example/commerce_site/application/partner/PartnerService.java +++ b/src/main/java/org/example/commerce_site/application/partner/PartnerService.java @@ -1,14 +1,15 @@ package org.example.commerce_site.application.partner; import org.example.commerce_site.application.partner.dto.PartnerRequestDto; -import org.example.commerce_site.application.partner.dto.PartnerResponseDto; +import org.example.commerce_site.application.user.dto.UserRequestDto; +import org.example.commerce_site.attribute.PartnerStatus; import org.example.commerce_site.common.exception.CustomException; import org.example.commerce_site.common.exception.ErrorCode; import org.example.commerce_site.domain.Partner; import org.example.commerce_site.infrastructure.partner.PartnerRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; -import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -19,14 +20,30 @@ public class PartnerService { private final PartnerRepository partnerRepository; @Transactional - public PartnerResponseDto.Create create(PartnerRequestDto.Create dto) { - // TODO : email 중복 체크 - return PartnerResponseDto.Create.of(partnerRepository.save(PartnerRequestDto.Create.toEntity(dto))); + public Partner create(PartnerRequestDto.CreateWebHook dto) { + return partnerRepository.save(PartnerRequestDto.CreateWebHook.toEntity(dto)); } + @Transactional(readOnly = true) public Partner getPartner(Long partnerId) { return partnerRepository.findById(partnerId).orElseThrow( () -> new CustomException(ErrorCode.PARTNER_NOT_FOUND) ); } + + @Transactional + public void updatePartnerStatusActive(UserRequestDto.Create dto) { + Partner partner = partnerRepository.findByEmail(dto.getEmail()).orElseThrow( + () -> new CustomException(ErrorCode.PARTNER_NOT_FOUND) + ); + partner.updateStatus(PartnerStatus.ACTIVE); + partnerRepository.save(partner); + } + + @Transactional + public void updateAuthId(Partner partner, String authId) { + partner.updateAuthId(authId); + partner.updateStatus(PartnerStatus.ACTIVE); + partnerRepository.save(partner); + } } diff --git a/src/main/java/org/example/commerce_site/application/partner/dto/PartnerRequestDto.java b/src/main/java/org/example/commerce_site/application/partner/dto/PartnerRequestDto.java index 827e463..f00c89c 100644 --- a/src/main/java/org/example/commerce_site/application/partner/dto/PartnerRequestDto.java +++ b/src/main/java/org/example/commerce_site/application/partner/dto/PartnerRequestDto.java @@ -12,18 +12,30 @@ public class PartnerRequestDto { @Builder @ToString public static class Create { - private String name; + private String firstName; + private String lastName; private String email; + private String shopName; private String password; private String businessNumber; + } + + @Getter + @Builder + @ToString + public static class CreateWebHook { + private String id; + private String name; + private String email; + private String bizId; - public static Partner toEntity(PartnerRequestDto.Create dto) { + public static Partner toEntity(PartnerRequestDto.CreateWebHook dto) { return Partner.builder() .name(dto.getName()) + .authId(dto.getId()) .email(dto.getEmail()) - .password(dto.getPassword()) + .businessNumber(dto.getBizId()) .status(PartnerStatus.ACTIVE) - .businessNumber(dto.getBusinessNumber()) .build(); } } diff --git a/src/main/java/org/example/commerce_site/application/partner/dto/PartnerResponseDto.java b/src/main/java/org/example/commerce_site/application/partner/dto/PartnerResponseDto.java index 19d190d..3ac7258 100644 --- a/src/main/java/org/example/commerce_site/application/partner/dto/PartnerResponseDto.java +++ b/src/main/java/org/example/commerce_site/application/partner/dto/PartnerResponseDto.java @@ -13,13 +13,11 @@ public class PartnerResponseDto { public static class Create { private String name; private String email; - private String businessNumber; public static PartnerResponseDto.Create of(Partner partner) { return Create.builder() .name(partner.getName()) .email(partner.getEmail()) - .businessNumber(partner.getBusinessNumber()) .build(); } } diff --git a/src/main/java/org/example/commerce_site/attribute/UserRoles.java b/src/main/java/org/example/commerce_site/attribute/UserRoles.java new file mode 100644 index 0000000..ce733bd --- /dev/null +++ b/src/main/java/org/example/commerce_site/attribute/UserRoles.java @@ -0,0 +1,6 @@ +package org.example.commerce_site.attribute; + +public enum UserRoles { + ROLE_USER, + ROLE_PARTNER +} diff --git a/src/main/java/org/example/commerce_site/config/OpenApiConfig.java b/src/main/java/org/example/commerce_site/config/OpenApiConfig.java index 3aedafe..32af146 100644 --- a/src/main/java/org/example/commerce_site/config/OpenApiConfig.java +++ b/src/main/java/org/example/commerce_site/config/OpenApiConfig.java @@ -53,7 +53,7 @@ public GroupedOpenApi userOpenApi() { @Bean public GroupedOpenApi partnerOpenApi() { - String[] paths = {"/partner/**"}; + String[] paths = {"/partners/**"}; return GroupedOpenApi.builder().group("PARTNER API").pathsToMatch(paths).build(); } @@ -65,7 +65,7 @@ public GroupedOpenApi productOpenApi() { @Bean public GroupedOpenApi categoryOpenApi() { - String[] paths = {"/category/**"}; + String[] paths = {"/categories/**"}; return GroupedOpenApi.builder().group("CATEGORY API").pathsToMatch(paths).build(); } diff --git a/src/main/java/org/example/commerce_site/config/SecurityConfig.java b/src/main/java/org/example/commerce_site/config/SecurityConfig.java index c28fcea..4e4ac02 100644 --- a/src/main/java/org/example/commerce_site/config/SecurityConfig.java +++ b/src/main/java/org/example/commerce_site/config/SecurityConfig.java @@ -47,7 +47,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .oauth2ResourceServer( oauth2 -> oauth2.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverter))) .headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin)); - + return http.build(); } } diff --git a/src/main/java/org/example/commerce_site/domain/Partner.java b/src/main/java/org/example/commerce_site/domain/Partner.java index d830a7f..07da9d2 100644 --- a/src/main/java/org/example/commerce_site/domain/Partner.java +++ b/src/main/java/org/example/commerce_site/domain/Partner.java @@ -20,9 +20,17 @@ @Table(name = "partners") public class Partner extends BaseTimeEntity { private String name; + private String authId; private String businessNumber; - private String password; private String email; @Enumerated(EnumType.STRING) private PartnerStatus status; + + public void updateStatus(PartnerStatus partnerStatus) { + this.status = partnerStatus; + } + + public void updateAuthId(String authId) { + this.authId = authId; + } } diff --git a/src/main/java/org/example/commerce_site/infrastructure/partner/PartnerRepository.java b/src/main/java/org/example/commerce_site/infrastructure/partner/PartnerRepository.java index b6bac39..78f8fba 100644 --- a/src/main/java/org/example/commerce_site/infrastructure/partner/PartnerRepository.java +++ b/src/main/java/org/example/commerce_site/infrastructure/partner/PartnerRepository.java @@ -1,9 +1,12 @@ package org.example.commerce_site.infrastructure.partner; +import java.util.Optional; + import org.example.commerce_site.domain.Partner; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface PartnerRepository extends JpaRepository { + Optional findByEmail(String email); } diff --git a/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java b/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java index 5868425..c0beba9 100644 --- a/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java +++ b/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java @@ -1,13 +1,17 @@ package org.example.commerce_site.representation.partner; +import org.example.commerce_site.application.auth.KeycloakAuthService; import org.example.commerce_site.application.partner.PartnerService; import org.example.commerce_site.common.response.ApiSuccessResponse; -import org.example.commerce_site.representation.partner.request.PartnerRequest; -import org.example.commerce_site.representation.partner.response.PartnerResponse; +import org.example.commerce_site.config.KeycloakProperties; +import org.example.commerce_site.representation.partner.dto.PartnerRequest; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -19,11 +23,23 @@ @RequestMapping("/partners") public class PartnerController { private final PartnerService partnerService; + private final KeycloakAuthService keycloakAuthService; + private final KeycloakProperties keycloakProperties; @PostMapping() - public ApiSuccessResponse createPartner( + public ApiSuccessResponse createPartner( @Valid @RequestBody PartnerRequest.Create request) { - return ApiSuccessResponse.success( - PartnerResponse.Create.of(partnerService.create(PartnerRequest.Create.toDTO(request)))); + keycloakAuthService.createPartner(PartnerRequest.Create.toDTO(request)); + return ApiSuccessResponse.success(); + } + + @PostMapping("/keycloak/webhook") + public void createPartner( + @RequestHeader("X-API-KEY") String apiKey, + @RequestBody PartnerRequest.CreateWebHook request) { + if (!keycloakProperties.getApiKey().equals(apiKey)) { + throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Invalid API Key"); + } + partnerService.create(PartnerRequest.CreateWebHook.toDTO(request)); } } diff --git a/src/main/java/org/example/commerce_site/representation/partner/dto/PartnerRequest.java b/src/main/java/org/example/commerce_site/representation/partner/dto/PartnerRequest.java new file mode 100644 index 0000000..c0fd7e3 --- /dev/null +++ b/src/main/java/org/example/commerce_site/representation/partner/dto/PartnerRequest.java @@ -0,0 +1,66 @@ +package org.example.commerce_site.representation.partner.dto; + +import org.example.commerce_site.application.partner.dto.PartnerRequestDto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.Getter; +import lombok.ToString; + +public class PartnerRequest { + @Getter + @ToString + public static class Create { + @NotBlank + private String firstName; + + @NotBlank + private String lastName; + + @NotBlank + private String shopName; + + @NotBlank + @Email(message = "유효한 이메일 주소를 입력하세요.") + private String email; + + @NotBlank + @Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,20}$", + message = "패스워드는 8자리 이상 20자리 이하 영문자와 숫자를 포함해야 합니다.") + private String password; + + @NotBlank + private String businessNumber; + + public static PartnerRequestDto.Create toDTO(PartnerRequest.Create request) { + return PartnerRequestDto.Create.builder() + .firstName(request.getFirstName()) + .lastName(request.getLastName()) + .email(request.getEmail()) + .shopName(request.getShopName()) + .password(request.getPassword()) + .businessNumber(request.getBusinessNumber()) + .build(); + } + } + + @Getter + @ToString + public static class CreateWebHook { + private String id; + private String name; + private String email; + private String bizId; + + public static PartnerRequestDto.CreateWebHook toDTO(PartnerRequest.CreateWebHook request) { + return PartnerRequestDto.CreateWebHook.builder() + .id(request.getId()) + .name(request.getName()) + .email(request.getEmail()) + .bizId(request.getBizId()) + .build(); + } + } + +} diff --git a/src/main/java/org/example/commerce_site/representation/partner/request/PartnerRequest.java b/src/main/java/org/example/commerce_site/representation/partner/request/PartnerRequest.java deleted file mode 100644 index 407e09d..0000000 --- a/src/main/java/org/example/commerce_site/representation/partner/request/PartnerRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.example.commerce_site.representation.partner.request; - -import org.example.commerce_site.application.partner.dto.PartnerRequestDto; - -import jakarta.validation.constraints.NotBlank; -import lombok.Getter; -import lombok.ToString; - -public class PartnerRequest { - @Getter - @ToString - public static class Create { - @NotBlank - private String name; - @NotBlank - //TODO email 형식 체크 - private String email; - @NotBlank - //TODO 패스워드 형식 체크 (8자리 이상 20자리 이하 영문 + 숫자) - private String password; - @NotBlank - private String businessNumber; - - public static PartnerRequestDto.Create toDTO(PartnerRequest.Create request) { - return PartnerRequestDto.Create.builder() - .name(request.getName()) - .email(request.getEmail()) - //TODO PWD 암호화 - .password(request.getPassword()) - .businessNumber(request.getBusinessNumber()) - .build(); - } - } -} diff --git a/src/main/java/org/example/commerce_site/representation/partner/response/PartnerResponse.java b/src/main/java/org/example/commerce_site/representation/partner/response/PartnerResponse.java deleted file mode 100644 index 0c508dc..0000000 --- a/src/main/java/org/example/commerce_site/representation/partner/response/PartnerResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.example.commerce_site.representation.partner.response; - -import org.example.commerce_site.application.partner.dto.PartnerResponseDto; - -import lombok.Builder; -import lombok.Getter; -import lombok.ToString; - -public class PartnerResponse { - - @Getter - @Builder - @ToString - public static class Create { - private String name; - private String email; - private String businessNumber; - - public static PartnerResponse.Create of(PartnerResponseDto.Create dto) { - return PartnerResponse.Create.builder() - .name(dto.getName()) - .email(dto.getEmail()) - .businessNumber(dto.getBusinessNumber()) - .build(); - } - } -} diff --git a/src/main/java/org/example/commerce_site/representation/user/UserController.java b/src/main/java/org/example/commerce_site/representation/user/UserController.java index d0afbae..0bc48ea 100644 --- a/src/main/java/org/example/commerce_site/representation/user/UserController.java +++ b/src/main/java/org/example/commerce_site/representation/user/UserController.java @@ -21,6 +21,7 @@ public class UserController { private final UserService userService; private final KeycloakProperties keycloakProperties; + @PostMapping("/keycloak/webhook") public void createUser( @RequestHeader("X-API-KEY") String apiKey, diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e880b7e..8678b16 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -61,6 +61,8 @@ auth: exclude: post: - /users/keycloak/webhook + - /partners/keycloak/webhook + - /partners get: - /auth/** web: From 605a5f59396ec68821a2466a1204f98c7572556e Mon Sep 17 00:00:00 2001 From: suhaoh Date: Sun, 6 Oct 2024 23:00:25 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[36]=20=EB=8F=99=EC=9D=BC=ED=95=9C=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commerce_site/representation/partner/PartnerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java b/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java index c0beba9..12a8d8b 100644 --- a/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java +++ b/src/main/java/org/example/commerce_site/representation/partner/PartnerController.java @@ -34,7 +34,7 @@ public ApiSuccessResponse createPartner( } @PostMapping("/keycloak/webhook") - public void createPartner( + public void createPartnerWebhook( @RequestHeader("X-API-KEY") String apiKey, @RequestBody PartnerRequest.CreateWebHook request) { if (!keycloakProperties.getApiKey().equals(apiKey)) { From ac62cc7cc40e0ea2b89633f26cb0b310c64fbcd1 Mon Sep 17 00:00:00 2001 From: suhaoh Date: Wed, 9 Oct 2024 22:46:54 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[36]=20RestTemplate=20=EC=9D=84=20=EB=B9=88?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=83=9D=EC=84=B1=ED=95=98=EC=97=AC=20?= =?UTF-8?q?=EC=A3=BC=EC=9E=85=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/auth/KeycloakAuthService.java | 2 +- .../org/example/commerce_site/config/AppConfig.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/example/commerce_site/config/AppConfig.java diff --git a/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java b/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java index b31c339..bd03020 100644 --- a/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java +++ b/src/main/java/org/example/commerce_site/application/auth/KeycloakAuthService.java @@ -37,6 +37,7 @@ public class KeycloakAuthService { private final Keycloak keycloak; private final KeycloakProperties keycloakProperties; + private final RestTemplate restTemplate; public OAuthAccessTokenResponse.Keycloak getAccessToken(String code) { MultiValueMap info = new LinkedMultiValueMap<>(); @@ -51,7 +52,6 @@ public OAuthAccessTokenResponse.Keycloak getAccessToken(String code) { final HttpEntity> httpEntity = new HttpEntity<>(info, headers); - RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForEntity(keycloakProperties.getUri().getToken(), httpEntity, OAuthAccessTokenResponse.Keycloak.class).getBody(); } diff --git a/src/main/java/org/example/commerce_site/config/AppConfig.java b/src/main/java/org/example/commerce_site/config/AppConfig.java new file mode 100644 index 0000000..12fa81f --- /dev/null +++ b/src/main/java/org/example/commerce_site/config/AppConfig.java @@ -0,0 +1,13 @@ +package org.example.commerce_site.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class AppConfig { + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } +}