Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.dromara.soul.admin.service.DashboardUserService;
import org.dromara.soul.admin.service.EnumService;
import org.dromara.soul.admin.utils.SoulResultMessage;
import org.dromara.soul.admin.vo.DashboardUserVO;
import org.dromara.soul.admin.vo.LoginDashboardUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand Down Expand Up @@ -55,8 +55,8 @@ public PlatformController(final DashboardUserService dashboardUserService, final
*/
@GetMapping("/login")
public SoulAdminResult loginDashboardUser(final String userName, final String password) {
DashboardUserVO dashboardUserVO = dashboardUserService.login(userName, password);
return SoulAdminResult.success(SoulResultMessage.PLATFORM_LOGIN_SUCCESS, dashboardUserVO);
LoginDashboardUserVO loginVO = dashboardUserService.login(userName, password);
return SoulAdminResult.success(SoulResultMessage.PLATFORM_LOGIN_SUCCESS, loginVO);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
package org.dromara.soul.admin.exception;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.UnauthorizedException;
import org.dromara.soul.admin.result.SoulAdminResult;
import org.dromara.soul.admin.utils.SoulResultMessage;
import org.dromara.soul.common.exception.CommonErrorCode;
import org.dromara.soul.common.exception.SoulException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ControllerAdvice;
Expand All @@ -36,8 +38,8 @@
@ControllerAdvice
public class ExceptionHandlers {

@ExceptionHandler(Exception.class)
@ResponseBody
@ExceptionHandler(Exception.class)
protected SoulAdminResult serverExceptionHandler(final Exception exception) {
log.error(exception.getMessage(), exception);
String message;
Expand All @@ -56,4 +58,12 @@ protected SoulAdminResult serverExceptionHandler(final DuplicateKeyException exc
log.error(exception.getMessage(), exception);
return SoulAdminResult.error(SoulResultMessage.UNIQUE_INDEX_CONFLICT_ERROR);
}

@ResponseBody
@ExceptionHandler(UnauthorizedException.class)
private SoulAdminResult shiroExceptionHandler(final UnauthorizedException exception) {
log.error(exception.getMessage(), exception);
return SoulAdminResult.error(CommonErrorCode.TOKEN_NO_PERMISSION, SoulResultMessage.TOKEN_HAS_NO_PERMISSION);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.dromara.soul.admin.page.CommonPager;
import org.dromara.soul.admin.query.DashboardUserQuery;
import org.dromara.soul.admin.vo.DashboardUserVO;
import org.dromara.soul.admin.vo.LoginDashboardUserVO;

import java.util.List;

Expand Down Expand Up @@ -77,7 +78,7 @@ public interface DashboardUserService {
*
* @param userName default username is admin
* @param password admin password
* @return {@linkplain DashboardUserVO}
* @return {@linkplain LoginDashboardUserVO}
*/
DashboardUserVO login(String userName, String password);
LoginDashboardUserVO login(String userName, String password);
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.dromara.soul.admin.service.DashboardUserService;
import org.dromara.soul.admin.utils.AesUtils;
import org.dromara.soul.admin.vo.DashboardUserVO;
import org.dromara.soul.admin.vo.LoginDashboardUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

Expand All @@ -43,7 +44,7 @@
*/
@Service("dashboardUserService")
public class DashboardUserServiceImpl implements DashboardUserService {

@Resource
private SecretProperties secretProperties;

Expand Down Expand Up @@ -126,10 +127,10 @@ public CommonPager<DashboardUserVO> listByPage(final DashboardUserQuery dashboar
*
* @param userName default username is admin
* @param password admin password
* @return {@linkplain DashboardUserVO}
* @return {@linkplain LoginDashboardUserVO}
*/
@Override
public DashboardUserVO login(final String userName, final String password) {
public LoginDashboardUserVO login(final String userName, final String password) {
String key = secretProperties.getKey();
DashboardUserVO dashboardUserVO = findByQuery(userName, password);
if (dashboardUserVO != null) {
Expand All @@ -140,9 +141,10 @@ public DashboardUserVO login(final String userName, final String password) {
.role(dashboardUserVO.getRole())
.enabled(dashboardUserVO.getEnabled()).build();
createOrUpdate(dashboardUserDTO);
return dashboardUserVO;
} else {
return findByQuery(userName, AesUtils.aesEncryption(password, key));
dashboardUserVO = findByQuery(userName, AesUtils.aesEncryption(password, key));
}

return LoginDashboardUserVO.buildLoginDashboardUserVO(dashboardUserVO);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.dromara.soul.admin.result.SoulAdminResult;
import org.dromara.soul.admin.utils.SoulResultMessage;
import org.dromara.soul.common.exception.CommonErrorCode;
import org.dromara.soul.common.utils.GsonUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
Expand All @@ -41,7 +44,7 @@ public class StatelessAuthFilter extends AccessControlFilter {

@Override
protected boolean isAccessAllowed(final ServletRequest servletRequest, final ServletResponse servletResponse,
final Object o) throws Exception {
final Object o) {
return false;
}

Expand All @@ -52,19 +55,21 @@ protected boolean onAccessDenied(final ServletRequest servletRequest, final Serv
String tokenValue = httpServletRequest.getHeader(HEAD_TOKEN);

if (StringUtils.isEmpty(tokenValue)) {
onLoginFail(servletResponse);
log.error("token is null.");
unionFailResponse(servletResponse);
return false;
}

StatelessToken token = new StatelessToken();
token.setToken(tokenValue);

Subject subject = getSubject(servletRequest, servletResponse);

try {
subject.login(token);
} catch (AuthenticationException e) {
log.warn("token is warning, token : {}", token, e);
onLoginFail(servletResponse);
} catch (Exception e) {
log.error("token is warning. token : {}.", tokenValue, e);
unionFailResponse(servletResponse);
return false;
}

Expand All @@ -73,17 +78,18 @@ protected boolean onAccessDenied(final ServletRequest servletRequest, final Serv

/**
* union response same result form exception.
* todo: will change to global exception intercept.
*
* @param response {@link ServletResponse}
*/
private void onLoginFail(final ServletResponse response) throws IOException {
private void unionFailResponse(final ServletResponse response) throws IOException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.setHeader("Content-type", "text/html;charset=UTF-8");
httpResponse.setContentType("application/json;charset=utf-8");
httpResponse.setCharacterEncoding("utf-8");
wrapCorsResponse(httpResponse);
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResponse.getWriter().write("token失效");
SoulAdminResult result = SoulAdminResult.error(CommonErrorCode.TOKEN_ERROR,
SoulResultMessage.TOKEN_IS_ERROR);
httpResponse.getWriter().println(GsonUtils.getInstance().toJson(result));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
**/
public class ShiroRealm extends AuthorizingRealm {

@Override
public boolean supports(final AuthenticationToken token) {
return token instanceof StatelessToken;
}

@Override
protected AuthorizationInfo doGetAuthorizationInfo(final PrincipalCollection principalCollection) {
// todo: temporary, will use database to add permission
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,7 @@ public final class SoulResultMessage {

public static final String APPKEY_NOT_EXIST_ERROR = "the appKey passed in does not exist";

public static final String TOKEN_IS_ERROR = "token is error";

public static final String TOKEN_HAS_NO_PERMISSION = "toke has no permission";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dromara.soul.admin.vo;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.dromara.soul.admin.utils.JwtUtils;
import org.springframework.beans.BeanUtils;

import java.util.Optional;

/**
* login dashboard return user info's vo.
*
* @author YuI
**/
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class LoginDashboardUserVO extends DashboardUserVO {

/**
* token.
*/
private String token;

/**
* build loginDashboardUserVO.
*
* @param dashboardUserVO {@linkplain DashboardUserVO}
* @return {@linkplain LoginDashboardUserVO}
*/
public static LoginDashboardUserVO buildLoginDashboardUserVO(final DashboardUserVO dashboardUserVO) {
return Optional.ofNullable(dashboardUserVO)
.map(item -> {
LoginDashboardUserVO vo = new LoginDashboardUserVO();
BeanUtils.copyProperties(item, vo);
vo.setToken(JwtUtils.generateToken(vo.getUserName()));
return vo;
}).orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@

package org.dromara.soul.admin.controller;

import org.dromara.soul.admin.config.JwtProperties;
import org.dromara.soul.admin.service.DashboardUserService;
import org.dromara.soul.admin.service.EnumService;
import org.dromara.soul.admin.spring.SpringBeanUtils;
import org.dromara.soul.admin.utils.SoulResultMessage;
import org.dromara.soul.admin.vo.DashboardUserVO;
import org.dromara.soul.admin.vo.LoginDashboardUserVO;
import org.dromara.soul.common.exception.CommonErrorCode;
import org.dromara.soul.common.utils.DateUtils;
import org.junit.Before;
Expand All @@ -29,6 +32,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
Expand All @@ -39,6 +43,8 @@
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

Expand All @@ -63,10 +69,11 @@ public final class PlatformControllerTest {
private EnumService enumService;

/**
* loginDashboardUser mock data.
* dashboardUser mock data.
*/
private final DashboardUserVO dashboardUserVO = new DashboardUserVO("1", "admin", "123456", 1, true,
DateUtils.localDateTimeToString(LocalDateTime.now()), DateUtils.localDateTimeToString(LocalDateTime.now()));
private final DashboardUserVO dashboardUserVO = new DashboardUserVO("1", "admin", "123456",
1, true, DateUtils.localDateTimeToString(LocalDateTime.now()),
DateUtils.localDateTimeToString(LocalDateTime.now()));

/**
* init mockmvc.
Expand All @@ -81,14 +88,21 @@ public void setUp() {
*/
@Test
public void testLoginDashboardUser() throws Exception {
ConfigurableApplicationContext context = mock(ConfigurableApplicationContext.class);
SpringBeanUtils.getInstance().setCfgContext(context);
JwtProperties jwtProperties = new JwtProperties();
jwtProperties.setKey("2095132720951327");
when(context.getBean(JwtProperties.class)).thenReturn(jwtProperties);

final String loginUri = "/platform/login?userName=admin&password=123456";

given(this.dashboardUserService.login(eq("admin"), eq("123456"))).willReturn(dashboardUserVO);
LoginDashboardUserVO loginDashboardUserVO = LoginDashboardUserVO.buildLoginDashboardUserVO(dashboardUserVO);
given(this.dashboardUserService.login(eq("admin"), eq("123456"))).willReturn(loginDashboardUserVO);
this.mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.GET, loginUri))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code", is(CommonErrorCode.SUCCESSFUL)))
.andExpect(jsonPath("$.message", is(SoulResultMessage.PLATFORM_LOGIN_SUCCESS)))
.andExpect(jsonPath("$.data.id", is(dashboardUserVO.getId())))
.andExpect(jsonPath("$.data.id", is(loginDashboardUserVO.getId())))
.andReturn();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,24 @@
*/
public class CommonErrorCode {

/**
* The constant SUCCESSFUL.
*/
public static final int SUCCESSFUL = 200;

/**
* The constant ERROR.
*/
public static final int ERROR = 500;

/**
* The constant SUCCESSFUL.
* The constant TOKEN_ERROR.
*/
public static final int SUCCESSFUL = 200;
public static final int TOKEN_ERROR = 600;

/**
* The constant TOKEN_NO_PERMISSION.
*/
public static final int TOKEN_NO_PERMISSION = 601;

}