Skip to content

Commit

Permalink
fix: 머지 충돌 해결 (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
seok019283501 committed Nov 27, 2024
2 parents b9558fe + 9bb1c19 commit 996cc11
Show file tree
Hide file tree
Showing 23 changed files with 174 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.ioteatime.meonghanyangserver.auth.dto.db;

import org.ioteatime.meonghanyangserver.groupmember.doamin.enums.GroupMemberRole;

public record LoginWithMemberInfo(
Long memberId,
String nickname,
String password,
boolean isGroupMember,
GroupMemberRole role) {}
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
package org.ioteatime.meonghanyangserver.auth.dto.reponse;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;
import org.ioteatime.meonghanyangserver.groupmember.doamin.enums.GroupMemberRole;

@JsonInclude(JsonInclude.Include.NON_NULL)
public record LoginResponse(
@NotNull @Schema(description = "회원 ID", example = "1") Long memberId,
@NotBlank @Schema(description = "회원 AccessToken", example = "Bearer abcd...")
String accessToken,
@NotBlank @Schema(description = "회원 RefreshToken", example = "Bearer abcd...")
String refreshToken) {
String refreshToken,
@NotNull @Schema(description = "회원이 가입한 그룹이 있는지 여부", example = "true")
Boolean isGroupMember,
@Schema(description = "회원의 그룹 역할", example = "MASTER") GroupMemberRole role) {

@Builder
public LoginResponse(Long memberId, String accessToken, String refreshToken) {
public LoginResponse(
Long memberId,
String accessToken,
String refreshToken,
Boolean isGroupMember,
GroupMemberRole role) {
this.memberId = memberId;
this.accessToken = accessToken;
this.refreshToken = refreshToken;
this.isGroupMember = isGroupMember;
this.role = role;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ioteatime.meonghanyangserver.auth.mapper;

import org.ioteatime.meonghanyangserver.auth.dto.db.LoginWithMemberInfo;
import org.ioteatime.meonghanyangserver.auth.dto.reponse.LoginResponse;
import org.ioteatime.meonghanyangserver.auth.dto.reponse.RefreshResponse;
import org.ioteatime.meonghanyangserver.member.dto.response.MemberSimpleResponse;
Expand All @@ -9,11 +10,14 @@ public static MemberSimpleResponse from(Long id, String email) {
return new MemberSimpleResponse(id, email);
}

public static LoginResponse from(Long id, String accessToken, String refreshToken) {
public static LoginResponse from(
LoginWithMemberInfo memberInfo, String accessToken, String refreshToken) {
return LoginResponse.builder()
.memberId(id)
.memberId(memberInfo.memberId())
.accessToken(accessToken)
.refreshToken(refreshToken)
.isGroupMember(memberInfo.isGroupMember())
.role(memberInfo.role())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
import lombok.RequiredArgsConstructor;
import org.ioteatime.meonghanyangserver.auth.dto.db.LoginWithMemberInfo;
import org.ioteatime.meonghanyangserver.auth.dto.reponse.LoginResponse;
import org.ioteatime.meonghanyangserver.auth.dto.request.LoginRequest;
import org.ioteatime.meonghanyangserver.auth.mapper.AuthEntityMapper;
Expand Down Expand Up @@ -39,34 +40,36 @@ public class AuthService {
private final RefreshTokenRepository refreshTokenRepository;

public LoginResponse login(LoginRequest loginRequest) {
MemberEntity memberEntity =
LoginWithMemberInfo memberInfo =
memberRepository
.findByEmail(loginRequest.email())
.findGroupMemberInfoByEmail(loginRequest.email())
.orElseThrow(() -> new NotFoundException(AuthErrorType.NOT_FOUND));

boolean passwordMatch =
bCryptPasswordEncoder.matches(loginRequest.password(), memberEntity.getPassword());
bCryptPasswordEncoder.matches(loginRequest.password(), memberInfo.password());
if (!passwordMatch) {
throw new BadRequestException(AuthErrorType.PASSWORD_NOT_MATCH);
}

String accessToken = jwtUtils.generateAccessToken(memberEntity);
String refreshToken = jwtUtils.generateRefreshToken(memberEntity);
String accessToken =
jwtUtils.generateAccessToken(memberInfo.nickname(), memberInfo.memberId());
String refreshToken =
jwtUtils.generateRefreshToken(memberInfo.nickname(), memberInfo.memberId());

if (accessToken.isEmpty() || refreshToken.isEmpty()) {
throw new NotFoundException(AuthErrorType.TOKEN_NOT_FOUND);
}
RefreshToken refreshTokenEntity =
RefreshToken.builder()
.memberId(memberEntity.getId())
.memberId(memberInfo.memberId())
.refreshToken(refreshToken)
.build();

refreshTokenRepository.save(refreshTokenEntity);
accessToken = jwtUtils.includeBearer(accessToken);
refreshToken = jwtUtils.includeBearer(refreshToken);

return AuthResponseMapper.from(memberEntity.getId(), accessToken, refreshToken);
return AuthResponseMapper.from(memberInfo, accessToken, refreshToken);
}

public MemberSimpleResponse joinProcess(JoinRequest userDto) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public Api<?> out(@LoginMember Long userId, @PathVariable("cctvId") Long cctvId)

@GetMapping("/list/{groupId}")
public Api<CctvInfoListResponse> cctvInfoList(
@LoginMember Long memberId, @PathVariable Long groupId) {
@LoginMember Long memberId, @PathVariable("groupId") Long groupId) {
CctvInfoListResponse cctvInfoListResponse = cctvService.cctvInfoList(memberId, groupId);
return Api.success(CctvSuccessType.GET_CCTV_DETAIL_LIST, cctvInfoListResponse);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.ioteatime.meonghanyangserver.cctv.mapper;

import java.util.List;
import org.ioteatime.meonghanyangserver.cctv.domain.CctvEntity;
import org.ioteatime.meonghanyangserver.cctv.dto.response.CctvInfoListResponse;
import org.ioteatime.meonghanyangserver.cctv.dto.response.CctvInfoResponse;

public class CctvResponseMapper {
Expand All @@ -11,4 +13,8 @@ public static CctvInfoResponse from(CctvEntity cctvEntity) {
cctvEntity.getThingId(),
cctvEntity.getKvsChannelName());
}

public static CctvInfoListResponse from(List<CctvInfoResponse> cctvInfoResponseList) {
return new CctvInfoListResponse(cctvInfoResponseList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.ioteatime.meonghanyangserver.common.type.GroupErrorType;
import org.ioteatime.meonghanyangserver.group.domain.GroupEntity;
import org.ioteatime.meonghanyangserver.group.repository.GroupRepository;
import org.ioteatime.meonghanyangserver.groupmember.doamin.GroupMemberEntity;
import org.ioteatime.meonghanyangserver.groupmember.doamin.enums.GroupMemberRole;
import org.ioteatime.meonghanyangserver.groupmember.repository.GroupMemberRepository;
import org.springframework.stereotype.Service;

Expand Down Expand Up @@ -82,29 +84,36 @@ public CctvInfoResponse cctvInfo(Long cctvId) {
}

public CctvInfoListResponse cctvInfoList(Long memberId, Long groupId) {
if (!groupMemberRepository.existsByMemberIdAndGroupId(memberId, groupId)) {
throw new BadRequestException(GroupErrorType.GROUP_MEMBER_NOT_FOUND);
}
validateMaster(memberId, groupId);
List<CctvEntity> cctvEntityList = cctvRepository.findByGroupId(groupId);
List<CctvInfoResponse> cctvInfoResponseList =
cctvEntityList.stream().map(CctvResponseMapper::from).toList();
CctvInfoListResponse cctvInfoListResponse = new CctvInfoListResponse(cctvInfoResponseList);
return cctvInfoListResponse;
return CctvResponseMapper.from(cctvInfoResponseList);
}

@Transactional
public CctvInfoResponse updateNickname(Long memberId, UpdateCctvNickname request) {
// cctvId로 cctv 객체 찾기
// CctvId로 cctv 객체 찾기
CctvEntity cctvEntity =
cctvRepository
.findById(request.cctvId())
.orElseThrow(() -> new NotFoundException(CctvErrorType.NOT_FOUND));
// groupId와 memberId로 groupMember가 존재하는지 확인 -> 아니면 에러
groupMemberRepository
.findByGroupIdAndMemberId(cctvEntity.getGroup().getId(), memberId)
.orElseThrow(() -> new NotFoundException(GroupErrorType.GROUP_MEMBER_NOT_FOUND));
validateMaster(memberId, cctvEntity.getGroup().getId());
// cctv 이름 변경
cctvEntity = cctvEntity.updateNickname(request.cctvNickname());
return CctvResponseMapper.from(cctvEntity);
}

private void validateMaster(Long memberId, Long groupId) {
// GroupId와 memberId로 groupMember가 존재하는지 확인 -> 아니면 에러
GroupMemberEntity groupMemberEntity =
groupMemberRepository
.findByGroupIdAndMemberId(groupId, memberId)
.orElseThrow(
() -> new NotFoundException(GroupErrorType.GROUP_MEMBER_NOT_FOUND));
// Member가 Master인지 확인 -> 아니면 에러
if (groupMemberEntity.getRole() != GroupMemberRole.ROLE_MASTER) {
throw new BadRequestException(GroupErrorType.ONLY_MASTER);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ public enum GroupErrorType implements ErrorTypeCode {
ONLY_MASTER_REMOVE_GROUP_MASTER("BAD REQUEST", "방장은 자신을 제외시킬 수 있습니다."),
GROUP_MEMBER_NOT_FOUND("GROUP MEMBER NOT FOUND", "그룹 회원 정보를 찾을 수 없습니다."),
GROUP_MEMBER_NOT_FOUND_IN_GROUP("GROUP MEMBER NOT FOUND", "회원이 그룹에 속해 있지 않습니다."),
ONLY_MASTER_GET_GROUP_MEMBER_INFO("BAD REQUEST", "방장만 그룹 참여자 정보를 받을 수 있습니다.");
ONLY_MASTER_GET_GROUP_MEMBER_INFO("BAD REQUEST", "방장만 그룹 참여자 정보를 받을 수 있습니다."),
ONLY_MASTER_UPDATE_CCTV_NICKNAME("BAD REQUEST", "방장만 그룹의 CCTV 이름을 변경할 수 있습니다."),
ONLY_MASTER("BAD REQUEST", "방장 권한이 없습니다.");

private final String message;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ public JwtUtils(Environment env, AccessTokenRepository accessTokenRepository) {
this.key = Keys.hmacShaKeyFor(decodedKey);
}

public String generateAccessToken(MemberEntity memberEntity) {
public String generateAccessToken(String nickname, Long memberId) {
Date nowDate = new Date();
Date expiration = new Date(nowDate.getTime() + Duration.ofHours(2).toMillis());
String jwtToken =
Jwts.builder()
.claim("name", memberEntity.getNickname())
.claim("name", nickname)
.claim("sub", "meong-ha-nyang")
.claim("jti", String.valueOf(memberEntity.getId()))
.claim("jti", String.valueOf(memberId))
.claim("iat", nowDate)
.claim("exp", expiration)
.signWith(key)
Expand All @@ -44,14 +44,14 @@ public String generateAccessToken(MemberEntity memberEntity) {
return jwtToken;
}

public String generateRefreshToken(MemberEntity memberEntity) {
public String generateRefreshToken(String nickname, Long memberId) {
Date nowDate = new Date();
Date expiration = new Date(nowDate.getTime() + Duration.ofDays(30).toMillis());
String jwtToken =
Jwts.builder()
.claim("name", memberEntity.getNickname())
.claim("name", nickname)
.claim("sub", "meong-ha-nyang")
.claim("jti", String.valueOf(memberEntity.getId()))
.claim("jti", String.valueOf(memberId))
.claim("iat", nowDate)
.claim("exp", expiration)
.signWith(key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

@Configuration
@EnableRedisRepositories(
enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP,
keyspaceNotificationsConfigParameter = "")
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
import java.time.LocalDateTime;
import java.util.List;
import org.ioteatime.meonghanyangserver.cctv.dto.response.CctvInfoResponse;
import org.ioteatime.meonghanyangserver.groupmember.dto.response.GroupMemberInfoResponse;

@Schema(description = "그룹 통합 정보 응답")
public record GroupTotalResponse(
@NotNull Long groupId,
@NotBlank String groupName,
@NotNull LocalDateTime createdAt,
List<GroupMemberInfoResponse> member,
List<CctvInfoResponse> cctv) {}
@NotNull @Schema(description = "그룹 ID", example = "1") Long groupId,
@NotBlank @Schema(description = "그룹 이름", example = "멍하냥 그룹") String groupName,
@NotNull @Schema(description = "그룹 생성 시간", example = "2024-10-10 15:00")
LocalDateTime createdAt,
@Schema(description = "그룹의 CCTV 정보 목록") List<CctvInfoResponse> cctv) {}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import org.ioteatime.meonghanyangserver.group.dto.response.CreateGroupResponse;
import org.ioteatime.meonghanyangserver.group.dto.response.GroupTotalResponse;
import org.ioteatime.meonghanyangserver.group.dto.response.UpdateNicknameAndGroupNameResponse;
import org.ioteatime.meonghanyangserver.groupmember.dto.response.GroupMemberInfoResponse;
import org.ioteatime.meonghanyangserver.groupmember.mapper.GroupMemberResponseMapper;

public class GroupResponseMapper {
public static CreateGroupResponse from(GroupEntity groupEntity) {
Expand All @@ -17,19 +15,13 @@ public static CreateGroupResponse from(GroupEntity groupEntity) {
}

public static GroupTotalResponse fromGroupTotal(GroupEntity groupEntity) {
List<GroupMemberInfoResponse> deviceInfoResponseList =
groupEntity.getGroupMemberEntities().stream()
.map(GroupMemberResponseMapper::from)
.toList();

List<CctvInfoResponse> cctvInfoResponseList =
groupEntity.getCctvEntities().stream().map(CctvResponseMapper::from).toList();

return new GroupTotalResponse(
groupEntity.getId(),
groupEntity.getGroupName(),
groupEntity.getCreatedAt(),
deviceInfoResponseList,
cctvInfoResponseList);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public Api<?> deleteMasterGroupMember(
@PathVariable Long groupId,
@PathVariable Long groupMemberId);

@Operation(summary = "그룹에서 참여자를 제외합니다.", description = "담당자: 최민석")
@Operation(summary = "그룹에서 참여자가 스스로 퇴장합니다.", description = "담당자: 최민석")
public Api<?> deleteGroupMember(@LoginMember Long memberId, @PathVariable Long groupId);

@Operation(summary = "그룹 참여자들의 정보를 조회합니다.", description = "담당자: 최민석")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.ioteatime.meonghanyangserver.group.dto.response.UpdateNicknameAndGroupNameResponse;
import org.ioteatime.meonghanyangserver.member.dto.request.ChangePasswordRequest;
import org.ioteatime.meonghanyangserver.member.dto.request.UpdateNicknameAndGroupNameRequest;
import org.ioteatime.meonghanyangserver.member.dto.response.MemberDetailResponse;
import org.ioteatime.meonghanyangserver.member.dto.response.MemberWithGroupDetailResponse;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
Expand All @@ -17,7 +17,7 @@
public interface MemberApi {

@Operation(summary = "회원 상세 정보를 조회합니다.", description = "담당자: 임지인")
Api<MemberDetailResponse> getMemberDetail(@PathVariable("memberId") Long memberId);
Api<MemberWithGroupDetailResponse> getMemberDetail(@PathVariable("memberId") Long memberId);

@Operation(summary = "회원 정보를 삭제합니다.", description = "담당자: 임지인")
Api<Object> deleteMember(@LoginMember Long memberId);
Expand All @@ -35,7 +35,4 @@ Api<Object> changeMemberPassword(
"담당자: 양원채\n\n닉네임 또는 그룹명을 갱신할 수 있으며, 한꺼번에 갱신도 가능합니다.\n\n갱신하고 싶지 않은 필드는 아예 적지 않거나 null로 담아 요청하시면 됩니다. 응답으로는 변경된 사항만 응답합니다.")
Api<UpdateNicknameAndGroupNameResponse> updateNicknameAndGroupName(
@LoginMember Long memberId, @RequestBody UpdateNicknameAndGroupNameRequest request);

@Operation(summary = "로그아웃을 진행합니다.", description = "담당자: 최민석")
Api<?> logout();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import org.ioteatime.meonghanyangserver.group.dto.response.UpdateNicknameAndGroupNameResponse;
import org.ioteatime.meonghanyangserver.member.dto.request.ChangePasswordRequest;
import org.ioteatime.meonghanyangserver.member.dto.request.UpdateNicknameAndGroupNameRequest;
import org.ioteatime.meonghanyangserver.member.dto.response.MemberDetailResponse;
import org.ioteatime.meonghanyangserver.member.dto.response.MemberWithGroupDetailResponse;
import org.ioteatime.meonghanyangserver.member.service.MemberService;
import org.springframework.web.bind.annotation.*;

Expand All @@ -21,8 +21,9 @@ public class MemberController implements MemberApi {
private final MemberService memberService;

@GetMapping("/{memberId}")
public Api<MemberDetailResponse> getMemberDetail(@PathVariable("memberId") Long memberId) {
MemberDetailResponse userDto = memberService.getMemberDetail(memberId);
public Api<MemberWithGroupDetailResponse> getMemberDetail(
@PathVariable("memberId") Long memberId) {
MemberWithGroupDetailResponse userDto = memberService.getMemberDetail(memberId);
return Api.success(AuthSuccessType.GET_USER_DETAIL, userDto);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.ioteatime.meonghanyangserver.member.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import org.ioteatime.meonghanyangserver.group.domain.GroupEntity;

@Schema(description = "그룹의 상세 정보 조회")
public record GroupDetailResponse(
@NotNull @Schema(description = "그룹 ID", example = "1") Long id,
@NotNull @Schema(description = "그룹 이름", example = "멍하냥 그룹") String groupName) {
public static GroupDetailResponse from(GroupEntity group) {
return new GroupDetailResponse(group.getId(), group.getGroupName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.ioteatime.meonghanyangserver.member.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;

@Schema(description = "회원 및 그룹 정보 조회")
public record MemberWithGroupDetailResponse(
@NotNull @Schema(description = "회원 정보") MemberDetailResponse member,
@Schema(description = "그룹 정보") GroupDetailResponse group) {
@Builder
public MemberWithGroupDetailResponse(MemberDetailResponse member, GroupDetailResponse group) {
this.member = member;
this.group = group;
}
}
Loading

0 comments on commit 996cc11

Please sign in to comment.