Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
@SpringBootApplication
@EnableJpaAuditing
@EntityScan(basePackages = "com.neighbors.tohero.infrastructure.entity")
public class SantaApplication {
public class ToHeroApplication {

public static void main(String[] args) {
SpringApplication.run(SantaApplication.class, args);
SpringApplication.run(ToHeroApplication.class, args);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ public enum BaseResponseMessage {
//address
주소_검색_쿼리의_길이는_1부터_50까지만_가능합니다("주소 검색 쿼리의 길이는 1부터 50까지만 가능합니다"),
일치하는_관할서_정보가_없습니다("일치하는 관할서 정보가 없습니다"),
주소_검색이_성공적으로_응답되었습니다("주소 검색이 성공적으로 응답되었습니다");
주소_검색이_성공적으로_응답되었습니다("주소 검색이 성공적으로 응답되었습니다"),

//letter
편지가_성공적으로_생성_되었습니다("편지가 성공적으로 생성 되었습니다"),
편지_생성이_실패_했습니다("편지 생성이 실패했습니다");

private final String message;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
package com.neighbors.tohero.application.letter.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.neighbors.tohero.common.enums.TargetJob;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Length;

public record CreateLetterRequest (
@NotBlank
@Length(min =1, max = 1000)
String content,

@JsonInclude(JsonInclude.Include.NON_NULL)
TargetJob targetJob,

@JsonInclude(JsonInclude.Include.NON_NULL)
Long addressId,

@JsonInclude(JsonInclude.Include.NON_NULL)
@Length(min = 1, max = 100)
String heroName,

@JsonInclude(JsonInclude.Include.NON_NULL)
Boolean readingAlarm,

@NotNull
boolean isPublic
){
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.neighbors.tohero.application.letter.dto;

public record CreateLetterResponse(
long createdLetterId
) {
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,86 @@
package com.neighbors.tohero.application.letter.service;

import com.neighbors.tohero.application.baseResponse.BaseResponse;
import com.neighbors.tohero.application.baseResponse.BaseResponseMessage;
import com.neighbors.tohero.application.baseResponse.BaseResponseStatus;
import com.neighbors.tohero.application.letter.dto.CreateLetterRequest;
import com.neighbors.tohero.application.letter.dto.CreateLetterResponse;
import com.neighbors.tohero.common.enums.Role;
import com.neighbors.tohero.common.exception.address.AddressException;
import com.neighbors.tohero.common.exception.letter.LetterException;
import com.neighbors.tohero.common.jwt.JwtUserDetails;
import com.neighbors.tohero.domain.domain.address.service.GetAddress;
import com.neighbors.tohero.domain.domain.letter.service.CreateLetter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class LetterService {

public BaseResponse createLetter(CreateLetterRequest createLetterRequest) {
return null;
private final CreateLetter createLetter;
private final GetAddress getAddress;

public BaseResponse<CreateLetterResponse> createLetter(final JwtUserDetails jwtUserDetail, final CreateLetterRequest createLetterRequest) {

throwExceptionIfAddressIsNotExist(createLetterRequest.addressId());

if(jwtUserDetail.getRole() == Role.GUEST){
return createGuestLetter(jwtUserDetail.getNickname(), createLetterRequest);
}
long createdLetterId = createLetter.createLetter(
jwtUserDetail.getUserId(),
jwtUserDetail.getNickname(),
createLetterRequest
);

throwIfLetterNotCreate(createdLetterId);

return new BaseResponse<>(
BaseResponseStatus.OK,
BaseResponseMessage.편지가_성공적으로_생성_되었습니다.getMessage(),
new CreateLetterResponse(createdLetterId)
);
}

private BaseResponse<CreateLetterResponse> createGuestLetter(final String nickname, final CreateLetterRequest createLetterRequest) {
long createdLetterId = createLetter.createGuestLetter(
nickname,
createLetterRequest.content(),
createLetterRequest.targetJob(),
createLetterRequest.addressId(),
createLetterRequest.heroName(),
createLetterRequest.isPublic()
);

throwIfLetterNotCreate(createdLetterId);

return new BaseResponse<>(
BaseResponseStatus.OK,
BaseResponseMessage.편지가_성공적으로_생성_되었습니다.getMessage(),
new CreateLetterResponse(createdLetterId)
);
}

private void throwExceptionIfAddressIsNotExist(final Long addressId){
if(addressId == null) {return ;}
if(!getAddress.existAddressById(addressId)){
throw new AddressException(
BaseResponseStatus.NO_RESULT,
BaseResponseMessage.일치하는_관할서_정보가_없습니다.getMessage()
);
}
}

private void throwIfLetterNotCreate(final long createdLetterId){
if(createdLetterId == 0){
throw new LetterException(
BaseResponseStatus.BAD_REQUEST,
BaseResponseMessage.편지_생성이_실패_했습니다.getMessage()
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ public record OpenedLetter(
String content
){
public static OpenedLetter from(Letter letter){
return new OpenedLetter(letter.getTargetName(), letter.getFromUserName(), letter.getLetterContent());
return new OpenedLetter(letter.getTargetName(), letter.getWriter(), letter.getLetterContent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.ArrayList;
import java.util.List;

@Configuration
Expand Down Expand Up @@ -55,9 +56,6 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.formLogin(AbstractHttpConfigurer::disable) //form login 비활성화
.httpBasic(AbstractHttpConfigurer::disable)//http 기본 인증 비활성화
.cors(Customizer.withDefaults())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated())
.sessionManagement(session -> {
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
})
Expand All @@ -75,7 +73,11 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 쿠키 포함 허용
config.setAllowedOrigins(List.of("http://localhost:5173", "https://glittery-madeleine-215e2f.netlify.app")); // 허용할 도메인
// 여러 도메인 허용
List<String> allowedOrigins = new ArrayList<>();
allowedOrigins.add("https://glittery-madeleine-215e2f.netlify.app");
allowedOrigins.add("https://tohero.co.kr");
config.setAllowedOrigins(allowedOrigins); // 여러 도메인 추가
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 허용할 HTTP 메서드
config.setAllowedHeaders(List.of("*")); // 모든 헤더 허용
config.setExposedHeaders(List.of("Authorization")); // 노출할 헤더
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public OpenAPI openAPI() {
.addSecurityItem(securityRequirement)
.components(components)
.servers(Arrays.asList(new Server().url("https://tohero.co.kr"),
new Server().url("http://localhost:8080"),new Server().url("https://tohero.co.kr")));
new Server().url("http://localhost:8080")));
}
private Info apiInfo() {
return new Info()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.neighbors.tohero.common.exception.letter;

import com.neighbors.tohero.application.baseResponse.BaseResponseStatus;

public class LetterException extends RuntimeException {

private final BaseResponseStatus status;
private final String message;

public LetterException(BaseResponseStatus status, String message) {
super(message);
this.status = status;
this.message = message;
}
}
14 changes: 12 additions & 2 deletions src/main/java/com/neighbors/tohero/common/jwt/JwtProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public AuthTokens createToken(JwtUserDetails jwtUserDetails) {

claims.put("role", jwtUserDetails.getRole());
if(jwtUserDetails.getRole() == Role.USER) {
claims.put("id", jwtUserDetails.getUserId());
claims.put("userId", jwtUserDetails.getUserId());
claims.put("email", jwtUserDetails.getEmail());
}

Expand Down Expand Up @@ -105,7 +105,7 @@ public void loggingToken(String token) {

public Long getId(String token) {
Claims claims = getBody(token);
return Long.parseLong(claims.get("id").toString());
return Long.parseLong(claims.get("userId").toString());
}

private Claims getBody(String token) {
Expand All @@ -131,4 +131,14 @@ public JwtUserDetails getJwtUserDetails(String token) {
.build();

}

public JwtUserDetails getGuestJwtUserDetails(String token) {
Claims claims = getBody(token);

return JwtUserDetails.builder()
.nickname(String.valueOf(claims.getSubject()))
.role(Role.valueOf(claims.get("role").toString()))
.build();

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.neighbors.tohero.common.security;

import com.neighbors.tohero.common.enums.Role;
import com.neighbors.tohero.common.jwt.JwtProvider;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -29,8 +30,8 @@ public void setAuthenticationFromRequest(HttpServletRequest request) {
});
}

private Boolean isRequestAvailableToGuest(HttpServletRequest request) {
return request.getRequestURI().contains("/realEstate") && request.getMethod().equals("GET");
private Boolean isRequestAvailableToGuest(String token) {
return jwtProvider.getGuestJwtUserDetails(token).getRole() == Role.GUEST;
}

private Optional<UserAuthentication> makeAuthentication(HttpServletRequest request, String token) {
Expand All @@ -40,12 +41,15 @@ private Optional<UserAuthentication> makeAuthentication(HttpServletRequest reque
UserAuthentication authentication = null;

if(isTokenValid(token)) {
String role = jwtProvider.getJwtUserDetails(token).getRole().toString();
log.info("[AuthenticationUtil.makeAuthentication : {} 권한 부여]", role);
authentication = UserAuthentication.from(jwtProvider.getJwtUserDetails(token));
} else if (isRequestAvailableToGuest(request)) {
log.info("[AuthenticationUtil.makeAuthentication : Guest 권한 부여]");
// authentication = UserAuthentication.makeGuestAuthentication();
if (isRequestAvailableToGuest(token)) {
log.info("[AuthenticationUtil.makeAuthentication : Guest 권한 부여]");
String nickname = jwtProvider.getGuestJwtUserDetails(token).getNickname();
authentication = UserAuthentication.makeGuestAuthentication(nickname);
}
else {
log.info("[AuthenticationUtil.makeAuthentication : User 권한 부여]");
authentication = UserAuthentication.from(jwtProvider.getJwtUserDetails(token));
}
}

if(authentication != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ public static UserAuthentication from(JwtUserDetails jwtUserDetails) {
return new UserAuthentication(jwtUserDetails, null, jwtUserDetails.getRole().getAuthority());
}

// public static UserAuthentication makeGuestAuthentication() {
// return new UserAuthentication(JwtUserDetails.makeGuestJwtDetails(), null, Role.GUEST.getAuthority());
// }
public static UserAuthentication makeGuestAuthentication(String nickname) {
return new UserAuthentication(JwtUserDetails.makeGuestJwtDetails(nickname), null, Role.GUEST.getAuthority());
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.neighbors.tohero.domain.domain.address.model;

import com.neighbors.tohero.common.enums.TargetJob;
import lombok.AllArgsConstructor;
import lombok.Getter;

Expand All @@ -11,8 +12,9 @@ public class Address {
private String roadAddress;
private String phoneNumber;
private String queryPath;
private TargetJob targetJob;

public static Address of(long addressId, String officeName, String roadAddress, String phoneNumber, String queryPath){
return new Address(addressId, officeName, roadAddress, phoneNumber, queryPath);
public static Address of(long addressId, String officeName, String roadAddress, String phoneNumber, String queryPath, TargetJob targetJob){
return new Address(addressId, officeName, roadAddress, phoneNumber, queryPath, targetJob);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@ public List<Address> searchAddressByOfficeName(String queryPath, TargetJob targe
public List<Address> searchAddressByRoadAddress(String queryRoadAddress, TargetJob targetJob){
return addressRepository.searchAddressByRoadAddress(queryRoadAddress, targetJob);
}

public boolean existAddressById(long addressId) {
return addressRepository.existAddressById(addressId);
}
}
Loading
Loading