Skip to content

Commit

Permalink
Merge branch 'feature/borrowPosts' of https://github.com/billbill-pro…
Browse files Browse the repository at this point in the history
…ject/bill-api-server into feature/borrowPosts
  • Loading branch information
jainefer committed Dec 4, 2024
2 parents d16dff4 + 7443dd7 commit fdf778a
Show file tree
Hide file tree
Showing 65 changed files with 1,847 additions and 53 deletions.
1 change: 1 addition & 0 deletions .github/workflows/dev_deply.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
-e KAKAO_PROVIDER_TOKEN_URI=${{secrets.KAKAO_PROVIDER_TOKEN_URI}} \
-e KAKAO_PROVIDER_USER_INFO_URI=${{secrets.KAKAO_PROVIDER_USER_INFO_URI}} \
-e PORTONE_API_SECRET=${{secrets.PORTONE_API_SECRET}} \
-e WEBHOOK_URL=${{secrets.WEBHOOK_URL}} \
${{ secrets.DOCKERHUB_USERNAME }}/bill-api:latest
sudo docker rm $(sudo docker ps --filter 'status=exited' -a -q)
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-mail'
//S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

implementation 'org.springframework.boot:spring-boot-starter-webflux'

// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package site.billbill.apiserver.api.auth.controller;

import com.nimbusds.openid.connect.sdk.assurance.IdentityVerification;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import site.billbill.apiserver.api.auth.dto.request.IdentityRequest;
import site.billbill.apiserver.api.auth.dto.request.LoginRequest;
import site.billbill.apiserver.api.auth.dto.request.ReissueRequest;
import site.billbill.apiserver.api.auth.dto.request.SignupRequest;
import site.billbill.apiserver.api.auth.dto.request.*;
import site.billbill.apiserver.api.auth.service.AuthService;
import site.billbill.apiserver.api.auth.service.OAuthService;
import site.billbill.apiserver.common.response.BaseResponse;
import site.billbill.apiserver.common.utils.jwt.dto.JwtDto;

Expand All @@ -27,12 +24,12 @@
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Server Error", content = @Content),
@ApiResponse(responseCode = "404", description = "Server Error", content = @Content),
@ApiResponse(responseCode = "409", description = "Server Error", content = @Content),
@ApiResponse(responseCode = "500", description = "Server Error", content = @Content)
})
public class AuthController {

private final AuthService authService;
private final OAuthService oAuthService;

@Operation(summary = "회원 가입(일반)", description = "일반 회원 가입 API")
@ResponseStatus(HttpStatus.CREATED)
Expand All @@ -55,10 +52,16 @@ public BaseResponse<JwtDto> reissue(@RequestBody ReissueRequest request) {
return new BaseResponse<>(authService.reissue(request.getRefreshToken()));
}

// @Operation(summary = "휴대폰 본인인증", description = "PASS NICE 본인인증 API")
// @ResponseStatus(HttpStatus.OK)
// @PostMapping("/identity")
// public BaseResponse<JwtDto> identity(@RequestBody IdentityRequest request) {
// return null;
// }
@ResponseStatus(HttpStatus.OK)
@GetMapping("/oauth2/code/kakao/callback")
public BaseResponse<JwtDto> kakaoCallback(@RequestParam("code") String code) {
return new BaseResponse<JwtDto>(oAuthService.kakaoCallback(code));
}

@Operation(summary = "휴대폰 본인인증", description = "PASS NICE 본인인증 API")
@ResponseStatus(HttpStatus.OK)
@PostMapping("/identity")
public BaseResponse<JwtDto> identity(@RequestBody IdentityVerificationRequest request) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package site.billbill.apiserver.api.auth.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.Data;
import site.billbill.apiserver.common.enums.user.identity.IdentityVerificationOperator;

@Data
public class IdentityVerificationRequest {
@Schema(description = "회원 본명", example = "홍길동")
private String name;
@Schema(description = "회원 전화번호", example = "010-1234-5678")
private String phoneNumber;
@Schema(description = "주민번호 앞 7자리", example = "0001013")
private String identityNumber;
@Enumerated(EnumType.STRING)
@Schema(description = "본인인증 통신사", example = "SKT")
private IdentityVerificationOperator operator;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

@Data
public class LoginRequest {
@Schema(description = "전화번호", example = "010-1234-5678")
@Schema(description = "전화번호", example = "010-0000-0001")
private String phoneNumber;
@Schema(description = "비밀번호", example = "password")
private String password;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package site.billbill.apiserver.api.auth.service;

import site.billbill.apiserver.api.auth.dto.request.IdentityRequest;
import site.billbill.apiserver.api.auth.dto.request.LoginRequest;
import site.billbill.apiserver.api.auth.dto.request.SignupRequest;
import site.billbill.apiserver.common.utils.jwt.dto.JwtDto;
Expand All @@ -10,4 +11,6 @@ public interface AuthService {
JwtDto login(LoginRequest request);

JwtDto reissue(String refreshToken);

boolean identifyUser(IdentityRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import site.billbill.apiserver.api.auth.domain.UserBaseInfo;
import site.billbill.apiserver.api.auth.dto.request.IdentityRequest;
import site.billbill.apiserver.api.auth.dto.request.LocationRequest;
import site.billbill.apiserver.api.auth.dto.request.LoginRequest;
import site.billbill.apiserver.api.auth.dto.request.SignupRequest;
Expand Down Expand Up @@ -110,6 +111,13 @@ public JwtDto reissue(String refreshToken) {
}
}

@Override
public boolean identifyUser(IdentityRequest request) {


return false;
}

/**
* Method that if user is withdrawn
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package site.billbill.apiserver.api.auth.service;

import site.billbill.apiserver.common.utils.jwt.dto.JwtDto;

public interface OAuthService {
JwtDto kakaoCallback(String code);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package site.billbill.apiserver.api.auth.service;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import site.billbill.apiserver.common.enums.exception.ErrorCode;
import site.billbill.apiserver.common.enums.user.Provider;
import site.billbill.apiserver.common.enums.user.UserRole;
import site.billbill.apiserver.common.utils.ULID.ULIDUtil;
import site.billbill.apiserver.common.utils.jwt.JWTUtil;
import site.billbill.apiserver.common.utils.jwt.dto.JwtDto;
import site.billbill.apiserver.common.utils.users.oauth.kakao.KakaoUtil;
import site.billbill.apiserver.exception.CustomException;
import site.billbill.apiserver.external.oauth.kakao.dto.response.KakaoUserInfoResponse;
import site.billbill.apiserver.model.user.UserIdentityJpaEntity;
import site.billbill.apiserver.model.user.UserJpaEntity;
import site.billbill.apiserver.repository.user.UserIdentityRepository;
import site.billbill.apiserver.repository.user.UserRepository;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class OAuthServiceImpl implements OAuthService {
private final KakaoUtil kakaoUtil;
private final JWTUtil jwtUtil;
private final UserRepository userRepository;
private final UserIdentityRepository userIdentityRepository;

@Override
public JwtDto kakaoCallback(String code) {
String accessToken = kakaoUtil.getAccessToken(code);
if (accessToken == null)
throw new CustomException(ErrorCode.ServerError, "토큰을 발급받는데 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
KakaoUserInfoResponse userInfo = kakaoUtil.getUserInfo(accessToken);

Optional<UserJpaEntity> optionalUser = userRepository.findByProviderId(userInfo.partner.getUuid());

// 만약 이미 가입된 회원이라면 토큰 반환
if (optionalUser.isPresent()) {
return jwtUtil.generateJwtDto(optionalUser.get().getUserId(), optionalUser.get().getRole());
}

// 만약 신규 회원이라면
String userId = ULIDUtil.generatorULID("USER");

String birthDateString = userInfo.kakaoAccount.getBirthYear() + userInfo.kakaoAccount.getBirthDay();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate birth = LocalDate.parse(birthDateString, formatter);

char gender = Character.toUpperCase(userInfo.kakaoAccount.getGender().charAt(0));

UserJpaEntity user = UserJpaEntity.builder()
.userId(userId)
.email(userInfo.kakaoAccount.getEmail())
.password(null)
.nickname(userInfo.kakaoAccount.profile.getNickName())
.profile(userInfo.kakaoAccount.profile.getProfileImageUrl())
.provider(Provider.KAKAO)
.providerId(userInfo.getId().toString())
.role(UserRole.USER)
.withdrawAt(null)
.build();

UserIdentityJpaEntity userIdentity = UserIdentityJpaEntity.builder()
.userId(userId)
.name(userInfo.kakaoAccount.getName())
.phoneNumber(userInfo.kakaoAccount.getPhoneNumber().replace("+82 ", "0"))
.birth(birth)
.gender(gender)
.build();

userRepository.save(user);
userIdentityRepository.save(userIdentity);

// UserAgreeHist 랑 UserDevice, UserLocation 은 별도로 추가해야됨

return jwtUtil.generateJwtDto(userId, UserRole.USER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package site.billbill.apiserver.api.base.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import site.billbill.apiserver.api.auth.dto.request.SignupRequest;
import site.billbill.apiserver.api.base.dto.request.ReportRequest;
import site.billbill.apiserver.api.base.service.BaseService;
import site.billbill.apiserver.common.enums.base.ReportType;
import site.billbill.apiserver.common.response.BaseResponse;
import site.billbill.apiserver.common.utils.jwt.dto.JwtDto;

@Slf4j
@RestController
@Tag(name = "Base", description = "Base API")
@RequestMapping("/api/v1/base")
@RequiredArgsConstructor
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Server Error", content = @Content),
@ApiResponse(responseCode = "404", description = "Server Error", content = @Content),
@ApiResponse(responseCode = "500", description = "Server Error", content = @Content)
})
public class BaseController {
private final BaseService baseService;

@Operation(summary = "신고하기", description = "신고하기 API")
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/report/{type}")
public BaseResponse<String> report(@PathVariable ReportType type, @RequestBody ReportRequest request) {
baseService.report(type, request);
return new BaseResponse<>(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package site.billbill.apiserver.api.base.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import site.billbill.apiserver.common.enums.base.ReportCode;

@Data
public class ReportRequest {
@Schema(description = "신고할 유저 ID", example = "USER-XXXXX")
private String userId;
@Schema(description = "신고 사유 코드", example = "FRAUD / HARMFUL / DRUG / IMPOSTER / UNHEALTHY / ETC")
private ReportCode reportCode;
@Schema(description = "신고 상세 사유", example = "상세 설명")
private String description;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package site.billbill.apiserver.api.base.service;

import site.billbill.apiserver.api.base.dto.request.ReportRequest;
import site.billbill.apiserver.common.enums.base.ReportType;

public interface BaseService {
void report(ReportType type, ReportRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package site.billbill.apiserver.api.base.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import site.billbill.apiserver.api.base.dto.request.ReportRequest;
import site.billbill.apiserver.common.enums.base.ReportStatus;
import site.billbill.apiserver.common.enums.base.ReportType;
import site.billbill.apiserver.common.utils.jwt.JWTUtil;
import site.billbill.apiserver.model.report.ReportHistJpaEntity;
import site.billbill.apiserver.repository.report.ReportHistRepository;

@Slf4j
@Service
@RequiredArgsConstructor
public class BaseServiceImpl implements BaseService {
private final ReportHistRepository reportHistRepository;

@Override
@Transactional
public void report(ReportType type, ReportRequest request) {
String currentUserId = MDC.get(JWTUtil.MDC_USER_ID);

ReportHistJpaEntity reportHistJpaEntity = ReportHistJpaEntity.builder()
.reportSeq(null)
.reportType(type)
.targetId(request.getUserId())
.reporterId(currentUserId)
.reportCode(request.getReportCode())
.description(request.getDescription())
.reportStatus(ReportStatus.REPORTED)
.build();

reportHistRepository.save(reportHistJpaEntity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package site.billbill.apiserver.api.chat.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jboss.logging.MDC;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import site.billbill.apiserver.api.chat.dto.request.ChatRequest;
import site.billbill.apiserver.api.chat.dto.response.ChatResponse;
import site.billbill.apiserver.api.chat.service.ChatService;
import site.billbill.apiserver.common.response.BaseResponse;
import site.billbill.apiserver.common.utils.jwt.JWTUtil;

@Slf4j
@RestController
@Tag(name = "Chat", description = "Chat API")
@RequestMapping("/api/v1/chat")
@RequiredArgsConstructor
public class ChatController {
private final ChatService chatService;

@Operation(summary = "채팅방 나가기", description = "채팅방 나가기 API")
@PatchMapping("/{channelId}")
public BaseResponse<String> leaveChatChannel(@PathVariable(value = "channelId") String channelId) {
log.info("api 호출 정상적~");
String userId = MDC.get(JWTUtil.MDC_USER_ID).toString();
return new BaseResponse<>(chatService.leaveChatChannel(channelId,userId));
}

@Operation(summary = "채팅방 생성 및 id 조회", description = "빌리기 버튼 누를 때 api")
@PostMapping("")
public BaseResponse<String> startChannel(@RequestBody ChatRequest.borrowInfo request) {
log.info("api 호출 정상적~");
String userId = MDC.get(JWTUtil.MDC_USER_ID).toString();
return new BaseResponse<>(chatService.startChannel(request, userId));
}

@Operation(summary = "채팅방 info 조회", description = "채팅방 info 조회 API")
@GetMapping("/{channelId}")
public BaseResponse<ChatResponse.ViewChannelInfoResponse> getInfoChannel(@PathVariable(value = "channelId") String channelId) {
log.info("api 호출 정상적~");
String userId = MDC.get(JWTUtil.MDC_USER_ID).toString();
return new BaseResponse<>(chatService.getInfoChannel(channelId,userId));
}
}
Loading

0 comments on commit fdf778a

Please sign in to comment.