Skip to content
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
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ dependencies {
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'


testImplementation 'io.rest-assured:rest-assured:5.4.0'
testImplementation 'io.rest-assured:json-path:5.4.0'
testImplementation 'io.rest-assured:json-schema-validator:5.4.0'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/org/runimo/runimo/auth/jwt/JwtResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,9 @@
@Component
public class JwtResolver {

private static final String ISSUER = "RunUSAuthService";
private static final String ISSUER = "RUNIMO_SERVICE";
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.expiration}")
private long jwtExpiration;
@Value("${jwt.refresh.expiration}")
private long jwtRefreshExpiration;

public DecodedJWT verifyAccessToken(String token) throws JWTVerificationException {
return JWT.require(Algorithm.HMAC256(jwtSecret)).withIssuer(ISSUER).build().verify(token);
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/runimo/runimo/auth/jwt/JwtTokenFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,24 @@ public class JwtTokenFactory {
@Value("${jwt.refresh.expiration}")
private long jwtRefreshExpiration;

public String generateAccessToken(User user) {
public String generateAccessToken(String userPublicId) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpiration);

return JWT.create()
.withSubject(user.getPublicId())
.withSubject(userPublicId)
.withIssuedAt(now)
.withExpiresAt(expiryDate)
.withIssuer(ISSUER)
.sign(Algorithm.HMAC256(jwtSecret));
}

public String generateRefreshToken(User user) {
public String generateRefreshToken(String userPublicId) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtRefreshExpiration);

return JWT.create()
.withSubject(user.getPublicId())
.withSubject(userPublicId)
.withIssuedAt(now)
.withExpiresAt(expiryDate)
.withIssuer(ISSUER)
Expand All @@ -49,8 +49,8 @@ public String generateRefreshToken(User user) {
}

public TokenPair generateTokenPair(User user) {
String accessToken = generateAccessToken(user);
String refreshToken = generateRefreshToken(user);
String accessToken = generateAccessToken(user.getPublicId());
String refreshToken = generateRefreshToken(user.getPublicId());
return new TokenPair(accessToken, refreshToken);
}
}
5 changes: 1 addition & 4 deletions src/main/java/org/runimo/runimo/common/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package org.runimo.runimo.common;

import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
Expand Down
8 changes: 2 additions & 6 deletions src/main/java/org/runimo/runimo/common/GlobalConsts.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,15 @@
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.time.ZoneId;
import java.util.Set;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class GlobalConsts {

public static final String TIME_ZONE_ID = "Asia/Seoul";
public static final ZoneId ZONE_ID = ZoneId.of(TIME_ZONE_ID);
public static final String DEFAULT_IMG_URL = "default_img_url";
public static final String SESSION_ATTRIBUTE_USER = "user-info";
public static final Set<String> WHITE_LIST_ENDPOINTS = Set.of(
"/test/auth",
"/auth",
"/api/v1/test/auth",
"/api/v1/users/auth",
"/swagger-ui",
"/v3/api-docs"
);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/runimo/runimo/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/auth/**").permitAll()
.requestMatchers("/api/v1/users/auth/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
Expand All @@ -45,7 +45,7 @@ public SecurityFilterChain devSecurityFilterChain(HttpSecurity http) throws Exce
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/auth/**").permitAll()
.requestMatchers("/api/v1/users/auth/**").permitAll()
.requestMatchers("/swagger-ui/**", "/swagger-ui.html", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated()
);
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/org/runimo/runimo/config/WebMvcConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.runimo.runimo.config;

import lombok.RequiredArgsConstructor;
import org.runimo.runimo.user.controller.UserIdResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@RequiredArgsConstructor
public class WebMvcConfig implements WebMvcConfigurer {

private final UserIdResolver userIdResolver;

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(userIdResolver);
}
}
9 changes: 4 additions & 5 deletions src/main/java/org/runimo/runimo/item/domain/ItemActivity.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.runimo.runimo.item.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -17,11 +15,12 @@
public class ItemActivity extends BaseEntity {
@Column(name = "activity_user_id", nullable = false)
private Long userId;
@Column(name = "activity_event_id", nullable = false)
@Column(name = "activity_item_id", nullable = false)
private Long itemId;

@Column(name = "quantity", nullable = false)
private Long quantity;
@Column(name = "activity_event_type", nullable = false)
@Enumerated(EnumType.STRING)
private ActivityType type;

@Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class UserController {
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터"),
@ApiResponse(responseCode = "401", description = "인증 실패")
})
@PostMapping("/login")
@PostMapping("/auth/login")
public ResponseEntity<SuccessResponse<AuthResponse>> login(
@Valid @RequestBody AuthLoginRequest request
) {
Expand All @@ -63,7 +63,7 @@ public ResponseEntity<SuccessResponse<AuthResponse>> login(
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터"),
@ApiResponse(responseCode = "409", description = "이미 존재하는 사용자")
})
@PostMapping("/signup")
@PostMapping("/auth/signup")
public ResponseEntity<SuccessResponse<AuthResponse>> signupAndLogin(
@Valid @RequestBody AuthSignupRequest request) {
SignupUserInfo authResult = userOAuthUsecase.validateAndSignup(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
if (authentication == null || !authentication.isAuthenticated()) {
throw new SecurityException("No authentication found");
}
User user = userFinder.findUserById(Long.valueOf(authentication.getName()))
User user = userFinder.findUserByPublicId(authentication.getName())
.orElseThrow(NoPermissionException::new);
return user.getId();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.runimo.runimo.user.controller;

import lombok.RequiredArgsConstructor;
import org.runimo.runimo.common.response.SuccessResponse;
import org.runimo.runimo.user.enums.UserHttpResponseCode;
import org.runimo.runimo.user.service.dtos.ItemQueryResponse;
import org.runimo.runimo.user.service.usecases.MyItemQueryUsecase;
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
@RequestMapping("/api/v1/users/me/items")
@RequiredArgsConstructor
public class UserItemController {

private final MyItemQueryUsecase myItemQueryUsecase;

@GetMapping
public ResponseEntity<SuccessResponse<ItemQueryResponse>> queryItems(
@UserId Long userId
) {
ItemQueryResponse response = myItemQueryUsecase.execute(userId);
return ResponseEntity.ok(SuccessResponse.of(UserHttpResponseCode.MY_PAGE_DATA_FETCHED, response));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.runimo.runimo.user.repository;

import org.runimo.runimo.user.domain.UserItem;
import org.runimo.runimo.user.service.dtos.InventoryItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface MyItemRepository extends JpaRepository<UserItem, Integer> {

@Query("SELECT new org.runimo.runimo.user.service.dtos.InventoryItem(i.itemId, it.name, i.quantity, it.imgUrl) " +
"FROM UserItem i" +
" join Item it on i.itemId = it.id" +
" WHERE i.userId = :userId")
List<InventoryItem> findInventoryItemsByUserId(Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.runimo.runimo.user.service.dtos;

public record InventoryItem(
Long itemId,
String name,
Long amount,
String imgUrl
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.runimo.runimo.user.service.dtos;

import java.util.List;

public record ItemQueryResponse(
List<InventoryItem> items
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.runimo.runimo.user.service.usecases;

import org.runimo.runimo.user.service.dtos.ItemQueryResponse;

public interface MyItemQueryUsecase {
ItemQueryResponse execute(Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.runimo.runimo.user.service.usecases;


import lombok.RequiredArgsConstructor;
import org.runimo.runimo.user.repository.MyItemRepository;
import org.runimo.runimo.user.service.dtos.InventoryItem;
import org.runimo.runimo.user.service.dtos.ItemQueryResponse;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class MyItemQueryUsecaseImpl implements MyItemQueryUsecase {

private final MyItemRepository myItemRepository;

@Override
public ItemQueryResponse execute(Long userId) {
List<InventoryItem> myItems = myItemRepository.findInventoryItemsByUserId(userId);
return new ItemQueryResponse(myItems);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public SignupUserInfo validateAndSignup(final UserSignupCommand command, final S
.ifPresent(oAuthInfo -> {
throw new IllegalArgumentException();
});
User savedUser = userRegisterService.register(command, provider, pid);
User savedUser = userRegisterService.register(command, pid);
return new SignupUserInfo(savedUser.getId(), jwtfactory.generateTokenPair(savedUser));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import lombok.RequiredArgsConstructor;
import org.runimo.runimo.rewards.service.eggs.EggGrantService;
import org.runimo.runimo.user.domain.SocialProvider;
import org.runimo.runimo.user.domain.User;
import org.runimo.runimo.user.service.UserCreator;
import org.runimo.runimo.user.service.UserItemCreator;
Expand All @@ -19,9 +18,9 @@ public class UserRegisterService {
private final EggGrantService eggGrantService;

@Transactional
public User register(UserSignupCommand command, SocialProvider provider, String providerId) {
public User register(UserSignupCommand command, String providerId) {
User savedUser = userCreator.createUser(command);
userCreator.createUserOAuthInfo(savedUser, provider, providerId);
userCreator.createUserOAuthInfo(savedUser, command.provider(), providerId);
userItemCreator.createAll(savedUser.getId());
eggGrantService.grantGreetingEggToUser(savedUser);
return savedUser;
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ spring:
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: ${JPA_DDL_AUTO:update}
ddl-auto: ${JPA_DDL_AUTO:none}
properties:
hibernate:
dialect: ${JPA_DIALECT}
Expand Down
Loading
Loading