|
|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
package cn.iocoder.yudao.module.system.service.auth;
|
|
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
|
|
|
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
|
|
|
|
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
|
|
|
|
@ -9,7 +10,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
|
|
|
|
import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.system.service.common.CaptchaService;
|
|
|
|
|
import cn.iocoder.yudao.module.system.service.dept.PostService;
|
|
|
|
|
import cn.iocoder.yudao.module.system.service.logger.LoginLogService;
|
|
|
|
|
import cn.iocoder.yudao.module.system.service.social.SocialUserService;
|
|
|
|
|
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
|
|
|
|
@ -17,23 +17,16 @@ import org.junit.jupiter.api.BeforeEach;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
|
|
|
import org.springframework.context.annotation.Import;
|
|
|
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
|
|
|
import org.springframework.security.authentication.BadCredentialsException;
|
|
|
|
|
import org.springframework.security.authentication.DisabledException;
|
|
|
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
|
|
import org.springframework.security.core.Authentication;
|
|
|
|
|
import org.springframework.security.core.AuthenticationException;
|
|
|
|
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import javax.validation.Validator;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
|
|
|
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
|
|
|
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
|
|
|
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
|
|
|
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
|
|
|
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
|
import static org.mockito.ArgumentMatchers.eq;
|
|
|
|
|
import static org.mockito.Mockito.*;
|
|
|
|
|
|
|
|
|
|
@ -46,10 +39,6 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
|
|
|
|
@MockBean
|
|
|
|
|
private AdminUserService userService;
|
|
|
|
|
@MockBean
|
|
|
|
|
private AuthenticationManager authenticationManager;
|
|
|
|
|
@MockBean
|
|
|
|
|
private Authentication authentication;
|
|
|
|
|
@MockBean
|
|
|
|
|
private CaptchaService captchaService;
|
|
|
|
|
@MockBean
|
|
|
|
|
private LoginLogService loginLogService;
|
|
|
|
|
@ -58,8 +47,6 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
|
|
|
|
@MockBean
|
|
|
|
|
private SocialUserService socialService;
|
|
|
|
|
@MockBean
|
|
|
|
|
private PostService postService;
|
|
|
|
|
@MockBean
|
|
|
|
|
private SmsCodeApi smsCodeApi;
|
|
|
|
|
|
|
|
|
|
@MockBean
|
|
|
|
|
@ -71,131 +58,124 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLoadUserByUsername_success() {
|
|
|
|
|
public void testLogin0_success() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String username = randomString();
|
|
|
|
|
// mock 方法
|
|
|
|
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username));
|
|
|
|
|
String password = randomString();
|
|
|
|
|
// mock user 数据
|
|
|
|
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
|
|
|
|
.setPassword(password).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
|
|
|
|
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
|
|
|
|
// mock password 匹配
|
|
|
|
|
when(userService.isPasswordMatch(eq(password), eq(user.getPassword()))).thenReturn(true);
|
|
|
|
|
|
|
|
|
|
// 调用
|
|
|
|
|
LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
|
|
|
|
|
LoginUser loginUser = authService.login0(username, password);
|
|
|
|
|
// 校验
|
|
|
|
|
AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
|
|
|
|
|
assertPojoEquals(user, loginUser);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLoadUserByUsername_userNotFound() {
|
|
|
|
|
public void testLogin0_userNotFound() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String username = randomString();
|
|
|
|
|
// mock 方法
|
|
|
|
|
String password = randomString();
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertThrows(UsernameNotFoundException.class, // 抛出 UsernameNotFoundException 异常
|
|
|
|
|
() -> authService.loadUserByUsername(username),
|
|
|
|
|
username); // 异常提示为 username
|
|
|
|
|
AssertUtils.assertServiceException(() -> authService.login0(username, password),
|
|
|
|
|
AUTH_LOGIN_BAD_CREDENTIALS);
|
|
|
|
|
verify(loginLogService).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.BAD_CREDENTIALS.getResult())
|
|
|
|
|
&& o.getUserId() == null)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLogin_captchaNotFound() {
|
|
|
|
|
public void testLogin0_badCredentials() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
String username = randomString();
|
|
|
|
|
String password = randomString();
|
|
|
|
|
// mock user 数据
|
|
|
|
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
|
|
|
|
.setPassword(password).setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
|
|
|
|
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_NOT_FOUND);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.CAPTCHA_NOT_FOUND.getResult()))
|
|
|
|
|
AssertUtils.assertServiceException(() -> authService.login0(username, password),
|
|
|
|
|
AUTH_LOGIN_BAD_CREDENTIALS);
|
|
|
|
|
verify(loginLogService).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.BAD_CREDENTIALS.getResult())
|
|
|
|
|
&& o.getUserId().equals(user.getId()))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLogin_captchaCodeError() {
|
|
|
|
|
public void testLogin0_userDisabled() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
|
|
|
|
|
// mock 验证码不正确
|
|
|
|
|
String code = randomString();
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(code);
|
|
|
|
|
String username = randomString();
|
|
|
|
|
String password = randomString();
|
|
|
|
|
// mock user 数据
|
|
|
|
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername(username)
|
|
|
|
|
.setPassword(password).setStatus(CommonStatusEnum.DISABLE.getStatus()));
|
|
|
|
|
when(userService.getUserByUsername(eq(username))).thenReturn(user);
|
|
|
|
|
// mock password 匹配
|
|
|
|
|
when(userService.isPasswordMatch(eq(password), eq(user.getPassword()))).thenReturn(true);
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_CAPTCHA_CODE_ERROR);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.CAPTCHA_CODE_ERROR.getResult()))
|
|
|
|
|
AssertUtils.assertServiceException(() -> authService.login0(username, password),
|
|
|
|
|
AUTH_LOGIN_USER_DISABLED);
|
|
|
|
|
verify(loginLogService).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.USER_DISABLED.getResult())
|
|
|
|
|
&& o.getUserId().equals(user.getId()))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLogin_badCredentials() {
|
|
|
|
|
public void testCaptcha_success() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
|
|
|
|
|
// mock 验证码正确
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
|
|
|
|
// mock 抛出异常
|
|
|
|
|
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
|
|
|
|
.thenThrow(new BadCredentialsException("测试账号或密码不正确"));
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_BAD_CREDENTIALS);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.BAD_CREDENTIALS.getResult()))
|
|
|
|
|
);
|
|
|
|
|
// 调用
|
|
|
|
|
authService.verifyCaptcha(reqVO);
|
|
|
|
|
// 断言
|
|
|
|
|
verify(captchaService).deleteCaptchaCode(reqVO.getUuid());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLogin_userDisabled() {
|
|
|
|
|
public void testCaptcha_notFound() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
|
|
|
|
|
// mock 验证码正确
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
|
|
|
|
// mock 抛出异常
|
|
|
|
|
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
|
|
|
|
.thenThrow(new DisabledException("测试用户被禁用"));
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_USER_DISABLED);
|
|
|
|
|
assertServiceException(() -> authService.verifyCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_NOT_FOUND);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.USER_DISABLED.getResult()))
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.CAPTCHA_NOT_FOUND.getResult()))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLogin_unknownError() {
|
|
|
|
|
public void testCaptcha_codeError() {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
// mock 验证码正确
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
|
|
|
|
// mock 抛出异常
|
|
|
|
|
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
|
|
|
|
.thenThrow(new AuthenticationException("测试未知异常") {});
|
|
|
|
|
|
|
|
|
|
// mock 验证码不正确
|
|
|
|
|
String code = randomString();
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(code);
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
assertServiceException(() -> authService.login(reqVO, userIp, userAgent), AUTH_LOGIN_FAIL_UNKNOWN);
|
|
|
|
|
assertServiceException(() -> authService.verifyCaptcha(reqVO), AUTH_LOGIN_CAPTCHA_CODE_ERROR);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
verify(loginLogService).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.UNKNOWN_ERROR.getResult()))
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.CAPTCHA_CODE_ERROR.getResult()))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -204,29 +184,32 @@ public class AuthServiceImplTest extends BaseDbUnitTest {
|
|
|
|
|
// 准备参数
|
|
|
|
|
String userIp = randomString();
|
|
|
|
|
String userAgent = randomString();
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class);
|
|
|
|
|
AuthLoginReqVO reqVO = randomPojo(AuthLoginReqVO.class, o ->
|
|
|
|
|
o.setUsername("test_username").setPassword("test_password"));
|
|
|
|
|
|
|
|
|
|
// mock 验证码正确
|
|
|
|
|
when(captchaService.getCaptchaCode(reqVO.getUuid())).thenReturn(reqVO.getCode());
|
|
|
|
|
// mock authentication
|
|
|
|
|
Long userId = randomLongId();
|
|
|
|
|
Set<Long> userRoleIds = randomSet(Long.class);
|
|
|
|
|
LoginUser loginUser = randomPojo(LoginUser.class, o -> o.setId(userId));
|
|
|
|
|
when(authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(reqVO.getUsername(), reqVO.getPassword())))
|
|
|
|
|
.thenReturn(authentication);
|
|
|
|
|
when(authentication.getPrincipal()).thenReturn(loginUser);
|
|
|
|
|
// mock user 数据
|
|
|
|
|
AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setUsername("test_username")
|
|
|
|
|
.setPassword("test_password").setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
|
|
|
|
when(userService.getUserByUsername(eq("test_username"))).thenReturn(user);
|
|
|
|
|
// mock password 匹配
|
|
|
|
|
when(userService.isPasswordMatch(eq("test_password"), eq(user.getPassword()))).thenReturn(true);
|
|
|
|
|
// mock 缓存登录用户到 Redis
|
|
|
|
|
String token = randomString();
|
|
|
|
|
when(userSessionService.createUserSession(loginUser, userIp, userAgent)).thenReturn(token);
|
|
|
|
|
when(userSessionService.createUserSession(argThat(argument -> {
|
|
|
|
|
AssertUtils.assertPojoEquals(user, argument);
|
|
|
|
|
return true;
|
|
|
|
|
}), eq(userIp), eq(userAgent))).thenReturn(token);
|
|
|
|
|
|
|
|
|
|
// 调用, 并断言异常
|
|
|
|
|
String login = authService.login(reqVO, userIp, userAgent);
|
|
|
|
|
assertEquals(token, login);
|
|
|
|
|
String result = authService.login(reqVO, userIp, userAgent);
|
|
|
|
|
assertEquals(token, result);
|
|
|
|
|
// 校验调用参数
|
|
|
|
|
verify(captchaService, times(1)).deleteCaptchaCode(reqVO.getUuid());
|
|
|
|
|
verify(loginLogService, times(1)).createLoginLog(
|
|
|
|
|
verify(loginLogService).createLoginLog(
|
|
|
|
|
argThat(o -> o.getLogType().equals(LoginLogTypeEnum.LOGIN_USERNAME.getType())
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult()))
|
|
|
|
|
&& o.getResult().equals(LoginResultEnum.SUCCESS.getResult())
|
|
|
|
|
&& o.getUserId().equals(user.getId()))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|