Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-microservice-exam
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
汪想
spring-microservice-exam
Commits
b822b4d2
Commit
b822b4d2
authored
Nov 14, 2019
by
tangyi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev'
parents
8660b235
ec73b1e7
Show whitespace changes
Inline
Side-by-side
Showing
45 changed files
with
734 additions
and
448 deletions
+734
-448
README.md
README.md
+1
-1
pom.xml
common/common-security/pom.xml
+6
-0
AdminAuthorization.java
...angyi/common/security/annotations/AdminAuthorization.java
+18
-0
AdminTenantTeacherAuthorization.java
...security/annotations/AdminTenantTeacherAuthorization.java
+18
-0
UserAuthorization.java
...tangyi/common/security/annotations/UserAuthorization.java
+18
-0
SecurityConstant.java
...hub/tangyi/common/security/constant/SecurityConstant.java
+0
-15
CustomUserDetailsService.java
...tangyi/common/security/core/CustomUserDetailsService.java
+6
-6
Roles.java
...n/java/com/github/tangyi/common/security/enums/Roles.java
+36
-0
CustomAuthenticationFailureEvent.java
...mmon/security/event/CustomAuthenticationFailureEvent.java
+25
-0
CustomAuthenticationSuccessEvent.java
...mmon/security/event/CustomAuthenticationSuccessEvent.java
+23
-0
CustomOauthException.java
...ngyi/common/security/exceptions/CustomOauthException.java
+0
-27
MobileAuthenticationProvider.java
.../common/security/mobile/MobileAuthenticationProvider.java
+8
-1
MobileSecurityConfigurer.java
...ngyi/common/security/mobile/MobileSecurityConfigurer.java
+5
-0
CustomOauthExceptionSerializer.java
...n/security/serializer/CustomOauthExceptionSerializer.java
+0
-40
WxAuthenticationProvider.java
...b/tangyi/common/security/wx/WxAuthenticationProvider.java
+7
-0
WxSecurityConfigurer.java
...ithub/tangyi/common/security/wx/WxSecurityConfigurer.java
+5
-0
package-lock.json
frontend/spring-microservice-exam-web/package-lock.json
+0
-0
AopConfig.java
...rc/main/java/com/github/tangyi/auth/config/AopConfig.java
+16
-0
CustomAuthorizationServerConfigurer.java
...ngyi/auth/config/CustomAuthorizationServerConfigurer.java
+3
-38
SecurityConfig.java
...in/java/com/github/tangyi/auth/config/SecurityConfig.java
+27
-1
OauthClientDetailsController.java
.../tangyi/auth/controller/OauthClientDetailsController.java
+5
-6
CustomOAuth2AccessDeniedHandler.java
...ub/tangyi/auth/error/CustomOAuth2AccessDeniedHandler.java
+48
-0
CustomOAuth2ExceptionRenderer.java
...thub/tangyi/auth/error/CustomOAuth2ExceptionRenderer.java
+106
-0
CustomTokenEndpointAuthenticationFilter.java
.../auth/filter/CustomTokenEndpointAuthenticationFilter.java
+0
-94
LoginFailureListener.java
...com/github/tangyi/auth/listener/LoginFailureListener.java
+29
-0
LoginSuccessListener.java
...com/github/tangyi/auth/listener/LoginSuccessListener.java
+103
-0
CustomUserDetailsAuthenticationProvider.java
...uth/security/CustomUserDetailsAuthenticationProvider.java
+11
-3
CustomUserDetailsServiceImpl.java
...ub/tangyi/auth/security/CustomUserDetailsServiceImpl.java
+10
-88
ValidateTenantAspect.java
...com/github/tangyi/auth/security/ValidateTenantAspect.java
+42
-0
CourseController.java
...a/com/github/tangyi/exam/controller/CourseController.java
+5
-6
ExamRecordController.java
...m/github/tangyi/exam/controller/ExamRecordController.java
+4
-62
ExaminationController.java
.../github/tangyi/exam/controller/ExaminationController.java
+5
-7
SubjectCategoryController.java
...hub/tangyi/exam/controller/SubjectCategoryController.java
+4
-5
SubjectController.java
.../com/github/tangyi/exam/controller/SubjectController.java
+7
-8
ExamRecordService.java
...ava/com/github/tangyi/exam/service/ExamRecordService.java
+47
-0
ExaminationService.java
...va/com/github/tangyi/exam/service/ExaminationService.java
+0
-1
SubjectService.java
...n/java/com/github/tangyi/exam/service/SubjectService.java
+0
-1
MenuConstant.java
...ava/com/github/tangyi/user/api/constant/MenuConstant.java
+23
-0
DeptController.java
...ava/com/github/tangyi/user/controller/DeptController.java
+4
-5
LogController.java
...java/com/github/tangyi/user/controller/LogController.java
+3
-8
MenuController.java
...ava/com/github/tangyi/user/controller/MenuController.java
+6
-7
RoleController.java
...ava/com/github/tangyi/user/controller/RoleController.java
+5
-6
UserController.java
...ava/com/github/tangyi/user/controller/UserController.java
+8
-8
MenuService.java
...main/java/com/github/tangyi/user/service/MenuService.java
+29
-4
pom.xml
pom.xml
+8
-0
No files found.
README.md
View file @
b822b4d2
...
...
@@ -46,7 +46,7 @@
| 名称 | 版本 |
| --------- | -------- |
|
`Spring Boot`
|
`2.1.
8
.RELEASE`
|
|
`Spring Boot`
|
`2.1.
9
.RELEASE`
|
|
`Spring Cloud`
|
`Greenwich.SR3`
|
# 5 系统架构
...
...
common/common-security/pom.xml
View file @
b822b4d2
...
...
@@ -35,5 +35,11 @@
<artifactId>
commons-io
</artifactId>
<version>
${commons-io.version}
</version>
</dependency>
<!-- jjwt -->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
</dependency>
</dependencies>
</project>
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/AdminAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 超级管理员权限注解
*
* @author tangyi
* @date 2019/11/02 12:33
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN)"
)
public
@interface
AdminAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/AdminTenantTeacherAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 租户或超管权限
*
* @author tangyi
* @date 2019/11/02 12:40
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TENANT_ADMIN) or hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_TEACHER)"
)
public
@interface
AdminTenantTeacherAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/annotations/UserAuthorization.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
annotations
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
java.lang.annotation.*
;
/**
* 普通用户权限
*
* @author tangyi
* @date 2019/11/02 12:44
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Inherited
@PreAuthorize
(
"hasRole(T(com.github.tangyi.common.security.enums.Roles).ROLE_USER)"
)
public
@interface
UserAuthorization
{
}
common/common-security/src/main/java/com/github/tangyi/common/security/constant/SecurityConstant.java
View file @
b822b4d2
...
...
@@ -7,16 +7,6 @@ package com.github.tangyi.common.security.constant;
public
class
SecurityConstant
{
/**
* 基础角色
*/
public
static
final
String
BASE_ROLE
=
"role_user"
;
/**
* 超级管理员角色
*/
public
static
final
String
ROLE_ADMIN
=
"role_admin"
;
/**
* 租户管理员角色
*/
public
static
final
String
ROLE_TENANT_ADMIN
=
"role_tenant_admin"
;
...
...
@@ -37,11 +27,6 @@ public class SecurityConstant {
public
static
final
String
NORMAL
=
"0"
;
/**
* 异常状态
*/
public
static
final
String
ABNORMAL
=
"1"
;
/**
* 手机登录URL
*/
public
static
final
String
MOBILE_TOKEN_URL
=
"/mobile/token"
;
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/core/CustomUserDetailsService.java
View file @
b822b4d2
...
...
@@ -16,35 +16,35 @@ public interface CustomUserDetailsService {
/**
* 根据用户名和租户标识查询
*
* @param username username
* @param tenantCode tenantCode
* @param username username
* @return UserDetails
* @author tangyi
* @date 2019/05/28 21:06
*/
UserDetails
loadUserByIdentifierAndTenantCode
(
String
username
,
String
tenantCod
e
)
throws
UsernameNotFoundException
;
UserDetails
loadUserByIdentifierAndTenantCode
(
String
tenantCode
,
String
usernam
e
)
throws
UsernameNotFoundException
;
/**
* 根据社交账号和租户标识查询
*
* @param social social
* @param tenantCode tenantCode
* @param social social
* @param mobileUser mobileUser
* @return UserDetails
* @author tangyi
* @date 2019/06/22 21:08
*/
UserDetails
loadUserBySocialAndTenantCode
(
String
social
,
String
tenantCode
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
;
UserDetails
loadUserBySocialAndTenantCode
(
String
tenantCode
,
String
social
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
;
/**
* 根据微信openId和租户标识查询
*
* @param code code
* @param tenantCode tenantCode
* @param code code
* @param wxUser wxUser
* @return UserDetails
* @author tangyi
* @date 2019/07/05 20:04:59
*/
UserDetails
loadUserByWxCodeAndTenantCode
(
String
code
,
String
tenantC
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
;
UserDetails
loadUserByWxCodeAndTenantCode
(
String
tenantCode
,
String
c
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
;
}
common/common-security/src/main/java/com/github/tangyi/common/security/enums/Roles.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
enums
;
import
org.springframework.security.core.GrantedAuthority
;
/**
* 角色枚举
*
* @author tangyi
* @date 2019/11/02 12:30
*/
public
enum
Roles
implements
GrantedAuthority
{
/**
* 普通用户
*/
ROLE_USER
,
/**
* 超级管理员
*/
ROLE_ADMIN
,
/**
* 租户管理员
*/
ROLE_TENANT_ADMIN
,
/**
* 老师
*/
ROLE_TEACHER
;
@Override
public
String
getAuthority
()
{
return
name
();
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/event/CustomAuthenticationFailureEvent.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
event
;
import
lombok.Data
;
import
org.springframework.context.ApplicationEvent
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
*
* 登录失败事件
*
* @author tangyi
* @date 2019-11-11 23:46
*/
@Data
public
class
CustomAuthenticationFailureEvent
extends
ApplicationEvent
{
private
UserDetails
userDetails
;
public
CustomAuthenticationFailureEvent
(
Authentication
authentication
,
UserDetails
userDetails
)
{
super
(
authentication
);
this
.
userDetails
=
userDetails
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/event/CustomAuthenticationSuccessEvent.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
event
;
import
lombok.Data
;
import
org.springframework.context.ApplicationEvent
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
* 登录成功事件
*
* @author tangyi
* @date 2019-11-11 23:40
*/
@Data
public
class
CustomAuthenticationSuccessEvent
extends
ApplicationEvent
{
private
UserDetails
userDetails
;
public
CustomAuthenticationSuccessEvent
(
Authentication
authentication
,
UserDetails
userDetails
)
{
super
(
authentication
);
this
.
userDetails
=
userDetails
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/exceptions/CustomOauthException.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
common
.
security
.
exceptions
;
import
com.fasterxml.jackson.databind.annotation.JsonSerialize
;
import
com.github.tangyi.common.security.serializer.CustomOauthExceptionSerializer
;
import
lombok.Data
;
import
org.springframework.security.oauth2.common.exceptions.OAuth2Exception
;
/**
* 定制OAuth2Exception
*
* @author tangyi
* @date 2019/3/18 22:36
*/
@Data
@JsonSerialize
(
using
=
CustomOauthExceptionSerializer
.
class
)
public
class
CustomOauthException
extends
OAuth2Exception
{
/**
* 错误码
*/
private
int
code
;
public
CustomOauthException
(
String
msg
,
int
code
)
{
super
(
msg
);
this
.
code
=
code
;
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/mobile/MobileAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
mobile
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.support.MessageSourceAccessor
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.BadCredentialsException
;
...
...
@@ -24,17 +27,21 @@ public class MobileAuthenticationProvider implements AuthenticationProvider {
private
CustomUserDetailsService
customUserDetailsService
;
private
ApplicationEventPublisher
publisher
;
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
MobileAuthenticationToken
mobileAuthenticationToken
=
(
MobileAuthenticationToken
)
authentication
;
String
principal
=
mobileAuthenticationToken
.
getPrincipal
().
toString
();
UserDetails
userDetails
=
customUserDetailsService
.
loadUserBySocialAndTenantCode
(
principal
,
TenantContextHolder
.
getTenantCode
()
,
mobileAuthenticationToken
.
getMobileUser
());
UserDetails
userDetails
=
customUserDetailsService
.
loadUserBySocialAndTenantCode
(
TenantContextHolder
.
getTenantCode
(),
principal
,
mobileAuthenticationToken
.
getMobileUser
());
if
(
userDetails
==
null
)
{
log
.
debug
(
"Authentication failed: no credentials provided"
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.noopBindAccount"
,
"Noop Bind Account"
));
}
MobileAuthenticationToken
authenticationToken
=
new
MobileAuthenticationToken
(
userDetails
,
userDetails
.
getAuthorities
());
authenticationToken
.
setDetails
(
mobileAuthenticationToken
.
getDetails
());
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
return
authenticationToken
;
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/mobile/MobileSecurityConfigurer.java
View file @
b822b4d2
...
...
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
...
...
@@ -27,6 +28,9 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
@Autowired
private
AuthenticationEventPublisher
defaultAuthenticationEventPublisher
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
private
AuthenticationSuccessHandler
mobileLoginSuccessHandler
;
private
CustomUserDetailsService
userDetailsService
;
...
...
@@ -40,6 +44,7 @@ public class MobileSecurityConfigurer extends SecurityConfigurerAdapter<DefaultS
mobileAuthenticationFilter
.
setEventPublisher
(
defaultAuthenticationEventPublisher
);
MobileAuthenticationProvider
mobileAuthenticationProvider
=
new
MobileAuthenticationProvider
();
mobileAuthenticationProvider
.
setCustomUserDetailsService
(
userDetailsService
);
mobileAuthenticationProvider
.
setPublisher
(
applicationEventPublisher
);
// 增加手机登录的过滤器
http
.
authenticationProvider
(
mobileAuthenticationProvider
).
addFilterAfter
(
mobileAuthenticationFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/serializer/CustomOauthExceptionSerializer.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
common
.
security
.
serializer
;
import
com.fasterxml.jackson.core.JsonGenerator
;
import
com.fasterxml.jackson.databind.SerializerProvider
;
import
com.fasterxml.jackson.databind.ser.std.StdSerializer
;
import
com.github.tangyi.common.security.exceptions.CustomOauthException
;
import
java.io.IOException
;
import
java.util.Map
;
/**
* 定制OauthException序列化
*
* @author tangyi
* @date 2019/3/18 22:37
*/
public
class
CustomOauthExceptionSerializer
extends
StdSerializer
<
CustomOauthException
>
{
public
CustomOauthExceptionSerializer
()
{
super
(
CustomOauthException
.
class
);
}
@Override
public
void
serialize
(
CustomOauthException
value
,
JsonGenerator
gen
,
SerializerProvider
provider
)
throws
IOException
{
gen
.
writeStartObject
();
// 封装属性,和ResponseBean对应
gen
.
writeNumberField
(
"status"
,
value
.
getCode
());
// 返回给前端的code
gen
.
writeNumberField
(
"code"
,
value
.
getCode
());
// 提示信息
gen
.
writeStringField
(
"msg"
,
value
.
getMessage
());
if
(
value
.
getAdditionalInformation
()
!=
null
)
{
for
(
Map
.
Entry
<
String
,
String
>
entry
:
value
.
getAdditionalInformation
().
entrySet
())
{
String
key
=
entry
.
getKey
();
String
add
=
entry
.
getValue
();
gen
.
writeStringField
(
key
,
add
);
}
}
gen
.
writeEndObject
();
}
}
common/common-security/src/main/java/com/github/tangyi/common/security/wx/WxAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
common
.
security
.
wx
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.Data
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.support.MessageSourceAccessor
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.authentication.BadCredentialsException
;
...
...
@@ -24,6 +27,8 @@ public class WxAuthenticationProvider implements AuthenticationProvider {
private
CustomUserDetailsService
customUserDetailsService
;
private
ApplicationEventPublisher
publisher
;
@Override
public
Authentication
authenticate
(
Authentication
authentication
)
throws
AuthenticationException
{
WxAuthenticationToken
wxAuthenticationToken
=
(
WxAuthenticationToken
)
authentication
;
...
...
@@ -32,10 +37,12 @@ public class WxAuthenticationProvider implements AuthenticationProvider {
UserDetails
userDetails
=
customUserDetailsService
.
loadUserByWxCodeAndTenantCode
(
principal
,
TenantContextHolder
.
getTenantCode
(),
wxAuthenticationToken
.
getWxUser
());
if
(
userDetails
==
null
)
{
log
.
debug
(
"Authentication failed: no credentials provided"
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.noopBindAccount"
,
"Noop Bind Account"
));
}
WxAuthenticationToken
authenticationToken
=
new
WxAuthenticationToken
(
userDetails
,
userDetails
.
getAuthorities
());
authenticationToken
.
setDetails
(
wxAuthenticationToken
.
getDetails
());
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
return
authenticationToken
;
}
...
...
common/common-security/src/main/java/com/github/tangyi/common/security/wx/WxSecurityConfigurer.java
View file @
b822b4d2
...
...
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationEventPublisher
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.config.annotation.SecurityConfigurerAdapter
;
...
...
@@ -27,6 +28,9 @@ public class WxSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecur
@Autowired
private
AuthenticationEventPublisher
defaultAuthenticationEventPublisher
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
private
AuthenticationSuccessHandler
wxLoginSuccessHandler
;
private
CustomUserDetailsService
userDetailsService
;
...
...
@@ -40,6 +44,7 @@ public class WxSecurityConfigurer extends SecurityConfigurerAdapter<DefaultSecur
wxAuthenticationFilter
.
setEventPublisher
(
defaultAuthenticationEventPublisher
);
WxAuthenticationProvider
wxAuthenticationProvider
=
new
WxAuthenticationProvider
();
wxAuthenticationProvider
.
setCustomUserDetailsService
(
userDetailsService
);
wxAuthenticationProvider
.
setPublisher
(
applicationEventPublisher
);
// 增加微信登录的过滤器
http
.
authenticationProvider
(
wxAuthenticationProvider
).
addFilterAfter
(
wxAuthenticationFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
...
...
frontend/spring-microservice-exam-web/package-lock.json
0 → 100644
View file @
b822b4d2
This source diff could not be displayed because it is too large. You can
view the blob
instead.
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/AopConfig.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.EnableAspectJAutoProxy
;
/**
*
* 配置aop
*
* @author tangyi
* @date 2019-11-12 20:13
*/
@Configuration
@EnableAspectJAutoProxy
public
class
AopConfig
{
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/CustomAuthorizationServerConfigurer.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
com.github.tangyi.auth.filter.CustomTokenEndpointAuthenticationFilter
;
import
com.github.tangyi.auth.security.CustomTokenConverter
;
import
com.github.tangyi.common.security.core.ClientDetailsServiceImpl
;
import
com.github.tangyi.common.security.exceptions.CustomOauthException
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cloud.bootstrap.encrypt.KeyProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.data.redis.connection.RedisConnectionFactory
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.oauth2.common.exceptions.OAuth2Exception
;
import
org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer
;
import
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter
;
import
org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer
;
import
org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer
;
import
org.springframework.security.oauth2.provider.ClientDetailsService
;
import
org.springframework.security.oauth2.provider.OAuth2RequestFactory
;
import
org.springframework.security.oauth2.provider.token.TokenStore
;
import
org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter
;
import
org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory
;
...
...
@@ -37,11 +30,6 @@ import javax.sql.DataSource;
public
class
CustomAuthorizationServerConfigurer
extends
AuthorizationServerConfigurerAdapter
{
/**
* 认证管理器
*/
private
final
AuthenticationManager
authenticationManager
;
/**
* redis连接工厂
*/
private
final
RedisConnectionFactory
redisConnectionFactory
;
...
...
@@ -56,21 +44,13 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
*/
private
final
KeyProperties
keyProperties
;
private
final
UserServiceClient
userServiceClient
;
private
OAuth2RequestFactory
oAuth2RequestFactory
;
@Autowired
public
CustomAuthorizationServerConfigurer
(
AuthenticationManager
authenticationManager
,
RedisConnectionFactory
redisConnectionFactory
,
public
CustomAuthorizationServerConfigurer
(
RedisConnectionFactory
redisConnectionFactory
,
DataSource
dataSource
,
KeyProperties
keyProperties
,
UserServiceClient
userServiceClient
)
{
this
.
authenticationManager
=
authenticationManager
;
KeyProperties
keyProperties
)
{
this
.
redisConnectionFactory
=
redisConnectionFactory
;
this
.
dataSource
=
dataSource
;
this
.
keyProperties
=
keyProperties
;
this
.
userServiceClient
=
userServiceClient
;
}
/**
...
...
@@ -123,25 +103,11 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
*/
@Override
public
void
configure
(
AuthorizationServerEndpointsConfigurer
endpoints
)
{
oAuth2RequestFactory
=
endpoints
.
getOAuth2RequestFactory
();
endpoints
// 将token存储到redis
.
tokenStore
(
tokenStore
())
// token增强
.
tokenEnhancer
(
jwtTokenEnhancer
())
// 认证管理器
.
authenticationManager
(
authenticationManager
)
// 异常处理
.
exceptionTranslator
(
e
->
{
if
(
e
instanceof
OAuth2Exception
)
{
OAuth2Exception
oAuth2Exception
=
(
OAuth2Exception
)
e
;
return
ResponseEntity
.
status
(
oAuth2Exception
.
getHttpErrorCode
())
.
body
(
new
CustomOauthException
(
oAuth2Exception
.
getMessage
(),
oAuth2Exception
.
getHttpErrorCode
()));
}
else
{
throw
e
;
}
});
.
tokenEnhancer
(
jwtTokenEnhancer
());
}
/**
...
...
@@ -158,7 +124,6 @@ public class CustomAuthorizationServerConfigurer extends AuthorizationServerConf
// 开启/oauth/check_token验证端口认证权限访问
.
checkTokenAccess
(
"isAuthenticated()"
)
.
allowFormAuthenticationForClients
();
//.addTokenEndpointAuthenticationFilter(new CustomTokenEndpointAuthenticationFilter(authenticationManager, oAuth2RequestFactory, userServiceClient));
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/config/SecurityConfig.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
config
;
import
com.github.tangyi.auth.error.CustomOAuth2AccessDeniedHandler
;
import
com.github.tangyi.auth.security.CustomUserDetailsAuthenticationProvider
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.security.authentication.AuthenticationManager
;
...
...
@@ -12,7 +14,10 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
/**
* Spring Security配置
...
...
@@ -28,6 +33,12 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private
CustomUserDetailsService
userDetailsService
;
@Autowired
private
AuthorizationServerEndpointsConfiguration
endpoints
;
@Autowired
private
ApplicationEventPublisher
applicationEventPublisher
;
@Override
protected
void
configure
(
HttpSecurity
http
)
throws
Exception
{
http
...
...
@@ -35,6 +46,16 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.
csrf
().
disable
()
.
authorizeRequests
()
.
anyRequest
().
authenticated
();
if
(!
endpoints
.
getEndpointsConfigurer
().
isUserDetailsServiceOverride
())
{
UserDetailsService
userDetailsService
=
http
.
getSharedObject
(
UserDetailsService
.
class
);
endpoints
.
getEndpointsConfigurer
().
userDetailsService
(
userDetailsService
);
}
// 认证管理器
endpoints
.
getEndpointsConfigurer
().
authenticationManager
(
authenticationManager
());
// accessDeniedHandler
http
.
exceptionHandling
()
.
accessDeniedHandler
(
accessDeniedHandler
());
}
@Bean
...
...
@@ -54,7 +75,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
*/
@Bean
public
AuthenticationProvider
authProvider
()
{
return
new
CustomUserDetailsAuthenticationProvider
(
encoder
(),
userDetailsService
);
return
new
CustomUserDetailsAuthenticationProvider
(
encoder
(),
userDetailsService
,
applicationEventPublisher
);
}
@Override
...
...
@@ -62,5 +83,10 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
protected
AuthenticationManager
authenticationManager
()
throws
Exception
{
return
super
.
authenticationManager
();
}
@Bean
public
AccessDeniedHandler
accessDeniedHandler
()
{
return
new
CustomOAuth2AccessDeniedHandler
();
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/controller/OauthClientDetailsController.java
View file @
b822b4d2
...
...
@@ -9,7 +9,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminAuthorization
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.web.bind.annotation.*
;
...
...
@@ -113,7 +112,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:57
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:client:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"创建客户端"
,
notes
=
"创建客户端"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端实体oauthClientDetails"
,
required
=
true
,
dataType
=
"OauthClientDetails"
)
@Log
(
"新增客户端"
)
...
...
@@ -133,7 +132,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:56
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:client:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"更新客户端信息"
,
notes
=
"根据客户端id更新客户端的基本信息"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端实体oauthClientDetails"
,
required
=
true
,
dataType
=
"OauthClientDetails"
)
@Log
(
"修改客户端"
)
...
...
@@ -155,7 +154,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 16:59
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:client:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"删除客户端"
,
notes
=
"根据ID删除客户端"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"客户端ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除客户端"
)
...
...
@@ -176,7 +175,7 @@ public class OauthClientDetailsController extends BaseController {
* @date 2019/03/30 17:01
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:client:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"批量删除客户端"
,
notes
=
"根据客户端id批量删除客户端"
)
@ApiImplicitParam
(
name
=
"oauthClientDetails"
,
value
=
"客户端信息"
,
dataType
=
"OauthClientDetails"
)
@Log
(
"批量删除客户端"
)
...
...
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/error/CustomOAuth2AccessDeniedHandler.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
error
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.security.access.AccessDeniedException
;
import
org.springframework.security.oauth2.provider.error.AbstractOAuth2SecurityExceptionHandler
;
import
org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator
;
import
org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator
;
import
org.springframework.security.web.access.AccessDeniedHandler
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
*
* accessDeniedHandler,return ResponseBean
*
* @author tangyi
* @date 2019-11-11 21:24
*/
@Slf4j
public
class
CustomOAuth2AccessDeniedHandler
extends
AbstractOAuth2SecurityExceptionHandler
implements
AccessDeniedHandler
{
private
WebResponseExceptionTranslator
<?>
exceptionTranslator
=
new
DefaultWebResponseExceptionTranslator
();
private
CustomOAuth2ExceptionRenderer
exceptionRenderer
=
new
CustomOAuth2ExceptionRenderer
();
public
void
handle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
AccessDeniedException
authException
)
throws
IOException
{
try
{
ResponseEntity
<?>
result
=
exceptionTranslator
.
translate
(
authException
);
result
=
enhanceResponse
(
result
,
authException
);
exceptionRenderer
.
handleResponseBeanResponse
(
result
,
new
ServletWebRequest
(
request
,
response
));
response
.
flushBuffer
();
}
catch
(
ServletException
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
catch
(
IOException
|
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
// Wrap other Exceptions. These are not expected to happen
throw
new
RuntimeException
(
e
);
}
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/error/CustomOAuth2ExceptionRenderer.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
error
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.*
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.server.ServerHttpResponse
;
import
org.springframework.http.server.ServletServerHttpRequest
;
import
org.springframework.http.server.ServletServerHttpResponse
;
import
org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2ExceptionMessageConverter
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.context.request.NativeWebRequest
;
import
org.springframework.web.context.request.ServletWebRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
/**
*
* render异常
*
* @author tangyi
* @date 2019-11-11 21:29
*/
@Slf4j
public
class
CustomOAuth2ExceptionRenderer
{
private
List
<
HttpMessageConverter
<?>>
messageConverters
=
geDefaultMessageConverters
();
public
void
handleResponseBeanResponse
(
ResponseEntity
<?>
responseEntity
,
ServletWebRequest
webRequest
)
throws
Exception
{
if
(
responseEntity
==
null
)
{
return
;
}
HttpInputMessage
inputMessage
=
createHttpInputMessage
(
webRequest
);
HttpOutputMessage
outputMessage
=
createHttpOutputMessage
(
webRequest
);
if
(
outputMessage
instanceof
ServerHttpResponse
)
{
((
ServerHttpResponse
)
outputMessage
).
setStatusCode
(
responseEntity
.
getStatusCode
());
}
HttpHeaders
entityHeaders
=
responseEntity
.
getHeaders
();
if
(!
entityHeaders
.
isEmpty
())
{
outputMessage
.
getHeaders
().
putAll
(
entityHeaders
);
}
Object
body
=
responseEntity
.
getBody
();
if
(
body
!=
null
)
{
// 返回ResponseBean
ResponseBean
<?>
responseBean
=
new
ResponseBean
<>(
body
);
responseBean
.
setStatus
(
responseEntity
.
getStatusCode
().
value
());
writeWithMessageConverters
(
responseBean
,
inputMessage
,
outputMessage
);
}
else
{
// flush headers
outputMessage
.
getBody
();
}
}
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
private
void
writeWithMessageConverters
(
Object
returnValue
,
HttpInputMessage
inputMessage
,
HttpOutputMessage
outputMessage
)
throws
IOException
,
HttpMediaTypeNotAcceptableException
{
List
<
MediaType
>
acceptedMediaTypes
=
inputMessage
.
getHeaders
().
getAccept
();
if
(
acceptedMediaTypes
.
isEmpty
())
{
acceptedMediaTypes
=
Collections
.
singletonList
(
MediaType
.
ALL
);
}
MediaType
.
sortByQualityValue
(
acceptedMediaTypes
);
Class
<?>
returnValueType
=
returnValue
.
getClass
();
List
<
MediaType
>
allSupportedMediaTypes
=
new
ArrayList
<>();
for
(
MediaType
acceptedMediaType
:
acceptedMediaTypes
)
{
for
(
HttpMessageConverter
messageConverter
:
messageConverters
)
{
if
(
messageConverter
.
canWrite
(
returnValueType
,
acceptedMediaType
))
{
messageConverter
.
write
(
returnValue
,
acceptedMediaType
,
outputMessage
);
if
(
log
.
isDebugEnabled
())
{
MediaType
contentType
=
outputMessage
.
getHeaders
().
getContentType
();
if
(
contentType
==
null
)
{
contentType
=
acceptedMediaType
;
}
log
.
debug
(
"Written ["
+
returnValue
+
"] as \""
+
contentType
+
"\" using ["
+
messageConverter
+
"]"
);
}
return
;
}
}
}
for
(
HttpMessageConverter
messageConverter
:
messageConverters
)
{
allSupportedMediaTypes
.
addAll
(
messageConverter
.
getSupportedMediaTypes
());
}
throw
new
HttpMediaTypeNotAcceptableException
(
allSupportedMediaTypes
);
}
private
List
<
HttpMessageConverter
<?>>
geDefaultMessageConverters
()
{
List
<
HttpMessageConverter
<?>>
result
=
new
ArrayList
<>(
new
RestTemplate
().
getMessageConverters
());
result
.
add
(
new
JaxbOAuth2ExceptionMessageConverter
());
return
result
;
}
private
HttpInputMessage
createHttpInputMessage
(
NativeWebRequest
webRequest
)
{
return
new
ServletServerHttpRequest
(
webRequest
.
getNativeRequest
(
HttpServletRequest
.
class
));
}
private
HttpOutputMessage
createHttpOutputMessage
(
NativeWebRequest
webRequest
)
{
return
new
ServletServerHttpResponse
((
HttpServletResponse
)
webRequest
.
getNativeResponse
());
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/filter/CustomTokenEndpointAuthenticationFilter.java
deleted
100644 → 0
View file @
8660b235
package
com
.
github
.
tangyi
.
auth
.
filter
;
import
com.github.tangyi.auth.model.CustomUserDetails
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.constant.ServiceConstant
;
import
com.github.tangyi.common.core.model.Log
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.oauth2.provider.OAuth2RequestFactory
;
import
org.springframework.security.oauth2.provider.endpoint.TokenEndpointAuthenticationFilter
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.ServletResponse
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
*
* 登录成功后的处理,如记录登录日志
*
* @author tangyi
* @date 2019-10-11 12:08
*/
@Slf4j
public
class
CustomTokenEndpointAuthenticationFilter
extends
TokenEndpointAuthenticationFilter
{
private
UserServiceClient
userServiceClient
;
public
CustomTokenEndpointAuthenticationFilter
(
AuthenticationManager
authenticationManager
,
OAuth2RequestFactory
oAuth2RequestFactory
,
UserServiceClient
userServiceClient
)
{
super
(
authenticationManager
,
oAuth2RequestFactory
);
this
.
userServiceClient
=
userServiceClient
;
}
@Override
protected
void
onSuccessfulAuthentication
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Authentication
authentication
)
throws
IOException
{
// 登录成功后的处理
log
.
info
(
"CustomTokenEndpointAuthenticationFilter onSuccessfulAuthentication"
);
CustomUserDetails
userDetails
=
(
CustomUserDetails
)
authentication
.
getPrincipal
();
String
tenantCode
=
userDetails
.
getTenantCode
();
String
username
=
userDetails
.
getUsername
();
log
.
info
(
"CustomTokenEndpointAuthenticationFilter 登录成功, tenantCode: {}, username: {}"
,
tenantCode
,
username
);
// 记录日志
Log
logInfo
=
new
Log
();
logInfo
.
setCommonValue
(
username
,
SysUtil
.
getSysCode
(),
tenantCode
);
logInfo
.
setTitle
(
"用户登录"
);
logInfo
.
setType
(
CommonConstant
.
STATUS_NORMAL
);
logInfo
.
setMethod
(
request
.
getMethod
());
logInfo
.
setTime
(
String
.
valueOf
(
System
.
currentTimeMillis
()
-
userDetails
.
getStart
()));
logInfo
.
setRequestUri
(
request
.
getRequestURI
());
// 获取ip、浏览器信息
logInfo
.
setIp
(
request
.
getRemoteAddr
());
logInfo
.
setUserAgent
(
request
.
getHeader
(
HttpHeaders
.
USER_AGENT
));
logInfo
.
setServiceId
(
ServiceConstant
.
AUTH_SERVICE
);
// 记录日志
saveLoginSuccessLog
(
logInfo
);
}
@Override
public
void
doFilter
(
ServletRequest
req
,
ServletResponse
res
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
// 认证前的特殊处理
// if (!condition) {
// throw new AuthenticationServiceException("condition not satisfied");
// }
log
.
info
(
"CustomTokenEndpointAuthenticationFilter doFilter"
);
super
.
doFilter
(
req
,
res
,
chain
);
}
/**
* 异步记录登录日志
*
* @author tangyi
* @date 2019/05/30 23:30
*/
@Async
public
void
saveLoginSuccessLog
(
Log
logInfo
)
{
try
{
userServiceClient
.
saveLog
(
logInfo
);
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/listener/LoginFailureListener.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
listener
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.stereotype.Component
;
/**
*
* 处理登录失败事件
*
* @author tangyi
* @date 2019-11-11 23:52
*/
@Slf4j
@AllArgsConstructor
@Component
public
class
LoginFailureListener
implements
ApplicationListener
<
CustomAuthenticationFailureEvent
>
{
private
final
UserServiceClient
userServiceClient
;
@Override
public
void
onApplicationEvent
(
CustomAuthenticationFailureEvent
event
)
{
// 登录失败后的处理
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/listener/LoginSuccessListener.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
listener
;
import
com.github.tangyi.auth.model.CustomUserDetails
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.constant.ServiceConstant
;
import
com.github.tangyi.common.core.model.Log
;
import
com.github.tangyi.common.core.utils.DateUtils
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.user.api.dto.UserDto
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.request.RequestAttributes
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.http.HttpServletRequest
;
import
java.time.LocalDateTime
;
/**
*
* 处理登录成功事件
*
* @author tangyi
* @date 2019-11-11 23:48
*/
@Slf4j
@AllArgsConstructor
@Component
public
class
LoginSuccessListener
implements
ApplicationListener
<
CustomAuthenticationSuccessEvent
>
{
private
final
UserServiceClient
userServiceClient
;
@Override
public
void
onApplicationEvent
(
CustomAuthenticationSuccessEvent
event
)
{
// 登录成功后的处理
UserDetails
userDetails
=
event
.
getUserDetails
();
if
(
userDetails
instanceof
CustomUserDetails
)
{
CustomUserDetails
customUserDetails
=
(
CustomUserDetails
)
userDetails
;
String
tenantCode
=
customUserDetails
.
getTenantCode
();
String
username
=
userDetails
.
getUsername
();
log
.
info
(
"{} login success, tenantCode: {}"
,
username
,
tenantCode
);
// 记录日志
Log
logInfo
=
new
Log
();
logInfo
.
setTitle
(
"用户登录"
);
logInfo
.
setCommonValue
(
username
,
SysUtil
.
getSysCode
(),
tenantCode
);
logInfo
.
setTime
(
String
.
valueOf
(
System
.
currentTimeMillis
()
-
customUserDetails
.
getStart
()));
logInfo
.
setType
(
CommonConstant
.
STATUS_NORMAL
);
HttpServletRequest
request
=
currentRequestAttributes
().
getRequest
();
logInfo
.
setMethod
(
request
.
getMethod
());
logInfo
.
setRequestUri
(
request
.
getRequestURI
());
// 获取ip、浏览器信息
logInfo
.
setIp
(
request
.
getRemoteAddr
());
logInfo
.
setUserAgent
(
request
.
getHeader
(
HttpHeaders
.
USER_AGENT
));
logInfo
.
setServiceId
(
ServiceConstant
.
AUTH_SERVICE
);
// 记录日志和登录时间
UserDto
userDto
=
new
UserDto
();
userDto
.
setIdentifier
(
username
);
userDto
.
setLoginTime
(
DateUtils
.
asDate
(
LocalDateTime
.
now
()));
saveLoginInfo
(
logInfo
,
userDto
);
}
}
/**
* 异步记录登录日志
*
* @param logInfo logInfo
* @param userDto userDto
* @author tangyi
* @date 2019/05/30 23:30
*/
@Async
public
void
saveLoginInfo
(
Log
logInfo
,
UserDto
userDto
)
{
try
{
userServiceClient
.
saveLog
(
logInfo
);
//userServiceClient.updateUser(userDto);
}
catch
(
Exception
e
)
{
log
.
error
(
e
.
getMessage
(),
e
);
}
}
/**
*
* 获取当前request
*
* @return ServletRequestAttributes
* @author tangyi
* @date 2019-11-12 00:15
*/
private
static
ServletRequestAttributes
currentRequestAttributes
()
{
RequestAttributes
requestAttr
=
RequestContextHolder
.
currentRequestAttributes
();
if
(!(
requestAttr
instanceof
ServletRequestAttributes
))
{
throw
new
IllegalStateException
(
"Current request is not a servlet request"
);
}
return
(
ServletRequestAttributes
)
requestAttr
;
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/CustomUserDetailsAuthenticationProvider.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
security
;
import
com.github.tangyi.common.security.event.CustomAuthenticationFailureEvent
;
import
com.github.tangyi.common.security.event.CustomAuthenticationSuccessEvent
;
import
com.github.tangyi.common.core.exceptions.TenantNotFoundException
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.tenant.TenantContextHolder
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.context.ApplicationEventPublisher
;
import
org.springframework.security.authentication.BadCredentialsException
;
import
org.springframework.security.authentication.InternalAuthenticationServiceException
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
...
...
@@ -30,9 +33,12 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
private
String
userNotFoundEncodedPassword
;
public
CustomUserDetailsAuthenticationProvider
(
PasswordEncoder
passwordEncoder
,
CustomUserDetailsService
userDetailsService
)
{
private
ApplicationEventPublisher
publisher
;
public
CustomUserDetailsAuthenticationProvider
(
PasswordEncoder
passwordEncoder
,
CustomUserDetailsService
userDetailsService
,
ApplicationEventPublisher
publisher
)
{
this
.
passwordEncoder
=
passwordEncoder
;
this
.
userDetailsService
=
userDetailsService
;
this
.
publisher
=
publisher
;
}
@Override
...
...
@@ -46,8 +52,10 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
// 匹配密码
if
(!
passwordEncoder
.
matches
(
presentedPassword
,
userDetails
.
getPassword
()))
{
log
.
debug
(
"认证失败: 密码错误."
);
publisher
.
publishEvent
(
new
CustomAuthenticationFailureEvent
(
authentication
,
userDetails
));
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.badCredentials"
,
"密码错误."
));
}
publisher
.
publishEvent
(
new
CustomAuthenticationSuccessEvent
(
authentication
,
userDetails
));
}
@Override
...
...
@@ -70,9 +78,9 @@ public class CustomUserDetailsAuthenticationProvider extends AbstractUserDetails
UserDetails
loadedUser
;
try
{
// 加载用户信息
loadedUser
=
this
.
userDetailsService
.
loadUserByIdentifierAndTenantCode
(
authentication
.
getPrincipal
().
toString
(),
TenantContextHolder
.
getTenantCode
());
loadedUser
=
this
.
userDetailsService
.
loadUserByIdentifierAndTenantCode
(
TenantContextHolder
.
getTenantCode
(),
authentication
.
getPrincipal
().
toString
());
}
catch
(
TenantNotFoundException
tenantNotFound
)
{
throw
tenantNotFound
;
throw
new
InternalAuthenticationServiceException
(
tenantNotFound
.
getMessage
(),
tenantNotFound
)
;
}
catch
(
UsernameNotFoundException
notFound
)
{
if
(
authentication
.
getCredentials
()
!=
null
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
...
...
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/CustomUserDetailsServiceImpl.java
View file @
b822b4d2
...
...
@@ -9,24 +9,18 @@ import com.github.tangyi.common.core.exceptions.CommonException;
import
com.github.tangyi.common.core.exceptions.ServiceException
;
import
com.github.tangyi.common.core.exceptions.TenantNotFoundException
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.properties.SysProperties
;
import
com.github.tangyi.common.core.utils.DateUtils
;
import
com.github.tangyi.common.core.utils.ResponseUtil
;
import
com.github.tangyi.common.core.vo.RoleVo
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.security.core.CustomUserDetailsService
;
import
com.github.tangyi.common.security.core.GrantedAuthorityImpl
;
import
com.github.tangyi.common.security.mobile.MobileUser
;
import
com.github.tangyi.common.security.wx.WxUser
;
import
com.github.tangyi.user.api.constant.MenuConstant
;
import
com.github.tangyi.user.api.dto.UserDto
;
import
com.github.tangyi.user.api.enums.IdentityType
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
com.github.tangyi.user.api.module.Menu
;
import
com.github.tangyi.user.api.module.Tenant
;
import
com.google.common.collect.Lists
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.security.core.GrantedAuthority
;
...
...
@@ -35,8 +29,6 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import
org.springframework.stereotype.Service
;
import
java.time.LocalDateTime
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
...
...
@@ -52,21 +44,19 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
private
final
UserServiceClient
userServiceClient
;
private
final
SysProperties
sysProperties
;
private
final
WxSessionService
wxService
;
/**
* 加载用户信息
*
* @param tenantCode 租户标识
* @param username 用户名
* @return UserDetails
* @throws UsernameNotFoundException,TenantNotFoundException
*/
@Override
public
UserDetails
loadUserByIdentifierAndTenantCode
(
String
username
,
String
tenantCod
e
)
throws
UsernameNotFoundException
,
TenantNotFoundException
{
public
UserDetails
loadUserByIdentifierAndTenantCode
(
String
tenantCode
,
String
usernam
e
)
throws
UsernameNotFoundException
,
TenantNotFoundException
{
long
start
=
System
.
currentTimeMillis
();
Tenant
tenant
=
this
.
validateTenantCode
(
tenantCode
);
ResponseBean
<
UserVo
>
userVoResponseBean
=
userServiceClient
.
findUserByIdentifier
(
username
,
tenantCode
);
if
(!
ResponseUtil
.
isSuccess
(
userVoResponseBean
))
throw
new
ServiceException
(
"查询用户信息失败: "
+
userVoResponseBean
.
getMsg
());
...
...
@@ -79,17 +69,16 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
/**
* 根据社交账号查询
*
* @param social social
* @param tenantCode tenantCode
* @param social social
* @param mobileUser mobileUser
* @return UserDetails
* @author tangyi
* @date 2019/06/22 21:08
*/
@Override
public
UserDetails
loadUserBySocialAndTenantCode
(
String
social
,
String
tenantCode
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
{
public
UserDetails
loadUserBySocialAndTenantCode
(
String
tenantCode
,
String
social
,
MobileUser
mobileUser
)
throws
UsernameNotFoundException
{
long
start
=
System
.
currentTimeMillis
();
Tenant
tenant
=
this
.
validateTenantCode
(
tenantCode
);
ResponseBean
<
UserVo
>
userVoResponseBean
=
userServiceClient
.
findUserByIdentifier
(
social
,
IdentityType
.
PHONE_NUMBER
.
getValue
(),
tenantCode
);
if
(!
ResponseUtil
.
isSuccess
(
userVoResponseBean
))
throw
new
ServiceException
(
"查询用户信息失败: "
+
userVoResponseBean
.
getMsg
());
...
...
@@ -113,12 +102,6 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
if
(!
ResponseUtil
.
isSuccess
(
userVoResponseBean
))
throw
new
ServiceException
(
"查询用户信息失败: "
+
userVoResponseBean
.
getMsg
());
userVo
=
userVoResponseBean
.
getData
();
}
else
{
// TODO 记录登录时间,IP等信息
UserDto
userDto
=
new
UserDto
();
BeanUtils
.
copyProperties
(
userVo
,
userDto
);
userDto
.
setLoginTime
(
DateUtils
.
asDate
(
LocalDateTime
.
now
()));
//userServiceClient.updateUser(userDto);
}
return
new
CustomUserDetails
(
userVo
.
getIdentifier
(),
userVo
.
getCredential
(),
CommonConstant
.
STATUS_NORMAL
.
equals
(
userVo
.
getStatus
()),
getAuthority
(
userVo
),
userVo
.
getTenantCode
(),
start
,
LoginType
.
SMS
);
}
...
...
@@ -127,17 +110,16 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
* 根据微信code和租户标识查询
* 将code换成openId和sessionKey
*
* @param code code
* @param tenantCode tenantCode
* @param code code
* @param wxUser wxUser
* @return UserDetails
* @author tangyi
* @date 2019/07/05 20:05:36
*/
@Override
public
UserDetails
loadUserByWxCodeAndTenantCode
(
String
code
,
String
tenantC
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
{
public
UserDetails
loadUserByWxCodeAndTenantCode
(
String
tenantCode
,
String
c
ode
,
WxUser
wxUser
)
throws
UsernameNotFoundException
{
long
start
=
System
.
currentTimeMillis
();
Tenant
tenant
=
this
.
validateTenantCode
(
tenantCode
);
// 根据code获取openId和sessionKey
WxSession
wxSession
=
wxService
.
code2Session
(
code
);
if
(
wxSession
==
null
)
...
...
@@ -166,37 +148,11 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
if
(!
ResponseUtil
.
isSuccess
(
userVoResponseBean
))
throw
new
ServiceException
(
"查询用户信息失败: "
+
userVoResponseBean
.
getMsg
());
userVo
=
userVoResponseBean
.
getData
();
}
else
{
// TODO 更新sessionKey,记录登录时间,IP等信息
UserDto
userDto
=
new
UserDto
();
BeanUtils
.
copyProperties
(
userVo
,
userDto
);
//userDto.setCredential(wxSession.getSessionKey());
userDto
.
setLoginTime
(
DateUtils
.
asDate
(
LocalDateTime
.
now
()));
//userServiceClient.updateUser(userDto);
}
return
new
CustomUserDetails
(
userVo
.
getIdentifier
(),
userVo
.
getCredential
(),
CommonConstant
.
STATUS_NORMAL
.
equals
(
userVo
.
getStatus
()),
getAuthority
(
userVo
),
userVo
.
getTenantCode
(),
start
,
LoginType
.
WECHAT
);
}
/**
* 校验租户标识
*
* @param tenantCode tenantCode
* @return Tenant
*/
private
Tenant
validateTenantCode
(
String
tenantCode
)
throws
TenantNotFoundException
{
if
(
StringUtils
.
isBlank
(
tenantCode
))
throw
new
TenantNotFoundException
(
"租户code不能为空."
);
// 先获取租户信息
ResponseBean
<
Tenant
>
tenantResponseBean
=
userServiceClient
.
findTenantByTenantCode
(
tenantCode
);
if
(!
ResponseUtil
.
isSuccess
(
tenantResponseBean
))
throw
new
ServiceException
(
"查询租户信息失败: "
+
tenantResponseBean
.
getMsg
());
Tenant
tenant
=
tenantResponseBean
.
getData
();
if
(
tenant
==
null
)
throw
new
TenantNotFoundException
(
"租户不存在."
);
return
tenant
;
}
/**
* 获取用户权限
*
* @param userVo userVo
...
...
@@ -205,43 +161,9 @@ public class CustomUserDetailsServiceImpl implements CustomUserDetailsService {
* @date 2019/03/17 14:41
*/
private
Set
<
GrantedAuthority
>
getAuthority
(
UserVo
userVo
)
{
// 权限集合
Set
<
GrantedAuthority
>
authorities
=
new
HashSet
<>();
// 根据角色查找菜单权限
List
<
Menu
>
menus
=
Lists
.
newArrayList
();
// 判断是否是管理员,是则查找所有菜单权限
if
(
userVo
.
getIdentifier
().
equals
(
sysProperties
.
getAdminUser
()))
{
// 查找所有菜单权限,因为角色一般是一个,这里只会执行一次
ResponseBean
<
List
<
Menu
>>
menusResponseBean
=
userServiceClient
.
findAllMenu
(
userVo
.
getTenantCode
());
if
(!
ResponseUtil
.
isSuccess
(
menusResponseBean
))
{
throw
new
ServiceException
(
"查询所有菜单失败: "
+
menusResponseBean
.
getMsg
());
}
menus
=
menusResponseBean
.
getData
();
}
else
{
// 根据角色查询菜单权限
List
<
RoleVo
>
roleList
=
userVo
.
getRoleList
();
if
(
CollectionUtils
.
isNotEmpty
(
roleList
))
{
for
(
RoleVo
role
:
roleList
)
{
// 根据角色查找菜单权限
ResponseBean
<
List
<
Menu
>>
roleMenusResponseBean
=
userServiceClient
.
findMenuByRole
(
role
.
getRoleCode
(),
userVo
.
getTenantCode
());
if
(!
ResponseUtil
.
isSuccess
(
roleMenusResponseBean
))
{
throw
new
ServiceException
(
"查询角色菜单失败: "
+
roleMenusResponseBean
.
getMsg
());
}
List
<
Menu
>
roleMenus
=
roleMenusResponseBean
.
getData
();
if
(
CollectionUtils
.
isNotEmpty
(
roleMenus
))
menus
.
addAll
(
roleMenus
);
// 权限如果前缀是ROLE_,security就会认为这是个角色信息,而不是权限,例如ROLE_ADMIN就是ADMIN角色,MENU:ADD就是MENU:ADD权限
authorities
.
add
(
new
GrantedAuthorityImpl
(
role
.
getRoleCode
()));
}
}
}
if
(
CollectionUtils
.
isNotEmpty
(
menus
))
{
// 菜单权限
List
<
GrantedAuthority
>
authorityList
=
menus
.
stream
()
.
filter
(
menu
->
MenuConstant
.
MENU_TYPE_PERMISSION
.
equals
(
menu
.
getType
()))
.
map
(
menu
->
new
GrantedAuthorityImpl
(
menu
.
getPermission
())).
collect
(
Collectors
.
toList
());
authorities
.
addAll
(
authorityList
);
}
return
authorities
;
return
userVo
.
getRoleList
()
.
stream
()
.
map
(
role
->
new
GrantedAuthorityImpl
(
role
.
getRoleCode
().
toUpperCase
()))
.
collect
(
Collectors
.
toSet
());
}
}
modules/auth-service-parent/auth-service/src/main/java/com/github/tangyi/auth/security/ValidateTenantAspect.java
0 → 100644
View file @
b822b4d2
package
com
.
github
.
tangyi
.
auth
.
security
;
import
com.github.tangyi.common.core.exceptions.ServiceException
;
import
com.github.tangyi.common.core.exceptions.TenantNotFoundException
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.ResponseUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
com.github.tangyi.user.api.module.Tenant
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.lang.StringUtils
;
import
org.aspectj.lang.annotation.Aspect
;
import
org.aspectj.lang.annotation.Before
;
import
org.springframework.stereotype.Component
;
/**
*
* 校验租户
*
* @author tangyi
* @date 2019-11-12 20:14
*/
@AllArgsConstructor
@Aspect
@Component
public
class
ValidateTenantAspect
{
private
final
UserServiceClient
userServiceClient
;
@Before
(
"execution(* com.github.tangyi.auth.security.CustomUserDetailsServiceImpl.load*(..)) && args(tenantCode,..)"
)
public
void
validateTenantCode
(
String
tenantCode
)
throws
TenantNotFoundException
{
// 获取tenantCode
if
(
StringUtils
.
isBlank
(
tenantCode
))
throw
new
TenantNotFoundException
(
"租户code不能为空."
);
// 先获取租户信息
ResponseBean
<
Tenant
>
tenantResponseBean
=
userServiceClient
.
findTenantByTenantCode
(
tenantCode
);
if
(!
ResponseUtil
.
isSuccess
(
tenantResponseBean
))
throw
new
ServiceException
(
"查询租户信息失败: "
+
tenantResponseBean
.
getMsg
());
Tenant
tenant
=
tenantResponseBean
.
getData
();
if
(
tenant
==
null
)
throw
new
TenantNotFoundException
(
"租户不存在."
);
}
}
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/CourseController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.module.Course
;
import
com.github.tangyi.exam.service.CourseService
;
import
io.swagger.annotations.Api
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -93,7 +92,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:31
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:course:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建课程"
,
notes
=
"创建课程"
)
@ApiImplicitParam
(
name
=
"course"
,
value
=
"课程实体course"
,
required
=
true
,
dataType
=
"Course"
)
@Log
(
"新增课程"
)
...
...
@@ -111,7 +110,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:31
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:course:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新课程信息"
,
notes
=
"根据课程id更新课程的基本信息"
)
@ApiImplicitParam
(
name
=
"course"
,
value
=
"课程实体course"
,
required
=
true
,
dataType
=
"Course"
)
@Log
(
"更新课程"
)
...
...
@@ -129,7 +128,7 @@ public class CourseController extends BaseController {
* @date 2018/11/10 21:32
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:course:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除课程"
,
notes
=
"根据ID删除课程"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"课程ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除课程"
)
...
...
@@ -158,7 +157,7 @@ public class CourseController extends BaseController {
* @date 2018/12/4 11:26
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:course:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除课程"
,
notes
=
"根据课程id批量删除课程"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"课程ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除课程"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/ExamRecordController.java
View file @
b822b4d2
...
...
@@ -4,11 +4,9 @@ import com.github.pagehelper.PageInfo;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.ExaminationRecordDto
;
import
com.github.tangyi.exam.api.dto.StartExamDto
;
import
com.github.tangyi.exam.api.enums.SubmitStatusEnum
;
...
...
@@ -18,7 +16,6 @@ import com.github.tangyi.exam.service.AnswerService;
import
com.github.tangyi.exam.service.ExamRecordService
;
import
com.github.tangyi.exam.service.ExaminationService
;
import
com.github.tangyi.exam.utils.ExamRecordUtil
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
...
...
@@ -29,7 +26,6 @@ import org.apache.commons.collections4.CollectionUtils;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
...
...
@@ -58,8 +54,6 @@ public class ExamRecordController extends BaseController {
private
final
ExaminationService
examinationService
;
private
final
UserServiceClient
userServiceClient
;
private
final
AnswerService
answerService
;
/**
...
...
@@ -113,9 +107,6 @@ public class ExamRecordController extends BaseController {
if
(
CollectionUtils
.
isNotEmpty
(
examRecordPageInfo
.
getList
()))
{
// 查询考试信息
List
<
Examination
>
examinations
=
examinationService
.
findListById
(
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getExaminationId
).
distinct
().
toArray
(
Long
[]::
new
));
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getUserId
).
distinct
().
toArray
(
Long
[]::
new
));
if
(
returnT
!=
null
&&
CollectionUtils
.
isNotEmpty
(
returnT
.
getData
()))
{
examRecordPageInfo
.
getList
().
forEach
(
tempExamRecord
->
{
// 找到考试记录所属的考试信息
Examination
examinationRecordExamination
=
examinations
.
stream
()
...
...
@@ -139,29 +130,7 @@ public class ExamRecordController extends BaseController {
examRecordDtoList
.
add
(
examRecordDto
);
}
});
// 查询部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询、设置用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
()
.
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
// 设置用户名
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询、设置部门信息
if
(
deptResponseBean
!=
null
&&
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
// 根据部门ID过滤
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
examRecordService
.
fillExamUserInfo
(
examRecordDtoList
,
examRecordPageInfo
.
getList
().
stream
().
map
(
ExaminationRecord:
:
getUserId
).
distinct
().
toArray
(
Long
[]::
new
));
}
examRecordDtoPageInfo
.
setTotal
(
examRecordPageInfo
.
getTotal
());
examRecordDtoPageInfo
.
setPages
(
examRecordPageInfo
.
getPages
());
...
...
@@ -184,10 +153,6 @@ public class ExamRecordController extends BaseController {
@ApiImplicitParam
(
name
=
"examRecord"
,
value
=
"考试记录实体examRecord"
,
required
=
true
,
dataType
=
"ExamRecord"
)
@Log
(
"新增考试记录"
)
public
ResponseBean
<
ExaminationRecord
>
addExamRecord
(
@RequestBody
@Valid
ExaminationRecord
examRecord
)
{
Examination
examination
=
new
Examination
();
examination
.
setId
(
examRecord
.
getExaminationId
());
// 查找考试信息
examination
=
examinationService
.
get
(
examination
);
examRecord
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
examRecord
.
setStartTime
(
examRecord
.
getCreateDate
());
examRecordService
.
insert
(
examRecord
);
...
...
@@ -245,7 +210,7 @@ public class ExamRecordController extends BaseController {
* @date 2018/12/31 22:28
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('exam:examRecord:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出考试成绩"
,
notes
=
"根据成绩id导出成绩"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"成绩ID"
,
required
=
true
,
dataType
=
"Long"
)
@Log
(
"导出考试记录"
)
...
...
@@ -292,30 +257,7 @@ public class ExamRecordController extends BaseController {
examRecordDtoList
.
add
(
recordDto
);
}
});
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
userIdSet
.
toArray
(
new
Long
[
0
]));
if
(
returnT
!=
null
&&
CollectionUtils
.
isNotEmpty
(
returnT
.
getData
()))
{
// 获取部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
().
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询部门信息
if
(
deptResponseBean
!=
null
&&
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
// 查找用户所属部门
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置所属部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
examRecordService
.
fillExamUserInfo
(
examRecordDtoList
,
userIdSet
.
toArray
(
new
Long
[
0
]));
// 导出
ExcelToolUtil
.
exportExcel
(
request
.
getInputStream
(),
response
.
getOutputStream
(),
MapUtil
.
java2Map
(
examRecordDtoList
),
ExamRecordUtil
.
getExamRecordDtoMap
());
}
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/ExaminationController.java
View file @
b822b4d2
...
...
@@ -7,8 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.exam.api.dto.AnswerCartDto
;
import
com.github.tangyi.common.security.annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.ExaminationDto
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.api.module.Course
;
...
...
@@ -25,7 +24,6 @@ import lombok.extern.slf4j.Slf4j;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -152,7 +150,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:14
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建考试"
,
notes
=
"创建考试"
)
@ApiImplicitParam
(
name
=
"examinationDto"
,
value
=
"考试实体examinationDto"
,
required
=
true
,
dataType
=
"ExaminationDto"
)
@Log
(
"新增考试"
)
...
...
@@ -173,7 +171,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:15
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新考试信息"
,
notes
=
"根据考试id更新考试的基本信息"
)
@ApiImplicitParam
(
name
=
"examinationDto"
,
value
=
"考试实体answer"
,
required
=
true
,
dataType
=
"ExaminationDto"
)
@Log
(
"更新考试"
)
...
...
@@ -195,7 +193,7 @@ public class ExaminationController extends BaseController {
* @date 2018/11/10 21:20
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除考试"
,
notes
=
"根据ID删除考试"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"考试ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除考试"
)
...
...
@@ -224,7 +222,7 @@ public class ExaminationController extends BaseController {
* @date 2018/12/03 22:03
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除考试"
,
notes
=
"根据考试id批量删除考试"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"考试ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除考试"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/SubjectCategoryController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.SysUtil;
import
com.github.tangyi.common.core.utils.TreeUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.constants.ExamSubjectConstant
;
import
com.github.tangyi.exam.api.dto.SubjectCategoryDto
;
import
com.github.tangyi.exam.api.module.SubjectCategory
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiImplicitParam;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -89,7 +88,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:00
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:subject:category:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建分类"
,
notes
=
"创建分类"
)
@ApiImplicitParam
(
name
=
"subjectCategory"
,
value
=
"分类实体subjectCategory"
,
required
=
true
,
dataType
=
"SubjectCategory"
)
@Log
(
"新增题目分类"
)
...
...
@@ -108,7 +107,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:01
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:subject:category:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新分类信息"
,
notes
=
"根据分类id更新分类的基本信息"
)
@ApiImplicitParam
(
name
=
"subjectCategory"
,
value
=
"分类实体subjectCategory"
,
required
=
true
,
dataType
=
"SubjectCategory"
)
@Log
(
"更新题目分类"
)
...
...
@@ -126,7 +125,7 @@ public class SubjectCategoryController extends BaseController {
* @date 2018/12/04 22:02
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:subject:category:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除分类"
,
notes
=
"根据ID删除分类"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"分类ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除题目分类"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/controller/SubjectController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.service.AnswerService
;
import
com.github.tangyi.exam.service.SubjectService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.*;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -101,7 +100,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建题目"
,
notes
=
"创建题目"
)
@ApiImplicitParam
(
name
=
"subject"
,
value
=
"题目信息"
,
required
=
true
,
dataType
=
"SubjectDto"
)
@Log
(
"新增题目"
)
...
...
@@ -119,7 +118,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新题目信息"
,
notes
=
"根据题目id更新题目的基本信息"
)
@ApiImplicitParam
(
name
=
"subject"
,
value
=
"角色实体subject"
,
required
=
true
,
dataType
=
"Subject"
)
@Log
(
"更新题目"
)
...
...
@@ -137,7 +136,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/10 21:43
*/
@DeleteMapping
(
"{id}"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除题目"
,
notes
=
"根据ID删除题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"id"
,
value
=
"题目ID"
,
required
=
true
,
dataType
=
"Long"
,
paramType
=
"path"
),
...
...
@@ -161,7 +160,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/28 12:53
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出题目"
,
notes
=
"根据分类id导出题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"题目ID"
,
required
=
true
,
dataType
=
"Long"
),
...
...
@@ -200,7 +199,7 @@ public class SubjectController extends BaseController {
* @date 2018/11/28 12:59
*/
@RequestMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入题目"
,
notes
=
"导入题目"
)
@ApiImplicitParams
({
@ApiImplicitParam
(
name
=
"examinationId"
,
value
=
"考试ID"
,
dataType
=
"Long"
),
...
...
@@ -232,7 +231,7 @@ public class SubjectController extends BaseController {
* @date 2018/12/04 9:55
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('exam:exam:subject:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除题目"
,
notes
=
"根据题目id批量删除题目"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"题目ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除题目"
)
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/ExamRecordService.java
View file @
b822b4d2
package
com
.
github
.
tangyi
.
exam
.
service
;
import
com.github.tangyi.common.core.constant.CommonConstant
;
import
com.github.tangyi.common.core.model.ResponseBean
;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.core.utils.ResponseUtil
;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.exam.api.dto.ExaminationRecordDto
;
import
com.github.tangyi.exam.api.module.ExaminationRecord
;
import
com.github.tangyi.exam.mapper.ExamRecordMapper
;
import
com.github.tangyi.user.api.feign.UserServiceClient
;
import
lombok.AllArgsConstructor
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.cache.annotation.CacheEvict
;
import
org.springframework.cache.annotation.Cacheable
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
/**
* 考试记录service
*
...
...
@@ -20,6 +29,8 @@ import org.springframework.transaction.annotation.Transactional;
@Service
public
class
ExamRecordService
extends
CrudService
<
ExamRecordMapper
,
ExaminationRecord
>
{
private
final
UserServiceClient
userServiceClient
;
/**
* 查询考试记录
*
...
...
@@ -90,4 +101,40 @@ public class ExamRecordService extends CrudService<ExamRecordMapper, Examination
public
int
deleteAll
(
Long
[]
ids
)
{
return
super
.
deleteAll
(
ids
);
}
/**
* 获取用户、部门相关信息
* @param examRecordDtoList examRecordDtoList
* @param userIds userIds
*/
public
void
fillExamUserInfo
(
List
<
ExaminationRecordDto
>
examRecordDtoList
,
Long
[]
userIds
)
{
// 查询用户信息
ResponseBean
<
List
<
UserVo
>>
returnT
=
userServiceClient
.
findUserById
(
userIds
);
if
(
ResponseUtil
.
isSuccess
(
returnT
))
{
// 查询部门信息
ResponseBean
<
List
<
DeptVo
>>
deptResponseBean
=
userServiceClient
.
findDeptById
(
returnT
.
getData
().
stream
().
map
(
UserVo:
:
getDeptId
).
distinct
().
toArray
(
Long
[]::
new
));
if
(
ResponseUtil
.
isSuccess
(
deptResponseBean
))
{
examRecordDtoList
.
forEach
(
tempExamRecordDto
->
{
// 查询、设置用户信息
UserVo
examRecordDtoUserVo
=
returnT
.
getData
().
stream
()
.
filter
(
tempUserVo
->
tempExamRecordDto
.
getUserId
().
equals
(
tempUserVo
.
getId
()))
.
findFirst
().
orElse
(
null
);
if
(
examRecordDtoUserVo
!=
null
)
{
// 设置用户名
tempExamRecordDto
.
setUserName
(
examRecordDtoUserVo
.
getName
());
// 查询、设置部门信息
if
(
CollectionUtils
.
isNotEmpty
(
deptResponseBean
.
getData
()))
{
DeptVo
examRecordDtoDeptVo
=
deptResponseBean
.
getData
().
stream
()
// 根据部门ID过滤
.
filter
(
tempDept
->
tempDept
.
getId
().
equals
(
examRecordDtoUserVo
.
getDeptId
()))
.
findFirst
().
orElse
(
null
);
// 设置部门名称
if
(
examRecordDtoDeptVo
!=
null
)
tempExamRecordDto
.
setDeptName
(
examRecordDtoDeptVo
.
getDeptName
());
}
}
});
}
}
}
}
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/ExaminationService.java
View file @
b822b4d2
...
...
@@ -5,7 +5,6 @@ import com.github.tangyi.common.core.constant.CommonConstant;
import
com.github.tangyi.common.core.service.CrudService
;
import
com.github.tangyi.common.core.utils.PageUtil
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.exam.api.dto.AnswerCartDto
;
import
com.github.tangyi.exam.api.dto.SubjectDto
;
import
com.github.tangyi.exam.api.module.Examination
;
import
com.github.tangyi.exam.api.module.ExaminationSubject
;
...
...
modules/exam-service-parent/exam-service/src/main/java/com/github/tangyi/exam/service/SubjectService.java
View file @
b822b4d2
...
...
@@ -23,7 +23,6 @@ import java.util.HashMap;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
/**
* 题目service
...
...
modules/user-service-parent/user-service-api/src/main/java/com/github/tangyi/user/api/constant/MenuConstant.java
View file @
b822b4d2
...
...
@@ -45,5 +45,28 @@ public class MenuConstant {
* 修改
*/
public
static
final
String
PERMISSION_SUFFIX_MODIFY
=
":edit"
;
public
static
final
String
MENU_SYS
=
"sys"
;
/**
* 终端管理
*/
public
static
final
String
MENU_CLIENT
=
"sys:client"
;
/**
* 路由管理
*/
public
static
final
String
MENU_ROUTE
=
"sys:route"
;
/**
* 租户中心
*/
public
static
final
String
MENU_TENANT
=
"tenant"
;
/**
* 系统监控
*/
public
static
final
String
MENU_MONITOR
=
"monitor"
;
}
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/DeptController.java
View file @
b822b4d2
...
...
@@ -8,7 +8,7 @@ import com.github.tangyi.common.core.utils.TreeUtil;
import
com.github.tangyi.common.core.vo.DeptVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.dto.DeptDto
;
import
com.github.tangyi.user.api.module.Dept
;
import
com.github.tangyi.user.service.DeptService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.ApiImplicitParam;
import
io.swagger.annotations.ApiOperation
;
import
lombok.AllArgsConstructor
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -91,7 +90,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:15
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:dept:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建部门"
,
notes
=
"创建部门"
)
@ApiImplicitParam
(
name
=
"dept"
,
value
=
"部门实体"
,
required
=
true
,
dataType
=
"Dept"
)
@Log
(
"新增部门"
)
...
...
@@ -109,7 +108,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:16
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:dept:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除部门"
,
notes
=
"根据ID删除部门"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"部门ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除部门"
)
...
...
@@ -129,7 +128,7 @@ public class DeptController extends BaseController {
* @date 2018/8/28 10:22
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:dept:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新部门信息"
,
notes
=
"根据部门id更新部门的基本信息"
)
@ApiImplicitParam
(
name
=
"dept"
,
value
=
"部门实体"
,
required
=
true
,
dataType
=
"Dept"
)
@Log
(
"更新部门"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/LogController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.PageUtil
;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminAuthorization
;
import
com.github.tangyi.user.service.LogService
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
...
...
@@ -16,7 +16,6 @@ import io.swagger.annotations.ApiOperation;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -98,10 +97,6 @@ public class LogController extends BaseController {
@ApiOperation
(
value
=
"新增日志"
,
notes
=
"新增日志"
)
@ApiImplicitParam
(
name
=
"log"
,
value
=
"日志实体Log"
,
required
=
true
,
dataType
=
"Log"
)
public
ResponseBean
<
Boolean
>
addLog
(
@RequestBody
@Valid
Log
log
)
{
if
(
log
.
getId
()
!=
null
)
log
.
setCommonValue
(
SysUtil
.
getUser
(),
SysUtil
.
getSysCode
(),
SysUtil
.
getTenantCode
());
if
(
true
)
return
null
;
// 保存日志
return
new
ResponseBean
<>(
logService
.
insert
(
log
)
>
0
);
}
...
...
@@ -115,7 +110,7 @@ public class LogController extends BaseController {
* @date 2018/10/31 21:27
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('monitor:log:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"删除日志"
,
notes
=
"根据ID删除日志"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"日志ID"
,
required
=
true
,
paramType
=
"path"
)
public
ResponseBean
<
Boolean
>
delete
(
@PathVariable
Long
id
)
{
...
...
@@ -133,7 +128,7 @@ public class LogController extends BaseController {
* @date 2018/12/4 10:12
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('monitor:log:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminAuthorization
@ApiOperation
(
value
=
"批量删除日志"
,
notes
=
"根据日志ids批量删除日志"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"日志ID"
,
dataType
=
"Long"
)
public
ResponseBean
<
Boolean
>
deleteAllLog
(
@RequestBody
Long
[]
ids
)
{
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/MenuController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.model.ResponseBean;
import
com.github.tangyi.common.core.utils.*
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.dto.MenuDto
;
import
com.github.tangyi.user.api.module.Menu
;
import
com.github.tangyi.user.service.MenuService
;
...
...
@@ -17,7 +17,6 @@ import io.swagger.annotations.*;
import
lombok.AllArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.ArrayUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -90,7 +89,7 @@ public class MenuController extends BaseController {
* @date 2018/8/27 16:12
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:menu:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建菜单"
,
notes
=
"创建菜单"
)
@ApiImplicitParam
(
name
=
"menu"
,
value
=
"角色实体menu"
,
required
=
true
,
dataType
=
"Menu"
)
@Log
(
"新增菜单"
)
...
...
@@ -108,7 +107,7 @@ public class MenuController extends BaseController {
* @date 2018/10/24 16:34
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:menu:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新菜单信息"
,
notes
=
"根据菜单id更新菜单的基本信息"
)
@ApiImplicitParam
(
name
=
"menu"
,
value
=
"角色实体menu"
,
required
=
true
,
dataType
=
"Menu"
)
@Log
(
"更新菜单"
)
...
...
@@ -126,7 +125,7 @@ public class MenuController extends BaseController {
* @date 2018/8/27 16:19
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除菜单"
,
notes
=
"根据ID删除菜单"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"菜单ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除菜单"
)
...
...
@@ -243,7 +242,7 @@ public class MenuController extends BaseController {
* @date 2018/11/28 12:46
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出菜单"
,
notes
=
"根据菜单id导出菜单"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"菜单ID"
,
required
=
true
,
dataType
=
"Long"
)
@Log
(
"导出菜单"
)
...
...
@@ -280,7 +279,7 @@ public class MenuController extends BaseController {
* @date 2018/11/28 12:51
*/
@PostMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('sys:menu:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入菜单"
,
notes
=
"导入菜单"
)
@Log
(
"导入菜单"
)
public
ResponseBean
<
Boolean
>
importMenu
(
@ApiParam
(
value
=
"要上传的文件"
,
required
=
true
)
MultipartFile
file
)
{
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/RoleController.java
View file @
b822b4d2
...
...
@@ -7,7 +7,7 @@ import com.github.tangyi.common.core.utils.PageUtil;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.
constant.SecurityConstant
;
import
com.github.tangyi.common.security.
annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.user.api.module.Role
;
import
com.github.tangyi.user.service.RoleMenuService
;
import
com.github.tangyi.user.service.RoleService
;
...
...
@@ -19,7 +19,6 @@ import lombok.AllArgsConstructor;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang.ArrayUtils
;
import
org.apache.commons.lang.StringUtils
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.validation.Valid
;
...
...
@@ -120,7 +119,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:22
*/
@PutMapping
@
PreAuthorize
(
"hasAuthority('sys:role:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新角色信息"
,
notes
=
"根据角色id更新角色的基本信息"
)
@ApiImplicitParam
(
name
=
"role"
,
value
=
"角色实体role"
,
required
=
true
,
dataType
=
"RoleVo"
)
@Log
(
"修改角色"
)
...
...
@@ -162,7 +161,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:23
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:role:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建角色"
,
notes
=
"创建角色"
)
@ApiImplicitParam
(
name
=
"role"
,
value
=
"角色实体role"
,
required
=
true
,
dataType
=
"RoleVo"
)
@Log
(
"新增角色"
)
...
...
@@ -180,7 +179,7 @@ public class RoleController extends BaseController {
* @date 2018/9/14 18:24
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:role:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除角色"
,
notes
=
"根据ID删除角色"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"角色ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除角色"
)
...
...
@@ -201,7 +200,7 @@ public class RoleController extends BaseController {
* @date 2018/12/4 10:00
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:role:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除角色"
,
notes
=
"根据角色id批量删除角色"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"角色ID"
,
dataType
=
"Long"
)
@Log
(
"批量删除角色"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/controller/UserController.java
View file @
b822b4d2
...
...
@@ -8,6 +8,7 @@ import com.github.tangyi.common.core.utils.*;
import
com.github.tangyi.common.core.vo.UserVo
;
import
com.github.tangyi.common.core.web.BaseController
;
import
com.github.tangyi.common.log.annotation.Log
;
import
com.github.tangyi.common.security.annotations.AdminTenantTeacherAuthorization
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.user.api.dto.UserDto
;
import
com.github.tangyi.user.api.dto.UserInfoDto
;
...
...
@@ -26,7 +27,6 @@ import org.apache.commons.lang.ArrayUtils;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.BeanUtils
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.security.oauth2.provider.OAuth2Authentication
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
...
...
@@ -175,7 +175,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 14:34
*/
@PostMapping
@
PreAuthorize
(
"hasAuthority('sys:user:add') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"创建用户"
,
notes
=
"创建用户"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"新增用户"
)
...
...
@@ -193,7 +193,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 15:06
*/
@PutMapping
(
"/{id:[a-zA-Z0-9,]+}"
)
@
PreAuthorize
(
"hasAuthority('sys:user:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"更新用户信息"
,
notes
=
"根据用户id更新用户的基本信息、角色信息"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"修改用户"
)
...
...
@@ -266,7 +266,7 @@ public class UserController extends BaseController {
* @date 2018/8/26 15:28
*/
@DeleteMapping
(
"/{id}"
)
@
PreAuthorize
(
"hasAuthority('sys:user:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"删除用户"
,
notes
=
"根据ID删除用户"
)
@ApiImplicitParam
(
name
=
"id"
,
value
=
"用户ID"
,
required
=
true
,
paramType
=
"path"
)
@Log
(
"删除用户"
)
...
...
@@ -291,7 +291,7 @@ public class UserController extends BaseController {
* @date 2018/11/26 22:11
*/
@PostMapping
(
"export"
)
@
PreAuthorize
(
"hasAuthority('sys:user:export') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导出用户"
,
notes
=
"根据用户id导出用户"
)
@ApiImplicitParam
(
name
=
"userVo"
,
value
=
"用户信息"
,
required
=
true
,
dataType
=
"UserVo"
)
@Log
(
"导出用户"
)
...
...
@@ -339,7 +339,7 @@ public class UserController extends BaseController {
* @date 2018/11/28 12:44
*/
@PostMapping
(
"import"
)
@
PreAuthorize
(
"hasAuthority('sys:user:import') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"导入数据"
,
notes
=
"导入数据"
)
@Log
(
"导入用户"
)
public
ResponseBean
<
Boolean
>
importUser
(
@ApiParam
(
value
=
"要上传的文件"
,
required
=
true
)
MultipartFile
file
,
HttpServletRequest
request
)
{
...
...
@@ -365,7 +365,7 @@ public class UserController extends BaseController {
* @date 2018/12/4 9:58
*/
@PostMapping
(
"deleteAll"
)
@
PreAuthorize
(
"hasAuthority('sys:user:del') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"批量删除用户"
,
notes
=
"根据用户id批量删除用户"
)
@ApiImplicitParam
(
name
=
"ids"
,
value
=
"用户信息"
,
dataType
=
"Long"
)
@Log
(
"批量删除用户"
)
...
...
@@ -460,7 +460,7 @@ public class UserController extends BaseController {
* @date 2019/6/7 12:00
*/
@PutMapping
(
"/resetPassword"
)
@
PreAuthorize
(
"hasAuthority('sys:user:edit') or hasAnyRole('"
+
SecurityConstant
.
ROLE_ADMIN
+
"')"
)
@
AdminTenantTeacherAuthorization
@ApiOperation
(
value
=
"重置密码"
,
notes
=
"根据用户id重置密码"
)
@ApiImplicitParam
(
name
=
"userDto"
,
value
=
"用户实体user"
,
required
=
true
,
dataType
=
"UserDto"
)
@Log
(
"重置密码"
)
...
...
modules/user-service-parent/user-service/src/main/java/com/github/tangyi/user/service/MenuService.java
View file @
b822b4d2
...
...
@@ -7,6 +7,7 @@ import com.github.tangyi.common.core.service.CrudService;
import
com.github.tangyi.common.core.utils.SysUtil
;
import
com.github.tangyi.common.core.utils.TreeUtil
;
import
com.github.tangyi.common.security.constant.SecurityConstant
;
import
com.github.tangyi.common.security.enums.Roles
;
import
com.github.tangyi.common.security.utils.SecurityUtil
;
import
com.github.tangyi.user.api.constant.MenuConstant
;
import
com.github.tangyi.user.api.dto.MenuDto
;
...
...
@@ -80,7 +81,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
List
<
Role
>
roleList
=
SecurityUtil
.
getCurrentAuthentication
().
getAuthorities
().
stream
()
// 按角色过滤
.
filter
(
authority
->
authority
.
getAuthority
()
!=
null
&&
authority
.
getAuthority
()
.
startsWith
(
"role
_"
)).
map
(
authority
->
{
.
startsWith
(
"ROLE
_"
)).
map
(
authority
->
{
Role
role
=
new
Role
();
role
.
setRoleCode
(
authority
.
getAuthority
());
return
role
;
...
...
@@ -88,7 +89,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 根据角色code批量查找菜单
List
<
Menu
>
tenantMenus
=
finMenuByRoleList
(
roleList
,
tenantCode
);
// 组装数据
userMenus
=
mergeMenu
(
defaultMenus
,
tenantMenus
);
userMenus
=
mergeMenu
(
getTenantMenus
(
defaultMenus
)
,
tenantMenus
);
}
if
(
CollectionUtils
.
isNotEmpty
(
userMenus
))
{
userMenus
.
stream
()
...
...
@@ -99,7 +100,8 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 去重
.
distinct
().
forEach
(
menuDtoList:
:
add
);
// 排序、构建树形关系
return
TreeUtil
.
buildTree
(
CollUtil
.
sort
(
menuDtoList
,
Comparator
.
comparingInt
(
MenuDto:
:
getSort
)),
CommonConstant
.
ROOT
);
return
TreeUtil
.
buildTree
(
CollUtil
.
sort
(
menuDtoList
,
Comparator
.
comparingInt
(
MenuDto:
:
getSort
)),
CommonConstant
.
ROOT
);
}
return
Lists
.
newArrayList
();
}
...
...
@@ -298,7 +300,8 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
// 租户菜单
tenantMenus
.
forEach
(
tenantMenu
->
{
Optional
<
Menu
>
exist
=
userMenus
.
stream
()
.
filter
(
userMenu
->
userMenu
.
getName
().
equals
(
tenantMenu
.
getName
())
&&
userMenu
.
getParentId
().
equals
(
tenantMenu
.
getParentId
())).
findFirst
();
.
filter
(
userMenu
->
userMenu
.
getName
().
equals
(
tenantMenu
.
getName
())
&&
userMenu
.
getParentId
()
.
equals
(
tenantMenu
.
getParentId
())).
findFirst
();
if
(!
exist
.
isPresent
())
{
userMenus
.
add
(
tenantMenu
);
}
...
...
@@ -349,6 +352,7 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
/**
* 根据租户code删除
*
* @param menu menu
* @return int
*/
...
...
@@ -356,4 +360,25 @@ public class MenuService extends CrudService<MenuMapper, Menu> {
public
int
deleteByTenantCode
(
Menu
menu
)
{
return
this
.
dao
.
deleteByTenantCode
(
menu
);
}
/**
* 获取租户权限的菜单
* @param defaultMenus defaultMenus
* @return List
*/
private
List
<
Menu
>
getTenantMenus
(
List
<
Menu
>
defaultMenus
)
{
List
<
Menu
>
tenantMenus
=
new
ArrayList
<>();
if
(
CollectionUtils
.
isNotEmpty
(
defaultMenus
))
{
defaultMenus
.
forEach
(
menu
->
{
String
permission
=
menu
.
getPermission
();
// 过滤客户端管理、路由管理、系统监控菜单
if
(!
permission
.
equals
(
MenuConstant
.
MENU_CLIENT
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_ROUTE
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_TENANT
)
&&
!
permission
.
equals
(
MenuConstant
.
MENU_MONITOR
))
{
tenantMenus
.
add
(
menu
);
}
});
}
return
tenantMenus
;
}
}
pom.xml
View file @
b822b4d2
...
...
@@ -72,6 +72,7 @@
<okhttp.version>
3.8.1
</okhttp.version>
<aliyun.version>
4.0.3
</aliyun.version>
<weixin.version>
3.4.0
</weixin.version>
<jjwt.version>
0.9.0
</jjwt.version>
<!-- docker -->
<docker.maven.verion>
1.4.3
</docker.maven.verion>
...
...
@@ -301,6 +302,13 @@
<artifactId>
weixin-java-pay
</artifactId>
<version>
${weixin.version}
</version>
</dependency>
<!-- jjwt -->
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
<version>
${jjwt.version}
</version>
</dependency>
</dependencies>
</dependencyManagement>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment