Commit 9f43851e authored by zhengjie's avatar zhengjie
Browse files

1.7版本发布,详情查看版本说明

parent 1402e584
......@@ -34,7 +34,6 @@ public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
log.debug("processing authentication for '{}'", request.getRequestURL());
final String requestHeader = request.getHeader(this.tokenHeader);
......@@ -49,10 +48,7 @@ public class JwtAuthorizationTokenFilter extends OncePerRequestFilter {
}
}
log.debug("checking authentication for user '{}'", username);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
log.debug("security context was null, so authorizating user");
// It is not compelling necessary to load the use details from the database. You could also store the information
// in the token and read it from it. It's up to you ;)
......
......@@ -30,8 +30,14 @@ public class JwtUser implements UserDetails {
private final String email;
private final String phone;
private final String dept;
private final String job;
@JsonIgnore
private final Collection<? extends GrantedAuthority> authorities;
private final Collection<GrantedAuthority> authorities;
private final boolean enabled;
......
package me.zhengjie.modules.security.service;
import me.zhengjie.modules.system.domain.Permission;
import me.zhengjie.modules.system.domain.Role;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.PermissionRepository;
import me.zhengjie.modules.system.repository.RoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@CacheConfig(cacheNames = "role")
public class JwtPermissionService {
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Cacheable(key = "'loadPermissionByUser:' + #p0.username")
public Collection<GrantedAuthority> mapToGrantedAuthorities(User user) {
System.out.println("--------------------loadPermissionByUser:" + user.getUsername() + "---------------------");
Set<Role> roles = roleRepository.findByUsers_Id(user.getId());
Set<Permission> permissions = new HashSet<>();
for (Role role : roles) {
Set<Role> roleSet = new HashSet<>();
roleSet.add(role);
permissions.addAll(permissionRepository.findByRoles_Id(role.getId()));
}
return permissions.stream()
.map(permission -> new SimpleGrantedAuthority(permission.getName()))
.collect(Collectors.toList());
}
}
......@@ -6,10 +6,10 @@ import me.zhengjie.modules.system.domain.User;
import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.modules.system.repository.PermissionRepository;
import me.zhengjie.modules.system.repository.RoleRepository;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.modules.security.security.JwtUser;
import me.zhengjie.utils.ValidationUtil;
import me.zhengjie.modules.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
......@@ -31,56 +31,36 @@ import java.util.stream.Collectors;
public class JwtUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
private UserService userService;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
private JwtPermissionService permissionService;
@Override
public UserDetails loadUserByUsername(String username){
User user = null;
if(ValidationUtil.isEmail(username)){
user = userRepository.findByEmail(username);
} else {
user = userRepository.findByUsername(username);
}
User user = userService.findByName(username);
if (user == null) {
throw new EntityNotFoundException(User.class, "name", username);
} else {
return create(user);
return createJwtUser(user);
}
}
public UserDetails create(User user) {
public UserDetails createJwtUser(User user) {
return new JwtUser(
user.getId(),
user.getUsername(),
user.getPassword(),
user.getAvatar(),
user.getEmail(),
mapToGrantedAuthorities(roleRepository.findByUsers_Id(user.getId()),permissionRepository),
user.getPhone(),
user.getDept().getName(),
user.getJob().getName(),
permissionService.mapToGrantedAuthorities(user),
user.getEnabled(),
user.getCreateTime(),
user.getLastPasswordResetTime()
);
}
private static List<GrantedAuthority> mapToGrantedAuthorities(Set<Role> roles,PermissionRepository permissionRepository) {
Set<Permission> permissions = new HashSet<>();
for (Role role : roles) {
Set<Role> roleSet = new HashSet<>();
roleSet.add(role);
permissions.addAll(permissionRepository.findByRoles_Id(role.getId()));
}
return permissions.stream()
.map(permission -> new SimpleGrantedAuthority(permission.getName()))
.collect(Collectors.toList());
}
}
package me.zhengjie.modules.system.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.io.Serializable;
import java.util.Set;
/**
* @author jie
* @date 2019-03-25
*/
@Entity
@Data
@Table(name="dept")
public class Dept implements Serializable {
/**
* ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(groups = Update.class)
private Long id;
/**
* 名称
*/
@Column(name = "name",nullable = false)
@NotBlank
private String name;
@NotNull
private Boolean enabled;
/**
* 上级部门
*/
@Column(name = "pid",nullable = false)
@NotNull
private Long pid;
@Column(name = "create_time")
@CreationTimestamp
private Timestamp createTime;
@ManyToMany(mappedBy = "depts")
@JsonIgnore
private Set<Role> roles;
public @interface Update {}
}
\ No newline at end of file
package me.zhengjie.modules.system.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
/**
* @author jie
* @date 2019-04-10
*/
@Entity
@Data
@Table(name="dict")
public class Dict implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(groups = Update.class)
private Long id;
/**
* 字典名称
*/
@Column(name = "name",nullable = false,unique = true)
@NotBlank
private String name;
/**
* 描述
*/
@Column(name = "remark")
private String remark;
@OneToMany(mappedBy = "dict",cascade={CascadeType.PERSIST,CascadeType.REMOVE})
private List<DictDetail> dictDetails;
public @interface Update {}
}
\ No newline at end of file
package me.zhengjie.modules.system.domain;
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author jie
* @date 2019-04-10
*/
@Entity
@Data
@Table(name="dict_detail")
public class DictDetail implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(groups = Update.class)
private Long id;
/**
* 字典标签
*/
@Column(name = "label",nullable = false)
private String label;
/**
* 字典值
*/
@Column(name = "value",nullable = false)
private String value;
/**
* 排序
*/
@Column(name = "sort")
private String sort = "999";
/**
* 字典id
*/
@ManyToOne
@JoinColumn(name = "dict_id")
private Dict dict;
public @interface Update {}
}
\ No newline at end of file
package me.zhengjie.modules.system.domain;
import lombok.Data;
import org.hibernate.annotations.*;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.io.Serializable;
/**
* @author jie
* @date 2019-03-29
*/
@Entity
@Data
@Table(name="job")
public class Job implements Serializable {
/**
* ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
@NotNull(groups = Update.class)
private Long id;
/**
* 名称
*/
@Column(name = "name",nullable = false)
@NotBlank
private String name;
@Column(unique = true)
@NotNull
private Long sort;
/**
* 状态
*/
@Column(name = "enabled",nullable = false)
@NotNull
private Boolean enabled;
@OneToOne
@JoinColumn(name = "dept_id")
private Dept dept;
/**
* 创建日期
*/
@Column(name = "create_time")
@CreationTimestamp
private Timestamp createTime;
public @interface Update {}
}
\ No newline at end of file
......@@ -30,6 +30,7 @@ public class Menu implements Serializable {
private String name;
@Column(unique = true)
@NotNull
private Long sort;
@Column(name = "path")
......
......@@ -32,6 +32,10 @@ public class Role implements Serializable {
@NotBlank
private String name;
// 数据权限类型 全部 、 本级 、 自定义
@Column(name = "data_scope")
private String dataScope = "本级";
@Column
private String remark;
......@@ -47,6 +51,10 @@ public class Role implements Serializable {
@JoinTable(name = "roles_menus", joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "id")})
private Set<Menu> menus;
@ManyToMany
@JoinTable(name = "roles_depts", joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "dept_id",referencedColumnName = "id")})
private Set<Dept> depts;
@CreationTimestamp
@Column(name = "create_time")
private Timestamp createTime;
......
......@@ -29,6 +29,7 @@ public class User implements Serializable {
private Long id;
@NotBlank
@Column(unique = true)
private String username;
private String avatar;
......@@ -37,6 +38,9 @@ public class User implements Serializable {
@Pattern(regexp = "([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}",message = "格式错误")
private String email;
@NotBlank
private String phone;
@NotNull
private Boolean enabled;
......@@ -53,6 +57,14 @@ public class User implements Serializable {
@JoinTable(name = "users_roles", joinColumns = {@JoinColumn(name = "user_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")})
private Set<Role> roles;
@OneToOne
@JoinColumn(name = "job_id")
private Job job;
@OneToOne
@JoinColumn(name = "dept_id")
private Dept dept;
@Override
public String toString() {
return "User{" +
......
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.Dept;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
import java.util.Set;
/**
* @author jie
* @date 2019-03-25
*/
public interface DeptRepository extends JpaRepository<Dept, Long>, JpaSpecificationExecutor {
/**
* findByPid
* @param id
* @return
*/
List<Dept> findByPid(Long id);
Set<Dept> findByRoles_Id(Long id);
}
\ No newline at end of file
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.DictDetail;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author jie
* @date 2019-04-10
*/
public interface DictDetailRepository extends JpaRepository<DictDetail, Long>, JpaSpecificationExecutor {
}
\ No newline at end of file
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.Dict;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author jie
* @date 2019-04-10
*/
public interface DictRepository extends JpaRepository<Dict, Long>, JpaSpecificationExecutor {
}
\ No newline at end of file
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.Job;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
/**
* @author jie
* @date 2019-03-29
*/
public interface JobRepository extends JpaRepository<Job, Long>, JpaSpecificationExecutor {
}
\ No newline at end of file
......@@ -20,4 +20,6 @@ public interface RoleRepository extends JpaRepository<Role, Long>, JpaSpecificat
Role findByName(String name);
Set<Role> findByUsers_Id(Long id);
Set<Role> findByMenus_Id(Long id);
}
package me.zhengjie.modules.system.repository;
import me.zhengjie.modules.system.domain.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.util.Date;
import java.util.List;
/**
* @author jie
......@@ -29,28 +33,28 @@ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificat
/**
* 修改密码
* @param id
* @param username
* @param pass
*/
@Modifying
@Query(value = "update user set password = ?2 , last_password_reset_time = ?3 where id = ?1",nativeQuery = true)
void updatePass(Long id, String pass, Date lastPasswordResetTime);
@Query(value = "update user set password = ?2 , last_password_reset_time = ?3 where username = ?1",nativeQuery = true)
void updatePass(String username, String pass, Date lastPasswordResetTime);
/**
* 修改头像
* @param id
* @param username
* @param url
*/
@Modifying
@Query(value = "update user set avatar = ?2 where id = ?1",nativeQuery = true)
void updateAvatar(Long id, String url);
@Query(value = "update user set avatar = ?2 where username = ?1",nativeQuery = true)
void updateAvatar(String username, String url);
/**
* 修改邮箱
* @param id
* @param username
* @param email
*/
@Modifying
@Query(value = "update user set email = ?2 where id = ?1",nativeQuery = true)
void updateEmail(Long id, String email);
@Query(value = "update user set email = ?2 where username = ?1",nativeQuery = true)
void updateEmail(String username, String email);
}
package me.zhengjie.modules.system.rest;
import me.zhengjie.aop.log.Log;
import me.zhengjie.config.DataScope;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.service.DeptService;
import me.zhengjie.modules.system.service.dto.DeptDTO;
import me.zhengjie.modules.system.service.query.DeptQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Set;
/**
* @author jie
* @date 2019-03-25
*/
@RestController
@RequestMapping("api")
public class DeptController {
@Autowired
private DeptService deptService;
@Autowired
private DeptQueryService deptQueryService;
@Autowired
private DataScope dataScope;
private static final String ENTITY_NAME = "dept";
@Log("查询部门")
@GetMapping(value = "/dept")
@PreAuthorize("hasAnyRole('ADMIN','USER_ALL','USER_SELECT','DEPT_ALL','DEPT_SELECT')")
public ResponseEntity getDepts(DeptDTO resources){
// 数据权限
Set<Long> deptIds = dataScope.getDeptIds();
List<DeptDTO> deptDTOS = deptQueryService.queryAll(resources, deptIds);
return new ResponseEntity(deptService.buildTree(deptDTOS),HttpStatus.OK);
}
@Log("新增部门")
@PostMapping(value = "/dept")
@PreAuthorize("hasAnyRole('ADMIN','DEPT_ALL','DEPT_CREATE')")
public ResponseEntity create(@Validated @RequestBody Dept resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
return new ResponseEntity(deptService.create(resources),HttpStatus.CREATED);
}
@Log("修改部门")
@PutMapping(value = "/dept")
@PreAuthorize("hasAnyRole('ADMIN','DEPT_ALL','DEPT_EDIT')")
public ResponseEntity update(@Validated(Dept.Update.class) @RequestBody Dept resources){
deptService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log("删除部门")
@DeleteMapping(value = "/dept/{id}")
@PreAuthorize("hasAnyRole('ADMIN','DEPT_ALL','DEPT_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
deptService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
}
\ No newline at end of file
package me.zhengjie.modules.system.rest;
import me.zhengjie.aop.log.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.Dict;
import me.zhengjie.modules.system.service.DictService;
import me.zhengjie.modules.system.service.dto.DictDTO;
import me.zhengjie.modules.system.service.query.DictQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author jie
* @date 2019-04-10
*/
@RestController
@RequestMapping("api")
public class DictController {
@Autowired
private DictService dictService;
@Autowired
private DictQueryService dictQueryService;
private static final String ENTITY_NAME = "dict";
@Log("查询字典")
@GetMapping(value = "/dict")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_SELECT')")
public ResponseEntity getDicts(DictDTO resources, Pageable pageable){
return new ResponseEntity(dictQueryService.queryAll(resources,pageable),HttpStatus.OK);
}
@Log("新增字典")
@PostMapping(value = "/dict")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_CREATE')")
public ResponseEntity create(@Validated @RequestBody Dict resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
return new ResponseEntity(dictService.create(resources),HttpStatus.CREATED);
}
@Log("修改字典")
@PutMapping(value = "/dict")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_EDIT')")
public ResponseEntity update(@Validated(Dict.Update.class) @RequestBody Dict resources){
dictService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log("删除字典")
@DeleteMapping(value = "/dict/{id}")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
dictService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
}
\ No newline at end of file
package me.zhengjie.modules.system.rest;
import me.zhengjie.aop.log.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.system.domain.DictDetail;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.dto.DictDetailDTO;
import me.zhengjie.modules.system.service.query.DictDetailQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author jie
* @date 2019-04-10
*/
@RestController
@RequestMapping("api")
public class DictDetailController {
@Autowired
private DictDetailService dictDetailService;
@Autowired
private DictDetailQueryService dictDetailQueryService;
private static final String ENTITY_NAME = "dictDetail";
@Log("查询字典详情")
@GetMapping(value = "/dictDetail")
public ResponseEntity getDictDetails(DictDetailDTO resources,
@PageableDefault(value = 10, sort = {"sort"}, direction = Sort.Direction.ASC) Pageable pageable){
return new ResponseEntity(dictDetailQueryService.queryAll(resources,pageable),HttpStatus.OK);
}
@Log("新增字典详情")
@PostMapping(value = "/dictDetail")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_CREATE')")
public ResponseEntity create(@Validated @RequestBody DictDetail resources){
if (resources.getId() != null) {
throw new BadRequestException("A new "+ ENTITY_NAME +" cannot already have an ID");
}
return new ResponseEntity(dictDetailService.create(resources),HttpStatus.CREATED);
}
@Log("修改字典详情")
@PutMapping(value = "/dictDetail")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_EDIT')")
public ResponseEntity update(@Validated(DictDetail.Update.class) @RequestBody DictDetail resources){
dictDetailService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
@Log("删除字典详情")
@DeleteMapping(value = "/dictDetail/{id}")
@PreAuthorize("hasAnyRole('ADMIN','DICT_ALL','DICT_DELETE')")
public ResponseEntity delete(@PathVariable Long id){
dictDetailService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment