Skip to content
This repository has been archived by the owner on Jul 29, 2024. It is now read-only.

티스토리 API 연결 종료 #617

Merged
merged 14 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-be-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
file: ./backend/Dockerfile-dev
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/dong-gle-backend-dev:latest
platforms: linux/arm64
platforms: linux/amd64

deploy:
needs: build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-be-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@ jobs:
file: ./backend/Dockerfile-prod
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/dong-gle-backend-prod:latest
platforms: linux/arm64
platforms: linux/amd64
2 changes: 1 addition & 1 deletion .github/workflows/build-fe-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
file: ${{ vars.FE_DIRECTORY }}/Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/dong-gle-frontend-dev:latest
platforms: linux/arm64
platforms: linux/amd64

deploy:
needs: build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-fe-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ jobs:
file: ${{ vars.FE_DIRECTORY }}/Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/dong-gle-frontend-prod:latest
platforms: linux/arm64
platforms: linux/amd64
2 changes: 1 addition & 1 deletion .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ permissions:

jobs:
deploy:
runs-on: [self-hosted, dev]
runs-on: [self-hosted, donggle-dev]
steps:
- uses: actions/checkout@v3
- name: create .env
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
secrets: inherit

deploy:
runs-on: [self-hosted, prod]
runs-on: [self-hosted, donggle-prod]
needs: [fe-build, be-build]
steps:
- uses: actions/checkout@v3
Expand Down
1 change: 0 additions & 1 deletion backend/Dockerfile-dev
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ EXPOSE 8080
COPY ./build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT [ \
"java",\
"-javaagent:/javaagent/dd-java-agent.jar",\
"-jar",\
"-Duser.timezone=Asia/Seoul",\
"app.jar"\
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,123 +1,124 @@
package org.donggle.backend.infrastructure.client.tistory;

import org.donggle.backend.application.repository.MemberCredentialsRepository;
import org.donggle.backend.application.repository.MemberRepository;
import org.donggle.backend.application.service.request.OAuthAccessTokenRequest;
import org.donggle.backend.domain.member.Member;
import org.donggle.backend.domain.member.MemberCredentials;
import org.donggle.backend.exception.notfound.MemberNotFoundException;
import org.donggle.backend.infrastructure.client.exception.ClientException;
import org.donggle.backend.infrastructure.client.tistory.dto.response.TistoryAccessTokenResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.NoSuchElementException;

@Service
@Transactional
public class TistoryConnectionClient {
private static final String AUTHORIZE_URL = "https://www.tistory.com/oauth/authorize";
private static final String TOKEN_URL = "https://www.tistory.com/oauth";
private static final String PLATFORM_NAME = "Tistory";

private final String clientId;
private final String clientSecret;
private final WebClient webClient;
private final MemberCredentialsRepository memberCredentialsRepository;
private final MemberRepository memberRepository;
private final TistoryApiClient tistoryApiService;

@Autowired
public TistoryConnectionClient(@Value("${tistory_client_id}") final String clientId,
@Value("${tistory_client_secret}") final String clientSecret,
final MemberCredentialsRepository memberCredentialsRepository,
final MemberRepository memberRepository,
final TistoryApiClient tistoryApiService) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.memberCredentialsRepository = memberCredentialsRepository;
this.memberRepository = memberRepository;
this.tistoryApiService = tistoryApiService;
this.webClient = WebClient.create(TOKEN_URL);
}

public TistoryConnectionClient(final String clientId,
final String clientSecret,
final MemberCredentialsRepository memberCredentialsRepository,
final MemberRepository memberRepository,
final TistoryApiClient tistoryApiService,
final WebClient webClient) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.memberCredentialsRepository = memberCredentialsRepository;
this.memberRepository = memberRepository;
this.tistoryApiService = tistoryApiService;
this.webClient = webClient;
}

public String createAuthorizeRedirectUri(final String redirectUri) {
return UriComponentsBuilder.fromUriString(AUTHORIZE_URL)
.queryParam("client_id", clientId)
.queryParam("redirect_uri", redirectUri)
.queryParam("response_type", "code")
.build()
.toUriString();
}

public void saveAccessToken(final Long memberId, final OAuthAccessTokenRequest oAuthAccessTokenRequest) {
final Member member = findMember(memberId);
final MemberCredentials memberCredentials = findMemberCredentials(member);

final String accessToken = getAccessToken(oAuthAccessTokenRequest.code(), oAuthAccessTokenRequest.redirect_uri());
final String tistoryBlogName = tistoryApiService.findDefaultBlogName(accessToken);

memberCredentials.updateTistory(accessToken, tistoryBlogName);
}

private String getAccessToken(final String code, final String redirectUri) {
final String tokenUri = createTokenUri(redirectUri, code);

return webClient.get()
.uri(tokenUri)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError, clientResponse -> ClientException.handle4xxException(clientResponse.statusCode().value(), PLATFORM_NAME))
.onStatus(HttpStatusCode::is5xxServerError, clientResponse -> ClientException.handle5xxException(PLATFORM_NAME))
.bodyToMono(TistoryAccessTokenResponse.class)
.block().access_token();
}

public String createTokenUri(final String redirectUri, final String code) {
return UriComponentsBuilder.fromUriString("/access_token")
.queryParam("client_id", clientId)
.queryParam("client_secret", clientSecret)
.queryParam("redirect_uri", redirectUri)
.queryParam("code", code)
.queryParam("grant_type", "authorization_code")
.build()
.toUriString();
}

public void deleteAccessToken(final Long memberId) {
final Member member = findMember(memberId);
final MemberCredentials memberCredentials = findMemberCredentials(member);

memberCredentials.deleteTistoryConnection();
}

private Member findMember(final Long memberId) {
return memberRepository.findById(memberId)
.orElseThrow(() -> new MemberNotFoundException(memberId));
}

private MemberCredentials findMemberCredentials(final Member member) {
return memberCredentialsRepository.findByMember(member)
.orElseThrow(NoSuchElementException::new);
}
}
//package org.donggle.backend.infrastructure.client.tistory;
//
//import org.donggle.backend.application.repository.MemberCredentialsRepository;
//import org.donggle.backend.application.repository.MemberRepository;
//import org.donggle.backend.application.service.request.OAuthAccessTokenRequest;
//import org.donggle.backend.domain.member.Member;
//import org.donggle.backend.domain.member.MemberCredentials;
//import org.donggle.backend.exception.notfound.MemberNotFoundException;
//import org.donggle.backend.infrastructure.client.exception.ClientException;
//import org.donggle.backend.infrastructure.client.tistory.dto.response.TistoryAccessTokenResponse;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.http.HttpStatusCode;
//import org.springframework.http.MediaType;
//import org.springframework.stereotype.Service;
//import org.springframework.transaction.annotation.Transactional;
//import org.springframework.web.reactive.function.client.WebClient;
//import org.springframework.web.util.UriComponentsBuilder;
//
//import java.util.NoSuchElementException;
//
//@Service
//@Transactional
//public class TistoryConnectionClient {
// private static final String AUTHORIZE_URL = "https://www.tistory.com/oauth/authorize";
// private static final String TOKEN_URL = "https://www.tistory.com/oauth";
// private static final String PLATFORM_NAME = "Tistory";
//
// private final String clientId;
// private final String clientSecret;
// private final WebClient webClient;
// private final MemberCredentialsRepository memberCredentialsRepository;
// private final MemberRepository memberRepository;
// private final TistoryApiClient tistoryApiService;
//
// @Autowired
// public TistoryConnectionClient(@Value("${tistory_client_id}") final String clientId,
// @Value("${tistory_client_secret}") final String clientSecret,
// final MemberCredentialsRepository memberCredentialsRepository,
// final MemberRepository memberRepository
// final TistoryApiClient tistoryApiService
// ) {
// this.clientId = clientId;
// this.clientSecret = clientSecret;
// this.memberCredentialsRepository = memberCredentialsRepository;
// this.memberRepository = memberRepository;
// this.tistoryApiService = tistoryApiService;
// this.webClient = WebClient.create(TOKEN_URL);
// }
//
// public TistoryConnectionClient(final String clientId,
// final String clientSecret,
// final MemberCredentialsRepository memberCredentialsRepository,
// final MemberRepository memberRepository,
// final TistoryApiClient tistoryApiService,
// final WebClient webClient) {
// this.clientId = clientId;
// this.clientSecret = clientSecret;
// this.memberCredentialsRepository = memberCredentialsRepository;
// this.memberRepository = memberRepository;
// this.tistoryApiService = tistoryApiService;
// this.webClient = webClient;
// }
//
// public String createAuthorizeRedirectUri(final String redirectUri) {
// return UriComponentsBuilder.fromUriString(AUTHORIZE_URL)
// .queryParam("client_id", clientId)
// .queryParam("redirect_uri", redirectUri)
// .queryParam("response_type", "code")
// .build()
// .toUriString();
// }
//
// public void saveAccessToken(final Long memberId, final OAuthAccessTokenRequest oAuthAccessTokenRequest) {
// final Member member = findMember(memberId);
// final MemberCredentials memberCredentials = findMemberCredentials(member);
//
// final String accessToken = getAccessToken(oAuthAccessTokenRequest.code(), oAuthAccessTokenRequest.redirect_uri());
// final String tistoryBlogName = tistoryApiService.findDefaultBlogName(accessToken);
//
// memberCredentials.updateTistory(accessToken, tistoryBlogName);
// }
//
// private String getAccessToken(final String code, final String redirectUri) {
// final String tokenUri = createTokenUri(redirectUri, code);
//
// return webClient.get()
// .uri(tokenUri)
// .accept(MediaType.APPLICATION_JSON)
// .retrieve()
// .onStatus(HttpStatusCode::is4xxClientError, clientResponse -> ClientException.handle4xxException(clientResponse.statusCode().value(), PLATFORM_NAME))
// .onStatus(HttpStatusCode::is5xxServerError, clientResponse -> ClientException.handle5xxException(PLATFORM_NAME))
// .bodyToMono(TistoryAccessTokenResponse.class)
// .block().access_token();
// }
//
// public String createTokenUri(final String redirectUri, final String code) {
// return UriComponentsBuilder.fromUriString("/access_token")
// .queryParam("client_id", clientId)
// .queryParam("client_secret", clientSecret)
// .queryParam("redirect_uri", redirectUri)
// .queryParam("code", code)
// .queryParam("grant_type", "authorization_code")
// .build()
// .toUriString();
// }
//
// public void deleteAccessToken(final Long memberId) {
// final Member member = findMember(memberId);
// final MemberCredentials memberCredentials = findMemberCredentials(member);
//
// memberCredentials.deleteTistoryConnection();
// }
//
// private Member findMember(final Long memberId) {
// return memberRepository.findById(memberId)
// .orElseThrow(() -> new MemberNotFoundException(memberId));
// }
//
// private MemberCredentials findMemberCredentials(final Member member) {
// return memberCredentialsRepository.findByMember(member)
// .orElseThrow(NoSuchElementException::new);
// }
//}
52 changes: 26 additions & 26 deletions backend/src/main/java/org/donggle/backend/ui/BlogController.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
package org.donggle.backend.ui;

import lombok.RequiredArgsConstructor;
import org.donggle.backend.infrastructure.client.tistory.TistoryApiClient;
import org.donggle.backend.ui.common.AuthenticationPrincipal;
import org.donggle.backend.ui.response.TistoryCategoryListResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequiredArgsConstructor
@RequestMapping("/blogs")
public class BlogController {
private final TistoryApiClient tistoryApiService;

@GetMapping("/tistory/category")
public ResponseEntity<TistoryCategoryListResponse> tistoryCategoryList(
@AuthenticationPrincipal final Long memberId
) {
final TistoryCategoryListResponse response = tistoryApiService.findCategory(memberId);
return ResponseEntity.ok(response);
}
}
//package org.donggle.backend.ui;
//
//import lombok.RequiredArgsConstructor;
//import org.donggle.backend.infrastructure.client.tistory.TistoryApiClient;
//import org.donggle.backend.ui.common.AuthenticationPrincipal;
//import org.donggle.backend.ui.response.TistoryCategoryListResponse;
//import org.springframework.http.ResponseEntity;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RequestMapping;
//import org.springframework.web.bind.annotation.RestController;
//
//
//@RestController
//@RequiredArgsConstructor
//@RequestMapping("/blogs")
//public class BlogController {
// private final TistoryApiClient tistoryApiService;
//
// @GetMapping("/tistory/category")
// public ResponseEntity<TistoryCategoryListResponse> tistoryCategoryList(
// @AuthenticationPrincipal final Long memberId
// ) {
// final TistoryCategoryListResponse response = tistoryApiService.findCategory(memberId);
// return ResponseEntity.ok(response);
// }
//}
Loading
Loading