Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix : 호스트 이벤트 접근 권한 설정 #459

Merged
merged 3 commits into from
Feb 26, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Page<EventProfileResponse> toEventProfileResponsePage(Long userId, Pageab
}

public Slice<EventProfileResponse> toEventProfileResponseSlice(Long userId, Pageable pageable) {
List<Host> hosts = hostAdaptor.findAllByHostUsers_UserId(userId);
List<Host> hosts = hostAdaptor.querySliceHostsByActiveUserId(userId);
List<Long> hostIds = hosts.stream().map(Host::getId).toList();
Slice<Event> events = eventAdaptor.querySliceEventsByHostIdIn(hostIds, pageable);
return events.map(event -> this.toEventProfileResponse(hosts, event));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class HostController {
private final UpdateHostUserRoleUseCase updateHostUserRoleUseCase;
private final InviteHostUseCase inviteHostUseCase;
private final JoinHostUseCase joinHostUseCase;
private final RejectHostUseCase rejectHostUseCase;

@Operation(summary = "내가 속한 호스트 리스트를 가져옵니다.")
@GetMapping
Expand Down Expand Up @@ -80,6 +81,12 @@ public HostDetailResponse joinHost(@PathVariable Long hostId) {
return joinHostUseCase.execute(hostId);
}

@Operation(summary = "호스트 초대를 거절합니다.")
@PostMapping("/{hostId}/reject")
public HostDetailResponse rejectHost(@PathVariable Long hostId) {
return rejectHostUseCase.execute(hostId);
}

@Operation(summary = "다른 유저를 호스트 유저로 초대합니다.")
@PostMapping("/{hostId}/invite")
public HostDetailResponse inviteHost(
Expand All @@ -95,7 +102,6 @@ public HostDetailResponse patchHostUserRole(
return updateHostUserRoleUseCase.execute(hostId, updateHostUserRoleRequest);
}

// todo :: 슈퍼 호스트 이상으로?
@Operation(summary = "호스트 정보를 변경합니다. 매니저 이상만 가능합니다.")
@PatchMapping("/{hostId}/profile")
public HostDetailResponse patchHostById(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package band.gosrock.api.host.service;

import static band.gosrock.api.common.aop.hostRole.FindHostFrom.HOST_ID;
import static band.gosrock.api.common.aop.hostRole.HostQualification.GUEST;

import band.gosrock.api.common.aop.hostRole.HostRolesAllowed;
import band.gosrock.api.common.page.PageResponse;
import band.gosrock.api.host.model.dto.response.HostEventProfileResponse;
import band.gosrock.common.annotation.UseCase;
Expand All @@ -18,6 +21,7 @@ public class ReadHostEventsUseCase {
private final HostAdaptor hostAdaptor;
private final EventAdaptor eventAdaptor;

@HostRolesAllowed(role = GUEST, findHostFrom = HOST_ID)
public PageResponse<HostEventProfileResponse> execute(Long hostId, Pageable pageable) {
Host host = hostAdaptor.findById(hostId);
return PageResponse.of(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package band.gosrock.api.host.service;


import band.gosrock.api.common.UserUtils;
import band.gosrock.api.host.model.dto.response.HostDetailResponse;
import band.gosrock.api.host.model.mapper.HostMapper;
import band.gosrock.common.annotation.UseCase;
import band.gosrock.domain.domains.host.adaptor.HostAdaptor;
import band.gosrock.domain.domains.host.domain.Host;
import band.gosrock.domain.domains.host.service.HostService;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

@UseCase
@RequiredArgsConstructor
public class RejectHostUseCase {

private final UserUtils userUtils;
private final HostService hostService;
private final HostAdaptor hostAdaptor;
private final HostMapper hostMapper;

@Transactional
public HostDetailResponse execute(Long hostId) {
final Long userId = userUtils.getCurrentUserId();
final Host host = hostAdaptor.findById(hostId);

return hostMapper.toHostDetailResponse(hostService.removeHostUser(host, userId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ public Page<Host> findAllByHostUsers_UserId(Long userId, Pageable pageable) {
public List<Host> findAllByHostUsers_UserId(Long userId) {
return hostRepository.findAllByHostUsers_UserId(userId);
}

/** 자신이 속해있는 호스트 리스트 중 초대 수락한 호스트만 가져오는 쿼리 요청 */
public List<Host> querySliceHostsByActiveUserId(Long userId) {
return hostRepository.queryHostsByActiveUserId(userId);
}

public Slice<Host> querySliceHostsByActiveUserId(Long userId, Pageable pageable) {
return hostRepository.querySliceHostsByActiveUserId(userId, pageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ public class Host extends BaseTimeEntity {
private String slackUrl;

// 단방향 oneToMany 매핑
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OneToMany(
mappedBy = "host",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.EAGER)
@OrderBy("createdAt DESC")
private final Set<HostUser> hostUsers = new HashSet<>();

Expand Down Expand Up @@ -113,6 +117,11 @@ public void setHostUserRole(Long userId, HostRole role) {
.setHostRole(role);
}

public void removeHostUser(Long userId) {
if (this.isActiveHostUserId(userId)) throw AlreadyJoinedHostException.EXCEPTION;
this.hostUsers.remove(this.getHostUserByUserId(userId));
}

/** 해당 유저가 호스트에 이미 속하는지 확인하는 검증 로직입니다 */
public void validateHostUserIdExistence(Long userId) {
if (this.hasHostUserId(userId)) {
Expand All @@ -124,8 +133,6 @@ public void validateHostUserExistence(HostUser hostUser) {
validateHostUserIdExistence(hostUser.getUserId());
}

// todo :: 여기서부터 테스트 진행

/** 해당 유저가 호스트에 속하는지 확인하는 검증 로직입니다 */
public void validateHostUser(Long userId) {
if (!this.hasHostUserId(userId)) throw ForbiddenHostException.EXCEPTION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class HostUser extends BaseTimeEntity {
private Long id;

// 소속 호스트 아이디
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "host_id")
private Host host;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@


import band.gosrock.domain.domains.host.domain.Host;
import java.util.List;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;

public interface HostCustomRepository {
Slice<Host> querySliceHostsByUserId(Long id, Pageable pageable);

List<Host> queryHostsByActiveUserId(Long id);

Slice<Host> querySliceHostsByActiveUserId(Long id, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import band.gosrock.domain.common.util.SliceUtil;
import band.gosrock.domain.domains.host.domain.Host;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -22,12 +24,51 @@ public Slice<Host> querySliceHostsByUserId(Long userId, Pageable pageable) {
queryFactory
.select(host)
.from(host, hostUser)
.where(hostUser.userId.eq(userId), host.hostUsers.contains(hostUser))
.where(hostUserIdEq(userId), host.hostUsers.contains(hostUser))
.offset(pageable.getOffset())
.orderBy(host.id.desc())
.orderBy(hostIdDesc())
.limit(pageable.getPageSize() + 1)
.fetch();

return SliceUtil.valueOf(hosts, pageable);
}

@Override
public List<Host> queryHostsByActiveUserId(Long userId) {
return queryFactory
.select(host)
.from(host, hostUser)
.where(hostUserIdEq(userId), host.hostUsers.contains(hostUser), hostUserActive())
.fetch();
}

@Override
public Slice<Host> querySliceHostsByActiveUserId(Long userId, Pageable pageable) {
List<Host> hosts =
queryFactory
.select(host)
.from(host, hostUser)
.where(
hostUserIdEq(userId),
host.hostUsers.contains(hostUser),
hostUserActive())
.offset(pageable.getOffset())
.orderBy(hostIdDesc())
.limit(pageable.getPageSize() + 1)
.fetch();

return SliceUtil.valueOf(hosts, pageable);
}

private BooleanExpression hostUserIdEq(Long userId) {
return hostUser.userId.eq(userId);
}

private BooleanExpression hostUserActive() {
return hostUser.active.isTrue();
}

private OrderSpecifier<Long> hostIdDesc() {
return host.id.desc();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public Host activateHostUser(Host host, Long userId) {
return hostRepository.save(host);
}

public Host removeHostUser(Host host, Long userId) {
host.removeHostUser(userId);
return hostRepository.save(host);
}

public void validateDuplicatedSlackUrl(Host host, String url) {
if (StringUtils.equals(host.getSlackUrl(), url)) {
throw InvalidSlackUrlException.EXCEPTION;
Expand Down