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: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ dependencies {
// image
implementation 'software.amazon.awssdk:s3:2.30.18'
implementation 'org.imgscalr:imgscalr-lib:4.2'
implementation 'com.sksamuel.scrimage:scrimage-core:4.3.0'
implementation 'com.sksamuel.scrimage:scrimage-webp:4.3.0'

// gson
implementation 'com.google.code.gson:gson:2.8.6'

// base64
implementation 'commons-codec:commons-codec:1.15'
implementation 'io.seruco.encoding:base62:0.1.3'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
Expand Down
2 changes: 1 addition & 1 deletion server-config
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

Expand All @@ -44,7 +41,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
if (!matcher.match("/posts/{postId}/votes/guest", request.getRequestURI())) {
return;
}
String token = request.getHeader(CustomHeader.GUEST_ID);
String token = request.getHeader(CustomHeader.GUEST_TOKEN);
if (Objects.isNull(token)) {
throw new BadRequestException(ErrorCode.INVALID_GUEST_HEADER);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

@Qualifier(ShareUrlCryptoService.QUALIFIER)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
public @interface ShareUrlCryptoService {

String QUALIFIER = "shareUrlCryptoService";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class DataInitConfig {

private final DataInitializer dataInitializer;

@PostConstruct
// @PostConstruct
public void init() {
dataInitializer.init();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public enum ErrorCode {
NOT_POST_AUTHOR("κ²Œμ‹œκΈ€ μž‘μ„±μžκ°€ μ•„λ‹˜"),
POST_ALREADY_CLOSED("이미 마감된 κ²Œμ‹œκΈ€"),
INVALID_GUEST_HEADER("잘λͺ»λœ 게슀트 토큰 헀더"),
FILE_NAME_TOO_LONG("파일 이름이 λ„ˆλ¬΄ κΉ€"),

//401
EXPIRED_TOKEN("토큰 만료"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public abstract class CustomHeader {

public static final String GUEST_ID = "Guest-Id";
public static final String GUEST_TOKEN = "Guest-Token";
public static final String AUTHORIZATION_REFRESH = "Authorization-Refresh";

public static class CustomCookie{
Expand Down
34 changes: 0 additions & 34 deletions src/main/java/com/swyp8team2/crypto/application/Base62.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.swyp8team2.common.exception.BadRequestException;
import com.swyp8team2.common.exception.ErrorCode;
import com.swyp8team2.common.exception.InternalServerException;
import io.seruco.encoding.base62.Base62;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.encrypt.AesBytesEncryptor;
Expand All @@ -18,7 +19,7 @@ public class CryptoService {
public String encrypt(String data) {
try {
byte[] encrypt = encryptor.encrypt(data.getBytes(StandardCharsets.UTF_8));
return Base62.encode(encrypt);
return new String(Base62.createInstance().encode(encrypt), StandardCharsets.UTF_8);
} catch (Exception e) {
log.debug("encrypt error {}", e.getMessage());
throw new BadRequestException(ErrorCode.INVALID_TOKEN);
Expand All @@ -27,7 +28,7 @@ public String encrypt(String data) {

public String decrypt(String encryptedData) {
try {
byte[] decryptBytes = Base62.decode(encryptedData);
byte[] decryptBytes = Base62.createInstance().decode(encryptedData.getBytes(StandardCharsets.UTF_8));
byte[] decrypt = encryptor.decrypt(decryptBytes);
return new String(decrypt, StandardCharsets.UTF_8);
} catch (Exception e) {
Expand Down
22 changes: 20 additions & 2 deletions src/main/java/com/swyp8team2/image/application/R2Storage.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.swyp8team2.image.application;

import com.sksamuel.scrimage.ImmutableImage;
import com.swyp8team2.common.exception.BadRequestException;
import com.swyp8team2.common.exception.ErrorCode;
import com.swyp8team2.common.exception.ServiceUnavailableException;
import com.swyp8team2.common.util.DateTime;
Expand All @@ -13,6 +15,7 @@
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
Expand All @@ -22,6 +25,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
@Slf4j
Expand Down Expand Up @@ -52,6 +56,9 @@ public List<ImageFileDto> uploadImageFile(MultipartFile... files) {
for (int i = 0; i < files.length; i++) {
MultipartFile file = files[i];
String originFileName = file.getOriginalFilename();
if (originFileName.length() > 100) {
throw new BadRequestException(ErrorCode.FILE_NAME_TOO_LONG);
}
String realFileName = getRealFileName(originFileName, filePath, i);
File tempFile = File.createTempFile("upload_", "_" + originFileName);
file.transferTo(tempFile);
Expand Down Expand Up @@ -81,7 +88,18 @@ public List<ImageFileDto> uploadImageFile(MultipartFile... files) {

private String resizeImage(File file, String realFileName, int targetHeight) {
try {
BufferedImage srcImage = ImageIO.read(file);
String ext = Optional.of(realFileName)
.filter(name -> name.contains("."))
.map(name -> name.substring(name.lastIndexOf('.') + 1))
.orElseThrow(() -> new BadRequestException(ErrorCode.MISSING_FILE_EXTENSION))
.toLowerCase();

BufferedImage srcImage;
if ("webp".equals(ext)) {
srcImage = ImmutableImage.loader().fromFile(file).awt();
} else {
srcImage = ImageIO.read(file);
}
BufferedImage resizedImage = highQualityResize(srcImage, targetHeight);

int splitIndex = realFileName.lastIndexOf("/") + 1;
Expand Down Expand Up @@ -120,7 +138,7 @@ private File s3PutObject(File file, String realFileName, String imageType) {
.key(realFileName)
.build();

s3Client.putObject(objectRequest, RequestBody.fromFile(file));
PutObjectResponse putObjectResponse = s3Client.putObject(objectRequest, RequestBody.fromFile(file));
return file;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.swyp8team2.post.domain.PostImage;
import com.swyp8team2.post.domain.PostRepository;
import com.swyp8team2.post.presentation.dto.CreatePostRequest;
import com.swyp8team2.post.presentation.dto.CreatePostResponse;
import com.swyp8team2.post.presentation.dto.PostResponse;
import com.swyp8team2.post.presentation.dto.PostImageVoteStatusResponse;
import com.swyp8team2.post.presentation.dto.SimplePostResponse;
Expand Down Expand Up @@ -57,12 +58,12 @@ public PostService(
}

@Transactional
public Long create(Long userId, CreatePostRequest request) {
public CreatePostResponse create(Long userId, CreatePostRequest request) {
List<PostImage> postImages = createPostImages(request);
Post post = Post.create(userId, request.description(), postImages);
Post save = postRepository.save(post);
save.setShareUrl(shareUrlCryptoService.encrypt(String.valueOf(save.getId())));
return save.getId();
return new CreatePostResponse(save.getId(), save.getShareUrl());
}

private List<PostImage> createPostImages(CreatePostRequest request) {
Expand Down
14 changes: 7 additions & 7 deletions src/main/java/com/swyp8team2/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,20 @@ public class Post extends BaseEntity {
private Long userId;

@Enumerated(EnumType.STRING)
private State state;
private Status status;

@OneToMany(mappedBy = "post", orphanRemoval = true, cascade = CascadeType.ALL)
private List<PostImage> images = new ArrayList<>();

private String shareUrl;

public Post(Long id, Long userId, String description, State state, List<PostImage> images, String shareUrl) {
public Post(Long id, Long userId, String description, Status status, List<PostImage> images, String shareUrl) {
validateDescription(description);
validatePostImages(images);
this.id = id;
this.description = description;
this.userId = userId;
this.state = state;
this.status = status;
this.images = images;
images.forEach(image -> image.setPost(this));
this.shareUrl = shareUrl;
Expand All @@ -69,7 +69,7 @@ private void validateDescription(String description) {
}

public static Post create(Long userId, String description, List<PostImage> images) {
return new Post(null, userId, description, State.PROGRESS, images, null);
return new Post(null, userId, description, Status.PROGRESS, images, null);
}

public PostImage getBestPickedImage() {
Expand All @@ -96,10 +96,10 @@ public void cancelVote(Long imageId) {

public void close(Long userId) {
validateOwner(userId);
if (state == State.CLOSED) {
if (status == Status.CLOSED) {
throw new BadRequestException(ErrorCode.POST_ALREADY_CLOSED);
}
this.state = State.CLOSED;
this.status = Status.CLOSED;
}

public void validateOwner(Long userId) {
Expand All @@ -109,7 +109,7 @@ public void validateOwner(Long userId) {
}

public void validateProgress() {
if (!this.state.equals(State.PROGRESS)) {
if (!this.status.equals(Status.PROGRESS)) {
throw new BadRequestException(ErrorCode.POST_ALREADY_CLOSED);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.swyp8team2.post.domain;

public enum State {
public enum Status {
PROGRESS, CLOSED
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public ResponseEntity<CreatePostResponse> createPost(
@AuthenticationPrincipal UserInfo userInfo
) {

return ResponseEntity.ok(new CreatePostResponse(postService.create(userInfo.userId(), request)));
return ResponseEntity.ok(postService.create(userInfo.userId(), request));
}

@GetMapping("/{postId}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.swyp8team2.post.presentation.dto;

public record CreatePostResponse(Long postId) {
public record CreatePostResponse(Long postId, String shareUrl) {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.swyp8team2.post.presentation.dto;

import com.swyp8team2.post.domain.Post;
import com.swyp8team2.post.domain.Status;
import com.swyp8team2.user.domain.User;

import java.time.LocalDateTime;
Expand All @@ -13,6 +14,7 @@ public record PostResponse(
List<PostImageResponse> images,
String shareUrl,
boolean isAuthor,
Status status,
LocalDateTime createdAt
) {
public static PostResponse of(Post post, User user, List<PostImageResponse> images, boolean isAuthor) {
Expand All @@ -23,6 +25,7 @@ public static PostResponse of(Post post, User user, List<PostImageResponse> imag
images,
post.getShareUrl(),
isAuthor,
post.getStatus(),
post.getCreatedAt()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public ResponseEntity<Void> changeVote(
@PatchMapping("/guest")
public ResponseEntity<Void> changeGuestVote(
@PathVariable("postId") Long postId,
@RequestHeader(CustomHeader.GUEST_ID) String guestId,
@RequestHeader(CustomHeader.GUEST_TOKEN) String guestId,
@Valid @RequestBody ChangeVoteRequest request
) {
return ResponseEntity.ok().build();
Expand Down
45 changes: 0 additions & 45 deletions src/test/java/com/swyp8team2/crypto/application/Base62Test.java

This file was deleted.

Loading
Loading