Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
I
ioc_sixiang_license
Project
Project
Details
Activity
Releases
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
zengtianlai3
ioc_sixiang_license
Commits
fb1e7076
Commit
fb1e7076
authored
Sep 26, 2022
by
ma
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
新增找回密码功能,以及一些密码限制和频率限制
parent
8c7af349
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
563 additions
and
168 deletions
+563
-168
LoginController.java
.../java/iot/sixiang/license/controller/LoginController.java
+136
-12
UserController.java
...n/java/iot/sixiang/license/controller/UserController.java
+46
-1
JwtFilter.java
license/src/main/java/iot/sixiang/license/jwt/JwtFilter.java
+3
-1
UserUtils.java
license/src/main/java/iot/sixiang/license/jwt/UserUtils.java
+40
-1
CheckCodeDto.java
...main/java/iot/sixiang/license/model/dto/CheckCodeDto.java
+15
-0
UserResetPwdVo.java
...ain/java/iot/sixiang/license/model/vo/UserResetPwdVo.java
+13
-0
UserService.java
...rc/main/java/iot/sixiang/license/service/UserService.java
+4
-2
UserServiceImpl.java
...ava/iot/sixiang/license/service/impl/UserServiceImpl.java
+16
-8
CommonUtil.java
...se/src/main/java/iot/sixiang/license/util/CommonUtil.java
+283
-142
application.yml
license/src/main/resources/application.yml
+7
-1
No files found.
license/src/main/java/iot/sixiang/license/controller/LoginController.java
View file @
fb1e7076
...
...
@@ -2,8 +2,6 @@ package iot.sixiang.license.controller;
import
com.acc.secret.util.RSAUtil
;
import
io.swagger.annotations.Api
;
import
io.swagger.annotations.ApiImplicitParam
;
import
io.swagger.annotations.ApiImplicitParams
;
import
io.swagger.annotations.ApiOperation
;
import
iot.sixiang.license.consts.ResultCode
;
import
iot.sixiang.license.entity.User
;
...
...
@@ -15,24 +13,22 @@ import iot.sixiang.license.log.MyLog;
import
iot.sixiang.license.mapper.UserMapper
;
import
iot.sixiang.license.model.BaseResult
;
import
iot.sixiang.license.model.ResResult
;
import
iot.sixiang.license.model.dto.CheckCodeDto
;
import
iot.sixiang.license.model.vo.LoginReqVo
;
import
iot.sixiang.license.model.vo.LoginVo
;
import
iot.sixiang.license.model.vo.UserResetPwdVo
;
import
iot.sixiang.license.service.UserService
;
import
iot.sixiang.license.util.CommonUtil
;
import
iot.sixiang.license.util.EmailUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.util.DigestUtils
;
import
org.springframework.util.StreamUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.*
;
import
springfox.documentation.annotations.ApiIgnore
;
import
javax.annotation.Resource
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 登录Controller
...
...
@@ -47,13 +43,24 @@ public class LoginController {
EmailUtils
emailUtils
;
@Resource
UserMapper
userMapper
;
@Resource
UserService
userService
;
@Value
(
"${spring.mail.to}"
)
private
String
account
;
@Value
(
"${rsa.private_key}"
)
private
String
PRIVATE_KRY
;
@Value
(
"${other.error_count.forget_pwd}"
)
private
Integer
forgetPwdMaxErrCount
;
@Value
(
"${other.error_count.check_code}"
)
private
Integer
checkCodeMaxErrCount
;
@Value
(
"${other.code_exp_time}"
)
private
Integer
codeExpTimeStr
;
private
static
final
String
USER_NAME
=
"root"
;
private
static
final
String
OPERATION_CHECK
=
"check"
;
private
static
final
String
OPERATION_RESET
=
"reset"
;
/**
* 模拟用户登录
*/
...
...
@@ -154,11 +161,128 @@ public class LoginController {
return
BaseResult
.
failed
().
setMsgValue
(
"验证码还在有效期内"
);
}
String
code
=
CommonUtil
.
getValidateCode
();
String
content
=
"感谢您使用实名制服务器"
+
"\n"
+
"此次登录验证码为:"
+
code
+
"(有效期
三
分钟)。验证码提供给他人可能导致账号被盗,请勿转发或泄露。"
+
"\n"
+
"--------------------------------------------------------------"
+
"此邮件由系统自动发送,请勿回复此邮件"
+
"--------------------------------------------------------------"
;
String
content
=
"感谢您使用实名制服务器"
+
"\n"
+
"此次登录验证码为:"
+
code
+
"(有效期
"
+
codeExpTimeStr
+
"
分钟)。验证码提供给他人可能导致账号被盗,请勿转发或泄露。"
+
"\n"
+
"--------------------------------------------------------------"
+
"此邮件由系统自动发送,请勿回复此邮件"
+
"--------------------------------------------------------------"
;
emailUtils
.
sendSimpleMail
(
account
,
"感谢您使用实名制服务器"
,
content
);
UserUtils
.
setEmailCode
(
account
,
code
);
Date
codeExpTime
=
new
Date
(
System
.
currentTimeMillis
()
+
3
*
60
*
1000
);
Date
codeExpTime
=
new
Date
(
System
.
currentTimeMillis
()
+
codeExpTimeStr
*
60
*
1000
);
UserUtils
.
setEmailCodeExpTime
(
account
,
codeExpTime
);
return
BaseResult
.
success
();
}
@ApiOperation
(
value
=
"发送修改密码验证码"
,
notes
=
"发送修改密码验证码到邮箱"
)
@GetMapping
(
"send_code/change_pwd"
)
public
BaseResult
sendChangePwdCode
()
{
Date
emailCodeExpTime
=
UserUtils
.
getEmailCodeExpTime
(
account
+
OPERATION_CHECK
);
if
(
emailCodeExpTime
!=
null
&&
emailCodeExpTime
.
after
(
new
Date
()))
{
return
BaseResult
.
failed
().
setMsgValue
(
"验证码还在有效期内"
);
}
String
code
=
CommonUtil
.
getValidateCode
();
String
content
=
"感谢您使用实名制服务器"
+
"\n"
+
"此次修改密码的验证码为:"
+
code
+
"(有效期"
+
codeExpTimeStr
+
"分钟)。验证码提供给他人可能导致账号被盗,请勿转发或泄露。"
+
"\n"
+
"--------------------------------------------------------------"
+
"此邮件由系统自动发送,请勿回复此邮件"
+
"--------------------------------------------------------------"
;
emailUtils
.
sendSimpleMail
(
account
,
"感谢您使用实名制服务器"
,
content
);
UserUtils
.
setEmailCode
(
account
+
OPERATION_CHECK
,
code
);
Date
codeExpTime
=
new
Date
(
System
.
currentTimeMillis
()
+
codeExpTimeStr
*
60
*
1000
);
UserUtils
.
setEmailCodeExpTime
(
account
+
OPERATION_CHECK
,
codeExpTime
);
return
BaseResult
.
success
();
}
@ApiOperation
(
value
=
"校验验证码"
,
notes
=
"校验验证码"
)
@PostMapping
(
"check_code"
)
public
BaseResult
checkCode
(
@RequestBody
CheckCodeDto
checkCodeDto
)
{
String
code
=
checkCodeDto
.
getCode
();
String
emailCode
=
UserUtils
.
getEmailCode
(
account
+
OPERATION_CHECK
);
String
codeFreezeTimeStr
=
UserUtils
.
getCodeFreezeTimeMap
(
account
+
OPERATION_CHECK
);
// codeFreezeTimeStr不为空且冻结时间是今天直接报错,不是今天的话清空数据
if
(!
StringUtils
.
isEmpty
(
codeFreezeTimeStr
))
{
if
(
codeFreezeTimeStr
.
equals
(
CommonUtil
.
getCurDateStr
()))
{
return
BaseResult
.
failed
().
setMsgValue
(
"今日校验次数已达"
+
checkCodeMaxErrCount
+
"次,请明日再试"
);
}
else
{
UserUtils
.
removeCodeErrCntMap
(
account
+
OPERATION_CHECK
);
UserUtils
.
removeCodeFreezeTimeMap
(
account
+
OPERATION_CHECK
);
}
}
Date
emailCodeExpTime
=
UserUtils
.
getEmailCodeExpTime
(
account
+
OPERATION_CHECK
);
if
(
StringUtils
.
isEmpty
(
code
))
{
return
BaseResult
.
failed
().
setMsgValue
(
"验证码不能为空"
);
}
else
{
Integer
codeErrCnt
=
UserUtils
.
getCodeErrCntMap
(
account
+
OPERATION_CHECK
);
if
(
codeErrCnt
==
null
)
{
codeErrCnt
=
0
;
}
if
(
emailCodeExpTime
==
null
||
emailCodeExpTime
.
before
(
new
Date
()))
{
if
(
codeErrCnt
<
checkCodeMaxErrCount
-
1
)
{
UserUtils
.
setCodeErrCntMap
(
account
+
OPERATION_CHECK
,
codeErrCnt
+
1
);
}
else
{
UserUtils
.
setCodeFreezeTimeMap
(
account
+
OPERATION_CHECK
,
CommonUtil
.
getCurDateStr
());
}
return
BaseResult
.
failed
().
setMsgValue
(
"验证码已过期,请重发"
);
}
if
(!
code
.
equals
(
emailCode
))
{
if
(
codeErrCnt
<
checkCodeMaxErrCount
-
1
)
{
UserUtils
.
setCodeErrCntMap
(
account
+
OPERATION_CHECK
,
codeErrCnt
+
1
);
}
else
{
UserUtils
.
setCodeFreezeTimeMap
(
account
+
OPERATION_CHECK
,
CommonUtil
.
getCurDateStr
());
}
return
BaseResult
.
failed
().
setMsgValue
(
"验证码不正确,请重试"
);
}
else
{
return
BaseResult
.
success
();
}
}
}
@ApiOperation
(
value
=
"重置密码"
,
notes
=
"重置密码功能"
)
@PostMapping
(
"reset_pwd"
)
@MyLog
(
title
=
"重置密码"
,
businessType
=
BusinessType
.
UPDATE
)
public
BaseResult
resetPwd
(
@RequestBody
UserResetPwdVo
userResetPwdVo
)
{
String
errCntTimeMap
=
UserUtils
.
getErrCntTimeMap
(
account
+
OPERATION_RESET
);
if
(!
StringUtils
.
isEmpty
(
errCntTimeMap
))
{
if
(
errCntTimeMap
.
equals
(
CommonUtil
.
getCurDateStr
()))
{
return
BaseResult
.
failed
().
setMsgValue
(
"今日尝试重置密码次数已达"
+
forgetPwdMaxErrCount
+
"次,请明日再试"
);
}
else
{
UserUtils
.
removeErrCntTimeMap
(
account
+
OPERATION_RESET
);
UserUtils
.
removeErrCnt
(
account
+
OPERATION_RESET
);
}
}
String
newPassWord
=
userResetPwdVo
.
getPassword
();
newPassWord
=
RSAUtil
.
getDecryptString
(
newPassWord
,
PRIVATE_KRY
);
if
(
StringUtils
.
isEmpty
(
newPassWord
))
{
return
BaseResult
.
failed
().
setMsgValue
(
"密码不能为空"
);
}
Integer
errCnt
=
UserUtils
.
getErrCnt
(
account
+
OPERATION_RESET
);
if
(
errCnt
==
null
)
{
errCnt
=
0
;
}
User
user
=
userService
.
getUserByName
(
USER_NAME
);
if
(
newPassWord
.
length
()
<
8
)
{
computeResetPwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码不得小于8位"
);
}
if
(
CommonUtil
.
verifyPasswordContainAccount
(
newPassWord
,
user
.
getUserName
()))
{
computeResetPwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码中不得包含用户名的完整字符串、大小写变位或形似变换的字符串"
);
}
if
(
CommonUtil
.
isKeyBoardContinuousChar
(
newPassWord
))
{
computeResetPwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码不得包含键盘连续字符4个及以上"
);
}
if
(!
CommonUtil
.
checkPassword
(
newPassWord
))
{
computeResetPwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"至少由大写字母、小写字母、数字与特殊符号等4类中3类混合"
);
}
user
.
setPassword
(
newPassWord
);
boolean
b
=
userService
.
updateUser
(
user
);
if
(
b
)
{
return
BaseResult
.
success
().
setMsgValue
(
"密码修改成功"
);
}
else
{
return
BaseResult
.
failed
().
setMsgValue
(
"密码修改失败"
);
}
}
private
void
computeResetPwdErrCnt
(
int
errCnt
)
{
if
(
errCnt
<
forgetPwdMaxErrCount
-
1
)
{
UserUtils
.
setErrCnt
(
account
+
OPERATION_RESET
,
errCnt
+
1
);
}
else
{
UserUtils
.
setErrCntTimeMap
(
account
+
OPERATION_RESET
,
CommonUtil
.
getCurDateStr
());
}
}
}
license/src/main/java/iot/sixiang/license/controller/UserController.java
View file @
fb1e7076
...
...
@@ -48,6 +48,13 @@ public class UserController {
private
UserService
userService
;
@Value
(
"${rsa.private_key}"
)
private
String
PRIVATE_KRY
;
@Value
(
"${other.error_count.change_pwd}"
)
private
Integer
changePwdMaxErrCount
;
@Value
(
"${spring.mail.to}"
)
private
String
account
;
private
static
final
String
OPERATION_CHANGE
=
"change"
;
@InitBinder
public
void
initBinder
(
WebDataBinder
binder
)
{
...
...
@@ -127,6 +134,15 @@ public class UserController {
@PostMapping
(
"update_pwd"
)
@MyLog
(
title
=
"修改密码"
,
businessType
=
BusinessType
.
UPDATE
)
public
BaseResult
updatePwd
(
@RequestBody
UserUpdatePwdVo
userUpdatePwdVo
)
{
String
errCntTimeMap
=
UserUtils
.
getErrCntTimeMap
(
account
+
OPERATION_CHANGE
);
if
(!
StringUtils
.
isEmpty
(
errCntTimeMap
))
{
if
(
errCntTimeMap
.
equals
(
CommonUtil
.
getCurDateStr
()))
{
return
BaseResult
.
failed
().
setMsgValue
(
"今日尝试修改密码次数已达"
+
changePwdMaxErrCount
+
"次,请明日再试"
);
}
else
{
UserUtils
.
removeErrCntTimeMap
(
account
+
OPERATION_CHANGE
);
UserUtils
.
removeErrCnt
(
account
+
OPERATION_CHANGE
);
}
}
String
oldPassWord
=
userUpdatePwdVo
.
getOldPassWord
();
String
newPassWord
=
userUpdatePwdVo
.
getNewPassWord
();
String
userId
=
UserUtils
.
getLoginUserId
();
...
...
@@ -138,7 +154,27 @@ public class UserController {
}
oldPassWord
=
RSAUtil
.
getDecryptString
(
oldPassWord
,
PRIVATE_KRY
);
newPassWord
=
RSAUtil
.
getDecryptString
(
newPassWord
,
PRIVATE_KRY
);
Integer
errCnt
=
UserUtils
.
getErrCnt
(
account
+
OPERATION_CHANGE
);
if
(
errCnt
==
null
)
{
errCnt
=
0
;
}
if
(
oldPassWord
.
equals
(
user
.
getPassword
()))
{
if
(
newPassWord
.
length
()
<
8
)
{
computeChangePwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码不得小于8位"
);
}
if
(
CommonUtil
.
verifyPasswordContainAccount
(
newPassWord
,
user
.
getUserName
()))
{
computeChangePwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码中不得包含用户名的完整字符串、大小写变位或形似变换的字符串"
);
}
if
(
CommonUtil
.
isKeyBoardContinuousChar
(
newPassWord
))
{
computeChangePwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"密码不得包含键盘连续字符4个及以上"
);
}
if
(!
CommonUtil
.
checkPassword
(
newPassWord
))
{
computeChangePwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"至少由大写字母、小写字母、数字与特殊符号等4类中3类混合"
);
}
user
.
setPassword
(
newPassWord
);
boolean
b
=
userService
.
updateUser
(
user
);
if
(
b
)
{
...
...
@@ -147,10 +183,19 @@ public class UserController {
return
BaseResult
.
failed
().
setMsgValue
(
"密码修改失败"
);
}
}
else
{
computeChangePwdErrCnt
(
errCnt
);
return
BaseResult
.
failed
().
setMsgValue
(
"原密码出错"
);
}
}
private
void
computeChangePwdErrCnt
(
int
errCnt
)
{
if
(
errCnt
<
changePwdMaxErrCount
-
1
)
{
UserUtils
.
setErrCnt
(
account
+
OPERATION_CHANGE
,
errCnt
+
1
);
}
else
{
UserUtils
.
setErrCntTimeMap
(
account
+
OPERATION_CHANGE
,
CommonUtil
.
getCurDateStr
());
}
}
/**
* 分页查询所有的user
...
...
@@ -184,7 +229,7 @@ public class UserController {
List
<
UserVo
>
result
=
records
.
getResult
();
String
str
=
"uBtWZTiPMYkQLsp7rNly3RUIXKGqFbjnSg56H8ve49AC0mfO"
;
for
(
UserVo
u
:
result
)
{
u
.
setPassword
(
DigestUtils
.
md5DigestAsHex
((
str
+
u
.
getPassword
()).
getBytes
()));
u
.
setPassword
(
DigestUtils
.
md5DigestAsHex
((
str
+
u
.
getPassword
()).
getBytes
()));
}
return
new
PageResult
(
200
,
"查找成功"
,
pageNo
,
pages
,
total
,
result
);
}
...
...
license/src/main/java/iot/sixiang/license/jwt/JwtFilter.java
View file @
fb1e7076
...
...
@@ -25,6 +25,8 @@ public class JwtFilter implements Filter {
private
static
final
String
url4
=
"/v2/api-docs"
;
private
static
final
String
url7
=
"/swagger-resources"
;
private
static
final
String
url8
=
"/webjars/"
;
private
static
final
String
url9
=
"/check_code"
;
private
static
final
String
url10
=
"/reset_pwd"
;
@Override
public
void
init
(
FilterConfig
filterConfig
)
{
...
...
@@ -49,7 +51,7 @@ public class JwtFilter implements Filter {
boolean
check
=
true
;
String
uri
=
request
.
getRequestURI
();
if
(
uri
.
contains
(
url1
)
||
uri
.
contains
(
url2
)
||
uri
.
contains
(
url3
)
||
uri
.
contains
(
url4
)
||
uri
.
contains
(
url7
)
||
uri
.
contains
(
url8
))
{
if
(
uri
.
contains
(
url1
)
||
uri
.
contains
(
url2
)
||
uri
.
contains
(
url3
)
||
uri
.
contains
(
url4
)
||
uri
.
contains
(
url7
)
||
uri
.
contains
(
url8
)
||
uri
.
contains
(
url9
)
||
uri
.
contains
(
url10
)
)
{
if
(
uri
.
contains
(
url1
))
{
uri
=
XssUtil
.
checkXSS
(
uri
);
UserUtils
.
setUri
(
uri
);
...
...
license/src/main/java/iot/sixiang/license/jwt/UserUtils.java
View file @
fb1e7076
...
...
@@ -13,9 +13,13 @@ public abstract class UserUtils {
static
Map
<
String
,
String
>
tokenMap
=
new
HashMap
<>();
static
Map
<
String
,
Date
>
tokenExpTimeMap
=
new
HashMap
<>();
static
Map
<
String
,
Integer
>
errCntMap
=
new
HashMap
<>();
static
Map
<
String
,
String
>
errCntTimeMap
=
new
HashMap
<>();
static
Map
<
String
,
String
>
emailCodeMap
=
new
HashMap
<>();
static
Map
<
String
,
Date
>
emailCodeExpTimeMap
=
new
HashMap
<>();
static
Map
<
String
,
Date
>
countFreezeDateMap
=
new
HashMap
<>();
static
Map
<
String
,
Integer
>
codeErrCntMap
=
new
HashMap
<>();
static
Map
<
String
,
String
>
codeFreezeTimeMap
=
new
HashMap
<>();
/**
* 线程变量,存放user实体类信息,即使是静态的也与其他线程也是隔离的
*/
...
...
@@ -136,8 +140,43 @@ public abstract class UserUtils {
return
emailCodeExpTimeMap
.
get
(
email
);
}
public
static
void
removeEmailCodeExpTime
(
String
email
)
{
emailCodeExpTimeMap
.
remove
(
email
);
}
public
static
void
setCodeErrCntMap
(
String
account
,
int
count
)
{
codeErrCntMap
.
put
(
account
,
count
);
}
public
static
Integer
getCodeErrCntMap
(
String
account
)
{
return
codeErrCntMap
.
get
(
account
);
}
public
static
void
removeCodeErrCntMap
(
String
account
)
{
codeErrCntMap
.
remove
(
account
);
}
public
static
void
setCodeFreezeTimeMap
(
String
account
,
String
timeStr
)
{
codeFreezeTimeMap
.
put
(
account
,
timeStr
);
}
public
static
String
getCodeFreezeTimeMap
(
String
account
)
{
return
codeFreezeTimeMap
.
get
(
account
);
}
public
static
void
removeCodeFreezeTimeMap
(
String
account
)
{
codeFreezeTimeMap
.
remove
(
account
);
}
public
static
void
setErrCntTimeMap
(
String
account
,
String
timeStr
)
{
errCntTimeMap
.
put
(
account
,
timeStr
);
}
public
static
String
getErrCntTimeMap
(
String
account
)
{
return
errCntTimeMap
.
get
(
account
);
}
public
static
void
removeErrCntTimeMap
(
String
account
)
{
errCntTimeMap
.
remove
(
account
);
}
}
license/src/main/java/iot/sixiang/license/model/dto/CheckCodeDto.java
0 → 100644
View file @
fb1e7076
package
iot
.
sixiang
.
license
.
model
.
dto
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
/**
* Created by m33
* Date 2022/9/23 17:46
* Description
*/
@Data
public
class
CheckCodeDto
{
@ApiModelProperty
(
"验证码"
)
private
String
code
;
}
license/src/main/java/iot/sixiang/license/model/vo/UserResetPwdVo.java
0 → 100644
View file @
fb1e7076
package
iot
.
sixiang
.
license
.
model
.
vo
;
import
lombok.Data
;
/**
* Created by m33
* Date 2022/9/23 18:32
* Description
*/
@Data
public
class
UserResetPwdVo
{
private
String
password
;
}
license/src/main/java/iot/sixiang/license/service/UserService.java
View file @
fb1e7076
...
...
@@ -12,7 +12,7 @@ import iot.sixiang.license.model.vo.UserVo;
* @author m33
* @since 2022-06-06
*/
public
interface
UserService
{
public
interface
UserService
{
boolean
deleteUser
(
int
userIdVo
);
...
...
@@ -23,4 +23,6 @@ public interface UserService{
PageInfoModel
<
UserVo
>
getUserList
(
int
pageNo
,
int
pageSize
,
String
userName
,
String
company
);
User
getUserById
(
int
userId
);
User
getUserByName
(
String
root
);
}
license/src/main/java/iot/sixiang/license/service/impl/UserServiceImpl.java
View file @
fb1e7076
package
iot
.
sixiang
.
license
.
service
.
impl
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
iot.sixiang.license.consts.ResultCode
;
import
iot.sixiang.license.entity.User
;
...
...
@@ -34,11 +35,11 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
UserMapper
userMapper
;
@Override
public
PageInfoModel
<
UserVo
>
getUserList
(
int
pageNo
,
int
pageSize
,
String
userName
,
String
company
)
{
if
(
pageNo
==
0
||
pageSize
==
0
)
{
throw
new
IotLicenseException
(
ResultCode
.
VALIDATE_FAILED
.
getCode
(),
ResultCode
.
VALIDATE_FAILED
.
getMsg
());
public
PageInfoModel
<
UserVo
>
getUserList
(
int
pageNo
,
int
pageSize
,
String
userName
,
String
company
)
{
if
(
pageNo
==
0
||
pageSize
==
0
)
{
throw
new
IotLicenseException
(
ResultCode
.
VALIDATE_FAILED
.
getCode
(),
ResultCode
.
VALIDATE_FAILED
.
getMsg
());
}
List
<
UserVo
>
records
=
userMapper
.
getUserList
(
userName
,
company
);
List
<
UserVo
>
records
=
userMapper
.
getUserList
(
userName
,
company
);
records
=
records
.
stream
().
sorted
(
Comparator
.
comparing
(
UserVo:
:
getCreateTime
,
Comparator
.
reverseOrder
())).
collect
(
Collectors
.
toList
());
List
<
UserVo
>
result
=
new
ArrayList
<>();
int
begin
=
(
pageNo
-
1
)
*
pageSize
;
...
...
@@ -56,10 +57,17 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
return
userMapper
.
getUserById
(
userId
);
}
@Override
public
User
getUserByName
(
String
root
)
{
LambdaQueryWrapper
<
User
>
wrapper
=
new
LambdaQueryWrapper
<>();
wrapper
.
eq
(
User:
:
getUserName
,
root
).
last
(
"limit 1"
);
return
userMapper
.
selectOne
(
wrapper
);
}
@Override
public
boolean
deleteUser
(
int
userId
)
{
if
(
userId
==
0
)
{
throw
new
IotLicenseException
(
ResultCode
.
VALIDATE_FAILED
.
getCode
(),
ResultCode
.
VALIDATE_FAILED
.
getMsg
());
if
(
userId
==
0
)
{
throw
new
IotLicenseException
(
ResultCode
.
VALIDATE_FAILED
.
getCode
(),
ResultCode
.
VALIDATE_FAILED
.
getMsg
());
}
return
userMapper
.
deleteUser
(
userId
);
}
...
...
@@ -73,7 +81,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
if
(
res
!=
null
)
{
throw
new
IotLicenseException
(
403
,
"用户名已存在"
);
}
return
userMapper
.
addUser
(
userName
,
company
,
password
);
return
userMapper
.
addUser
(
userName
,
company
,
password
);
}
@Override
...
...
license/src/main/java/iot/sixiang/license/util/CommonUtil.java
View file @
fb1e7076
...
...
@@ -4,6 +4,7 @@ import iot.sixiang.license.consts.Consts;
import
iot.sixiang.license.model.ResResult
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.http.util.TextUtils
;
import
org.springframework.boot.system.ApplicationHome
;
import
java.io.File
;
...
...
@@ -14,9 +15,143 @@ import java.text.SimpleDateFormat;
import
java.util.Date
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
@Slf4j
public
class
CommonUtil
{
/**
* 验证密码-是否包含用户名字符(密码应与用户名无相关性,密码中不得包含用户名的完整字符串、大小写变位或形似变换的字符串)
*/
public
static
boolean
verifyPasswordContainAccount
(
String
password
,
String
account
)
{
boolean
isContain
=
false
;
if
(!
TextUtils
.
isEmpty
(
password
)
&&
!
TextUtils
.
isEmpty
(
account
))
{
password
=
password
.
toLowerCase
();
account
=
account
.
toLowerCase
();
if
(
password
.
contains
(
account
))
{
return
true
;
}
String
[]
likes
=
{
"a"
,
"l"
,
"o"
};
String
[]
likeSign
=
{
"@"
,
"!"
,
"0"
};
String
originalAccount
=
account
+
""
;
for
(
int
i
=
0
;
i
<
likes
.
length
;
i
++)
{
String
tempAccount
=
originalAccount
.
replace
(
likes
[
i
],
likeSign
[
i
]);
account
=
account
.
replace
(
likes
[
i
],
likeSign
[
i
]);
if
(
password
.
contains
(
tempAccount
)
||
password
.
contains
(
account
))
{
return
true
;
}
}
}
return
isContain
;
}
/**
* 键盘连续字符统计4个
*
* @param str
* @return
*/
public
static
boolean
isKeyBoardContinuousChar
(
String
str
)
{
boolean
result
=
false
;
char
[][]
c1
=
{
{
'!'
,
'@'
,
'#'
,
'$'
,
'%'
,
'^'
,
'&'
,
'*'
,
'('
,
')'
,
'_'
,
'+'
},
{
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
'o'
,
'p'
,
'{'
,
'}'
,
'|'
},
{
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
':'
,
'"'
},
{
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
,
'<'
,
'>'
,
'?'
}
};
char
[][]
c2
=
{
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'0'
,
'-'
,
'='
},
{
'q'
,
'w'
,
'e'
,
'r'
,
't'
,
'y'
,
'u'
,
'i'
,
'o'
,
'p'
,
'{'
,
'}'
,
'\\'
},
{
'a'
,
's'
,
'd'
,
'f'
,
'g'
,
'h'
,
'j'
,
'k'
,
'l'
,
';'
,
'\''
},
{
'z'
,
'x'
,
'c'
,
'v'
,
'b'
,
'n'
,
'm'
,
','
,
'.'
,
'/'
}
};
for
(
char
[][]
c
:
new
char
[][][]{
c1
,
c2
})
{
//横向
for
(
char
[]
chars
:
c
)
{
for
(
int
j
=
0
;
j
<
chars
.
length
-
3
;
j
++)
{
//创建连续字符
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
k
=
j
;
k
<
j
+
4
;
k
++)
{
sb
.
append
(
chars
[
k
]);
}
String
keyStr
=
sb
.
toString
();
if
(
str
.
contains
(
keyStr
))
{
return
true
;
}
}
}
//纵向
for
(
int
i
=
0
;
i
<
c
[
3
].
length
;
i
++)
{
//创建连续字符--每列只有4个
StringBuffer
sb
=
new
StringBuffer
();
for
(
int
j
=
0
;
j
<
4
;
j
++)
{
sb
.
append
(
c
[
j
][
i
]);
}
String
keyStr
=
sb
.
toString
();
if
(
str
.
contains
(
keyStr
))
{
return
true
;
}
}
}
return
result
;
}
public
static
void
main
(
String
[]
args
)
{
boolean
b
=
checkPassword
(
"1234qwe123"
);
System
.
out
.
println
(
b
);
}
/**
* 密码验证
* (至少由8位及以上大写字母、小写字母、数字与特殊符号等4类中3类混合)
*
* @param password
* @return
*/
public
static
boolean
checkPassword
(
String
password
)
{
boolean
flag
=
false
;
try
{
int
c
=
0
;
if
(
find
(
"[a-z]+"
,
password
))
{
c
++;
}
if
(
find
(
"[A-Z]+"
,
password
))
{
c
++;
}
if
(
find
(
"[0-9]+"
,
password
))
{
c
++;
}
if
(
find
(
"\\W+|_"
,
password
)
&&
!
find
(
"\\s+"
,
password
))
{
//特殊符号
c
++;
}
if
(
c
>=
3
)
{
flag
=
true
;
}
}
catch
(
Exception
e
)
{
flag
=
false
;
}
return
flag
;
}
//通用匹配
public
static
boolean
find
(
String
regexStr
,
String
input
)
{
boolean
flag
;
try
{
Pattern
regex
=
Pattern
.
compile
(
regexStr
);
Matcher
matcher
=
regex
.
matcher
(
input
);
// 部分进行匹配
flag
=
matcher
.
find
();
}
catch
(
Exception
e
)
{
flag
=
false
;
}
return
flag
;
}
/**
* 获取随机验证码
*/
...
...
@@ -45,8 +180,8 @@ public class CommonUtil {
int
maxNum
=
36
;
int
i
=
-
1
;
int
count
=
0
;
char
[]
str
=
{
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
};
char
[]
str
=
{
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
'O'
,
'P'
,
'Q'
,
'R'
,
'S'
,
'T'
,
'U'
,
'V'
,
'W'
,
'X'
,
'Y'
,
'Z'
,
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
};
StringBuilder
pwd
=
new
StringBuilder
(
""
);
SecureRandom
secureRandom
=
null
;
try
{
...
...
@@ -67,7 +202,6 @@ public class CommonUtil {
}
public
static
String
getSystemTime
()
{
SimpleDateFormat
df
=
new
SimpleDateFormat
(
"yyyy-MM-dd HH:mm:ss"
);
// 设置日期格式
String
time
=
df
.
format
(
new
Date
());
...
...
@@ -100,7 +234,7 @@ public class CommonUtil {
}
public
static
String
getServerParentDirectory
()
{
return
new
File
(
new
ApplicationHome
(
Consts
.
class
).
getSource
().
getParentFile
().
getPath
()).
getParent
()
+
File
.
separator
+
"lib"
;
return
new
File
(
new
ApplicationHome
(
Consts
.
class
).
getSource
().
getParentFile
().
getPath
()).
getParent
()
+
File
.
separator
+
"lib"
;
}
/**
...
...
@@ -147,6 +281,13 @@ public class CommonUtil {
return
res
;
}
public
static
String
getCurDateStr
()
{
Date
date
=
new
Date
();
String
pattern
=
"yyyy-MM-dd"
;
SimpleDateFormat
simpleDateFormat
=
new
SimpleDateFormat
(
pattern
);
return
simpleDateFormat
.
format
(
date
);
}
// 用于测试存储型xss
public
static
Object
reverseData
(
Object
obj
,
Class
clazz
)
{
...
...
license/src/main/resources/application.yml
View file @
fb1e7076
...
...
@@ -32,12 +32,18 @@ server:
cros
:
# 需要设置访问白名单
cros_allowed_origins
:
http://192.168.1.88:8080, http://
localhost:8868, http://localhost
:8080
cros_allowed_origins
:
http://192.168.1.88:8080, http://
192.168.1.88:8081, http://localhost:8868, http://localhost:8080, http://192.168.1.54
:8080
cros_allowed_method
:
GET,POST
other
:
md5
:
salt
:
PI7dBYlEfeP8IZ6vogqFL1U5pVnyCuNAGja3lsREx4M9r0SX
error_count
:
change_pwd
:
5
# 修改密码的最大错误次数
forget_pwd
:
5
# 忘记密码的最大错误次数
check_code
:
5
# 校验验证码的最大错误次数
code_exp_time
:
3
# 验证码失效时间,单位:分钟
rsa
:
public_key
:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA18W2H1hO98dUWf1PNKNWTWmxCyvvy0NOR7iSvp76J0LdzyMJxs8WHVAmRfSGOb9SvpDZhBVx11bhTBqkl1qMzJWzn+F2ZtTCH2nXZcJHwSfLuGqin5FRBYW1WrFkqwg+R80aOuRSrbo0k1bZg3JPkkCxISHieEZPjSV5a4r7+Xopj0a9Dnh3rh4nDmH2p/wvotkx1oMKdhFglYcAITlk9ucEUf+CDuSdTAFFeKg9+fPqwKqWZRJZPQXqV3pGZ1/JS7gPnBFGZojW44eJufkBeiW3pbBvm/cKOkTnb8o4oltYUJsirYSQCCG+sDtxUAuGxuDCv8p+r8dWE1z5+xKclQIDAQAB
private_key
:
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDXxbYfWE73x1RZ/U80o1ZNabELK+/LQ05HuJK+nvonQt3PIwnGzxYdUCZF9IY5v1K+kNmEFXHXVuFMGqSXWozMlbOf4XZm1MIfaddlwkfBJ8u4aqKfkVEFhbVasWSrCD5HzRo65FKtujSTVtmDck+SQLEhIeJ4Rk+NJXlrivv5eimPRr0OeHeuHicOYfan/C+i2THWgwp2EWCVhwAhOWT25wRR/4IO5J1MAUV4qD358+rAqpZlElk9BepXekZnX8lLuA+cEUZmiNbjh4m5+QF6JbelsG+b9wo6ROdvyjiiW1hQmyKthJAIIb6wO3FQC4bG4MK/yn6vx1YTXPn7EpyVAgMBAAECggEAR7YQ+kfqLtVThnj2mwLyCtZmndTjZEWhPZrtQmcpsmS5vT7i3+0xZ1qc7cD/3y9j+6u+bvSFmlDondd4/kh85P2X7joLlM9/GNufV9WC7YIhZdAi7i9ooxI2HMc6MtGRiWF0J0B87folwRYrQlF6epv/goh1cQ3FIJ7kxMYzSk0gF0JcmOZn3KH8tMt3t/GK+uVUIycuEQQKsaTTq45nIM7oqhlAwD/M+IO2pGFkLXJ23FzFACI10qBdpn+xL2xFGRO6EE8EAeDslT4OvvN3/vtnSnRNn8CJqfoEG40XO0xrZzH1noI35iPWX1WrN7qFLAhl2oLhu1ZSIA1tz0+I/QKBgQD3X/islXfVmV2XeuHvaf4qcMAdrgLQwtmLlHhFxfFURPh6au8uatDgUA8HWcRACmhtTruytlFRGKKFwZxuQE/LOZh67Uts3GTs5eHN8xvZTL+en+n7B/cCRYrrg3+yAM/k0eezIlk65iW700o+icEHxkwTXhhVBmIROBzpXsVCwwKBgQDfS6kVhgZxLMQePbXUQ1NBr2KbfhXLzceINhsoyWLa1rIk8+9HLSxw8q0zma12Jqkd22OAgkbeLDy+niYPi3pUrWAm8O59Ot1aaOarxMTvEv7+eS+urKId57sli/hQTWsS+xghA4+VfW2+EY++pYyZIp+j+1/Q2ciXWVJy4iv9xwKBgFzW8+kxn2vWxz1WrPzBdtZOwothB0V6G1M7QXhONag+ylKHV4TAKexFn55Onky6mz6K0f7cVeBtsnEonKD0Gf5Xe1aHQEt225ndHMXCe60uFKxfr9y6vIVpvB1vmLkhfOSPsrmUJpDoVzkKr06RPJTCY0LRiag/YQa9XHxpSPcpAoGAKbsiJnudyJjtLhmqWbkbXjNA4n515FjY6YPzH3RDnVJyiKVuGoc+vv0bkYEvAd3HzWSq++FdDTiHQbictFsEyb59McnlSFIv/C2Orptfkq6iKTzMxIBO6/fa6fF2vss5L5rtr33S38VJNTRjAOY/mH74BtV72rRY4LA40G+keRECgYEAiGg0DYxcSGf2bEP1WESYPTTdgS5ke1niIwZ00SgtkIjPSVgTCmf4Tciys6lGSe/Oqnvk24VR6pz07wzcbH92AURVaeqiEvVuVonzA6Yl0jxeOIM31S1BSBJRT8kDijuvwoJu2tPoZG0306KF9L8pyy1Z6cTTmIfGR0NpZCHWPSg=
\ No newline at end of file
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