Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public CalenderDateServiceResponse readCalenderDates(Member member, Long memberI
Long partnerId = coupleReadService.getPartnerId(member);

DatingDatesServiceResponse datingDates = datingReadService.readDatingDates(
member, coupleId, year, month);
coupleId, year, month);
ScheduleDatesServiceResponse myScheduleDates = scheduleReadService.readScheduleDates(
member, memberId, year, month);
ScheduleDatesServiceResponse partnerScheduleDates = scheduleReadService.readScheduleDates(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,9 @@ public class DatingController {

@ResponseStatus(value = HttpStatus.CREATED)
@PostMapping("/{couple_id}/dating")
public ApiResponse<Void> createDating(
@PathVariable("couple_id") Long coupleId,
@Valid @RequestBody DatingCreateRequest request
) {
public ApiResponse<Void> createDating(@Valid @RequestBody DatingCreateRequest request) {
final Member member = MemberThreadLocal.get();
datingService.createDating(member, coupleId, request.toDatingCreateServiceRequest());
datingService.createDating(member, request.toDatingCreateServiceRequest());
return ApiResponse.ofSuccess();
}

Expand All @@ -50,43 +47,36 @@ public ApiResponse<DatingDatesResponse> readDatingDates(
@RequestParam(value = "year", required = false) Integer year,
@RequestParam(value = "month", required = false) Integer month
) {
final Member member = MemberThreadLocal.get();
DatingDatesServiceResponse response = datingReadService.readDatingDates(
member, coupleId, year, month);
DatingDatesServiceResponse response = datingReadService.readDatingDates(coupleId, year,
month);
return ApiResponse.ofSuccess(DatingDatesResponse.from(response));
}

@PutMapping("/{couple_id}/dating/{dating_id}")
public ApiResponse<Void> updateDating(
@PathVariable("couple_id") Long coupleId,
@PathVariable("dating_id") Long datingId,
@Valid @RequestBody DatingUpdateRequest request
) {
final Member member = MemberThreadLocal.get();
datingService.updateDating(member, coupleId, datingId,
request.toDatingUpdateServiceRequest());
datingService.updateDating(datingId, request.toDatingUpdateServiceRequest());
return ApiResponse.ofSuccess();
}

@GetMapping("/{couple_id}/dating")
public ApiResponse<DatingResponse> readDating(
@PathVariable("couple_id") Long coupleId,
@RequestParam("year") Integer year,
@RequestParam("month") Integer month,
@RequestParam("day") Integer day
) {
final Member member = MemberThreadLocal.get();
DatingServiceResponse response = datingReadService.readDating(member, coupleId, year, month,
day);
DatingServiceResponse response = datingReadService.readDating(coupleId, year, month, day);
return ApiResponse.ofSuccess(DatingResponse.from(response));
}

@DeleteMapping("/{couple_id}/dating/{dating_id}")
public ApiResponse<Void> deleteDating(
@PathVariable("couple_id") Long coupleId,
@PathVariable("dating_id") Long datingId
) {
final Member member = MemberThreadLocal.get();
datingService.deleteDating(member, coupleId, datingId);
datingService.deleteDating(datingId);
return ApiResponse.ofSuccess();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.dateplan.dateplan.domain.dating.interceptor;

import com.dateplan.dateplan.domain.couple.entity.Couple;
import com.dateplan.dateplan.domain.couple.service.CoupleReadService;
import com.dateplan.dateplan.domain.dating.entity.Dating;
import com.dateplan.dateplan.domain.dating.service.DatingReadService;
import com.dateplan.dateplan.domain.member.entity.Member;
import com.dateplan.dateplan.global.auth.MemberThreadLocal;
import com.dateplan.dateplan.global.constant.Operation;
import com.dateplan.dateplan.global.constant.Resource;
import com.dateplan.dateplan.global.exception.auth.NoPermissionException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.HandlerMapping;

@Component
@RequiredArgsConstructor
public class DatingAuthInterceptor implements HandlerInterceptor {

private final CoupleReadService coupleReadService;
private final DatingReadService datingReadService;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
Map<String, String> map = (Map<String, String>) request.getAttribute(
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
String method = request.getMethod();

Member member = MemberThreadLocal.get();
String coupleId = map.get("couple_id");
String datingId = map.get("dating_id");
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);

if (coupleId != null) {
if (isNotSameCouple(Long.valueOf(coupleId), couple.getId())) {
throwNoPermissionException(method);
}
if (datingId != null) {
Dating dating = datingReadService.findByDatingId(Long.valueOf(datingId));
if (isNotDatingOwner(Long.valueOf(coupleId), dating.getCouple().getId())) {
throwNoPermissionException(method);
}
}
}

return true;
}

private boolean isNotSameCouple(Long requestId, Long coupleId) {
return !Objects.equals(requestId, coupleId);
}

private boolean isNotDatingOwner(Long coupleId, Long datingOwnerId) {
return !Objects.equals(coupleId, datingOwnerId);
}

private void throwNoPermissionException(String method) {
Operation operation = switch (method) {
case "GET" -> Operation.READ;
case "POST" -> Operation.CREATE;
case "PUT" -> Operation.UPDATE;
default -> Operation.DELETE;
};
throw new NoPermissionException(Resource.DATING, operation);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
package com.dateplan.dateplan.domain.dating.service;

import com.dateplan.dateplan.domain.couple.entity.Couple;
import com.dateplan.dateplan.domain.couple.service.CoupleReadService;
import com.dateplan.dateplan.domain.dating.entity.Dating;
import com.dateplan.dateplan.domain.dating.repository.DatingQueryRepository;
import com.dateplan.dateplan.domain.dating.repository.DatingRepository;
import com.dateplan.dateplan.domain.dating.service.dto.response.DatingDatesServiceResponse;
import com.dateplan.dateplan.domain.dating.service.dto.response.DatingServiceResponse;
import com.dateplan.dateplan.domain.member.entity.Member;
import com.dateplan.dateplan.global.constant.Operation;
import com.dateplan.dateplan.global.constant.Resource;
import com.dateplan.dateplan.global.exception.auth.NoPermissionException;
import com.dateplan.dateplan.global.exception.dating.DatingNotFoundException;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -26,7 +19,6 @@
public class DatingReadService {

private final DatingQueryRepository datingQueryRepository;
private final CoupleReadService coupleReadService;
private final DatingRepository datingRepository;

public Dating findByDatingId(Long datingId) {
Expand All @@ -35,34 +27,21 @@ public Dating findByDatingId(Long datingId) {
}

public DatingServiceResponse readDating(
Member member,
Long coupleId,
Integer year,
Integer month,
Integer day
) {
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);
if (isNotSameCouple(coupleId, couple.getId())) {
throw new NoPermissionException(Resource.COUPLE, Operation.READ);
}

List<Dating> datingList = datingQueryRepository
.findByDateBetween(coupleId, year, month, day);
return DatingServiceResponse.from(datingList);
}

public DatingDatesServiceResponse readDatingDates(
Member member,
Long coupleId,
Integer year,
Integer month
) {
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);

if (isNotSameCouple(coupleId, couple.getId())) {
throw new NoPermissionException(Resource.COUPLE, Operation.READ);
}

List<Dating> datingList = datingQueryRepository.findByYearAndMonthOrderByDate(coupleId,
year, month);
return DatingDatesServiceResponse.builder()
Expand Down Expand Up @@ -101,8 +80,4 @@ private boolean checkDateRange(Integer year, Integer month, LocalDate date) {
}
return date.getYear() == year && date.getMonthValue() == month;
}

private boolean isNotSameCouple(Long requestId, Long coupleId) {
return !Objects.equals(requestId, coupleId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
import com.dateplan.dateplan.domain.dating.service.dto.request.DatingCreateServiceRequest;
import com.dateplan.dateplan.domain.dating.service.dto.request.DatingUpdateServiceRequest;
import com.dateplan.dateplan.domain.member.entity.Member;
import com.dateplan.dateplan.global.constant.Operation;
import com.dateplan.dateplan.global.constant.Resource;
import com.dateplan.dateplan.global.exception.auth.NoPermissionException;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -24,35 +20,19 @@ public class DatingService {
private final CoupleReadService coupleReadService;
private final DatingReadService datingReadService;

public void createDating(Member member, Long coupleId, DatingCreateServiceRequest request) {
public void createDating(Member member, DatingCreateServiceRequest request) {
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);

if (isNotSameCouple(coupleId, couple.getId())) {
throw new NoPermissionException(Resource.COUPLE, Operation.CREATE);
}

Dating dating = request.toDatingEntity(couple);
datingRepository.save(dating);
}

public void updateDating(
Member member,
Long coupleId,
Long datingId,
DatingUpdateServiceRequest request
) {
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);

if (isNotSameCouple(coupleId, couple.getId())) {
throw new NoPermissionException(Resource.COUPLE, Operation.UPDATE);
}

Dating dating = datingReadService.findByDatingId(datingId);

if (isNotDatingOwner(couple.getId(), dating.getCouple().getId())) {
throw new NoPermissionException(Resource.DATING, Operation.UPDATE);
}

dating.updateDating(
request.getTitle(),
request.getLocation(),
Expand All @@ -62,27 +42,9 @@ public void updateDating(
);
}

public void deleteDating(Member member, Long coupleId, Long datingId) {
Couple couple = coupleReadService.findCoupleByMemberOrElseThrow(member);

if (isNotSameCouple(coupleId, couple.getId())) {
throw new NoPermissionException(Resource.COUPLE, Operation.DELETE);
}

public void deleteDating(Long datingId) {
Dating dating = datingReadService.findByDatingId(datingId);

if (isNotDatingOwner(couple.getId(), dating.getCouple().getId())) {
throw new NoPermissionException(Resource.DATING, Operation.DELETE);
}

datingRepository.delete(dating);
}

private boolean isNotSameCouple(Long requestId, Long coupleId) {
return !Objects.equals(requestId, coupleId);
}

private boolean isNotDatingOwner(Long coupleId, Long datingOwnerId) {
return !Objects.equals(coupleId, datingOwnerId);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.dateplan.dateplan.global.config.web;

import com.dateplan.dateplan.domain.anniversary.interceptor.AnniversaryAuthInterceptor;
import com.dateplan.dateplan.domain.dating.interceptor.DatingAuthInterceptor;
import com.dateplan.dateplan.global.interceptor.AuthInterceptor;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
Expand All @@ -13,6 +14,7 @@ public class WebConfig implements WebMvcConfigurer {

private final AuthInterceptor authInterceptor;
private final AnniversaryAuthInterceptor anniversaryAuthInterceptor;
private final DatingAuthInterceptor datingAuthInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
Expand All @@ -24,5 +26,9 @@ public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(anniversaryAuthInterceptor)
.addPathPatterns("/api/couples/**/anniversary/**");

registry
.addInterceptor(datingAuthInterceptor)
.addPathPatterns("/api/couples/**/dating/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.dateplan.dateplan.domain.couple.service.CoupleReadService;
import com.dateplan.dateplan.domain.couple.service.CoupleService;
import com.dateplan.dateplan.domain.dating.controller.DatingController;
import com.dateplan.dateplan.domain.dating.interceptor.DatingAuthInterceptor;
import com.dateplan.dateplan.domain.dating.service.DatingReadService;
import com.dateplan.dateplan.domain.dating.service.DatingService;
import com.dateplan.dateplan.domain.member.controller.AuthController;
Expand Down Expand Up @@ -89,4 +90,7 @@ public abstract class ControllerTestSupport {

@MockBean
protected CalenderReadService calenderReadService;

@MockBean
protected DatingAuthInterceptor datingAuthInterceptor;
}
Loading