Skip to content

Commit

Permalink
Update manager
Browse files Browse the repository at this point in the history
  • Loading branch information
in27sung committed Dec 19, 2024
1 parent beb065b commit f75bbb7
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 23 deletions.
12 changes: 9 additions & 3 deletions stockMate/src/main/java/com/stockm8/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
Expand All @@ -44,6 +42,7 @@
import com.stockm8.interceptor.AdminInterceptor;
import com.stockm8.interceptor.AuthorizationInterceptor;
import com.stockm8.interceptor.FlashMessageInterceptor;
import com.stockm8.interceptor.ManagerInterceptor;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

Expand All @@ -65,6 +64,9 @@ public class WebConfig implements WebMvcConfigurer {
@Autowired
private AdminInterceptor adminInterceptor;

@Autowired
private ManagerInterceptor managerInterceptor;

/**
* 인터셉터 설정
* 특정 URL 패턴에 대해 AuthorizationInterceptor를 적용하며, 일부 URL은 제외합니다.
Expand All @@ -83,10 +85,14 @@ public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(adminInterceptor)
.addPathPatterns("/admin/**") // /admin/** 경로에만 적용
.excludePathPatterns(excludedPaths.toArray(new String[0]));

registry.addInterceptor(managerInterceptor)
.addPathPatterns("/manager/**") // /admin/** 경로에만 적용
.excludePathPatterns(excludedPaths.toArray(new String[0]));

// Intercepter 적용
registry.addInterceptor(authorizationInterceptor)
.addPathPatterns("/dashboard", "/business", "/category/**", "/product/**", "/warehouse/**", "/stock/**", "/order/**") // 인터셉터를 적용할 경로
.addPathPatterns("/dashboard", "/business", "/category/**", "/product/**", "/warehouse/**", "/stock/**", "/order/**") // 인터셉터를 적용할 경로
.excludePathPatterns( // 제외할 경로들
"/", // 홈 경로 제외
"/favicon.ico", // 브라우저 기본 요청 제외
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public String registBusinessGET() throws Exception {

return "business/register"; // 회사 등록 폼 페이지로 이동
}

// 비즈니스 등록 처리
@PostMapping("/register")
public String registerBusinessPOST(BusinessVO business, HttpServletRequest request, Model model) throws Exception {
Expand Down
24 changes: 21 additions & 3 deletions stockMate/src/main/java/com/stockm8/controller/HomeController.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.stockm8.domain.enums.UserRole;
import com.stockm8.domain.vo.UserVO;
import com.stockm8.service.UserService;

/**
* Handles requests for the application home page.
*/
Expand All @@ -30,6 +34,9 @@ public class HomeController {

private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

@Autowired
private UserService userService;

/**
* Simply selects the home view to render by returning its name.
*/
Expand All @@ -45,20 +52,31 @@ public String home(Locale locale, Model model) {
model.addAttribute("serverTime", formattedDate );
return "main";
}

//http://localhost:8088/dashboard
@RequestMapping(value = "/dashboard", method = RequestMethod.GET)
public String dash(Locale locale, Model model) {
public String dash(HttpSession session, Locale locale, Model model) throws Exception {
logger.info("😁Welcome dashboad😁! The client locale is {}.", locale);

// 세션에서 userId 가져오기
Long userId = (session != null) ? (Long) session.getAttribute("userId") : null;

// userId로 사용자 정보 조회
UserVO user = userService.getUserById(userId);
logger.info("세션으로 들고온 유저정보: " + user);
UserRole userRole = user.getUserRole();

Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

String formattedDate = dateFormat.format(date);

model.addAttribute("serverTime", formattedDate );

model.addAttribute("userRole", userRole);

return "dashboard";
}

// http://localhost:8088/qrScanner
@RequestMapping(value = "/qrScanner", method = RequestMethod.GET)
public String qrScanner(Locale locale, Model model) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
package com.stockm8.controller;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttribute;

import com.stockm8.domain.dto.PendingUserDTO;
import com.stockm8.domain.enums.UserRole;
import com.stockm8.domain.vo.UserVO;
import com.stockm8.service.UserService;

@Controller
@RequestMapping(value = "/manager/*")
public class ManagerController {

private static final Logger logger = LoggerFactory.getLogger(AdminController.class);

@Autowired
private UserService userService;

/**
* 매니저 메인 페이지 표시(GET)
*
* @throws Exception
*
*/
// http://localhost:8088/admin/main
@GetMapping("/main")
public String managerMainGET(@SessionAttribute("userId") Long userId, Model model) throws Exception {
logger.info("managerMainGET() 호출 - 페이지 접근 (userId: {})", userId);

// userId로 사용자 정보 가져오기
UserVO user = userService.getUserById(userId);

if (user != null) {
// 관리자 여부 확인 (MANAGER인 경우)
boolean isManager = user.getUserRole() == UserRole.MANAGER;
model.addAttribute("isManager", isManager); // JSP에 전달할 데이터
}
return "manager/main"; // 메인 페이지 반환
}

// http://localhost:8088/manager/approve
@GetMapping("/approve")
public String managerApproveGET(@SessionAttribute("userId") Long userId, Model model) throws Exception {
logger.info("managerApproveGET() 호출 - 페이지 접근 (userId: {})", userId);

// userId로 사용자 정보 가져오기
UserVO user = userService.getUserById(userId);
int businessId = user.getBusinessId();

// 조건에 맞는 사용자와 사업자 정보 가져오기
List<PendingUserDTO> pendingUsers = userService.getStaffByBusinessId(businessId);

// JSP로 전달
model.addAttribute("pendingUsers", pendingUsers);

return "admin/approve"; // JSP 페이지 반환
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public String userSignUpPOST(/* @ModelAttribute */ UserVO user) throws Exception
return "redirect:/user/signin";
}

// http://localhost:8088/user/login (GET)
// http://localhost:8088/user/signin (GET)
// 로그인 - 정보입력 / GET
@RequestMapping(value = "/signin", method = RequestMethod.GET)
public String userSgininGET(HttpServletRequest request, Model model) {
Expand All @@ -100,7 +100,6 @@ public String userSgininGET(HttpServletRequest request, Model model) {
model.addAttribute("errorMessage", errorMessage);
}
}

return "/user/signin";
}

Expand All @@ -121,6 +120,7 @@ public String userLoginPOST(UserVO user, RedirectAttributes rttr, HttpSession se

// 세션에 사용자 ID 저장
session.setAttribute("userId", resultVO.getUserId());
logger.debug("세션 저장 완료 - Session ID: {}, User ID: {}", session.getId(), session.getAttribute("userId"));

// 원래 요청 URL로 리다이렉트
String redirectUrl = (String) session.getAttribute("redirectAfterLogin");
Expand All @@ -131,7 +131,6 @@ public String userLoginPOST(UserVO user, RedirectAttributes rttr, HttpSession se
}
return "redirect:/dashboard";
}

// 로그인 실패 처리
logger.warn("로그인 실패, 사용자 정보를 찾을 수 없습니다.");
rttr.addFlashAttribute("errorMessage", "로그인에 실패했습니다. 아이디와 비밀번호를 확인해주세요.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.stockm8.interceptor;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private boolean sendErrorMessage(HttpServletRequest request, HttpServletResponse
private boolean isValidUser(HttpServletRequest request, HttpServletResponse response, UserVO user) throws Exception {

// 허용된 역할 정의
List<UserRole> allowedRoles = Arrays.asList(UserRole.MANAGER, UserRole.ADMIN /*Role.STAFF*/);
List<UserRole> allowedRoles = Arrays.asList(UserRole.MANAGER, UserRole.ADMIN /*UserRole.STAFF*/);

// 1. PENDING 상태 처리
if (user.getUserStatus() == UserStatus.PENDING) {
Expand All @@ -148,18 +148,18 @@ private boolean isValidUser(HttpServletRequest request, HttpServletResponse resp

if (user.getBusinessId() != null) {
logger.info("PENDING 상태의 사용자({})가 businessId({})를 가지고 있습니다. 메인 페이지로 이동합니다.", user.getUserId(), user.getBusinessId());
sendErrorMessage(request, response, "승인 절차가 완료될 때까지 기다려주세요.", "/user/main");
sendErrorMessage(request, response, "승인 절차가 완료될 때까지 기다려주세요.", "/main");
return false;
}
}

// 2. APPROVED 상태 처리
if (user.getUserStatus() == UserStatus.APPROVED) {
if (!allowedRoles.contains(user.getUserRole())) {
logger.warn("권한 없는 사용자({})가 접근을 시도했습니다. 대시보드로 이동합니다. (역할: {})", user.getUserId(), user.getUserRole());
return sendErrorMessage(request, response, "접근 권한이 없습니다.", "/dashboard");
}

// if (!allowedRoles.contains(user.getUserRole())) {
// logger.warn("권한 없는 사용자({})가 접근을 시도했습니다. 대시보드로 이동합니다. (역할: {})", user.getUserId(), user.getUserRole());
// return sendErrorMessage(request, response, "접근 권한이 없습니다.", "/dashboard");
// }
//
logger.info("APPROVED 상태의 사용자({})가 대시보드로 접근합니다.", user.getUserId());
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.stockm8.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.FlashMap;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;

import com.stockm8.domain.enums.UserRole;
import com.stockm8.domain.vo.UserVO;
import com.stockm8.service.UserService;

@Component
public class ManagerInterceptor implements HandlerInterceptor {

private static final Logger logger = LoggerFactory.getLogger(ManagerInterceptor.class);

@Autowired
private UserService userService; // 유저 정보를 가져오기 위한 서비스 클래스

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession(false);
Long userId = (session != null) ? (Long) session.getAttribute("userId") : null;

// 1. 세션에서 사용자 ID 확인
if (userId == null) {
logger.warn("세션에 유저 ID가 없습니다. 로그인 페이지로 이동합니다.");
saveRequestedUrlToSession(request);
return sendErrorMessage(request, response, "세션이 만료되었습니다. 다시 로그인해주세요.", "/user/signin");
}

// 2. DB에서 사용자 정보 조회
UserVO user = userService.getUserById(userId);
if (user == null) {
logger.warn("해당 유저({}) 정보를 찾을 수 없습니다. 회원가입 페이지로 이동합니다.", userId);
return sendErrorMessage(request, response, "유저 정보를 찾을 수 없습니다. 회원가입을 진행해주세요.", "/user/signup");
}

// 3. 삭제된 계정 확인
if (Boolean.TRUE.equals(user.getIsDeleted())) {
logger.warn("삭제된 유저({})입니다. 로그인 페이지로 이동합니다.", userId);
return sendErrorMessage(request, response, "삭제된 계정입니다. 관리자에게 문의해주세요.", "/user/signin");
}

// 4. 관리자 권한 확인
if (user.getUserRole() != UserRole.MANAGER) {
logger.warn("권한 없는 접근 시도 (유저 ID: {}, 역할: {}).", userId, user.getUserRole());
return sendErrorMessage(request, response, "매니저 전용 페이지입니다. 접근 권한이 없습니다.", "/user/signin");
}

// 검증 성공: 사용자 정보 저장
logger.info("매니저 확인 완료 (유저 ID: {}, 이름: {}).", userId, user.getUserName());
request.setAttribute("currentUser", user);
return true;
}

/**
* 에러 메시지와 함께 리다이렉트 처리
*/
private boolean sendErrorMessage(HttpServletRequest request, HttpServletResponse response, String message, String redirectUrl)
throws Exception {

// FlashMap 객체 생성 및 에러 메시지 저장
FlashMap flashMap = new FlashMap();
flashMap.put("errorMessage", message);

// FlashMap 저장소에 FlashMap 추가
RequestContextUtils.getFlashMapManager(request).saveOutputFlashMap(flashMap, request, response);

// 로그 출력
logger.info("FlashMap에 저장된 에러 메시지: {}", message);
logger.info("리다이렉트 대상 URL: {}", redirectUrl);

// 리다이렉트 수행
response.sendRedirect(redirectUrl);
return false; // handlerInterceptor 처리 중단
}

/**
* 요청한 URL을 세션에 저장 (로그인 후 리다이렉트를 위해)
*/
private void saveRequestedUrlToSession(HttpServletRequest request) {
String requestedUrl = request.getRequestURI();
String queryString = request.getQueryString();
if (queryString != null) {
requestedUrl += "?" + queryString;
}
request.getSession().setAttribute("requestedUrl", requestedUrl);
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub

}

}
2 changes: 1 addition & 1 deletion stockMate/src/main/resources/mappers/userMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
ORDER BY u.created_at DESC
</select>

<select id="selectStaffByBusinessId" parameterType="long" resultType="com.stockm8.domain.dto.PendingUserDTO">
<select id="selectStaffByBusinessId" parameterType="int" resultType="com.stockm8.domain.dto.PendingUserDTO">
SELECT u.user_id AS approvedUserId,
u.email,
u.user_name,
Expand Down
Loading

0 comments on commit f75bbb7

Please sign in to comment.