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

feat: 어드민 기능 구현 (유저 조회, 권한 변경, 회원 탈퇴, 팀 소개 수정) #12

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
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 @@ -12,9 +12,11 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
@Setter
@Table(name = "introduction")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Introduction {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.gdscuos.recruit.global.auth.api;

import com.gdscuos.recruit.global.auth.dto.UpdateIntroAboutDTO;
import com.gdscuos.recruit.global.auth.dto.UpdateIntroActivityDTO;
import com.gdscuos.recruit.global.auth.dto.UpdateIntroTargetDTO;
import com.gdscuos.recruit.global.auth.dto.UserDTO;
import com.gdscuos.recruit.global.auth.service.AdminService;
import com.gdscuos.recruit.global.common.Role;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/api/admin")
public class AdminController {
/*
리드 멤버만 사용할 수 있는 기능입니다.
*/

private final AdminService adminService;

public AdminController(AdminService adminService) {
this.adminService = adminService;
}

// 유저 리스트 반환
@GetMapping("/userList")
public ResponseEntity<List<UserDTO>> showUserList(HttpServletRequest request) {

return ResponseEntity.ok().body(adminService.getUserList(request));
}

// 유저의 권한 변경 (지원자|멤버|코어|리드)
@PatchMapping("/role/{userId}")
public ResponseEntity<Void> changeUserRole(HttpServletRequest request, @PathVariable Long userId, Role role) {

adminService.changeUserRole(request, userId, role);
return ResponseEntity.ok().build();
}

// 회원탈퇴
@DeleteMapping("/withdrawal/{userId}")
public ResponseEntity<Void> deleteUser(HttpServletRequest request, @PathVariable Long userId) {

adminService.deleteUser(request, userId);
return ResponseEntity.ok().build();
}

// 특정 팀의 소개 변경
@PatchMapping("/introduction/about")
public ResponseEntity<Void> changeTeamAbout(HttpServletRequest request, UpdateIntroAboutDTO updateIntroAboutDTO) {

adminService.changeTeamAbout(request, updateIntroAboutDTO);
return ResponseEntity.ok().build();
}

// 특정 팀의 활동 내용 변경
@PatchMapping("/introduction/activity")
public ResponseEntity<Void> changeTeamActivity(HttpServletRequest request, UpdateIntroActivityDTO updateIntroActivityDTO) {

adminService.changeTeamActivity(request, updateIntroActivityDTO);
return ResponseEntity.ok().build();
}

// 특정 팀의 인재상 변경
@PatchMapping("/introduction/target")
public ResponseEntity<Void> changeTeamTarget(HttpServletRequest request, UpdateIntroTargetDTO updateIntroTargetDTO) {

adminService.changeTeamTarget(request, updateIntroTargetDTO);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//package com.gdscuos.recruit.global.auth.domain;
//
//import com.gdscuos.recruit.global.common.Team;
//import lombok.NoArgsConstructor;
//import lombok.Setter;
//
//import javax.persistence.*;
//
//@Table(name = "introduction")
//@NoArgsConstructor
//@Setter
//public class Introduction {
//
// @Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// @Column(name = "id", nullable = false)
// private Long id;
//
// @Column(name = "team", nullable = false)
// @Enumerated(EnumType.STRING)
// private Team team;
//
// @Column(name = "about")
// private String about;
//
// @Column(name = "activity")
// private String activity;
//
// @Column(name = "target")
// private String target;
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.gdscuos.recruit.global.auth.dto;

import com.gdscuos.recruit.global.common.Team;
import lombok.Data;

@Data
public class UpdateIntroAboutDTO {

private final Team team;
private final String about;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.gdscuos.recruit.global.auth.dto;

import com.gdscuos.recruit.global.common.Team;
import lombok.Data;

@Data
public class UpdateIntroActivityDTO {

private final Team team;
private final String activity;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.gdscuos.recruit.global.auth.dto;

import com.gdscuos.recruit.global.common.Team;
import lombok.Data;

@Data
public class UpdateIntroTargetDTO {

private final Team team;
private final String target;
}
34 changes: 32 additions & 2 deletions src/main/java/com/gdscuos/recruit/global/auth/dto/UserDTO.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
package com.gdscuos.recruit.global.auth.dto;

import com.gdscuos.recruit.domain.applicant.domain.Application;
import com.gdscuos.recruit.domain.critic.domain.ApplicationCritic;
import com.gdscuos.recruit.global.common.Role;
import com.gdscuos.recruit.global.common.Team;
import com.gdscuos.recruit.global.common.User;
import lombok.Data;
import lombok.*;

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

@Data
@Builder
@AllArgsConstructor
public class UserDTO {

private long userId;
private Team team;
private List<Application> applications;
private List<ApplicationCritic> applicationCritics;
private String username;
private String email;
private Role role;

// Entity -> DTO
// Entity -> DTO mapping
public UserDTO(User entity) {
this.userId = entity.getId();
this.team = entity.getTeam();
this.applications = entity.getApplications();
this.applicationCritics = entity.getApplicationCritics();
this.username = entity.getUsername();
this.email = entity.getEmail();
this.role = entity.getRole();
}

// Entity -> return DTO
public static UserDTO from(User user) {
return UserDTO.builder()
.userId(user.getId())
.team(user.getTeam())
.applications(user.getApplications())
.applicationCritics(user.getApplicationCritics())
.username(user.getUsername())
.email(user.getEmail())
.role(user.getRole())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@
public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findUserByEmail(String email);

User findUserById(Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package com.gdscuos.recruit.global.auth.service;

import com.gdscuos.recruit.domain.applicant.domain.Introduction;
import com.gdscuos.recruit.domain.applicant.exception.IntroductionNotFoundException;
import com.gdscuos.recruit.domain.applicant.repository.IntroductionRepository;
import com.gdscuos.recruit.global.auth.dto.UpdateIntroAboutDTO;
import com.gdscuos.recruit.global.auth.dto.UpdateIntroActivityDTO;
import com.gdscuos.recruit.global.auth.dto.UpdateIntroTargetDTO;
import com.gdscuos.recruit.global.auth.dto.UserDTO;
import com.gdscuos.recruit.global.auth.repository.UserRepository;
import com.gdscuos.recruit.global.common.Role;
import com.gdscuos.recruit.global.common.User;
import com.gdscuos.recruit.global.error.exception.AccessDeniedException;
import com.gdscuos.recruit.global.error.exception.EntityNotFoundException;
import com.gdscuos.recruit.global.error.exception.ErrorCode;
import com.gdscuos.recruit.global.util.SessionConst;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class AdminService {

private final UserRepository userRepository;
private final IntroductionRepository introductionRepository;

public AdminService(UserRepository userRepository, IntroductionRepository introductionRepository) {
this.userRepository = userRepository;
this.introductionRepository = introductionRepository;
}

// 유저 리스트 반환
public List<UserDTO> getUserList(HttpServletRequest request) {

isUserRoleLead(getLoginUser(request));
return userRepository.findAll().stream().map(UserDTO::from).collect(Collectors.toList());
}

// 유저의 권한 변경
public void changeUserRole(HttpServletRequest request, Long userId, Role role) {

if (isUserRoleLead(getLoginUser(request))) {
if (isUserExists(userId)) {
User user = userRepository.findUserById(userId);
user.setRole(role);

userRepository.save(user);
} else {
throw new EntityNotFoundException("권한이 변경될 유저가 없습니다.");
}
}
}

// 유저 회원탈퇴
public void deleteUser(HttpServletRequest request, Long userId) {

if (isUserRoleLead(getLoginUser(request))) {
if (isUserExists(userId)) {
User user = userRepository.findUserById(userId);

userRepository.delete(user);
} else {
throw new EntityNotFoundException("회원탈퇴할 유저 정보가 없습니다.");
}
}
}

// 특정 팀의 소개 수정
public void changeTeamAbout(HttpServletRequest request, UpdateIntroAboutDTO updateIntroAboutDTO) {
if (isUserRoleLead(getLoginUser(request))) {
Introduction intro = introductionRepository.findByTeam(updateIntroAboutDTO.getTeam());
if (intro != null) {
intro.setAbout(updateIntroAboutDTO.getAbout());
} else {
throw new IntroductionNotFoundException();
}
}
}

// 특정 팀의 활동 내용 수정
public void changeTeamActivity(HttpServletRequest request, UpdateIntroActivityDTO updateIntroActivityDTO) {
if (isUserRoleLead(getLoginUser(request))) {
Introduction intro = introductionRepository.findByTeam(updateIntroActivityDTO.getTeam());
if (intro != null) {
intro.setActivity(updateIntroActivityDTO.getActivity());
} else {
throw new IntroductionNotFoundException();
}
}
}

// 특정 팀의 인재상 수정
public void changeTeamTarget(HttpServletRequest request, UpdateIntroTargetDTO updateIntroTargetDTO) {
if (isUserRoleLead(getLoginUser(request))) {
Introduction intro = introductionRepository.findByTeam(updateIntroTargetDTO.getTeam());
if (intro != null) {
intro.setTarget(updateIntroTargetDTO.getTarget());
} else {
throw new IntroductionNotFoundException();
}
}
}

// db에 유저가 존재하는 지 확인
private boolean isUserExists(Long userId) {
Optional<User> user = userRepository.findById(userId);
return user.isPresent();
}

// 유저의 권한이 Lead 인지 확인
private boolean isUserRoleLead(@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) UserDTO loginMember) {

if (loginMember.getRole() != Role.LEAD) {
throw new AccessDeniedException("권한이 필요한 기능입니다.", ErrorCode.USER_ACCESS_DENIED);
}

return true;
}

// HttpServletRequest 를 통해 세션에 저장된 userDTO 객체 반환
private UserDTO getLoginUser(HttpServletRequest request) {

return (UserDTO) request.getSession(false).getAttribute(SessionConst.LOGIN_MEMBER);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gdscuos.recruit.global.error;

import com.gdscuos.recruit.global.error.exception.AccessDeniedException;
import com.gdscuos.recruit.global.error.exception.BusinessException;
import com.gdscuos.recruit.global.error.exception.EntityNotFoundException;
import com.gdscuos.recruit.global.error.exception.ErrorCode;
Expand All @@ -18,6 +19,15 @@
@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(AccessDeniedException.class)
protected ResponseEntity<ErrorResponse> handleAccessDeniedException(
final AccessDeniedException exception) {
log.error("handleAccessDeniedException", exception);
final ErrorCode errorCode = exception.getErrorCode();
final ErrorResponse response = ErrorResponse.from(errorCode);
return new ResponseEntity<>(response, HttpStatus.valueOf(errorCode.getStatus()));
}

@ExceptionHandler(BusinessException.class)
protected ResponseEntity<ErrorResponse> handleBusinessException(
final BusinessException exception) {
Expand Down