enable security
This commit is contained in:
@@ -3,6 +3,7 @@ package edu.neu.neumall.configure;
|
||||
import edu.neu.neumall.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
@@ -28,7 +29,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable()
|
||||
.authorizeRequests().antMatchers("/register/**", "/img/**").permitAll()
|
||||
.anonymous()
|
||||
.and()
|
||||
.authorizeRequests().antMatchers("/login/**", "/register/**", "/img/**", "/js/**", "/css/**", "/fonts/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET, "/product/**").permitAll()
|
||||
.antMatchers(HttpMethod.POST, "/product/**").hasAnyAuthority("ADMIN", "SHOPKEEPER")
|
||||
.antMatchers(HttpMethod.DELETE, "/product/**").hasAnyAuthority("ADMIN", "SHOPKEEPER")
|
||||
.antMatchers("/home/**").hasAnyAuthority("ADMIN", "SHOPKEEPER", "CUSTOMER")
|
||||
.antMatchers("/admin/**").hasAuthority("ADMIN")
|
||||
.and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package edu.neu.neumall.controller;
|
||||
|
||||
import edu.neu.neumall.entity.User;
|
||||
import edu.neu.neumall.service.ProductService;
|
||||
import edu.neu.neumall.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
@@ -13,16 +14,20 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
public class AdminController {
|
||||
|
||||
private UserService userService;
|
||||
private ProductService productService;
|
||||
|
||||
@Autowired
|
||||
public AdminController(UserService userService) {
|
||||
public AdminController(UserService userService, ProductService productService) {
|
||||
this.userService = userService;
|
||||
this.productService = productService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String adminPage(Model model) {
|
||||
var users = userService.findAll();
|
||||
var product = productService.getAllProducts();
|
||||
model.addAttribute("userList", users);
|
||||
model.addAttribute("productList", product);
|
||||
return "admin.html";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package edu.neu.neumall.controller;
|
||||
|
||||
import edu.neu.neumall.entity.User;
|
||||
import edu.neu.neumall.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@@ -19,6 +21,12 @@ public class HomeController {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String myHomePage(@AuthenticationPrincipal User user, Model model) {
|
||||
model.addAttribute("user", user);
|
||||
return "homepage";
|
||||
}
|
||||
|
||||
@GetMapping("/{userID}")
|
||||
public String homePage(@PathVariable("userID") long userID, Model model) {
|
||||
var user = userService.findUserByID(userID);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package edu.neu.neumall.controller;
|
||||
|
||||
import edu.neu.neumall.entity.Product;
|
||||
import edu.neu.neumall.service.ProductService;
|
||||
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.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/product")
|
||||
@@ -35,4 +34,30 @@ public class ProductController {
|
||||
model.addAttribute("product", product.get());
|
||||
return "productDetail.html";
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@ResponseBody
|
||||
String deleteProduct(@RequestParam("id") long productID) {
|
||||
var productExist = productService.getProductByID(productID);
|
||||
if (productExist.isEmpty()) {
|
||||
return "\"success\":false";
|
||||
}
|
||||
var product = productExist.get();
|
||||
product.setStatus(Product.ProductStatus.OFFSALE);
|
||||
productService.save(product);
|
||||
return "\"success\":true";
|
||||
}
|
||||
|
||||
@PatchMapping
|
||||
@ResponseBody
|
||||
String unSaleProduct(@RequestParam("id") long productID) {
|
||||
var productExist = productService.getProductByID(productID);
|
||||
if (productExist.isEmpty()) {
|
||||
return "\"success\":false";
|
||||
}
|
||||
var product = productExist.get();
|
||||
product.setStatus(Product.ProductStatus.ONSALE);
|
||||
productService.save(product);
|
||||
return "\"success\":true";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package edu.neu.neumall.controller;
|
||||
|
||||
import edu.neu.neumall.entity.User;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/cart")
|
||||
public class ShoppingCartController {
|
||||
@GetMapping
|
||||
public String shoppingCartPage(@AuthenticationPrincipal User user, Model model) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,10 @@ public class ProductService {
|
||||
return productRepository.findAll();
|
||||
}
|
||||
|
||||
public void save(Product product) {
|
||||
productRepository.save(product);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ProductUpdateForm {
|
||||
private long productid;
|
||||
|
||||
-6757
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+4
-3
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-2377
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -5,10 +5,11 @@
|
||||
<title>Admin</title>
|
||||
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
<script src="/js/jquery.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script>
|
||||
function deleteUser(userID) {
|
||||
function deleteUser(userID, button) {
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: '/user',
|
||||
@@ -18,7 +19,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
function unlockUser(userID) {
|
||||
function unlockUser(userID, button) {
|
||||
$.ajax({
|
||||
type: 'PATCH',
|
||||
url: '/user',
|
||||
@@ -27,44 +28,143 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function offsaleProduct(productID, button) {
|
||||
$.ajax({
|
||||
type: 'DELETE',
|
||||
url: '/product',
|
||||
data: {
|
||||
id: productID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onsaleProduct(productID, button) {
|
||||
$.ajax({
|
||||
type: 'PATCH',
|
||||
url: '/product',
|
||||
data: {
|
||||
id: productID
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function switchToUserPage() {
|
||||
$('#user-table').show();
|
||||
$('#product-table').hide();
|
||||
}
|
||||
|
||||
function switchToProductPage() {
|
||||
$('#user-table').hide();
|
||||
$('#product-table').show();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg bg-light" role="navigation">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">Admin</a>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="nav navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" onclick="switchToUserPage()" href="#">用户<span
|
||||
class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" onclick="switchToProductPage()" href="#">商品</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<form class="form-inline my-2 my-lg-0">
|
||||
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container">
|
||||
<table class="table table-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">头像</th>
|
||||
<th scope="col">用户名</th>
|
||||
<th scope="col">手机号</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">类型</th>
|
||||
<th scope="col">注册时间</th>
|
||||
<th scope="col">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--/*@thymesVar id="userList" type="java.util.List<edu.neu.neumall.entity.User>"*/-->
|
||||
<tr th:each="user:${userList}">
|
||||
<th scope="row" th:text="${user.ID}"></th>
|
||||
<td><img width="50" height="50" th:src="${user.avatar}"/></td>
|
||||
<td th:text="${user.nickName}"></td>
|
||||
<td th:text="${user.phone}"></td>
|
||||
<td th:text="${user.email}"></td>
|
||||
<td th:text="${user.role}"></td>
|
||||
<td th:text="${user.create_time}"></td>
|
||||
<td>
|
||||
<button th:if="${user.isAccountNonLocked()}" th:onclick="deleteUser([[${user.ID}]])" type="button"
|
||||
class="btn btn-danger">锁定
|
||||
</button>
|
||||
<button th:if="${!user.isAccountNonLocked()}" th:onclick="unlockUser([[${user.ID}]])" type="button"
|
||||
class="btn btn-success">解锁
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row">
|
||||
|
||||
<div class="col" id="user-table">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">头像</th>
|
||||
<th scope="col">用户名</th>
|
||||
<th scope="col">手机号</th>
|
||||
<th scope="col">Email</th>
|
||||
<th scope="col">类型</th>
|
||||
<th scope="col">注册时间</th>
|
||||
<th scope="col">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--/*@thymesVar id="userList" type="java.util.List<edu.neu.neumall.entity.User>"*/-->
|
||||
<tr th:each="user:${userList}">
|
||||
<th scope="row" th:text="${user.ID}"></th>
|
||||
<td><img width="50" height="50" th:src="${user.avatar}"/></td>
|
||||
<td th:text="${user.nickName}"></td>
|
||||
<td th:text="${user.phone}"></td>
|
||||
<td th:text="${user.email}"></td>
|
||||
<td th:text="${user.role}"></td>
|
||||
<td th:text="${user.create_time}"></td>
|
||||
<td>
|
||||
<button th:if="${user.isAccountNonLocked()}" th:onclick="deleteUser([[${user.ID}]], this)"
|
||||
type="button"
|
||||
class="btn btn-danger">锁定
|
||||
</button>
|
||||
<button th:if="${!user.isAccountNonLocked()}" th:onclick="unlockUser([[${user.ID}]], this)"
|
||||
type="button"
|
||||
class="btn btn-success">解锁
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col" id="product-table">
|
||||
<table class="table ">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
<th scope="col">图片</th>
|
||||
<th scope="col">名称</th>
|
||||
<th scope="col">价格</th>
|
||||
<th scope="col">类型</th>
|
||||
<th scope="col">更新时间</th>
|
||||
<th scope="col">创建时间</th>
|
||||
<th scope="col">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--/*@thymesVar id="productList" type="java.util.List<edu.neu.neumall.entity.Product>"*/-->
|
||||
<tr th:each="product:${productList}">
|
||||
<th scope="row" th:text="${product.ID}"></th>
|
||||
<td><img width="50" height="50" th:src="${product.main_img}"/></td>
|
||||
<td th:text="${product.name}"></td>
|
||||
<td th:text="${product.price}"></td>
|
||||
<td th:text="${product.category.name}"></td>
|
||||
<td th:text="${product.updateTime}"></td>
|
||||
<td th:text="${product.createTime}"></td>
|
||||
<td>
|
||||
<button type="button"
|
||||
th:if="${product.status.toString()}==ONSALE"
|
||||
th:onclick="offsaleProduct([[${product.ID}]], this)"
|
||||
class="btn btn-danger">下架
|
||||
</button>
|
||||
<button type="button"
|
||||
th:if="${product.status.toString()}==OFFSALE"
|
||||
th:onclick="onsaleProduct([[${product.ID}]], this)"
|
||||
class="btn btn-success">上架
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user