From 15e8930a74aa94208616a3b974df870b35cfe7f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?lkd9125=28=EC=9D=B4=EA=B2=BD=EB=8F=84=29?= Date: Tue, 20 Feb 2024 15:55:42 +0900 Subject: [PATCH] =?UTF-8?q?feature:=20User=EB=AA=A8=EB=93=88=20-=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/kac-app/src/docs/asciidoc/index.adoc | 69 ++++ .../src/main/resources/static/docs/index.html | 345 ++++++++++++++++-- .../test/java/kr/co/palnet/kac/BaseTest.java | 78 +++- .../account/UserAccountControllerTest.java | 228 ++++++++++++ .../kac/data/pty/model/PtyCstmrGroup.java | 5 +- .../pty/service/PtyCstmrDomainService.java | 4 + .../account/service/UserAccountService.java | 11 +- .../controller/UserCertificateController.java | 17 + 8 files changed, 715 insertions(+), 42 deletions(-) create mode 100644 app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java create mode 100644 web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/certificate/controller/UserCertificateController.java diff --git a/app/kac-app/src/docs/asciidoc/index.adoc b/app/kac-app/src/docs/asciidoc/index.adoc index 1751cce..fee2ef1 100644 --- a/app/kac-app/src/docs/asciidoc/index.adoc +++ b/app/kac-app/src/docs/asciidoc/index.adoc @@ -172,4 +172,73 @@ include::{snippets}/com/code/lang/delete/query-parameters.adoc[] ==== [HTTP RESPONSE INFO] include::{snippets}/com/code/lang/delete/http-response.adoc[] +*** + +[[User-Account-API]] +== User-Account API + +=== [User 회원가입] + +==== [HTTP REQUEST INFO] +include::{snippets}/user/account/register/http-request.adoc[] + +include::{snippets}/user/account/register/request-fields.adoc[] + +==== [HTTP RESPONSE INFO] +include::{snippets}/user/account/register/http-response.adoc[] + +*** + +=== [User 회원탈퇴] + +==== [HTTP REQUEST INFO] +include::{snippets}/user/account/delete/http-request.adoc[] + +include::{snippets}/user/account/delete/request-headers.adoc[] + +==== [HTTP RESPONSE INFO] +include::{snippets}/user/account/delete/http-response.adoc[] + +*** + +=== [User 회원정보 조회] + +==== [HTTP REQUEST INFO] +include::{snippets}/user/account/profile/http-request.adoc[] + +include::{snippets}/user/account/profile/request-headers.adoc[] + +==== [HTTP RESPONSE INFO] +include::{snippets}/user/account/profile/http-response.adoc[] + +include::{snippets}/user/account/profile/response-fields.adoc[] + +*** + +=== [User 회원암호 변경] + +==== [HTTP REQUEST INFO] +include::{snippets}/user/account/update/pswd/http-request.adoc[] + +include::{snippets}/user/account/update/pswd/request-headers.adoc[] + +include::{snippets}/user/account/update/pswd/request-fields.adoc[] + +==== [HTTP RESPONSE INFO] +include::{snippets}/user/account/update/pswd/http-response.adoc[] + +*** + +=== [User 회원정보 변경] + +==== [HTTP REQUEST INFO] +include::{snippets}/user/account/update/http-request.adoc[] + +include::{snippets}/user/account/update/request-headers.adoc[] + +include::{snippets}/user/account/update/request-fields.adoc[] + +==== [HTTP RESPONSE INFO] +include::{snippets}/user/account/update/http-response.adoc[] + *** \ No newline at end of file diff --git a/app/kac-app/src/main/resources/static/docs/index.html b/app/kac-app/src/main/resources/static/docs/index.html index ddab2f6..2fdafe0 100644 --- a/app/kac-app/src/main/resources/static/docs/index.html +++ b/app/kac-app/src/main/resources/static/docs/index.html @@ -464,6 +464,11 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • [Code 언어 삭제]
  • +
  • User-Account API + +
  • @@ -515,11 +520,20 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 143
     
     [ {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411842",
       "siteCd" : "KAC",
       "groupCdNm" : "신규그룹001",
       "rm" : "비고....",
    @@ -626,7 +640,7 @@ Content-Length: 143
     

    [HTTP REQUEST INFO]

    -
    GET /v1/com/code/code?groupCd=NEW_GROUP_1707924397&langDivCd=ko_KR HTTP/1.1
    +
    GET /v1/com/code/code?groupCd=NEW_GROUP_1708411842&langDivCd=ko_KR HTTP/1.1
     Content-Type: application/json;charset=UTF-8
     Accept: application/json
     Host: localhost:8080
    @@ -664,11 +678,20 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 190
     
     [ {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411842",
       "cdId" : "NEW_CODE001",
       "cdNm" : "신규코드001",
       "upperCd" : null,
    @@ -759,11 +782,20 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 143
     
     [ {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411843",
       "siteCd" : "KAC",
       "groupCdNm" : "신규그룹001",
       "rm" : "비고....",
    @@ -835,7 +867,7 @@ Content-Length: 118
     Host: localhost:8080
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411843",
       "siteCd" : "KAC",
       "groupCdNm" : "신규그룹001",
       "rm" : "비고...."
    @@ -890,18 +922,27 @@ Host: localhost:8080
     
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    -Content-Length: 276
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
    +Content-Length: 275
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411843",
       "siteCd" : "KAC",
       "groupCdNm" : "신규그룹001",
       "rm" : "비고....",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.902778",
    +  "createDt" : "2024-02-20T15:50:43.127816",
       "updateUserId" : "CREATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.902782"
    +  "updateDt" : "2024-02-20T15:50:43.12782"
     }
    @@ -987,7 +1028,7 @@ Content-Length: 132 Host: localhost:8080 { - "groupCd" : "NEW_GROUP_1707924397", + "groupCd" : "NEW_GROUP_1708411843", "cdId" : "NEW_CODE001", "sortOrdr" : 0, "addInfoValue" : "추가!!", @@ -1049,20 +1090,29 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 310
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411843",
       "cdId" : "NEW_CODE001",
       "upperCd" : null,
       "sortOrdr" : 0,
       "addInfoValue" : "추가!!",
       "useYn" : "Y",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.887931",
    +  "createDt" : "2024-02-20T15:50:43.107273",
       "updateUserId" : "CREATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.887936"
    +  "updateDt" : "2024-02-20T15:50:43.107277"
     }
    @@ -1160,7 +1210,7 @@ Content-Length: 144 Host: localhost:8080 { - "groupCd" : "NEW_GROUP_1707924397", + "groupCd" : "NEW_GROUP_1708411842", "cdId" : "NEW_CODE001", "langDivCd" : "ko_KR", "cdNm" : "신규코드001", @@ -1222,19 +1272,28 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 302
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411842",
       "cdId" : "NEW_CODE001",
       "langDivCd" : "ko_KR",
       "cdNm" : "신규코드001",
       "rm" : "비고....",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.826757",
    +  "createDt" : "2024-02-20T15:50:43.009038",
       "updateUserId" : "CREATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.826761"
    +  "updateDt" : "2024-02-20T15:50:43.009043"
     }
    @@ -1326,7 +1385,7 @@ Content-Length: 118 Host: localhost:8080 { - "groupCd" : "NEW_GROUP_1707924397", + "groupCd" : "NEW_GROUP_1708411843", "siteCd" : "KAC", "groupCdNm" : "신규그룹001", "rm" : "비고...." @@ -1381,18 +1440,27 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    -Content-Length: 275
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
    +Content-Length: 276
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411843",
       "siteCd" : "KAC",
       "groupCdNm" : "신규그룹001",
       "rm" : "비고....",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.84228",
    +  "createDt" : "2024-02-20T15:50:43.031642",
       "updateUserId" : "UPDATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.844978"
    +  "updateDt" : "2024-02-20T15:50:43.035007"
     }
    @@ -1478,7 +1546,7 @@ Content-Length: 132 Host: localhost:8080 { - "groupCd" : "NEW_GROUP_1707924397", + "groupCd" : "NEW_GROUP_1708411842", "cdId" : "NEW_CODE001", "sortOrdr" : 0, "addInfoValue" : "수정!!", @@ -1540,20 +1608,29 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 310
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411842",
       "cdId" : "NEW_CODE001",
       "upperCd" : null,
       "sortOrdr" : 0,
       "addInfoValue" : "수정!!",
       "useYn" : "Y",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.757743",
    +  "createDt" : "2024-02-20T15:50:42.915944",
       "updateUserId" : "UPDATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.770459"
    +  "updateDt" : "2024-02-20T15:50:42.938404"
     }
    @@ -1651,7 +1728,7 @@ Content-Length: 143 Host: localhost:8080 { - "groupCd" : "NEW_GROUP_1707924397", + "groupCd" : "NEW_GROUP_1708411842", "cdId" : "NEW_CODE001", "langDivCd" : "ko_KR", "cdNm" : "신규코드001", @@ -1713,19 +1790,28 @@ Host: localhost:8080
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
     Content-Type: application/json;charset=UTF-8
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
     Content-Length: 301
     
     {
    -  "groupCd" : "NEW_GROUP_1707924397",
    +  "groupCd" : "NEW_GROUP_1708411842",
       "cdId" : "NEW_CODE001",
       "langDivCd" : "ko_KR",
       "cdNm" : "신규코드001",
       "rm" : "수정...",
       "createUserId" : "CREATE_USER",
    -  "createDt" : "2024-02-15T00:26:37.798977",
    +  "createDt" : "2024-02-20T15:50:42.973527",
       "updateUserId" : "UPDATE_USER",
    -  "updateDt" : "2024-02-15T00:26:37.803818"
    +  "updateDt" : "2024-02-20T15:50:42.978852"
     }
    @@ -1842,7 +1928,16 @@ Host: localhost:8080

    [HTTP RESPONSE INFO]

    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY

    @@ -1891,7 +1986,16 @@ Host: localhost:8080

    [HTTP RESPONSE INFO]

    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY

    @@ -1945,8 +2049,181 @@ Host: localhost:8080

    [HTTP RESPONSE INFO]

    -
    HTTP/1.1 200 OK
    +
    HTTP/1.1 200 OK
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
    +
    +
    +
    +
    +
    + + +
    +

    User-Account API

    +
    +
    +

    [User 회원가입]

    +
    +

    [HTTP REQUEST INFO]

    +
    +
    +
    POST /v1/user/account/register HTTP/1.1
    +Content-Type: application/json;charset=UTF-8
    +Accept: application/json
    +Content-Length: 337
    +Host: localhost:8080
    +
    +{
    +  "cstrmDivCd" : "MEMBER",
    +  "cstrmStatusCd" : "ACTIVE",
    +  "userId" : "TEST_1708411843171",
    +  "authId" : "USER",
    +  "siteCode" : "DRONE",
    +  "userPswd" : "palnet!234",
    +  "joinCrtfyCd" : "HP_CRTFD",
    +  "memberName" : "이경도",
    +  "brthdyDate" : "1999-09-07",
    +  "email" : "lkd9125@naver.com",
    +  "hpno" : "01083703435",
    +  "clncd" : "+82"
    +}
    +
    +
    + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    파라미터타입설명필수

    cstrmDivCd

    String

    회원타입 코드

    true

    cstrmStatusCd

    String

    회원 활성화 코드

    true

    userId

    String

    아이디

    true

    authId

    String

    권한 값

    true

    siteCode

    String

    사이트 코드

    true

    userPswd

    String

    암호

    true

    joinCrtfyCd

    String

    가입인증 분류 코드

    true

    memberName

    String

    이름

    true

    brthdyDate

    String

    생년월일

    true

    email

    String

    이메일

    true

    hpno

    String

    휴대폰 번호

    true

    clncd

    String

    휴대폰 국가번호

    true

    terms

    Array

    동의 약관 리스트

    false

    terms[].termsSno

    Number

    약관 식별번호

    true

    terms[].agreeYn

    String

    약관 동의여부

    true

    +
    +
    +

    [HTTP RESPONSE INFO]

    +
    +
    +
    HTTP/1.1 201 Created
    +Vary: Origin
    +Vary: Access-Control-Request-Method
    +Vary: Access-Control-Request-Headers
    +X-Content-Type-Options: nosniff
    +X-XSS-Protection: 0
    +Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    +Pragma: no-cache
    +Expires: 0
    +X-Frame-Options: DENY
    +
    +
    +

    Unresolved directive in index.adoc - include::./build/generated-snippets/user/account/register/response-fields.adoc[]


    @@ -1957,7 +2234,7 @@ Host: localhost:8080 diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java index 054591a..b96ab51 100644 --- a/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java +++ b/app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java @@ -1,18 +1,33 @@ package kr.co.palnet.kac; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.ServletException; +import kr.co.palnet.kac.api.v1.user.account.model.detail.SearchUserRS; +import kr.co.palnet.kac.api.v1.user.account.model.register.FormRegisterRQ; +import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService; import kr.co.palnet.kac.app.KacAppApplication; +import kr.co.palnet.kac.config.security.model.BaseUserDetails; +import kr.co.palnet.kac.config.security.service.BaseUserDetailsService; +import kr.co.palnet.kac.config.security.util.JwtUtil; +import kr.co.palnet.kac.util.ObjectMapperUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockFilterConfig; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation; +import org.springframework.security.config.BeanIds; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.filter.CharacterEncodingFilter; +import org.springframework.web.filter.DelegatingFilterProxy; + +import java.time.LocalDate; +import java.time.LocalDateTime; import static org.springframework.restdocs.operation.preprocess.Preprocessors.modifyUris; import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; @@ -24,12 +39,24 @@ public class BaseTest { @Autowired protected WebApplicationContext webApplicationContext; + @Autowired + protected UserAccountService userAccountService; + + @Autowired + protected BaseUserDetailsService baseUserDetailsService; + public MockMvc mockMvc; + protected final String CREATE_PASSWORD = "palnet!234"; + @BeforeEach - public void setUpAll(RestDocumentationContextProvider restDocumentationContextProvider){ + public void setUpAll(RestDocumentationContextProvider restDocumentationContextProvider) throws ServletException { + DelegatingFilterProxy delegateProxyFilter = new DelegatingFilterProxy(); + delegateProxyFilter.init(new MockFilterConfig(webApplicationContext.getServletContext(), BeanIds.SPRING_SECURITY_FILTER_CHAIN)); + + this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext) // @Autowired로 빈주입 받은 context - .addFilter(new CharacterEncodingFilter("UTF-8", true)) // UTF-8 인코딩 필터 + .addFilters(new CharacterEncodingFilter("UTF-8", true), delegateProxyFilter) // UTF-8 인코딩 필터, SecurityFilter .apply( MockMvcRestDocumentation.documentationConfiguration(restDocumentationContextProvider) .operationPreprocessors() @@ -42,4 +69,51 @@ public class BaseTest { ) .build(); } + + protected String getUserToken(){ + + String username = "TEST_" + System.currentTimeMillis(); + + String jsonRQ = """ + { + "cstrmDivCd" : "MEMBER", + "cstrmStatusCd" : "ACTIVE", + "userId" : "%s", + "authId" : "USER", + "siteCode" : "DRONE", + "userPswd" : "%s", + "joinCrtfyCd" : "HP_CRTFD", + "memberName" : "이경도", + "brthdyDate" : "1999-09-07", + "email" : "lkd9125@naver.com", + "hpno" : "01083703435", + "clncd" : "+82" + } + """.formatted(username, this.CREATE_PASSWORD); + + FormRegisterRQ rq = new FormRegisterRQ(); + rq.setCstrmDivCd("MEMBER"); + rq.setCstrmStatusCd("ACTIVE"); + rq.setUserId(username); + rq.setAuthId("USER"); + rq.setSiteCode("DRONE"); + rq.setUserPswd("palnet!234"); + rq.setJoinCrtfyCd("HP_CRTFD"); + rq.setMemberName("이경도"); + rq.setBrthdyDate(LocalDate.of(1999, 9, 7)); + rq.setEmail("lkd9125@naver.com"); + rq.setHpno("01083703435"); + rq.setClncd("+82"); + + try{ + userAccountService.createUser(rq); + } catch (Exception e){ + e.printStackTrace(); + } + + BaseUserDetails userDetails = (BaseUserDetails) baseUserDetailsService.loadUserByUsername(username); + + return JwtUtil.makeAuthToken(userDetails); + } + } diff --git a/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java b/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java new file mode 100644 index 0000000..e5f72f1 --- /dev/null +++ b/app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java @@ -0,0 +1,228 @@ +package kr.co.palnet.kac.user.account; + + +import kr.co.palnet.kac.BaseTest; +import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.headers.HeaderDocumentation; +import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; +import org.springframework.restdocs.payload.JsonFieldType; +import org.springframework.transaction.annotation.Transactional; + +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class UserAccountControllerTest extends BaseTest { + + @Autowired + private UserAccountService userAccountService; + + private final String BASE_URL = "/v1/user/account"; + + private final String GRANT_TYPE = "Bearer"; + + @DisplayName("회원정보 변경") + @Test + @Transactional + public void updateUser() throws Exception{ + String jsonRQ = """ + { + "email" : "lkd9125@naver.com", + "hpno" : "01083703435" + } + """; + + String token = this.getUserToken(); + + this.mockMvc.perform( + put(this.BASE_URL + "/update") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(jsonRQ) + .accept(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", GRANT_TYPE + " " + token) + ) + .andDo(print()) + .andDo( + document( + "user/account/update", + preprocessResponse(prettyPrint()), + HeaderDocumentation.requestHeaders( + HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") + ), + requestFields( + fieldWithPath("email").type(JsonFieldType.STRING).description("바꿀 이메일").optional(), + fieldWithPath("hpno").type(JsonFieldType.STRING).description("바꿀 전화번호").optional() + ) + ) + ) + .andExpect(status().isOk()); + } + + @DisplayName("암호 변경") + @Test + @Transactional + public void updatePassword() throws Exception{ + + String jsonRQ = """ + { + "userPswd" : "%s", + "newPswd" : "palnet!234", + "newPswdConfirm" : "palnet!234" + } + """.formatted(this.CREATE_PASSWORD); + + String token = this.getUserToken(); + + this.mockMvc.perform( + put(this.BASE_URL + "/update/pswd") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(jsonRQ) + .accept(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", GRANT_TYPE + " " + token) + ) + .andDo(print()) + .andDo( + document( + "user/account/update/pswd", + preprocessResponse(prettyPrint()), + HeaderDocumentation.requestHeaders( + HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") + ), + requestFields( + fieldWithPath("userPswd").type(JsonFieldType.STRING).description("현재 암호").optional(), + fieldWithPath("newPswd").type(JsonFieldType.STRING).description("바뀔 암호"), + fieldWithPath("newPswdConfirm").type(JsonFieldType.STRING).description("바뀔 암호 확인") + ) + ) + ) + .andExpect(status().isOk()); + } + + @DisplayName("회원정보 조회") + @Test + @Transactional + public void getUserInfo() throws Exception{ + String token = this.getUserToken(); + + this.mockMvc.perform( + get(this.BASE_URL + "/profile") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", GRANT_TYPE + " " + token) + ) + .andDo(print()) + .andDo( + document( + "user/account/profile", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름 + preprocessResponse(prettyPrint()), + HeaderDocumentation.requestHeaders( + HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") + ), + responseFields( + fieldWithPath("memberName").type(JsonFieldType.STRING).description("회원 이름"), + fieldWithPath("brthdyDate").type(JsonFieldType.STRING).description("생년월일"), + fieldWithPath("cntryCd").type(JsonFieldType.STRING).description("국적 구분코드"), + fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), + fieldWithPath("hpno").type(JsonFieldType.STRING).description("휴대폰 번호"), + fieldWithPath("userId").type(JsonFieldType.STRING).description("아이디"), + fieldWithPath("updateDt").type(JsonFieldType.STRING).description("수정일시"), + fieldWithPath("updateuserId").type(JsonFieldType.STRING).description("수정자 아이디"), + fieldWithPath("cptAuthCode").type(JsonFieldType.STRING).description("각 항청 구분코드") + ) + ) + ) + .andExpect(status().isOk()); + } + + @DisplayName("회원탈퇴") + @Test + @Transactional + public void deleteUser() throws Exception{ + String token = this.getUserToken(); + + this.mockMvc.perform( + RestDocumentationRequestBuilders.delete(this.BASE_URL + "/delete") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .accept(MediaType.APPLICATION_JSON_VALUE) + .header("Authorization", GRANT_TYPE + " " + token) + ) + .andDo(print()) + .andDo( + document( + "user/account/delete", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름 + preprocessResponse(prettyPrint()), + HeaderDocumentation.requestHeaders( + HeaderDocumentation.headerWithName("Authorization").description("Access토큰 [로그인 발급]") + ) + ) + ) + .andExpect(status().isOk()); + } + + @DisplayName("회원가입") + @Test + @Transactional + public void register() throws Exception{ + + String username = "TEST_" + System.currentTimeMillis(); + + String jsonRQ = """ + { + "cstrmDivCd" : "MEMBER", + "cstrmStatusCd" : "ACTIVE", + "userId" : "%s", + "authId" : "USER", + "siteCode" : "DRONE", + "userPswd" : "palnet!234", + "joinCrtfyCd" : "HP_CRTFD", + "memberName" : "이경도", + "brthdyDate" : "1999-09-07", + "email" : "lkd9125@naver.com", + "hpno" : "01083703435", + "clncd" : "+82" + } + """.formatted(username); + + this.mockMvc.perform( + post(this.BASE_URL + "/register") + .contentType(MediaType.APPLICATION_JSON_VALUE) + .content(jsonRQ) + .accept(MediaType.APPLICATION_JSON_VALUE) + ) + .andDo(print()) + .andDo( + document( + "user/account/register", // gradle build를 하게 되면 generated-snippets에 만들어질 폴더이름 + preprocessResponse(prettyPrint()), + requestFields( + fieldWithPath("cstrmDivCd").type(JsonFieldType.STRING).description("회원타입 코드"), + fieldWithPath("cstrmStatusCd").type(JsonFieldType.STRING).description("회원 활성화 코드"), + fieldWithPath("userId").type(JsonFieldType.STRING).description("아이디"), + fieldWithPath("authId").type(JsonFieldType.STRING).description("권한 값"), + fieldWithPath("siteCode").type(JsonFieldType.STRING).description("사이트 코드"), + fieldWithPath("userPswd").type(JsonFieldType.STRING).description("암호"), + fieldWithPath("joinCrtfyCd").type(JsonFieldType.STRING).description("가입인증 분류 코드"), + fieldWithPath("memberName").type(JsonFieldType.STRING).description("이름"), + fieldWithPath("brthdyDate").type(JsonFieldType.STRING).description("생년월일"), + fieldWithPath("email").type(JsonFieldType.STRING).description("이메일"), + fieldWithPath("hpno").type(JsonFieldType.STRING).description("휴대폰 번호"), + fieldWithPath("clncd").type(JsonFieldType.STRING).description("휴대폰 국가번호"), + fieldWithPath("terms").type(JsonFieldType.ARRAY).description("동의 약관 리스트").optional(), + fieldWithPath("terms[].termsSno").type(JsonFieldType.NUMBER).description("약관 식별번호"), + fieldWithPath("terms[].agreeYn").type(JsonFieldType.STRING).description("약관 동의여부") + ) + ) + ) + .andExpect(status().isCreated()); + } + + +} diff --git a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java index 496eb2e..2bdbe8b 100644 --- a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java +++ b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java @@ -4,6 +4,7 @@ import jakarta.persistence.*; import lombok.*; import java.time.Instant; +import java.time.LocalDateTime; @Data @@ -42,7 +43,7 @@ public class PtyCstmrGroup { // 승인일자 @Column(name = "APRVL_DT", columnDefinition = "datetime(6)") - private Instant aprvlDt; + private LocalDateTime aprvlDt; // 참여여부 @Column(name = "JOIN_YN", columnDefinition = "char(1) default 'N'", nullable = false) @@ -54,7 +55,7 @@ public class PtyCstmrGroup { // 탈퇴일시 @Column(name = "WTHDRW_DT", columnDefinition = "datetime(6)") - private Instant wthdrwDt; + private LocalDateTime wthdrwDt; // 터미널ID @Column(name = "TRMNL_ID", length = 20) diff --git a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java index 3be34c4..ff935e4 100644 --- a/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java +++ b/data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java @@ -31,6 +31,10 @@ public class PtyCstmrDomainService { public PtyCstmrBas savePtyCstmrBas(PtyCstmrBas entity) { return ptyCstmrBasRepository.save(entity); } + + public Optional findPtyCstmrDtlById(Long cstmrSno){ + return ptyCstmrDtlRepository.findById(cstmrSno); + } public PtyCstmrDtl savePtyCstmrDtl(PtyCstmrDtl entity){ return ptyCstmrDtlRepository.save(entity); } diff --git a/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java b/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java index f7feb54..900e7a0 100644 --- a/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java +++ b/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java @@ -162,15 +162,17 @@ public class UserAccountService { } } + @Transactional public SearchUserRS getUserInfo() { Long cstmrSno = SessionHelper.getCstmrSno(); Optional userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno); + Optional userDetailEntityData = ptyCstmrDomainService.findPtyCstmrDtlById(cstmrSno); - if(userEntityData.isPresent()){ + if(userEntityData.isPresent() && userDetailEntityData.isPresent()){ PtyCstmrBas userEntity = userEntityData.get(); - PtyCstmrDtl userDetailEntity = userEntity.getPtyCstmrDtl(); + PtyCstmrDtl userDetailEntity = userDetailEntityData.get(); SearchUserRS result = new SearchUserRS(); @@ -227,10 +229,11 @@ public class UserAccountService { String userId = SessionHelper.getUserId(); Optional userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno); + Optional userDetailEntityData = ptyCstmrDomainService.findPtyCstmrDtlById(cstmrSno); - if(userEntityData.isPresent()){ + if(userEntityData.isPresent() && userDetailEntityData.isPresent()){ PtyCstmrBas userEntity = userEntityData.get(); - PtyCstmrDtl userDetailEntity = userEntity.getPtyCstmrDtl(); + PtyCstmrDtl userDetailEntity = userDetailEntityData.get(); userDetailEntity.setUpdateDt(LocalDateTime.now()); userDetailEntity.setUpdateUserId(userId); diff --git a/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/certificate/controller/UserCertificateController.java b/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/certificate/controller/UserCertificateController.java new file mode 100644 index 0000000..99e6ea1 --- /dev/null +++ b/web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/certificate/controller/UserCertificateController.java @@ -0,0 +1,17 @@ +package kr.co.palnet.kac.api.v1.user.certificate.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping +@RestController +@Slf4j +@RequiredArgsConstructor +@Tag(name = "유저 - 인증", description = "유저 인증관련") +public class UserCertificateController { + + +}