Browse Source

feature/user (#8)

User모듈

https://www.notion.so/PAV-COMMON-1a78a0b396ad46a3a3b6a49fde8e673c?pvs=4

- 회원가입추가
- 회원탈퇴
- 회원정보 조회
- 회원정보 스웨거 및 코드정리
- 암호변경 추가
- 회원정보수정 추가
- 회원정보수정 안쓰는 import삭제
- 테스트 코드추가
Co-authored-by: lkd9125 <lkd9125@naver.com>
Co-committed-by: lkd9125 <lkd9125@naver.com>
develop
lkd9125 7 months ago committed by 지대한
parent
commit
44011e96b1
  1. 8
      app/kac-app/build.gradle
  2. 69
      app/kac-app/src/docs/asciidoc/index.adoc
  3. 1
      app/kac-app/src/main/java/kr/co/palnet/kac/app/core/security/AppSecurityConfig.java
  4. 345
      app/kac-app/src/main/resources/static/docs/index.html
  5. 78
      app/kac-app/src/test/java/kr/co/palnet/kac/BaseTest.java
  6. 228
      app/kac-app/src/test/java/kr/co/palnet/kac/user/account/UserAccountControllerTest.java
  7. 13
      common/util/src/main/java/kr/co/palnet/kac/util/EncryptUtil.java
  8. 3
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrDtl.java
  9. 6
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrGroup.java
  10. 5
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsAgreeTxn.java
  11. 2
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java
  12. 2
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrDtlRepository.java
  13. 12
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrGroupRepository.java
  14. 2
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java
  15. 27
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java
  16. 53
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java
  17. 19
      data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyTermsDomainService.java
  18. 2
      web/api-user/build.gradle
  19. 74
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/controller/UserAccountController.java
  20. 84
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/PtyCstmrDTO.java
  21. 63
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/PtyCstmrDtlDTO.java
  22. 40
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/detail/SearchUserRS.java
  23. 14
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/register/AgreeTermsModel.java
  24. 111
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/register/FormRegisterRQ.java
  25. 19
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/update/UpdatePasswordRQ.java
  26. 15
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/update/UpdateUserRQ.java
  27. 249
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java
  28. 17
      web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/certificate/controller/UserCertificateController.java
  29. 35
      web/api-user/src/main/java/kr/co/palnet/kac/util/HttpUtils.java
  30. 5
      web/security/src/main/java/kr/co/palnet/kac/config/security/SecurityConfig.java

8
app/kac-app/build.gradle

@ -39,13 +39,7 @@ dependencies {
implementation project(":common:util")
implementation project(":web:security")
implementation project(":web:api-common")
// implementation project(":data:cns")
// implementation project(":data:com")
// implementation project(":data:ctr")
// implementation project(":data:flt")
// implementation project(":data:other")
// implementation project(":data:pty")
implementation project(":web:api-user")
}
ext {

69
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[]
***

1
app/kac-app/src/main/java/kr/co/palnet/kac/app/core/security/AppSecurityConfig.java

@ -27,6 +27,7 @@ public class AppSecurityConfig extends SecurityConfig {
// 시큐리티 적용 안하는 URL 목록
private final String[] IGNORE_URL = {
"/v1/com/code/**",
"/v1/user/account/register",
};
// 권한(ROLE)별 URL

345
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
<li><a href="#_code_언어_삭제">[Code 언어 삭제]</a></li>
</ul>
</li>
<li><a href="#User-Account-API">User-Account API</a>
<ul class="sectlevel2">
<li><a href="#_user_회원가입">[User 회원가입]</a></li>
</ul>
</li>
</ul>
</div>
</div>
@ -515,11 +520,20 @@ Host: localhost:8080</code></pre>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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
<h4 id="_http_request_info_2"><a class="link" href="#_http_request_info_2">[HTTP REQUEST INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">GET /v1/com/code/code?groupCd=NEW_GROUP_1707924397&amp;langDivCd=ko_KR HTTP/1.1
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">GET /v1/com/code/code?groupCd=NEW_GROUP_1708411842&amp;langDivCd=ko_KR HTTP/1.1
Content-Type: application/json;charset=UTF-8
Accept: application/json
Host: localhost:8080</code></pre>
@ -664,11 +678,20 @@ Host: localhost:8080</code></pre>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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</code></pre>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -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
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
@ -1842,7 +1928,16 @@ Host: localhost:8080</code></pre>
<h4 id="_http_response_info_10"><a class="link" href="#_http_response_info_10">[HTTP RESPONSE INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">HTTP/1.1 200 OK</code></pre>
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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</code></pre>
</div>
</div>
<hr>
@ -1891,7 +1986,16 @@ Host: localhost:8080</code></pre>
<h4 id="_http_response_info_11"><a class="link" href="#_http_response_info_11">[HTTP RESPONSE INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">HTTP/1.1 200 OK</code></pre>
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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</code></pre>
</div>
</div>
<hr>
@ -1945,8 +2049,181 @@ Host: localhost:8080</code></pre>
<h4 id="_http_response_info_12"><a class="link" href="#_http_response_info_12">[HTTP RESPONSE INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">HTTP/1.1 200 OK</code></pre>
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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</code></pre>
</div>
</div>
<hr>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="User-Account-API"><a class="link" href="#User-Account-API">User-Account API</a></h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_user_회원가입"><a class="link" href="#_user_회원가입">[User 회원가입]</a></h3>
<div class="sect3">
<h4 id="_http_request_info_13"><a class="link" href="#_http_request_info_13">[HTTP REQUEST INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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"
}</code></pre>
</div>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">파라미터</th>
<th class="tableblock halign-left valign-top">타입</th>
<th class="tableblock halign-left valign-top">설명</th>
<th class="tableblock halign-left valign-top">필수</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cstrmDivCd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">회원타입 코드</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>cstrmStatusCd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">회원 활성화 코드</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>userId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">아이디</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>authId</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">권한 값</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>siteCode</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">사이트 코드</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>userPswd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">암호</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>joinCrtfyCd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">가입인증 분류 코드</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>memberName</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">이름</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>brthdyDate</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">생년월일</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>email</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">이메일</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>hpno</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">휴대폰 번호</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>clncd</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">휴대폰 국가번호</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>terms</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Array</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">동의 약관 리스트</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>terms[].termsSno</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Number</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">약관 식별번호</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>terms[].agreeYn</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>String</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">약관 동의여부</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="_http_response_info_13"><a class="link" href="#_http_response_info_13">[HTTP RESPONSE INFO]</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="http" class="language-http hljs">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</code></pre>
</div>
</div>
<div class="paragraph">
<p>Unresolved directive in index.adoc - include::./build/generated-snippets/user/account/register/response-fields.adoc[]</p>
</div>
<hr>
</div>
@ -1957,7 +2234,7 @@ Host: localhost:8080</code></pre>
<div id="footer">
<div id="footer-text">
Version 1.0.0<br>
Last updated 2024-02-07 14:39:05 +0900
Last updated 2024-02-20 15:50:06 +0900
</div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/github.min.css">

78
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);
}
}

228
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());
}
}

13
common/util/src/main/java/kr/co/palnet/kac/util/EncryptUtil.java

@ -1,5 +1,6 @@
package kr.co.palnet.kac.util;
import kr.co.palnet.kac.util.kisa.KISA_SHA256;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
@ -72,6 +73,18 @@ public class EncryptUtil {
return encrypted;
}
public static String sha256Encrypt(String str) {
byte[] bytes = str.getBytes();
byte[] pszDigest = new byte[32];
KISA_SHA256.SHA256_Encrpyt(bytes, bytes.length, pszDigest);
StringBuffer encrypted = new StringBuffer();
for (int i = 0; i < 32; i++) {
encrypted.append(String.format("%02x", pszDigest[i]));
}
return encrypted.toString();
}
public static void main(String[] args) {
String key = "1234567890123456";
String initVector = "1234567890123456";

3
data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyCstmrDtl.java

@ -5,6 +5,7 @@ import lombok.*;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@ -74,7 +75,7 @@ public class PtyCstmrDtl {
// 수정일시
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
private Instant updateDt;
private LocalDateTime updateDt;
// 수정사용자ID
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false)

6
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
@ -17,6 +18,7 @@ public class PtyCstmrGroup {
// 고객그룹일련번호
@Id
@Column(name = "CSTMR_GROUP_SNO") // mysql :: "int unsigned"
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long cstmrGroupSno;
// 고객일련번호
@ -41,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)
@ -53,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)

5
data/pty/src/main/java/kr/co/palnet/kac/data/pty/model/PtyTermsAgreeTxn.java

@ -4,6 +4,7 @@ import jakarta.persistence.*;
import lombok.*;
import java.time.Instant;
import java.time.LocalDateTime;
@Data
@ -40,7 +41,7 @@ public class PtyTermsAgreeTxn {
// 동의일시
@Column(name = "AGREE_DT", columnDefinition = "datetime")
private Instant agreeDt;
private LocalDateTime agreeDt;
// 처리IP주소
@Column(name = "PROC_IP", length = 39)
@ -48,7 +49,7 @@ public class PtyTermsAgreeTxn {
// 수정일시
@Column(name = "UPDATE_DT", columnDefinition = "datetime", nullable = false)
private Instant updateDt;
private LocalDateTime updateDt;
// 수정사용자ID
@Column(name = "UPDATE_USER_ID", length = 30, nullable = false)

2
data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrBasRepository.java

@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface PtyCstmrBasRepository extends JpaRepository<PtyCstmrBas, Integer> {
public interface PtyCstmrBasRepository extends JpaRepository<PtyCstmrBas, Long> {
@Query("select b from PtyCstmrBas b left join b.ptyCstmrDtl where b.userId = :userId")
PtyCstmrBas findByUserId(@Param("userId") String userId);
}

2
data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrDtlRepository.java

@ -3,6 +3,6 @@ package kr.co.palnet.kac.data.pty.repository;
import kr.co.palnet.kac.data.pty.model.PtyCstmrDtl;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PtyCstmrDtlRepository extends JpaRepository<PtyCstmrDtl, Integer> {
public interface PtyCstmrDtlRepository extends JpaRepository<PtyCstmrDtl, Long> {
}

12
data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyCstmrGroupRepository.java

@ -2,7 +2,19 @@ package kr.co.palnet.kac.data.pty.repository;
import kr.co.palnet.kac.data.pty.model.PtyCstmrGroup;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface PtyCstmrGroupRepository extends JpaRepository<PtyCstmrGroup, Integer> {
public Optional<List<PtyCstmrGroup>> findByCstmrSnoAndJoinYn(Long cstmrSno, String joinYn);
public Optional<List<PtyCstmrGroup>> findByGroupId(String groupId);
public Optional<List<PtyCstmrGroup>> findByCstmrSno(Long cstmrSno);
public Optional<PtyCstmrGroup> findByGroupIdAndCstmrSno(String groupId, Long cstmrSno);
}

2
data/pty/src/main/java/kr/co/palnet/kac/data/pty/repository/PtyGroupBasRepository.java

@ -2,7 +2,9 @@ package kr.co.palnet.kac.data.pty.repository;
import kr.co.palnet.kac.data.pty.model.PtyGroupBas;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface PtyGroupBasRepository extends JpaRepository<PtyGroupBas, String> {
}

27
data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyCstmrDomainService.java

@ -1,19 +1,46 @@
package kr.co.palnet.kac.data.pty.service;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import kr.co.palnet.kac.data.pty.model.PtyCstmrDtl;
import kr.co.palnet.kac.data.pty.repository.PtyCstmrBasRepository;
import kr.co.palnet.kac.data.pty.repository.PtyCstmrDtlRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Slf4j
@RequiredArgsConstructor
@Service
public class PtyCstmrDomainService {
private final PtyCstmrBasRepository ptyCstmrBasRepository;
private final PtyCstmrDtlRepository ptyCstmrDtlRepository;
public PtyCstmrBas getCstmrInfoByUserId(String userId) {
return ptyCstmrBasRepository.findByUserId(userId);
}
public Optional<PtyCstmrBas> findPtyCstmrBasById(Long cstmrSno){
return ptyCstmrBasRepository.findById(cstmrSno);
}
public PtyCstmrBas savePtyCstmrBas(PtyCstmrBas entity) {
return ptyCstmrBasRepository.save(entity);
}
public Optional<PtyCstmrDtl> findPtyCstmrDtlById(Long cstmrSno){
return ptyCstmrDtlRepository.findById(cstmrSno);
}
public PtyCstmrDtl savePtyCstmrDtl(PtyCstmrDtl entity){
return ptyCstmrDtlRepository.save(entity);
}
}

53
data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyGroupDomainService.java

@ -0,0 +1,53 @@
package kr.co.palnet.kac.data.pty.service;
import kr.co.palnet.kac.data.pty.model.PtyCstmrGroup;
import kr.co.palnet.kac.data.pty.model.PtyGroupBas;
import kr.co.palnet.kac.data.pty.repository.PtyCstmrGroupRepository;
import kr.co.palnet.kac.data.pty.repository.PtyGroupBasRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;
@Slf4j
@RequiredArgsConstructor
@Service
public class PtyGroupDomainService {
private final PtyGroupBasRepository ptyGroupBasRepository;
private final PtyCstmrGroupRepository ptyCstmrGroupRepository;
public Optional<List<PtyCstmrGroup>> findJoinGroupByCstmrSno(Long cstmrSno){
return ptyCstmrGroupRepository.findByCstmrSnoAndJoinYn(cstmrSno, "Y");
}
public Optional<List<PtyCstmrGroup>> findByGroupId(String groupId){
return ptyCstmrGroupRepository.findByGroupId(groupId);
}
public Optional<List<PtyCstmrGroup>> findByCstmrSno(Long cstmrSno){
return ptyCstmrGroupRepository.findByCstmrSno(cstmrSno);
}
public Optional<PtyCstmrGroup> findByGroupIdAndCstmrSno(String groupId, Long cstmrSno){
return ptyCstmrGroupRepository.findByGroupIdAndCstmrSno(groupId, cstmrSno);
}
public PtyCstmrGroup savePtyCstmrGroup(PtyCstmrGroup entity){
return ptyCstmrGroupRepository.save(entity);
}
public PtyGroupBas findById(String id){
return ptyGroupBasRepository.findById(id).orElse(null);
}
public PtyGroupBas savePtyGroupBas(PtyGroupBas entity){
return ptyGroupBasRepository.save(entity);
}
}

19
data/pty/src/main/java/kr/co/palnet/kac/data/pty/service/PtyTermsDomainService.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.data.pty.service;
import kr.co.palnet.kac.data.pty.model.PtyTermsAgreeTxn;
import kr.co.palnet.kac.data.pty.repository.PtyTermsAgreeTxnRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
public class PtyTermsDomainService {
private final PtyTermsAgreeTxnRepository ptyTermsAgreeTxnRepository;
public PtyTermsAgreeTxn savePtyTermsAgreeTxn(PtyTermsAgreeTxn entity){
return ptyTermsAgreeTxnRepository.save(entity);
}
}

2
web/api-user/build.gradle

@ -3,6 +3,7 @@
dependencies {
implementation "$boot:spring-boot-starter-web"
implementation "$boot:spring-boot-starter-data-jpa"
implementation "$boot:spring-boot-starter-security"
// for paging
// implementation("org.springframework.data:spring-data-commons")
@ -10,6 +11,7 @@ dependencies {
compileOnly 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
implementation project(":data:pty")
implementation project(":common:core")
implementation project(":common:util")
compileOnly project(":web:security")
}

74
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/controller/UserAccountController.java

@ -0,0 +1,74 @@
package kr.co.palnet.kac.api.v1.user.account.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
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.model.update.UpdatePasswordRQ;
import kr.co.palnet.kac.api.v1.user.account.model.update.UpdateUserRQ;
import kr.co.palnet.kac.api.v1.user.account.service.UserAccountService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/v1/user/account")
@Tag(name = "유저 - 계정", description = "계정 관련 API")
public class UserAccountController {
private final UserAccountService userAccountService;
@PostMapping("/register")
@Operation(summary = "회원가입", description = "유저의 계정을 추가합니다.")
public ResponseEntity<Boolean> createUser(@RequestBody FormRegisterRQ rq){
userAccountService.createUser(rq);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
@DeleteMapping("/delete")
@Operation(summary = "회원탈퇴", description = "유저의 계정을 탈퇴시키며 참여한 그룹도 탈퇴시킵니다.")
public ResponseEntity<Boolean> deleteUser(){
userAccountService.deleteUser();
return ResponseEntity.ok().build();
}
@GetMapping("/profile")
@Operation(summary = "회원정보 조회", description = "회원 정보를 조회합니다.")
public ResponseEntity<SearchUserRS> getUserInfo(){
SearchUserRS result = userAccountService.getUserInfo();
return ResponseEntity.ok().body(result);
}
@PutMapping("/update/pswd")
@Operation(summary = "회원암호 변경", description = "회원 암호를 변경합니다.")
public ResponseEntity<Boolean> updatePassword(@RequestBody UpdatePasswordRQ rq){
userAccountService.updatePassword(rq);
return ResponseEntity.ok().build();
}
@PutMapping("/update")
@Operation(summary = "회원정보 변경", description = "회원의 정보를 수정합니다.")
public ResponseEntity<Object> updateUser(@RequestBody UpdateUserRQ rq){
userAccountService.updateUser(rq);
return ResponseEntity.ok().build();
}
}

84
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/PtyCstmrDTO.java

@ -0,0 +1,84 @@
package kr.co.palnet.kac.api.v1.user.account.model;
import kr.co.palnet.kac.data.pty.model.PtyCstmrBas;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class PtyCstmrDTO {
private Long cstmrSno;
private String authId;
private String cstmrDivCd;
private String cstmrStatusCd;
private LocalDateTime cstmrStatusCngDt;
private String cptAuthCode;
private String userId;
private LocalDateTime joinDt;
private String joinIp;
private String siteCode;
private String memberDivCd;
private String userPswd;
private LocalDateTime pswdUpdtDt;
private String rtrshToken;
private String trmnlId;
public static PtyCstmrBas toEntity(PtyCstmrDTO dto){
return PtyCstmrBas.builder()
.cstmrSno(dto.getCstmrSno())
.authId(dto.getAuthId())
.cstmrDivCd(dto.getCstmrDivCd())
.cstmrStatusCd(dto.getCstmrStatusCd())
.cstmrStatusCngDt(dto.getCstmrStatusCngDt())
.cptAuthCode(dto.getCptAuthCode())
.userId(dto.getUserId())
.joinDt(dto.getJoinDt())
.joinIp(dto.getJoinIp())
.siteCode(dto.getSiteCode())
.memberDivCd(dto.getMemberDivCd())
.userPswd(dto.getUserPswd())
.pswdUpdtDt(dto.getPswdUpdtDt())
.rfrshToken(dto.getRtrshToken())
.trmnlId(dto.getTrmnlId())
.build();
}
public static PtyCstmrDTO toDto(PtyCstmrBas entity){
PtyCstmrDTO dto = new PtyCstmrDTO();
dto.setCstmrSno(entity.getCstmrSno());
dto.setAuthId(entity.getAuthId());
dto.setCstmrDivCd(entity.getCstmrDivCd());
dto.setCstmrStatusCd(entity.getCstmrStatusCd());
dto.setCstmrStatusCngDt(entity.getCstmrStatusCngDt());
dto.setCptAuthCode(entity.getCptAuthCode());
dto.setUserId(entity.getUserId());
dto.setJoinDt(entity.getJoinDt());
dto.setJoinIp(entity.getJoinIp());
dto.setSiteCode(entity.getSiteCode());
dto.setMemberDivCd(entity.getMemberDivCd());
dto.setUserPswd(entity.getUserPswd());
dto.setPswdUpdtDt(entity.getPswdUpdtDt());
dto.setRtrshToken(entity.getRfrshToken());
dto.setTrmnlId(entity.getTrmnlId());
return dto;
}
}

63
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/PtyCstmrDtlDTO.java

@ -0,0 +1,63 @@
package kr.co.palnet.kac.api.v1.user.account.model;
import kr.co.palnet.kac.data.pty.model.PtyCstmrDtl;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class PtyCstmrDtlDTO {
private Long cstmrSno;
private String ipinDi;
private String ipinCi;
private String joinCrtfyCd;
private String cntryCd;
private String genderCd;
private String memberName;
private LocalDate brthdyDate;
private String email;
private String hpno;
private String clncd;
private String addr;
private String addrDtlCn;
private String zip;
private LocalDateTime updateDt;
private String updateUserId;
public static PtyCstmrDtl toEntity(PtyCstmrDtlDTO dto){
return PtyCstmrDtl.builder()
.cstmrSno(dto.getCstmrSno())
.ipinCi(dto.getIpinCi())
.ipinDi(dto.getIpinDi())
.joinCrtfyCd(dto.getJoinCrtfyCd())
.cntryCd(dto.getCntryCd())
.genderCd(dto.getGenderCd())
.memberName(dto.getMemberName())
.brthdyDate(dto.getBrthdyDate())
.email(dto.getEmail())
.hpno(dto.getHpno())
.clncd(dto.getClncd())
.updateDt(dto.getUpdateDt())
.updateUserId(dto.getUpdateUserId())
.build();
}
}

40
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/detail/SearchUserRS.java

@ -0,0 +1,40 @@
package kr.co.palnet.kac.api.v1.user.account.model.detail;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class SearchUserRS {
@Schema(description = "이름" , example = "이경도")
private String memberName;
@Schema(description = "생년월일" , example = "1999-09-07")
private LocalDate brthdyDate;
@Schema(description = "국적코드" , example = "KOR")
private String cntryCd;
@Schema(description = "이메일" , example = "lkd9125@naver.com")
private String email;
@Schema(description = "휴대폰번호" , example = "01083703435")
private String hpno;
@Schema(description = "ID" , example = "lkd9125")
private String userId;
@Schema(description = "최종 업데이트 일시" , example = "2024-02-19T16:40:33.000")
private LocalDateTime updateDt;
@Schema(description = "최종 업데이트 유저" , example = "lkd9125")
private String updateuserId;
@Schema(description = "유저 청 구분코드" , example = "KAC")
private String cptAuthCode;
}

14
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/register/AgreeTermsModel.java

@ -0,0 +1,14 @@
package kr.co.palnet.kac.api.v1.user.account.model.register;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class AgreeTermsModel {
@Schema(description = "약관 일련번호", example = "1")
private Long termsSno;
@Schema(description = "동의여부", example = "Y")
private String agreeYn;
}

111
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/register/FormRegisterRQ.java

@ -0,0 +1,111 @@
package kr.co.palnet.kac.api.v1.user.account.model.register;
import io.swagger.v3.oas.annotations.media.Schema;
import kr.co.palnet.kac.api.v1.user.account.model.PtyCstmrDTO;
import kr.co.palnet.kac.api.v1.user.account.model.PtyCstmrDtlDTO;
import kr.co.palnet.kac.util.HttpUtils;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
public class FormRegisterRQ {
@Schema(description = "고객구분코드" , example = "MEMBER")
private String cstrmDivCd;
@Schema(description = "고객상태코드" , example = "A")
private String cstrmStatusCd;
@Schema(description = "유저 아이디(중복인 경우 숫자 변경)" , example = "tester01")
private String userId;
@Schema(description = "유저 권한" , example = "USER")
private String authId;
@Schema(description = "사이트 코드" , example = "DRON")
private String siteCode;
@Schema(description = "유저 비밀번호" , example = "test1234")
private String userPswd;
@Schema(description = "가입인증 수단 코드" , example = "HP_CRTFD")
private String joinCrtfyCd;
@Schema(description = "멤버 이름" , example = "TESTER")
private String memberName;
@Schema(description = "생년월일", example = "1997-05-05", implementation = String.class)
private LocalDate brthdyDate;
@Schema(description = "이메일" , example = "tester@test.co.kr")
private String email;
@Schema(description = "멤버 휴대폰번호" , example = "01012345678")
private String hpno;
@Schema(description = "국가 코드" , example = "+82")
private String clncd;
private AgreeTermsModel[] terms;
@Schema(description = "권한코드(부서)" , example = "KAC")
private String cptAuthCode;
// @Schema(hidden = true)
// private String memberDivCd;
@Schema(hidden = true)
private String ipinDi;
@Schema(hidden = true)
private String ipinCi;
@Schema(description = "국가코드" , example = "KOR")
private String cntryCd;
@Schema(description = "성별코드" , example = "M")
private String genderCd;
// @Schema(hidden = true)
// private Instant testDt;
// @Schema(hidden = true)
// private String trmnlId;
public static PtyCstmrDTO toBasicDto(FormRegisterRQ rq){
PtyCstmrDTO dto = new PtyCstmrDTO();
dto.setCstmrDivCd(rq.getCstrmDivCd());
dto.setCstmrStatusCd(rq.getCstrmStatusCd());
dto.setUserId(rq.getUserId());
dto.setAuthId(rq.getAuthId());
dto.setSiteCode(rq.getSiteCode());
dto.setUserPswd(rq.getUserPswd());
dto.setJoinDt(LocalDateTime.now());
dto.setJoinIp(HttpUtils.getRequestIp());
dto.setCptAuthCode(rq.getCptAuthCode() == null ? "KAC": rq.getCptAuthCode());
return dto;
}
public static PtyCstmrDtlDTO toDetailDto(FormRegisterRQ rq, Long cstmrSno){
PtyCstmrDtlDTO dto = new PtyCstmrDtlDTO();
dto.setCstmrSno(cstmrSno);
dto.setIpinCi(rq.getIpinCi());
dto.setIpinDi(rq.getIpinDi());
dto.setJoinCrtfyCd(rq.getJoinCrtfyCd());
dto.setCntryCd(rq.getCntryCd() == null || rq.getCntryCd().isEmpty() ? "KOR" : rq.getCntryCd());
dto.setGenderCd(rq.getGenderCd());
dto.setMemberName(rq.getMemberName());
dto.setBrthdyDate(rq.getBrthdyDate());
dto.setEmail(rq.getEmail());
dto.setHpno(rq.getHpno());
dto.setClncd(rq.getClncd());
dto.setUpdateDt(LocalDateTime.now());
dto.setUpdateUserId(rq.getUserId());
return dto;
}
}

19
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/update/UpdatePasswordRQ.java

@ -0,0 +1,19 @@
package kr.co.palnet.kac.api.v1.user.account.model.update;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class UpdatePasswordRQ {
// TODO :: 해당 컬럼은 Api실행시 로직상에서도 필요하지 않을뿐더러 클라이언트에서도 사용되지 않고있음
@Schema(description = "유저의 기존 비밀번호", example = "palnet!234")
private String userPswd;
@Schema(description = "유저의 새로운 비밀번호", example = "palnet1234")
private String newPswd;
@Schema(description = "유저의 새로운 비밀번호(확인)", example = "palnet1234")
private String newPswdConfirm;
}

15
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/model/update/UpdateUserRQ.java

@ -0,0 +1,15 @@
package kr.co.palnet.kac.api.v1.user.account.model.update;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class UpdateUserRQ {
@Schema(description = "유저 이메일" , example = "updateEmail@test.co.kr")
private String email;
@Schema(description = "업데이트할 핸드폰 번호", example = "01023457777")
private String hpno;
}

249
web/api-user/src/main/java/kr/co/palnet/kac/api/v1/user/account/service/UserAccountService.java

@ -0,0 +1,249 @@
package kr.co.palnet.kac.api.v1.user.account.service;
import kr.co.palnet.kac.api.v1.user.account.model.PtyCstmrDTO;
import kr.co.palnet.kac.api.v1.user.account.model.PtyCstmrDtlDTO;
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.model.register.AgreeTermsModel;
import kr.co.palnet.kac.api.v1.user.account.model.update.UpdatePasswordRQ;
import kr.co.palnet.kac.api.v1.user.account.model.update.UpdateUserRQ;
import kr.co.palnet.kac.config.security.util.SessionHelper;
import kr.co.palnet.kac.core.exception.BaseErrorCode;
import kr.co.palnet.kac.core.exception.BaseException;
import kr.co.palnet.kac.data.pty.model.*;
import kr.co.palnet.kac.data.pty.service.PtyCstmrDomainService;
import kr.co.palnet.kac.data.pty.service.PtyGroupDomainService;
import kr.co.palnet.kac.data.pty.service.PtyTermsDomainService;
import kr.co.palnet.kac.util.EncryptUtil;
import kr.co.palnet.kac.util.HttpUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Service
@Slf4j
@RequiredArgsConstructor
public class UserAccountService {
private final PtyCstmrDomainService ptyCstmrDomainService;
private final PtyGroupDomainService ptyGroupDomainService;
private final PtyTermsDomainService ptyTermsDomainService;
private final PasswordEncoder passwordEncoder;
@Transactional
public void createUser(FormRegisterRQ rq) {
PtyCstmrBas registeredUser = ptyCstmrDomainService.getCstmrInfoByUserId(rq.getUserId());
if(registeredUser != null) throw new BaseException(BaseErrorCode.DATA_ALREADY_EXISTS);
rq.setHpno(rq.getHpno().replaceAll("-", ""));
//처리 1. 민감정보 암호화 처리(비밀번호 , 이름 , 휴대폰번호 , 이메일)
rq.setUserPswd(passwordEncoder.encode(rq.getUserPswd()));
rq.setHpno(EncryptUtil.encrypt(rq.getHpno()));
rq.setEmail(EncryptUtil.encrypt(rq.getEmail()));
//처리 2. 마스터 정보 저장
PtyCstmrDTO basicDto = FormRegisterRQ.toBasicDto(rq);
PtyCstmrBas basEntity = ptyCstmrDomainService.savePtyCstmrBas(PtyCstmrDTO.toEntity(basicDto));
if(basEntity == null) {
throw new BaseException(BaseErrorCode.NOT_PROCESS);
}
//처리 3. 상세 정보 저장
PtyCstmrDtlDTO detailDto = FormRegisterRQ.toDetailDto(rq, basEntity.getCstmrSno());
ptyCstmrDomainService.savePtyCstmrDtl(PtyCstmrDtlDTO.toEntity(detailDto));
//처리 4. 약관 동의 정보 저장
if(rq.getTerms() != null && rq.getTerms().length > 0){
for(AgreeTermsModel model : rq.getTerms()){
PtyTermsAgreeTxn agreeEntity = new PtyTermsAgreeTxn();
agreeEntity.setCstmrSno(basEntity.getCstmrSno());
agreeEntity.setProcIp(HttpUtils.getRequestIp());
agreeEntity.setTermsSno(model.getTermsSno());
agreeEntity.setUpdateDt(LocalDateTime.now() );
agreeEntity.setUpdateUserId(basEntity.getUserId());
agreeEntity.setAgreeYn(model.getAgreeYn());
if(model.getAgreeYn().equals("Y")) {
agreeEntity.setAgreeDt(LocalDateTime.now() );
}
ptyTermsDomainService.savePtyTermsAgreeTxn(agreeEntity);
}
}
}
@Transactional
public void deleteUser() {
Long cstmrSno = SessionHelper.getCstmrSno();
if(cstmrSno == null) return;
Optional<List<PtyCstmrGroup>> groupData = ptyGroupDomainService.findJoinGroupByCstmrSno(cstmrSno);
if(groupData.isPresent() && !groupData.get().isEmpty()){
List<PtyCstmrGroup> groupInfo = groupData.get();
for(PtyCstmrGroup group : groupInfo) {
// 회원의 그룹 권한이 MASTER 일 경우
if(group.getGroupAuthCd().equals("MASTER")) {
PtyGroupBas groupEntity = ptyGroupDomainService.findById(group.getGroupId());
// 그룹이 있을경우 그룹의 사용여부 "N" 값으로 저장
if(groupEntity != null) {
groupEntity.setUseYn("N");
ptyGroupDomainService.savePtyGroupBas(groupEntity);
}
// 탈퇴하는 회원이 그룹의 MASTER일 경우 그룹 참여자의 Join여부를 N으로 업데이트 함
Optional<List<PtyCstmrGroup>> cstmrEntityData = ptyGroupDomainService.findByGroupId(group.getGroupId());
// cstmrEntity 값이 있을 경우 참여여부 "N" 값으로 저장
if(cstmrEntityData.isPresent()) {
List<PtyCstmrGroup> cstmrEntity = cstmrEntityData.get();
for(PtyCstmrGroup cstmr : cstmrEntity) {
cstmr.setJoinYn("N");
ptyGroupDomainService.savePtyCstmrGroup(cstmr);
}
}
}
// 회원 고유번호로 데이터베이스에서 그룹참여정보 가져옴
Optional<List<PtyCstmrGroup>> aprvlEntityData = ptyGroupDomainService.findByCstmrSno(cstmrSno);
// AprvlEntity[그룹참여 정보가] 있을경우
if(aprvlEntityData.isPresent()) {
List<PtyCstmrGroup> aprvlEntity = aprvlEntityData.get();
// 그룹 승인여부를 "N"값으로 저장
for(PtyCstmrGroup aprvl : aprvlEntity) {
aprvl.setAprvlYn("N");
aprvl.setAprvlDt(null);
ptyGroupDomainService.savePtyCstmrGroup(aprvl);
}
// 그룹 참여여부를 "N"값으로 저장
Optional<PtyCstmrGroup> cstmrEntityData = ptyGroupDomainService.findByGroupIdAndCstmrSno(group.getGroupId(), cstmrSno);
if(cstmrEntityData.isPresent()) {
PtyCstmrGroup cstmrEntity = cstmrEntityData.get();
cstmrEntity.setJoinYn("N");
ptyGroupDomainService.savePtyCstmrGroup(cstmrEntity);
}
}
}
}
Optional<PtyCstmrBas> userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno);
if(userEntityData.isPresent()){
PtyCstmrBas userEntity = userEntityData.get();
userEntity.setCstmrStatusCd("W");
userEntity.setCstmrStatusCngDt(LocalDateTime.now());
ptyCstmrDomainService.savePtyCstmrBas(userEntity);
} else {
throw new BaseException(BaseErrorCode.DATA_EMPTY);
}
}
@Transactional
public SearchUserRS getUserInfo() {
Long cstmrSno = SessionHelper.getCstmrSno();
Optional<PtyCstmrBas> userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno);
Optional<PtyCstmrDtl> userDetailEntityData = ptyCstmrDomainService.findPtyCstmrDtlById(cstmrSno);
if(userEntityData.isPresent() && userDetailEntityData.isPresent()){
PtyCstmrBas userEntity = userEntityData.get();
PtyCstmrDtl userDetailEntity = userDetailEntityData.get();
SearchUserRS result = new SearchUserRS();
result.setMemberName(userDetailEntity.getMemberName());
result.setUserId(userEntity.getUserId());
result.setBrthdyDate(userDetailEntity.getBrthdyDate());
result.setCntryCd(userDetailEntity.getCntryCd());
result.setEmail(EncryptUtil.decrypt(userDetailEntity.getEmail()));
result.setHpno(EncryptUtil.decrypt(userDetailEntity.getHpno()));
result.setUpdateDt(userDetailEntity.getUpdateDt());
result.setUpdateuserId(userDetailEntity.getUpdateUserId());
result.setCptAuthCode(userEntity.getCptAuthCode());
return result;
} else {
throw new BaseException(BaseErrorCode.DATA_EMPTY);
}
}
@Transactional
public void updatePassword(UpdatePasswordRQ rq) {
// 1. 토큰 유저 정보 불러오기
Long cstmrSno = SessionHelper.getCstmrSno();
// 2. DB의 유저정보 조회
Optional<PtyCstmrBas> userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno);
if(userEntityData.isEmpty()) throw new BaseException(BaseErrorCode.DATA_EMPTY);
// 5. 새로운 비밀번호 검증
if(!rq.getNewPswd().equals(rq.getNewPswdConfirm())) {
// 5.e 새로운 비밀번호 일치하지 않으면 예외처리
throw new BaseException(BaseErrorCode.FAILED); //임시...수정필요
}
// 6. 새로운 패스워드 암호화
String encryptNewPwd = passwordEncoder.encode(rq.getNewPswd());
PtyCstmrBas userEntity = userEntityData.get();
// 7. 유저 정보 저장
userEntity.setUserPswd(encryptNewPwd);
userEntity.setPswdUpdtDt(LocalDateTime.now());
ptyCstmrDomainService.savePtyCstmrBas(userEntity);
}
@Transactional
public void updateUser(UpdateUserRQ rq) {
Long cstmrSno = SessionHelper.getCstmrSno();
String userId = SessionHelper.getUserId();
Optional<PtyCstmrBas> userEntityData = ptyCstmrDomainService.findPtyCstmrBasById(cstmrSno);
Optional<PtyCstmrDtl> userDetailEntityData = ptyCstmrDomainService.findPtyCstmrDtlById(cstmrSno);
if(userEntityData.isPresent() && userDetailEntityData.isPresent()){
PtyCstmrBas userEntity = userEntityData.get();
PtyCstmrDtl userDetailEntity = userDetailEntityData.get();
userDetailEntity.setUpdateDt(LocalDateTime.now());
userDetailEntity.setUpdateUserId(userId);
if(rq.getEmail() != null) userDetailEntity.setEmail(EncryptUtil.encrypt(rq.getEmail()));
if(rq.getHpno() != null) userDetailEntity.setHpno(EncryptUtil.encrypt(rq.getHpno()));
userEntity.setPtyCstmrDtl(userDetailEntity);
} else {
throw new BaseException(BaseErrorCode.DATA_EMPTY);
}
}
}

17
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 {
}

35
web/api-user/src/main/java/kr/co/palnet/kac/util/HttpUtils.java

@ -0,0 +1,35 @@
package kr.co.palnet.kac.util;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@Slf4j
public class HttpUtils {
/**
* 클라이언트 IP 가져온다
* @return 클라이언트 IP
*/
public static String getRequestIp() {
HttpServletRequest req = getCurrentRequest();
String[] HEADER_CLIENT_IP = { "NS-CLIENT-IP", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};
for (String name : HEADER_CLIENT_IP) {
String clientIp = req.getHeader(name);
if(!StringUtils.isEmpty(clientIp) && !"unknown".equalsIgnoreCase(clientIp)) {
log.debug("{}={}", name, clientIp);
return clientIp;
}
}
return req.getRemoteAddr();
}
public static HttpServletRequest getCurrentRequest() {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return sra.getRequest();
}
}

5
web/security/src/main/java/kr/co/palnet/kac/config/security/SecurityConfig.java

@ -17,6 +17,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.RequestCacheConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@ -52,9 +53,9 @@ public abstract class SecurityConfig {
@Bean
PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
return new BCryptPasswordEncoder();
// TODO 테스트 후 BCryptPasswordEncoder 로 변경 - 회원가입 로직 구현 후 제거
return NoOpPasswordEncoder.getInstance();
// return NoOpPasswordEncoder.getInstance();
}
@Bean

Loading…
Cancel
Save