Skip to content
Draft
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
8 changes: 7 additions & 1 deletion src/main/java/io/spring/Util.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package io.spring;

public class Util {
public static boolean isEmpty(String value) {
public static boolean isNullOrEmpty(String value) {
return value == null || value.isEmpty();
}

/** @deprecated Use {@link #isNullOrEmpty(String)} instead */
@Deprecated
public static boolean isEmpty(String value) {
return isNullOrEmpty(value);
}
}
8 changes: 3 additions & 5 deletions src/main/java/io/spring/api/ArticleApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ public ResponseEntity deleteArticle(
}

private Map<String, Object> articleResponse(ArticleData articleData) {
return new HashMap<String, Object>() {
{
put("article", articleData);
}
};
Map<String, Object> response = new HashMap<>();
response.put("article", articleData);
return response;
}
}
10 changes: 4 additions & 6 deletions src/main/java/io/spring/api/ArticlesApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.spring.core.article.Article;
import io.spring.core.user.User;
import java.util.HashMap;
import java.util.Map;
import javax.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.http.ResponseEntity;
Expand All @@ -29,12 +30,9 @@ public class ArticlesApi {
public ResponseEntity createArticle(
@Valid @RequestBody NewArticleParam newArticleParam, @AuthenticationPrincipal User user) {
Article article = articleCommandService.createArticle(newArticleParam, user);
return ResponseEntity.ok(
new HashMap<String, Object>() {
{
put("article", articleQueryService.findById(article.getId(), user).get());
}
});
Map<String, Object> response = new HashMap<>();
response.put("article", articleQueryService.findById(article.getId(), user).get());
return ResponseEntity.ok(response);
}

@GetMapping(path = "feed")
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/io/spring/api/CommentsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,9 @@ public ResponseEntity getComments(
Article article =
articleRepository.findBySlug(slug).orElseThrow(ResourceNotFoundException::new);
List<CommentData> comments = commentQueryService.findByArticleId(article.getId(), user);
return ResponseEntity.ok(
new HashMap<String, Object>() {
{
put("comments", comments);
}
});
Map<String, Object> response = new HashMap<>();
response.put("comments", comments);
return ResponseEntity.ok(response);
}

@RequestMapping(path = "{id}", method = RequestMethod.DELETE)
Expand All @@ -85,11 +82,9 @@ public ResponseEntity deleteComment(
}

private Map<String, Object> commentResponse(CommentData commentData) {
return new HashMap<String, Object>() {
{
put("comment", commentData);
}
};
Map<String, Object> response = new HashMap<>();
response.put("comment", commentData);
return response;
}
}

Expand Down
15 changes: 7 additions & 8 deletions src/main/java/io/spring/api/CurrentUserApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public ResponseEntity currentUser(
@AuthenticationPrincipal User currentUser,
@RequestHeader(value = "Authorization") String authorization) {
UserData userData = userQueryService.findById(currentUser.getId()).get();
return ResponseEntity.ok(
userResponse(new UserWithToken(userData, authorization.split(" ")[1])));
String token = io.spring.api.security.AuthorizationHeaderParser.extractTokenOrThrow(authorization);
return ResponseEntity.ok(userResponse(new UserWithToken(userData, token)));
}

@PutMapping
Expand All @@ -45,14 +45,13 @@ public ResponseEntity updateProfile(

userService.updateUser(new UpdateUserCommand(currentUser, updateUserParam));
UserData userData = userQueryService.findById(currentUser.getId()).get();
return ResponseEntity.ok(userResponse(new UserWithToken(userData, token.split(" ")[1])));
String extractedToken = io.spring.api.security.AuthorizationHeaderParser.extractTokenOrThrow(token);
return ResponseEntity.ok(userResponse(new UserWithToken(userData, extractedToken)));
}

private Map<String, Object> userResponse(UserWithToken userWithToken) {
return new HashMap<String, Object>() {
{
put("user", userWithToken);
}
};
Map<String, Object> response = new HashMap<>();
response.put("user", userWithToken);
return response;
}
}
8 changes: 3 additions & 5 deletions src/main/java/io/spring/api/UsersApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ public ResponseEntity userLogin(@Valid @RequestBody LoginParam loginParam) {
}

private Map<String, Object> userResponse(UserWithToken userWithToken) {
return new HashMap<String, Object>() {
{
put("user", userWithToken);
}
};
Map<String, Object> response = new HashMap<>();
response.put("user", userWithToken);
return response;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.spring.api.security;

import java.util.Optional;

public class AuthorizationHeaderParser {
private static final String BEARER_PREFIX = "Bearer ";
private static final int TOKEN_INDEX = 1;

public static Optional<String> extractToken(String authorizationHeader) {
if (authorizationHeader == null) {
return Optional.empty();
}

String[] parts = authorizationHeader.split(" ");
if (parts.length < 2) {
return Optional.empty();
}

return Optional.ofNullable(parts[TOKEN_INDEX]);
}

public static String extractTokenOrThrow(String authorizationHeader) {
return extractToken(authorizationHeader)
.orElseThrow(() -> new IllegalArgumentException("Invalid authorization header"));
}
}
11 changes: 1 addition & 10 deletions src/main/java/io/spring/api/security/JwtTokenFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,6 @@ protected void doFilterInternal(
}

private Optional<String> getTokenString(String header) {
if (header == null) {
return Optional.empty();
} else {
String[] split = header.split(" ");
if (split.length < 2) {
return Optional.empty();
} else {
return Optional.ofNullable(split[1]);
}
}
return AuthorizationHeaderParser.extractToken(header);
}
}
39 changes: 22 additions & 17 deletions src/main/java/io/spring/application/Page.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
package io.spring.application;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Getter;

@NoArgsConstructor
@Data
@Getter
public class Page {
private static final int DEFAULT_OFFSET = 0;
private static final int DEFAULT_LIMIT = 20;
private static final int MAX_LIMIT = 100;
private int offset = 0;
private int limit = 20;
private static final int MIN_OFFSET = 0;
private static final int MIN_LIMIT = 1;

private final int offset;
private final int limit;

public Page() {
this.offset = DEFAULT_OFFSET;
this.limit = DEFAULT_LIMIT;
}

public Page(int offset, int limit) {
setOffset(offset);
setLimit(limit);
this.offset = validateOffset(offset);
this.limit = validateLimit(limit);
}

private void setOffset(int offset) {
if (offset > 0) {
this.offset = offset;
}
private int validateOffset(int offset) {
return Math.max(offset, MIN_OFFSET);
}

private void setLimit(int limit) {
if (limit > MAX_LIMIT) {
this.limit = MAX_LIMIT;
} else if (limit > 0) {
this.limit = limit;
private int validateLimit(int limit) {
if (limit < MIN_LIMIT) {
return DEFAULT_LIMIT;
}
return Math.min(limit, MAX_LIMIT);
}
}
45 changes: 23 additions & 22 deletions src/main/java/io/spring/application/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,30 +77,31 @@ public boolean isValid(UpdateUserCommand value, ConstraintValidatorContext conte
String inputUsername = value.getParam().getUsername();
final User targetUser = value.getTargetUser();

boolean isEmailValid =
userRepository.findByEmail(inputEmail).map(user -> user.equals(targetUser)).orElse(true);
boolean isUsernameValid =
userRepository
.findByUsername(inputUsername)
.map(user -> user.equals(targetUser))
.orElse(true);
boolean isEmailValid = isFieldAvailableForUser(inputEmail, targetUser, userRepository::findByEmail);
boolean isUsernameValid = isFieldAvailableForUser(inputUsername, targetUser, userRepository::findByUsername);

if (isEmailValid && isUsernameValid) {
return true;
} else {
context.disableDefaultConstraintViolation();
if (!isEmailValid) {
context
.buildConstraintViolationWithTemplate("email already exist")
.addPropertyNode("email")
.addConstraintViolation();
}
if (!isUsernameValid) {
context
.buildConstraintViolationWithTemplate("username already exist")
.addPropertyNode("username")
.addConstraintViolation();
}
return false;
}

context.disableDefaultConstraintViolation();
if (!isEmailValid) {
addConstraintViolation(context, "email", "email already exist");
}
if (!isUsernameValid) {
addConstraintViolation(context, "username", "username already exist");
}
return false;
}

private boolean isFieldAvailableForUser(String fieldValue, User targetUser, java.util.function.Function<String, java.util.Optional<User>> finder) {
return finder.apply(fieldValue).map(user -> user.equals(targetUser)).orElse(true);
}

private void addConstraintViolation(ConstraintValidatorContext context, String property, String message) {
context
.buildConstraintViolationWithTemplate(message)
.addPropertyNode(property)
.addConstraintViolation();
}
}
16 changes: 11 additions & 5 deletions src/main/java/io/spring/core/article/Article.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,23 @@ public Article(
}

public void update(String title, String description, String body) {
if (!Util.isEmpty(title)) {
boolean updated = false;

if (!Util.isNullOrEmpty(title)) {
this.title = title;
this.slug = toSlug(title);
this.updatedAt = new DateTime();
updated = true;
}
if (!Util.isEmpty(description)) {
if (!Util.isNullOrEmpty(description)) {
this.description = description;
this.updatedAt = new DateTime();
updated = true;
}
if (!Util.isEmpty(body)) {
if (!Util.isNullOrEmpty(body)) {
this.body = body;
updated = true;
}

if (updated) {
this.updatedAt = new DateTime();
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/io/spring/core/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ public User(String email, String username, String password, String bio, String i
}

public void update(String email, String username, String password, String bio, String image) {
if (!Util.isEmpty(email)) {
if (!Util.isNullOrEmpty(email)) {
this.email = email;
}

if (!Util.isEmpty(username)) {
if (!Util.isNullOrEmpty(username)) {
this.username = username;
}

if (!Util.isEmpty(password)) {
if (!Util.isNullOrEmpty(password)) {
this.password = password;
}

if (!Util.isEmpty(bio)) {
if (!Util.isNullOrEmpty(bio)) {
this.bio = bio;
}

if (!Util.isEmpty(image)) {
if (!Util.isNullOrEmpty(image)) {
this.image = image;
}
}
Expand Down
Loading