[JAVA] CRUD 토이 프로젝트 - 4

Hyeonseok Jeong·2023년 8월 26일
0

Java

목록 보기
4/5

오늘은 저번편 클라이언트 기능을 마무리하고 복습할겸 천천히 관리자 기능을 추가하였다.

진행상황

  • 관리자 로그인
  • 게시물 삭제 권한

관리자 로그인

관리자 로그인은 DB 테이블에서 유저의 컬럼중 admin이 TRUE(1) 인 경우에 로그인이 되며 따로 관리자는 회원가입이 아닌 직접적으로 지정을 해야한다고 생각이들어 회원가입은 따로 진행하지 않았다.

관리자 로그인 진행은 클라이언트 로그인에서도 가능하며 클라이언트 로그인 view에서 admin login 으로 페이지 전환을 한후 로그인이 되도록 진행

  • admin sign-in controller code
package com.CRUDp.web.admin.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.CRUDp.web.admin.service.SignInService;

@WebServlet("/admin/signIn")
public class SignInController extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		req.getRequestDispatcher("/WEB-INF/view/admin/signIn/signIn.jsp").forward(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		String email = req.getParameter("email");
		String pwd = req.getParameter("password");

		boolean state = false;
		HttpSession session = req.getSession();

		SignInService service = new SignInService();
		state = service.setUserLogIn(email, pwd);

		if (state) {
			// session 로그인
			session.setAttribute("userId", email);
			resp.sendRedirect("/admin/index");
		} else {
			resp.sendRedirect("/admin/signIn");
		}

	}
}
  • admin sign-in service
package com.CRUDp.web.admin.service;

import java.security.NoSuchAlgorithmException;

import com.CRUDp.web.admin.dao.UserDao;
import com.CRUDp.web.admin.dto.UserDto;
import com.CRUDp.web.security.Sha256;

public class SignInService {
	public boolean setUserLogIn(String email, String password) {
		System.out.printf("email : %s\n", email);
		System.out.printf("password : %s\n", password);

		UserDto user = new UserDto();
		UserDao userDao = new UserDao();
		Sha256 sha256 = new Sha256();

		String hashingPwd = null;
		boolean state = false;

		try {
			hashingPwd = sha256.encrypt(password);
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		user.setEmail(email);
		user.setPassword(hashingPwd);

		state = userDao.selectUserCheckDao(user);

		return state;
	}
}

컨트롤 부분과 Service 부분은 기존의 클라이언트 로그인에서의 로직과 차이가 없다
단지 Dao단에서 admin = true 인지에 대한 여부만 확인을 하게된다
(이부분은 service에서 재확인을 해야할까도 했지만 우선 Dao에서만 관리자 여부 확인을 진행)

  • admin sign-in Dao
	public boolean selectUserCheckDao(UserDto user) {

		String sql = "select email, password from member where email = ? and password = ? and admin = 1";

		boolean state = false;

		try {

			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection con = DriverManager.getConnection(url, dbName, dbPwd);
			PreparedStatement st = con.prepareStatement(sql);

			st.setString(1, user.getEmail());
			st.setString(2, user.getPassword());

			ResultSet rs = st.executeQuery();

			if (rs.next()) {
				if (!rs.getString("email").equals("")) {
					state = true;
				}
			}

			rs.close();
			st.close();
			con.close();

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return state;
	}

admin 부분 진행
String sql = "select email, password from member where email = ? and password = ? and admin = 1";

관리자 게시물 삭제 권한

관리자 게시물 삭제 권한은 관리자로 로그인시에 들어가지는 admin 페이지에서 전체 게시물을 삭제할 수 있는 view가 보여지고 삭제를 할 수있게 된다.
( 글을 쓰다보니 삭제 권한 부분에서 관리자인지 인증 하는 부분을 한번더 해도 좋았을것 같다는 생각이 들었다 => Dto에서 admin 부분을 추가해서 할까하다가 따로 Dao에서 selectAdminMember() 를 만들어 admin 부분이 True 인경우 result 값(boolean)을 가져와 True일때만 삭제가 되도록 수정)

  • board list controller

package com.CRUDp.web.admin.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.CRUDp.web.admin.dto.BoardDto;
import com.CRUDp.web.admin.service.BoardListService;

@WebServlet("/admin/board/list")
public class BoardListController extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String field_ = req.getParameter("filed");
		String query_ = req.getParameter("query");
		String page_ = req.getParameter("page");

		String field = field_ != null && !field_.equals("") ? field_ : "title";
		String query = query_ != null && !query_.equals("") ? query_ : "";
		int page = page_ != null && !page_.equals("") ? Integer.parseInt(page_) : 1;

		List<BoardDto> boardList = new ArrayList<>();
		int count = 0;

		BoardListService service = new BoardListService();
		boardList = service.getBoardList(field, query, page);
		count = service.getBoardListCount(field, query);

		req.setAttribute("list", boardList);
		req.setAttribute("count", count);

		req.getRequestDispatcher("/WEB-INF/view/admin/board/list/list.jsp").forward(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		HttpSession session = req.getSession();
		BoardListService service = new BoardListService();
		String[] chiBoardIds_ = req.getParameterValues("choice_board");
		int[] chiBoardIds = new int[chiBoardIds_.length];

		for (int i = 0; i < chiBoardIds_.length; i++) {
			chiBoardIds[i] = Integer.parseInt(chiBoardIds_[i]);
		}

		String email = (String) session.getAttribute("userId");

		int result = service.deletChoicePost(chiBoardIds, email);

		resp.sendRedirect("/admin/board/list");
	}
}

  • board list service
package com.CRUDp.web.admin.service;

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

import com.CRUDp.web.admin.dao.BoardDao;
import com.CRUDp.web.admin.dto.BoardDto;

public class BoardListService {
	public List<BoardDto> getBoardList(String field, String query, int page) {

		List<BoardDto> boardList = new ArrayList<>();

		BoardDao boardDao = new BoardDao();

		int start = 1 + (page - 1) * 10;
		int end = page * 10;

		boardList = boardDao.selectBoardListDao(field, query, start, end);

		return boardList;
	}

	public int getBoardListCount(String field, String query) {
		BoardDao boardDao = new BoardDao();
		int result = 0;
		result = boardDao.selectBoardCountDao(field, query);

		return result;
	}

	public int deletChoicePost(int[] chiBoardIds, String email) {
		int result = 0;

		BoardDao boardDao = new BoardDao();

		boolean state = boardDao.selectAdminMember(email);

		System.out.println("state : " + state);

		if (state) {
			boardDao.deleteChiPostCmtDao(chiBoardIds);
			result = boardDao.deleteChoicePostDao(chiBoardIds);
		}

		return result;
	}

}

service 부분에서 앞서 설명했던 admin 상태값으로 확인하는 코드가 작성되어 있다.

  • admin board list delete dao
// admin state check
	public boolean selectAdminMember(String email) {
		String sql = "select admin from member where email = ?";

		boolean result = false;

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection con = DriverManager.getConnection(url, dbName, dbPwd);
			PreparedStatement st = con.prepareStatement(sql);

			st.setString(1, email);

			ResultSet rs = st.executeQuery();

			if (rs.next()) {
				result = rs.getBoolean("admin");
			}

			rs.close();
			st.close();
			con.close();

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

// board delete

	public int deleteChiPostCmtDao(int[] chiBoardIds) {
		int result = 0;

		String params = "";

		for (int i = 0; i < chiBoardIds.length; i++) {
			params += chiBoardIds[i];
			if (i < chiBoardIds.length - 1)
				params += ",";
		}

		String sql = "delete cmt where board_id in ( " + params + " )";

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection con = DriverManager.getConnection(url, dbName, dbPwd);
			Statement st = con.createStatement();

			result = st.executeUpdate(sql);

			st.close();
			con.close();

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return result;
	}

	public int deleteChoicePostDao(int[] chiBoardIds) {
		int result = 0;

		String params = "";

		for (int i = 0; i < chiBoardIds.length; i++) {
			params += chiBoardIds[i];
			// i = 4 | chi.length = 5 - 1 = 4 | 1,2,3,4,5
			if (i < chiBoardIds.length - 1)
				params += ",";
		}

		String sql = "delete from board where id in ( " + params + " )";

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection con = DriverManager.getConnection(url, dbName, dbPwd);
			Statement st = con.createStatement();

			result = st.executeUpdate(sql);

			st.close();
			con.close();

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

		return result;
	}

dao에서 댓글 삭제 부분이 있는건 외래키로 설정되어 포스트에 연관된 댓글 삭제가 먼저 진행되어야 하기때문에 먼저 관련 댓글 전체를 삭제하고 그 뒤에 포스트를 삭제하는 식으로 진행되게 된다.

사진

  • admin 로그인



  • admin 게시물 선택 삭제 기능



마무리

관리자 기능을 진행하면서 Dto단에서 처음 MEMBER COLUMN의 ADMIN 부분을 처음 부터 추가해서 상태값을 계속 나두면 구지 관리자와 유저 파일을 나누어서 다시 컨트롤, 서비스, DAO 단을 새롭게 또 만드는게 아닌 재사용할 수 있었을것같다.

다음번엔 좀더 재사용 가능한 코드를 이런식으로 낭비하는건 막아야겠다.

끝!

추가

관리자 게시물 디테일 부분 삭제

관리자가 디테일 페이지에 들어가서 삭제할 수 있는 부분을 빠트려서 기능을 추가하였다.

  • admin board detail delete controller

package com.CRUDp.web.admin.controller;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.CRUDp.web.admin.service.PostService;

@WebServlet("/admin/post/action")
public class PostController extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		req.setCharacterEncoding("UTF-8");

		String actionState = req.getParameter("actionState");
		HttpSession session = req.getSession();
		PostService service = new PostService();
		String boardId_ = req.getParameter("board_id");
		int boardId = boardId_ != null && !boardId_.equals("") ? Integer.parseInt(boardId_) : 0;

		if (actionState.equals("삭제")) {
			String userId = (String) session.getAttribute("userId");

			// result 변수를 만들어 삭제에 실패하는경우도 산정하면 좋을것 같음
			service.delBoardPost(boardId, userId);
			resp.sendRedirect("/admin/board/list");

		} else if (actionState.equals("수정")) {

			resp.sendRedirect("/admin/board/reg?board_id=" + boardId);
		} else if (actionState.equals("선택삭제")) {
			// admin의 경우 게시물 전체를 삭제할 수 있는 권한이 있기 때문에 해당 기능을 구현
		}

	}
}

컨트롤단은 일반 유저와 같은 로직을 사용하며 service 부분에서 선택 삭제와 같이 admin 컬럼이 TRUE인 경우에 삭제가 가능하도록 구현하였다.


	public int delBoardPost(int boardId, String writerId) {
		BoardDao boardDao = new BoardDao();
		int result = 0;
        
        // 일반 유저와 다르게 ADMIN COLUMN 부분이 TRUE인 경우에 삭제 진행
		boolean adminState = boardDao.selectAdminMember(writerId);

		if (adminState) {
			boardDao.allDeleteCmt(boardId);
			result = boardDao.deleteBoardPost(boardId, writerId);
		}

		return result;
	}

사실 처음 로그인 부분에서 일반 유저가 로그인 못하도록 구현하였지만 우회가능성들을 염두해두고 저렇게 삭제 부분을 admin 부분이 1(TRUE) 인경우에만 삭제가 가능하도록 구현하였다.
(다음에는 Dto에서 admin 컬럼을 넣어서 구현해봐야겠다.)



진짜 마무리

해당 기능으로 이제 댓글 삭제 권한만 추가하게 되면 관리자 기능 구현은 끝이나며 이번 토이 프로젝트도 끝이 나게된다

진짜 끝!

profile
풀스텍 개발자

0개의 댓글