Commit 4e39694e authored by zhengjie's avatar zhengjie
Browse files

v1.6 版本发布 ,详情查看版本说明

parent f63407fd
......@@ -109,7 +109,7 @@ eladmin-qt和eladmin-qd只是命名方式的区别,无其他区别
<td><img src="https://i.loli.net/2018/12/22/5c1e10c7890ab.png"/></td>
</tr>
<tr>
<td><img src="https://i.loli.net/2018/12/22/5c1e10c782a05.png"/></td>
<td><img src="https://i.loli.net/2019/02/28/5c7795b707347.png"/></td>
<td><img src="https://i.loli.net/2018/12/22/5c1e10c7b089b.png"/></td>
</tr>
<tr>
......
......@@ -7,10 +7,10 @@ import me.zhengjie.exception.EntityNotFoundException;
import me.zhengjie.utils.ThrowableUtil;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.nio.file.AccessDeniedException;
import static org.springframework.http.HttpStatus.*;
/**
......
......@@ -94,10 +94,9 @@ public class RedisConfig extends CachingConfigurerSupport {
// 全局开启AutoType,不建议使用
// ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
// 建议使用这种方式,小范围指定白名单
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.service.dto");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.test.service.dto");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.system.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.quartz.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.monitor.domain");
ParserConfig.getGlobalInstance().addAccept("me.zhengjie.modules.security.security");
......
......@@ -2,7 +2,6 @@ package me.zhengjie.swagger2;
import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
......@@ -13,25 +12,17 @@ import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
/**
* api页面 /swagger-ui.html
* 如controller在不同的包中,@ComponentScan(basePackages = {"me.aurora.app.rest","..."})
* @author jie
* @date 2018-11-23
*/
@Configuration
@EnableSwagger2
@ComponentScan(basePackages = {
"me.zhengjie.rest",
"me.zhengjie.modules.system.rest",
"me.zhengjie.modules.monitor.rest",
"me.zhengjie.modules.monitor.rest",
"me.zhengjie.modules.quartz.rest"})
public class SwaggerConfig {
@Bean
......
package me.zhengjie.utils;
import org.springframework.util.DigestUtils;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
......
......@@ -2,7 +2,6 @@ package me.zhengjie.utils;
import cn.hutool.core.util.IdUtil;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
......
package me.zhengjie.utils;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* List按照指定字段排序工具类
* @author jie
* @date 2018/08/23 20:03:12
* @param <T>
*/
public class ListSortUtil<T> {
/**
* @param targetList 目标排序List
* @param sortField 排序字段(实体类属性名)
* @param sortMode 排序方式(asc or desc)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void sort(List<T> targetList, final String sortField, final String sortMode) {
Collections.sort(targetList, new Comparator() {
@Override
public int compare(Object obj1, Object obj2) {
int retVal = 0;
try {
//首字母转大写
String newStr=sortField.substring(0, 1).toUpperCase()+sortField.replaceFirst("\\w","");
String methodStr="get"+newStr;
Method method1 = ((T)obj1).getClass().getMethod(methodStr, new Class[0]);
Method method2 = ((T)obj2).getClass().getMethod(methodStr, new Class[0]);
if (sortMode != null && "desc".equals(sortMode)) {
// 倒序
retVal = method2.invoke(((T) obj2), new Object[0]).toString().compareTo(method1.invoke(((T) obj1), new Object[0]).toString());
} else {
// 正序
retVal = method1.invoke(((T) obj1), new Object[0]).toString().compareTo(method2.invoke(((T) obj2), new Object[0]).toString());
}
} catch (Exception e) {
throw new RuntimeException();
}
return retVal;
}
});
}
}
\ No newline at end of file
......@@ -21,6 +21,12 @@
<groupId>me.zhengjie</groupId>
<artifactId>eladmin-generator</artifactId>
<version>1.5</version>
<exclusions>
<exclusion>
<groupId>me.zhengjie</groupId>
<artifactId>eladmin-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
......
This diff is collapsed.
......@@ -5,6 +5,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* @author jie
......@@ -13,7 +14,7 @@ import javax.validation.constraints.NotBlank;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RedisVo {
public class RedisVo implements Serializable {
@NotBlank
private String key;
......
......@@ -5,6 +5,7 @@ import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
......@@ -21,6 +22,7 @@ public class QuartzJob implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = {Update.class})
private Long id;
/**
......@@ -75,4 +77,6 @@ public class QuartzJob implements Serializable {
@UpdateTimestamp
@Column(name = "update_time")
private Timestamp updateTime;
public interface Update{}
}
\ No newline at end of file
......@@ -68,10 +68,7 @@ public class QuartzJobController {
@Log("修改定时任务")
@PutMapping(value = "/jobs")
@PreAuthorize("hasAnyRole('ADMIN','JOB_ALL','JOB_EDIT')")
public ResponseEntity update(@Validated @RequestBody QuartzJob resources){
if (resources.getId() == null) {
throw new BadRequestException(ENTITY_NAME +" ID Can not be empty");
}
public ResponseEntity update(@Validated(QuartzJob.Update.class) @RequestBody QuartzJob resources){
quartzJobService.update(resources);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
......
......@@ -41,7 +41,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
private String tokenHeader;
@Value("${jwt.auth.path}")
private String authenticationPath;
private String loginPath;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
......@@ -74,9 +74,18 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
// 不创建会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests()
.antMatchers("/auth/**").permitAll()
// 过滤请求
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js"
).permitAll()
.antMatchers( HttpMethod.POST,"/auth/"+loginPath).permitAll()
.antMatchers("/websocket/**").permitAll()
.antMatchers("/druid/**").anonymous()
......@@ -91,33 +100,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/*/api-docs").anonymous()
// swagger end
// 接口限流测试
.antMatchers("/test/**").anonymous()
.antMatchers(HttpMethod.OPTIONS, "/**").anonymous()
// 所有请求都需要认证
.anyRequest().authenticated();
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) throws Exception {
// AuthenticationTokenFilter will ignore the below paths
web.ignoring()
.antMatchers(
HttpMethod.POST,
authenticationPath
)
// allow anonymous resource requests
.and()
.ignoring()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js"
);
}
}
......@@ -2,7 +2,7 @@ package me.zhengjie.modules.security.rest;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.aop.log.Log;
import me.zhengjie.modules.security.security.AuthenticationToken;
import me.zhengjie.modules.security.security.AuthenticationInfo;
import me.zhengjie.modules.security.security.AuthorizationUser;
import me.zhengjie.modules.security.security.JwtUser;
import me.zhengjie.utils.EncryptUtils;
......@@ -47,21 +47,21 @@ public class AuthenticationController {
@PostMapping(value = "${jwt.auth.path}")
public ResponseEntity login(@Validated @RequestBody AuthorizationUser authorizationUser){
final UserDetails userDetails = userDetailsService.loadUserByUsername(authorizationUser.getUsername());
final JwtUser jwtUser = (JwtUser) userDetailsService.loadUserByUsername(authorizationUser.getUsername());
if(!userDetails.getPassword().equals(EncryptUtils.encryptPassword(authorizationUser.getPassword()))){
if(!jwtUser.getPassword().equals(EncryptUtils.encryptPassword(authorizationUser.getPassword()))){
throw new AccountExpiredException("密码错误");
}
if(!userDetails.isEnabled()){
if(!jwtUser.isEnabled()){
throw new AccountExpiredException("账号已停用,请联系管理员");
}
// 生成令牌
final String token = jwtTokenUtil.generateToken(userDetails);
final String token = jwtTokenUtil.generateToken(jwtUser);
// 返回 token
return ResponseEntity.ok(new AuthenticationToken(token));
return ResponseEntity.ok(new AuthenticationInfo(token,jwtUser));
}
/**
......
package me.zhengjie.modules.security.security;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
/**
* @author jie
* @date 2018-11-23
* 返回token
*/
@Getter
@AllArgsConstructor
public class AuthenticationToken implements Serializable {
private final String token;
}
package me.zhengjie.modules.security.security;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
/**
* @author jie
* @date 2018-11-23
* 返回token
*/
@Getter
@AllArgsConstructor
public class AuthenticationInfo implements Serializable {
private final String token;
private final JwtUser user;
}
......@@ -4,12 +4,12 @@ import me.zhengjie.modules.system.domain.Permission;
import me.zhengjie.modules.system.domain.Role;
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 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.security.core.userdetails.UserDetails;
......@@ -33,6 +33,12 @@ public class JwtUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Autowired
private RoleRepository roleRepository;
@Autowired
private PermissionRepository permissionRepository;
@Override
public UserDetails loadUserByUsername(String username){
......@@ -57,20 +63,20 @@ public class JwtUserDetailsService implements UserDetailsService {
user.getPassword(),
user.getAvatar(),
user.getEmail(),
mapToGrantedAuthorities(user.getRoles()),
mapToGrantedAuthorities(roleRepository.findByUsers_Id(user.getId()),permissionRepository),
user.getEnabled(),
user.getCreateTime(),
user.getLastPasswordResetTime()
);
}
private static List<GrantedAuthority> mapToGrantedAuthorities(Set<Role> roles) {
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(role.getPermissions());
permissions.addAll(permissionRepository.findByRoles_Id(role.getId()));
}
return permissions.stream()
......
package me.zhengjie.modules.system.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Set;
......@@ -16,10 +19,11 @@ import java.util.Set;
@Getter
@Setter
@Table(name = "menu")
public class Menu {
public class Menu implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = {Update.class})
private Long id;
@NotBlank
......@@ -47,11 +51,13 @@ public class Menu {
@Column(name = "i_frame")
private Boolean iFrame;
@ManyToMany
@JoinTable(name = "menus_roles", joinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")})
@ManyToMany(mappedBy = "menus")
@JsonIgnore
private Set<Role> roles;
@CreationTimestamp
@Column(name = "create_time")
private Timestamp createTime;
public interface Update{}
}
......@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
......@@ -24,6 +23,7 @@ public class Permission implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = {Update.class})
private Long id;
@NotBlank
......@@ -57,4 +57,6 @@ public class Permission implements Serializable{
", createTime=" + createTime +
'}';
}
public interface Update{}
}
......@@ -7,6 +7,7 @@ import org.hibernate.annotations.CreationTimestamp;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Set;
......@@ -24,6 +25,7 @@ public class Role implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = {Update.class})
private Long id;
@Column(nullable = false)
......@@ -41,8 +43,8 @@ public class Role implements Serializable {
@JoinTable(name = "roles_permissions", joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "permission_id",referencedColumnName = "id")})
private Set<Permission> permissions;
@JsonIgnore
@ManyToMany(mappedBy = "roles")
@ManyToMany
@JoinTable(name = "roles_menus", joinColumns = {@JoinColumn(name = "role_id",referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "menu_id",referencedColumnName = "id")})
private Set<Menu> menus;
@CreationTimestamp
......@@ -58,4 +60,6 @@ public class Role implements Serializable {
", createDateTime=" + createTime +
'}';
}
public interface Update{}
}
......@@ -25,6 +25,7 @@ public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@NotNull(groups = Update.class)
private Long id;
@NotBlank
......@@ -65,4 +66,6 @@ public class User implements Serializable {
", lastPasswordResetTime=" + lastPasswordResetTime +
'}';
}
public @interface Update {}
}
\ 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