Skip to content

Commit

Permalink
Merge pull request #290 from team-yello/staging
Browse files Browse the repository at this point in the history
YEL-150 [deploy] 1.1.8v
  • Loading branch information
euije authored Sep 3, 2023
2 parents 0b39684 + b7972d9 commit 192a7be
Show file tree
Hide file tree
Showing 27 changed files with 281 additions and 50 deletions.
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ dependencies {

// jwt decode
implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
implementation 'io.jsonwebtoken:jjwt-api:0.11.2'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.2'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.2'

// AOP
implementation 'org.springframework.boot:spring-boot-starter-aop'
}

asciidoctor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

import static com.yello.server.global.common.SuccessCode.DELETE_COOLDOWN_ADMIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.DELETE_USER_ADMIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.LOGIN_USER_ADMIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.READ_COOLDOWN_ADMIN_SUCCESS;
import static com.yello.server.global.common.SuccessCode.READ_USER_ADMIN_SUCCESS;

import com.yello.server.domain.admin.dto.request.AdminLoginRequest;
import com.yello.server.domain.admin.dto.response.AdminCooldownResponse;
import com.yello.server.domain.admin.dto.response.AdminLoginResponse;
import com.yello.server.domain.admin.dto.response.AdminUserResponse;
import com.yello.server.domain.admin.service.AdminService;
import com.yello.server.domain.user.entity.User;
Expand All @@ -17,6 +20,8 @@
import lombok.val;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
Expand All @@ -28,6 +33,12 @@ public class AdminController {

private final AdminService adminService;

@PostMapping("/login")
public BaseResponse<AdminLoginResponse> postAdminLogin(@RequestBody AdminLoginRequest request) {
val data = adminService.login(request);
return BaseResponse.success(LOGIN_USER_ADMIN_SUCCESS, data);
}

@GetMapping("/user")
public BaseResponse<AdminUserResponse> getUserAdmin(@AccessTokenUser User user, @RequestParam Integer page,
@Nullable @RequestParam String yelloId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.yello.server.domain.admin.dto.request;

import lombok.Builder;

@Builder
public record AdminLoginRequest(
String password
) {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.yello.server.domain.admin.dto.response;

import lombok.Builder;

@Builder
public record AdminLoginResponse(
String accessToken
) {

public static AdminLoginResponse of(String accessToken) {
return AdminLoginResponse.builder()
.accessToken(accessToken)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
package com.yello.server.domain.admin.service;

import static com.yello.server.global.common.ErrorCode.USER_ADMIN_NOT_FOUND_EXCEPTION;

import com.yello.server.domain.admin.dto.request.AdminLoginRequest;
import com.yello.server.domain.admin.dto.response.AdminCooldownContentVO;
import com.yello.server.domain.admin.dto.response.AdminCooldownResponse;
import com.yello.server.domain.admin.dto.response.AdminLoginResponse;
import com.yello.server.domain.admin.dto.response.AdminUserContentVO;
import com.yello.server.domain.admin.dto.response.AdminUserResponse;
import com.yello.server.domain.admin.exception.UserAdminNotFoundException;
import com.yello.server.domain.admin.repository.UserAdminRepository;
import com.yello.server.domain.authorization.service.TokenProvider;
import com.yello.server.domain.cooldown.entity.Cooldown;
import com.yello.server.domain.cooldown.repository.CooldownRepository;
import com.yello.server.domain.user.entity.User;
import com.yello.server.domain.user.repository.UserRepository;
import com.yello.server.domain.user.service.UserManager;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
Expand All @@ -21,9 +29,28 @@
public class AdminService {

private final UserRepository userRepository;
private final UserManager userManager;
private final TokenProvider tokenProvider;
private final CooldownRepository cooldownRepository;
private final UserAdminRepository userAdminRepository;

public AdminLoginResponse login(AdminLoginRequest request) {
AtomicReference<String> accessToken = new AtomicReference<>();

userManager.getOfficialUsers()
.forEach((user) -> {
if (user.getYelloId().equals(request.password())) {
accessToken.set(tokenProvider.createAccessToken(user.getId(), user.getUuid()));
}
});

if (accessToken.get() == null || accessToken.get().isEmpty()) {
throw new UserAdminNotFoundException(USER_ADMIN_NOT_FOUND_EXCEPTION);
}

return AdminLoginResponse.of(accessToken.get());
}

public AdminUserResponse findUser(Long adminId, Pageable page) {
// exception
final User admin = userRepository.getById(adminId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.yello.server.domain.authorization.filter;

import static com.yello.server.domain.authorization.filter.JwtFilter.BEARER;
import static com.yello.server.domain.authorization.filter.JwtFilter.X_ACCESS_AUTH;
import static com.yello.server.domain.authorization.filter.JwtFilter.X_REFRESH_AUTH;
import static com.yello.server.global.common.ErrorCode.AUTHENTICATION_ERROR;
import static com.yello.server.global.common.ErrorCode.EXPIRED_TOKEN;
import static com.yello.server.global.common.ErrorCode.ILLEGAL_TOKEN;
Expand Down Expand Up @@ -43,25 +45,45 @@ protected void doFilterInternal(
if (requestPath.equals("/")
|| requestPath.startsWith("/docs")
|| requestPath.startsWith("/actuator") || requestPath.startsWith("/prometheus")
|| requestPath.startsWith("/api/v1/auth")) {
|| requestPath.startsWith("/api/v1/admin/login")
|| (requestPath.startsWith("/api/v1/auth")
&& !requestPath.startsWith("/api/v1/auth/token/issue"))) {
filterChain.doFilter(request, response);
return;
}

val accessHeader = request.getHeader(AUTHORIZATION);
log.info("Authorization : {}", accessHeader);
try {
if (requestPath.startsWith("/api/v1/auth/token/issue")) {
val accessHeader = request.getHeader(X_ACCESS_AUTH);
val refreshHeader = request.getHeader(X_REFRESH_AUTH);
log.info("Authorization-access : {}", accessHeader);
log.info("Authorization-refresh : {}", refreshHeader);

if (accessHeader==null || !accessHeader.startsWith(BEARER)) {
throw new CustomAuthenticationException(AUTHENTICATION_ERROR);
}
if (accessHeader == null || !accessHeader.startsWith(BEARER)
|| refreshHeader == null || !refreshHeader.startsWith(BEARER)) {
throw new CustomAuthenticationException(AUTHENTICATION_ERROR);
}

val token = accessHeader.substring(BEARER.length());
try {
Long userId = tokenProvider.getUserId(token);
request.setAttribute("userId", userId);
val token = accessHeader.substring(BEARER.length());
Long userId = tokenProvider.getUserId(token);
request.setAttribute("userId", userId);
} else {
val accessHeader = request.getHeader(AUTHORIZATION);
log.info("Authorization : {}", accessHeader);

if (accessHeader == null || !accessHeader.startsWith(BEARER)) {
throw new CustomAuthenticationException(AUTHENTICATION_ERROR);
}

val token = accessHeader.substring(BEARER.length());
Long userId = tokenProvider.getUserId(token);
request.setAttribute("userId", userId);
}
} catch (ExpiredJwtException e) {
log.info("토큰이 만료되었습니다. 토큰 재발급 API 호출이 필요합니다.");
throw new InvalidTokenException(EXPIRED_TOKEN);
if (!requestPath.startsWith("/api/v1/auth/token/issue")) {
log.info("토큰이 만료되었습니다. 토큰 재발급 API 호출이 필요합니다.");
throw new InvalidTokenException(EXPIRED_TOKEN);
}
} catch (MalformedJwtException e) {
log.info("토큰이 변조되었습니다.");
throw new InvalidTokenException(MALFORMED_TOKEN);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {

public static final String X_ACCESS_AUTH = "X-ACCESS-AUTH";
public static final String X_REFRESH_AUTH = "X-REFRESH-AUTH";
public static final String BEARER = "Bearer ";
private final UserRepository userRepository;

Expand All @@ -36,6 +38,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
if (requestPath.equals("/")
|| requestPath.startsWith("/docs")
|| requestPath.startsWith("/actuator") || requestPath.startsWith("/prometheus")
|| requestPath.startsWith("/api/v1/admin/login")
|| requestPath.startsWith("/api/v1/auth")) {
filterChain.doFilter(request, response);
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.yello.server.domain.authorization.service;

import static com.yello.server.global.common.ErrorCode.DEVICE_TOKEN_CONFLICT_USER_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.NOT_SIGNIN_USER_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.UUID_CONFLICT_USER_EXCEPTION;
import static com.yello.server.global.common.ErrorCode.YELLOID_CONFLICT_USER_EXCEPTION;
Expand Down Expand Up @@ -66,7 +67,7 @@ public ServiceTokenVO setNewAccessToken(String refreshToken) {

@Override
public void validateSignupRequest(SignUpRequest signUpRequest) {
userRepository.findByUuid(signUpRequest.uuid())
userRepository.findByUuidNotFiltered(signUpRequest.uuid())
.ifPresent(action -> {
throw new UserConflictException(UUID_CONFLICT_USER_EXCEPTION);
});
Expand All @@ -75,6 +76,11 @@ public void validateSignupRequest(SignUpRequest signUpRequest) {
.ifPresent(action -> {
throw new UserConflictException(YELLOID_CONFLICT_USER_EXCEPTION);
});

userRepository.findByDeviceTokenNotFiltered(signUpRequest.deviceToken())
.ifPresent(action -> {
throw new UserConflictException(DEVICE_TOKEN_CONFLICT_USER_EXCEPTION);
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public Purchase createTicket(User user, ProductType productType, Gateway gateway
@Override
public void handleAppleTransactionError(ResponseEntity<TransactionInfoResponse> response,
String transactionId) {
tokenFactory.decodeTransactionToken(response.getBody().signedTransactionInfo(),
transactionId);

if (!response.getStatusCode().is2xxSuccessful()) {
throw new AppleTokenServerErrorException(APPLE_TOKEN_SERVER_EXCEPTION);
Expand All @@ -54,4 +56,5 @@ public void handleAppleTransactionError(ResponseEntity<TransactionInfoResponse>
});
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public UserSubscribeNeededResponse getUserSubscribe(User user, LocalDateTime tim
final Optional<Purchase> mostRecentPurchase =
purchaseRepository.findTopByUserAndProductTypeOrderByCreatedAtDesc(
user, ProductType.YELLO_PLUS);
final Boolean isSubscribeNeeded = user.getSubscribe()==Subscribe.CANCELED
final Boolean isSubscribeNeeded = user.getSubscribe() == Subscribe.CANCELED
&& mostRecentPurchase.isPresent()
&& Duration.between(mostRecentPurchase.get().getCreatedAt(), time).getSeconds()
< 1 * 24 * 60 * 60;
Expand All @@ -94,7 +94,7 @@ public void verifyAppleSubscriptionTransaction(Long userId,

purchaseManager.handleAppleTransactionError(verifyReceiptResponse, request.transactionId());

if (user.getSubscribe()==Subscribe.ACTIVE) {
if (user.getSubscribe() == Subscribe.ACTIVE) {
throw new SubscriptionConflictException(SUBSCRIBE_ACTIVE_EXCEPTION);
}

Expand Down Expand Up @@ -141,7 +141,7 @@ public GoogleSubscriptionGetResponse verifyGoogleSubscriptionTransaction(Long us
User user = userRepository.getById(userId);

// exception
if (user.getSubscribe()!=Subscribe.NORMAL) {
if (user.getSubscribe() != Subscribe.NORMAL) {
throw new PurchaseConflictException(GOOGLE_SUBSCRIPTIONS_FORBIDDEN_EXCEPTION);
}

Expand Down Expand Up @@ -187,7 +187,7 @@ public GoogleSubscriptionGetResponse verifyGoogleSubscriptionTransaction(Long us
GOOGLE_SUBSCRIPTION_TRANSACTION_EXPIRED_EXCEPTION);
}
case ConstantUtil.GOOGLE_PURCHASE_SUBSCRIPTION_CANCELED -> {
if (user.getSubscribe()==Subscribe.CANCELED) {
if (user.getSubscribe() == Subscribe.CANCELED) {
throw new GoogleBadRequestException(
GOOGLE_SUBSCRIPTION_DUPLICATED_CANCEL_EXCEPTION);
} else {
Expand Down Expand Up @@ -239,8 +239,9 @@ public GoogleTicketGetResponse verifyGoogleTicketTransaction(Long userId,
if (!inAppResponse.getStatusCode().is2xxSuccessful()) {
throw new GoogleTokenServerErrorException(GOOGLE_TOKEN_SERVER_EXCEPTION);
}
System.out.println("inAppResponse = " + inAppResponse);

if (inAppResponse.getBody().purchaseState()==0) {
if (inAppResponse.getBody().purchaseState() == 0) {
purchaseRepository.findByTransactionId(inAppResponse.getBody().orderId())
.ifPresent(action -> {
throw new PurchaseConflictException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public interface UserJpaRepository extends JpaRepository<User, Long> {
"where u.uuid = :uuid")
Optional<User> findByUuid(@Param("uuid") String uuid);

@Query("select u from User u " +
"where u.uuid = :uuid")
Optional<User> findByUuidNotFiltered(@Param("uuid") String uuid);

@Query("select case when count(u) > 0 then true else false end from User u " +
"where u.uuid = :uuid " +
"and u.deletedAt is null")
Expand Down Expand Up @@ -76,7 +80,14 @@ List<User> findAllByGroupContainingYelloId(@Param("groupName") String groupName,
List<User> findAllByOtherGroupContainingYelloId(@Param("groupName") String groupName,
@Param("keyword") String keyword, @Param("uuidList") List<String> uuidList);

Optional<User> findByDeviceToken(String deviceToken);
@Query("select u from User u "
+ "where u.deviceToken = :deviceToken "
+ "and u.deletedAt is null")
Optional<User> findByDeviceToken(@Param("deviceToken") String deviceToken);

@Query("select u from User u " +
"where u.deviceToken = :deviceToken")
Optional<User> findByDeviceTokenNotFiltered(@Param("deviceToken") String deviceToken);

Long countAllByYelloIdContaining(String yelloId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public interface UserRepository {

Optional<User> findByUuid(String uuid);

Optional<User> findByUuidNotFiltered(String uuid);

User getByUuid(String uuid);

boolean existsByUuid(String uuid);
Expand All @@ -28,6 +30,8 @@ public interface UserRepository {

Optional<User> findByDeviceToken(String deviceToken);

Optional<User> findByDeviceTokenNotFiltered(String deviceToken);

List<User> findAllByGroupId(Long groupId);

List<User> findAllByGroupContainingName(String groupName, String keyword,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public Optional<User> findByUuid(String uuid) {
return userJpaRepository.findByUuid(uuid);
}

@Override
public Optional<User> findByUuidNotFiltered(String uuid) {
return userJpaRepository.findByUuidNotFiltered(uuid);
}

@Override
public User getByUuid(String uuid) {
return userJpaRepository.findByUuid(uuid)
Expand Down Expand Up @@ -74,6 +79,11 @@ public Optional<User> findByDeviceToken(String deviceToken) {
return userJpaRepository.findByDeviceToken(deviceToken);
}

@Override
public Optional<User> findByDeviceTokenNotFiltered(String deviceToken) {
return userJpaRepository.findByDeviceTokenNotFiltered(deviceToken);
}

@Override
public List<User> findAllByGroupId(Long groupId) {
return userJpaRepository.findAllByGroupId(groupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import com.yello.server.domain.user.entity.Gender;
import com.yello.server.domain.user.entity.User;
import java.util.List;

public interface UserManager {

User getOfficialUser(Gender gender);

List<User> getOfficialUsers();
}
Loading

0 comments on commit 192a7be

Please sign in to comment.