优化权限控制方式

This commit is contained in:
zhouhao
2017-03-04 14:15:45 +08:00
parent 89b2c43359
commit 269367c655
40 changed files with 1040 additions and 285 deletions

View File

@@ -18,7 +18,7 @@
|[hsweb-system-file](hsweb-system-file)|文件管理| 0%|
|[hsweb-system-history](hsweb-system-history)|历史记录管理| 0%|
|[hsweb-system-monitor](hsweb-system-monitor)|系统监控| 0%|
|[hsweb-system-organizational](hsweb-system-organizational)|组织架构| 0%|
|[hsweb-system-organizational](hsweb-system-organizational)|组织架构| 50%|
|[hsweb-system-schedule](hsweb-system-schedule)|任务调度| 0%|
|[hsweb-system-script](hsweb-system-script)|动态脚本| 0%|
|[hsweb-system-template](hsweb-system-template)|模板管理| 0%|

View File

@@ -1,3 +1,7 @@
## 权限功能模块
提供用户,角色,权限管理
## 授权
[AuthorizationController](hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java)
仅进行基础授权,通过触发`AuthorizationListener`,进行自定义控制逻辑.详细方式见:[hsweb-authorization-api](../../hsweb-authorization/hsweb-authorization-api)

View File

@@ -50,5 +50,10 @@
<artifactId>hsweb-commons-controller</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hswebframework.web</groupId>
<artifactId>hsweb-system-authorization-model</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -17,31 +17,24 @@
package org.hswebframework.web.controller.authorization;
import org.apache.commons.codec.binary.Base64;
import org.hswebframework.expands.security.Encrypt;
import org.hswebframework.expands.security.rsa.RSAEncrypt;
import org.hswebframework.expands.security.rsa.RSAPrivateEncrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.hswebframework.web.BusinessException;
import org.hswebframework.web.NotFoundException;
import org.hswebframework.web.authorization.Authorization;
import org.hswebframework.web.authorization.listener.UserAuthorizationConfigRegister;
import org.hswebframework.web.authorization.listener.UserAuthorizationListener;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
import org.hswebframework.web.authorization.listener.event.*;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.service.AbstractService;
import org.hswebframework.web.service.authorization.UserService;
import org.hswebframework.web.service.authorization.VerifyCode;
import org.hswebframework.web.service.authorization.VerifyCodeGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import java.util.function.Function;
import static org.hswebframework.web.controller.message.ResponseMessage.ok;
@@ -53,140 +46,113 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
@RestController
@RequestMapping("${hsweb.web.mappings.authorize:authorize}")
@AccessLogger("授权")
@Api(tags = "authorize-simple", description = "提供基本的授权功能")
public class AuthorizationController {
private static final String RSA_PRIVATE_KEY_NAME = "RSA_PRIVATE_KEY";
private static final String VERIFY_CODE_NAME = "VERIFY_CODE";
private static final String NEED_VERIFY_CODE_NAME = "NEED_VERIFY_CODE";
@Autowired(required = false)
private VerifyCodeGenerator verifyCodeGenerator;
// private static final String RSA_PRIVATE_KEY_NAME = "RSA_PRIVATE_KEY";
// private static final String VERIFY_CODE_NAME = "VERIFY_CODE";
@Autowired
private UserService userService;
@Autowired(required = false)
private List<UserAuthorizationListener> userAuthorizationListeners;
@Autowired
private AuthorizationListenerDispatcher authorizationListenerDispatcher;
@Value("${hsweb.web.authorize.rsa:false}")
private boolean useRsa = false;
// @GetMapping(value = "/public-key")
// @AccessLogger("获取公钥")
// @ApiOperation("获取rsa公钥,当开启了用户名密码加密的时候使用此接口获取用于加密的公钥")
// public ResponseMessage getAuthorizeToken(@ApiParam(hidden = true) HttpSession session) {
// RSAEncrypt rsaEncrypt = Encrypt.rsa();
// String publicKey = rsaEncrypt.publicEncrypt().getKey();
// String privateKey = rsaEncrypt.privateEncrypt().getKey();
// session.setAttribute(RSA_PRIVATE_KEY_NAME, privateKey);
// return ok(publicKey);
// }
private UserAuthorizationListenerAdapter listenerAdapter = new UserAuthorizationListenerAdapter();
@GetMapping(value = "/public-key")
@AccessLogger("获取公钥")
public ResponseMessage getAuthorizeToken(HttpSession session) {
RSAEncrypt rsaEncrypt = Encrypt.rsa();
String publicKey = rsaEncrypt.publicEncrypt().getKey();
String privateKey = rsaEncrypt.privateEncrypt().getKey();
session.setAttribute(RSA_PRIVATE_KEY_NAME, privateKey);
return ok(publicKey);
}
@GetMapping(value = "/verify-code")
@AccessLogger("获取验证码")
public void getVerifyCode(HttpServletResponse response, HttpSession session) throws IOException {
if (verifyCodeGenerator == null) throw new NotFoundException("{verify_code_not_found}");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
response.setHeader("Content-disposition", "attachment;filename=verify-code.png");
VerifyCode verifyCode = verifyCodeGenerator.generate();
session.setAttribute(RSA_PRIVATE_KEY_NAME, verifyCode.getCode());
verifyCode.write(response.getOutputStream());
}
@RequestMapping("/login-out")
@GetMapping("/login-out")
@AccessLogger("退出登录")
public ResponseMessage loginOut(Authorization authorization) {
listenerAdapter.onLoginOut(authorization);
@Authorize
@ApiOperation("退出当前登录")
public ResponseMessage exit(@ApiParam(hidden = true) Authorization authorization) {
authorizationListenerDispatcher.doEvent(new AuthorizationExitEvent(authorization));
return ok();
}
@PostMapping(value = "/login")
@AccessLogger("授权")
public ResponseMessage authorize(@RequestParam String username,
@RequestParam String password,
String verifyCode,
@RequestParam(defaultValue = "false") boolean remember,
HttpSession session) {
@ApiOperation("用户名密码登录")
public ResponseMessage<String> authorize(@RequestParam @ApiParam("用户名") String username,
@RequestParam @ApiParam("密码") String password,
@ApiParam(hidden = true) HttpServletRequest request) {
AuthorizationFailedEvent.Reason reason = AuthorizationFailedEvent.Reason.OTHER;
Function<String, Object> parameterGetter = request::getParameter;
try {
if (useRsa) {
String privateKey = (String) session.getAttribute(RSA_PRIVATE_KEY_NAME);
if (privateKey == null) throw new BusinessException("{private_key_is_null}");
// 解密用户名密码
try {
RSAEncrypt rsaEncrypt = Encrypt.rsa();
RSAPrivateEncrypt rsaPrivateEncrypt = rsaEncrypt.privateEncrypt(privateKey);
byte[] username_data = Base64.decodeBase64(username);
byte[] password_data = Base64.decodeBase64(password);
username = new String(rsaPrivateEncrypt.decrypt(username_data));
password = new String(rsaPrivateEncrypt.decrypt(password_data));
} catch (Exception e) {
throw new BusinessException("{decrypt_param_error}", e, 400);
}
}
UserAuthorizationConfigRegister configHolder = (useVerify) -> session.setAttribute(NEED_VERIFY_CODE_NAME, useVerify);
listenerAdapter.onConfig(username, configHolder);
Object useVerifyCode = session.getAttribute(NEED_VERIFY_CODE_NAME);
// 尝试使用验证码验证
if (useVerifyCode instanceof Boolean && (Boolean) useVerifyCode) {
String realVerifyCode = (String) session.getAttribute(VERIFY_CODE_NAME);
if (realVerifyCode == null || !realVerifyCode.equalsIgnoreCase(verifyCode)) {
throw new BusinessException("{verify_code_error}");
}
}
listenerAdapter.onAuthorizeBefore(username);
AuthorizationDecodeEvent decodeEvent = new AuthorizationDecodeEvent(username, password, parameterGetter);
authorizationListenerDispatcher.doEvent(decodeEvent);
username = decodeEvent.getUsername();
password = decodeEvent.getPassword();
AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter);
authorizationListenerDispatcher.doEvent(beforeEvent);
// if (useRsa) {
// String privateKey = (String) session.getAttribute(RSA_PRIVATE_KEY_NAME);
// if (privateKey == null) throw new BusinessException("{private_key_is_null}");
// // 解密用户名密码
// try {
// RSAEncrypt rsaEncrypt = Encrypt.rsa();
// RSAPrivateEncrypt rsaPrivateEncrypt = rsaEncrypt.privateEncrypt(privateKey);
// byte[] username_data = Base64.decodeBase64(username);
// byte[] password_data = Base64.decodeBase64(password);
// username = new String(rsaPrivateEncrypt.decrypt(username_data));
// password = new String(rsaPrivateEncrypt.decrypt(password_data));
// } catch (Exception e) {
// throw new BusinessException("{decrypt_param_error}", e, 400);
// }
// }
// UserAuthorizationConfigRegister configHolder = (useVerify) -> session.setAttribute(NEED_VERIFY_CODE_NAME, useVerify);
// listenerAdapter.onConfig(username, configHolder);
// Object useVerifyCode = session.getAttribute(NEED_VERIFY_CODE_NAME);
// // 尝试使用验证码验证
// if (Boolean.TRUE.equals(useVerifyCode)) {
// String realVerifyCode = (String) session.getAttribute(VERIFY_CODE_NAME);
// if (realVerifyCode == null || !realVerifyCode.equalsIgnoreCase(verifyCode)) {
// throw new BusinessException("{verify_code_error}");
// }
// }
// listenerAdapter.onAuthorizeBefore(username);
UserEntity entity = userService.selectByUsername(username);
AbstractService.assertNotNull(entity, "{user_not_exists}");
if (!entity.isEnabled()) {
if (entity == null) {
reason = AuthorizationFailedEvent.Reason.USER_NOT_EXISTS;
throw new NotFoundException("{user_not_exists}");
}
if (Boolean.FALSE.equals(entity.isEnabled())) {
reason = AuthorizationFailedEvent.Reason.USER_DISABLED;
throw new BusinessException("{user_is_disabled}", 400);
}
password = userService.encodePassword(password, entity.getSalt());
if (!entity.getPassword().equals(password)) {
listenerAdapter.onAuthorizeFail(username);
reason = AuthorizationFailedEvent.Reason.PASSWORD_ERROR;
throw new BusinessException("{password_error}", 400);
}
// TODO: 17-1-13 获取IP
userService.updateLoginInfo(entity.getId(), "", System.currentTimeMillis());
// 验证通过
Authorization authorization = userService.initUserAuthorization(entity.getId());
listenerAdapter.onAuthorizeSuccess(remember, authorization);
return ok(authorization.getPermissions());
AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(authorization, parameterGetter);
authorizationListenerDispatcher.doEvent(event);
return ok(entity.getId());
} catch (Exception e) {
AuthorizationFailedEvent failedEvent = new AuthorizationFailedEvent(username, password, parameterGetter, reason);
failedEvent.setException(e);
authorizationListenerDispatcher.doEvent(failedEvent);
throw e;
} finally {
//无论如何都清空验证码和私钥
session.removeAttribute(VERIFY_CODE_NAME);
session.removeAttribute(RSA_PRIVATE_KEY_NAME);
}
}
class UserAuthorizationListenerAdapter implements UserAuthorizationListener {
@Override
public void onConfig(String username, UserAuthorizationConfigRegister configHolder) {
if (userAuthorizationListeners != null)
userAuthorizationListeners.forEach(listener -> listener.onConfig(username, configHolder));
}
@Override
public void onAuthorizeBefore(String username) {
if (userAuthorizationListeners != null)
userAuthorizationListeners.forEach(listener -> listener.onAuthorizeBefore(username));
}
@Override
public void onAuthorizeFail(String username) {
if (userAuthorizationListeners != null)
userAuthorizationListeners.forEach(listener -> listener.onAuthorizeFail(username));
}
@Override
public void onLoginOut(Authorization authorization) {
if (userAuthorizationListeners != null)
userAuthorizationListeners.forEach(listener -> listener.onLoginOut(authorization));
}
@Override
public void onAuthorizeSuccess(boolean isRemembered, Authorization authorization) {
if (userAuthorizationListeners != null)
userAuthorizationListeners.forEach(listener -> listener.onAuthorizeSuccess(isRemembered, authorization));
// session.removeAttribute(VERIFY_CODE_NAME);
// session.removeAttribute(RSA_PRIVATE_KEY_NAME);
}
}

View File

@@ -18,19 +18,26 @@
package org.hswebframework.web.controller.authorization;
import io.swagger.annotations.*;
import org.apache.commons.collections.CollectionUtils;
import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.commons.entity.factory.EntityFactory;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.QueryController;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.hswebframework.web.entity.authorization.PermissionRoleEntity;
import org.hswebframework.web.entity.authorization.RoleEntity;
import org.hswebframework.web.entity.authorization.*;
import org.hswebframework.web.entity.authorization.bind.BindPermissionRoleEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.model.authorization.*;
import org.hswebframework.web.service.authorization.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
import static org.hswebframework.web.controller.QueryController.*;
import static org.hswebframework.web.controller.message.ResponseMessage.ok;
/**
@@ -42,35 +49,143 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
@RequestMapping("${hsweb.web.mappings.role:role}")
@AccessLogger("{role_manager}")
@Authorize(permission = "role")
@Api(tags = "role-manager", description = "角色管理")
public class RoleController implements QueryController<RoleEntity, String, QueryParamEntity> {
@Autowired
private RoleService roleService;
@Autowired
private EntityFactory entityFactory;
@Override
public RoleService getService() {
return roleService;
}
@SuppressWarnings("unchecked")
public BindPermissionRoleEntity<PermissionRoleEntity> modelToEntity(RoleModel roleModel) {
BindPermissionRoleEntity<PermissionRoleEntity> roleEntity = entityFactory.newInstance(BindPermissionRoleEntity.class);
roleEntity.setId(roleModel.getId());
roleEntity.setName(roleModel.getName());
roleEntity.setDescribe(roleModel.getDescribe());
List<PermissionRoleEntity> permissionRoleEntities =
roleModel.getPermissions().stream()
.map(model -> {
PermissionRoleEntity entity = entityFactory.newInstance(PermissionRoleEntity.class);
entity.setActions(model.getActions());
entity.setPermissionId(model.getPermissionId());
entity.setRoleId(roleModel.getId());
//copy field accesses
entity.setFieldAccesses(model.getFieldAccesses().stream().map(accessModel -> {
FieldAccessEntity accessEntity = new FieldAccessEntity();
accessEntity.setField(accessEntity.getField());
accessEntity.setDescribe(accessEntity.getDescribe());
accessEntity.setActions(accessModel.getActions().stream().map(actionModel -> {
ActionEntity actionEntity = new ActionEntity();
actionEntity.setAction(actionModel.getAction());
actionEntity.setDescribe(actionModel.getDescribe());
actionEntity.setDefaultCheck(actionModel.isDefaultCheck());
return actionEntity;
}).collect(Collectors.toList()));
return accessEntity;
}).collect(Collectors.toList()));
//copy data accesses
entity.setDataAccesses(model.getDataAccesses().stream().map(accessModel -> {
DataAccessEntity dataAccessEntity = new DataAccessEntity();
dataAccessEntity.setConfig(accessModel.getConfig());
dataAccessEntity.setType(accessModel.getType());
dataAccessEntity.setDescribe(accessModel.getDescribe());
dataAccessEntity.setAction(accessModel.getAction());
return dataAccessEntity;
}).collect(Collectors.toList()));
return entity;
}).collect(Collectors.toList());
roleEntity.setPermissions(permissionRoleEntities);
return roleEntity;
}
protected RoleModel entityToModel(RoleEntity roleEntity) {
RoleModel roleModel = entityFactory.newInstance(RoleModel.class);
roleModel.setId(roleEntity.getId());
roleModel.setDescribe(roleEntity.getDescribe());
roleModel.setName(roleEntity.getName());
if (roleEntity instanceof BindPermissionRoleEntity) {
BindPermissionRoleEntity<PermissionRoleEntity> permissionRoleEntity = (BindPermissionRoleEntity) roleEntity;
List<PermissionRoleEntity> roleEntities = permissionRoleEntity.getPermissions();
if (CollectionUtils.isNotEmpty(roleEntities)) {
List<PermissionRoleModel> roleModels = roleEntities.stream().map(entity -> {
PermissionRoleModel model = entityFactory.newInstance(PermissionRoleModel.class);
model.setActions(entity.getActions());
model.setPermissionId(entity.getPermissionId());
//copy field accesses
model.setFieldAccesses(entity.getFieldAccesses().stream().map(accessEntity -> {
FieldAccessModel accessModel = new FieldAccessModel();
accessModel.setField(accessModel.getField());
accessModel.setDescribe(accessModel.getDescribe());
accessModel.setActions(accessModel.getActions().stream().map(actionEntity -> {
ActionModel actionModel = new ActionModel();
actionModel.setAction(actionEntity.getAction());
actionModel.setDescribe(actionEntity.getDescribe());
actionModel.setDefaultCheck(actionEntity.isDefaultCheck());
return actionModel;
}).collect(Collectors.toList()));
return accessModel;
}).collect(Collectors.toList()));
//copy data accesses
model.setDataAccesses(model.getDataAccesses().stream().map(accessesEntity -> {
DataAccessModel dataAccessModel = new DataAccessModel();
dataAccessModel.setConfig(accessesEntity.getConfig());
dataAccessModel.setType(accessesEntity.getType());
dataAccessModel.setDescribe(accessesEntity.getDescribe());
dataAccessModel.setAction(accessesEntity.getAction());
return dataAccessModel;
}).collect(Collectors.toList()));
return model;
}).collect(Collectors.toList());
roleModel.setPermissions(roleModels);
}
}
return roleModel;
}
@Authorize(action = Permission.ACTION_GET)
@GetMapping(path = "/{id:.+}/detail")
@AccessLogger("{get_by_id}")
@ApiOperation("根据主键查询完整数据")
@ApiResponses({
@ApiResponse(code = 200, message = "查询成功"),
@ApiResponse(code = 401, message = "未授权"),
@ApiResponse(code = 403, message = "无权限"),
@ApiResponse(code = 404, message = "数据不存在")
})
public ResponseMessage<RoleModel> getDetailByPrimaryKey(@PathVariable String id) {
return ok(entityToModel(assertNotNull(getService().selectByPk(id))));
}
@PostMapping
@Authorize(action = Permission.ACTION_ADD)
@AccessLogger("{add}")
public ResponseMessage addRole(@RequestBody BindPermissionRoleEntity<PermissionRoleEntity> permissionRoleEntity) {
return ok(roleService.insert(permissionRoleEntity));
@ApiOperation("添加角色")
public ResponseMessage<String> addRole(@RequestBody RoleModel roleModel) {
return ok(roleService.insert(modelToEntity(roleModel)));
}
@PutMapping("/{id}")
@PutMapping("/{id:.+}")
@Authorize(action = Permission.ACTION_UPDATE)
@AccessLogger("{update}")
public ResponseMessage updateRole(@PathVariable String id, @RequestBody BindPermissionRoleEntity<PermissionRoleEntity> permissionRoleEntity) {
permissionRoleEntity.setId(id);
roleService.updateByPrimaryKey(permissionRoleEntity);
@ApiModelProperty("修改角色")
public ResponseMessage updateRole(@PathVariable String id, @RequestBody RoleModel roleModel) {
roleModel.setId(id);
roleService.updateByPrimaryKey(modelToEntity(roleModel));
return ok();
}
@PutMapping("/disable/{id}")
@PutMapping("/disable/{id:.+}")
@Authorize(action = Permission.ACTION_DISABLE)
@AccessLogger("{disable}")
@ApiModelProperty("禁用角色")
public ResponseMessage disable(@PathVariable String id) {
roleService.disable(id);
return ok();
@@ -79,6 +194,7 @@ public class RoleController implements QueryController<RoleEntity, String, Query
@PutMapping("/enable/{id}")
@Authorize(action = Permission.ACTION_ENABLE)
@AccessLogger("{disable}")
@ApiModelProperty("启用角色")
public ResponseMessage enable(@PathVariable String id) {
roleService.enable(id);
return ok();

View File

@@ -17,16 +17,24 @@
package org.hswebframework.web.controller.authorization;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.hswebframework.web.authorization.Authorization;
import org.hswebframework.web.authorization.AuthorizationHolder;
import org.hswebframework.web.authorization.Permission;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.commons.entity.PagerResult;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.CreateController;
import org.hswebframework.web.controller.QueryController;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.hswebframework.web.entity.authorization.UserEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.model.authorization.UserModel;
import org.hswebframework.web.service.authorization.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import static org.hswebframework.web.controller.message.ResponseMessage.ok;
@@ -40,50 +48,71 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
@RequestMapping("${hsweb.web.mappings.user:user}")
@Authorize(permission = "user")
@AccessLogger("用户管理")
public class UserController implements QueryController<UserEntity, String, QueryParamEntity>, CreateController<UserEntity, String> {
@Api(tags = "user-manager", description = "用户基本信息管理")
public class UserController implements
QueryController<UserEntity, String, QueryParamEntity>,
CreateController<UserEntity, String, UserModel> {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public ResponseMessage list(QueryParamEntity param) {
return QueryController.super.list(param)
.exclude(UserEntity.class, "password", "salt");
}
@Override
@SuppressWarnings("unchecked")
public UserService getService() {
return userService;
}
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public UserEntity modelToEntity(UserModel model, UserEntity entity) {
entity.setName(model.getName());
entity.setPassword(model.getPassword());
entity.setUsername(model.getUsername());
return entity;
}
@Override
public ResponseMessage<PagerResult<UserEntity>> list(QueryParamEntity param) {
return QueryController.super.list(param)
.exclude(UserEntity.class, "password", "salt");
}
@Override
public ResponseMessage<UserEntity> getByPrimaryKey(@PathVariable String id) {
return QueryController.super.getByPrimaryKey(id)
.exclude(UserEntity.class, "password", "salt");
}
@Authorize(action = "update")
@PutMapping(path = "/{id}")
@PutMapping(path = "/{id:.+}")
@AccessLogger("{update_by_primary_key}")
public ResponseMessage updateByPrimaryKey(@PathVariable String id, @RequestBody UserEntity data) {
data.setId(id);
getService().update(data);
@ApiOperation("根据ID修改用户信息")
public ResponseMessage<Void> updateByPrimaryKey(@PathVariable String id,
@RequestBody UserModel userModel) {
getService().update(id, modelToEntity(userModel, getService().createEntity()));
return ok();
}
@Authorize(merge = false)
@PutMapping(path = "/password")
@AccessLogger("{update_password_login_user}")
public ResponseMessage updateLoginUserPassword(Authorization authorization,
@RequestParam String password,
@ApiOperation("修改当前用户的密码")
public ResponseMessage<Void> updateLoginUserPassword(@RequestParam String password,
@RequestParam String oldPassword) {
Authorization authorization = AuthorizationHolder.get();
Assert.notNull(authorization);
getService().updatePassword(authorization.getUser().getId(), oldPassword, password);
return ok();
}
@Authorize(action = "update")
@PutMapping(path = "/password/{id}")
@Authorize(action = Permission.ACTION_UPDATE)
@PutMapping(path = "/password/{id:.+}")
@AccessLogger("{update_password_by_id}")
public ResponseMessage updateByPasswordPrimaryKey(@PathVariable String id,
@ApiOperation("修改指定用户的密码")
public ResponseMessage<Void> updateByPasswordPrimaryKey(@PathVariable String id,
@RequestParam String password,
@RequestParam String oldPassword) {
getService().updatePassword(id, oldPassword, password);
@@ -93,14 +122,17 @@ public class UserController implements QueryController<UserEntity, String, Query
@Authorize(action = "enable")
@PutMapping(path = "/{id}/enable")
@AccessLogger("{enable_user}")
public ResponseMessage enable(@PathVariable String id) {
@ApiOperation("启用用户")
public ResponseMessage<Boolean> enable(@PathVariable String id) {
return ok(getService().enable(id));
}
@Authorize(action = "disable")
@PutMapping(path = "/{id}/disable")
@AccessLogger("{disable_user}")
public ResponseMessage disable(@PathVariable String id) {
@ApiOperation("禁用用户")
public ResponseMessage<Boolean> disable(@PathVariable String id) {
return ok(getService().disable(id));
}
}

View File

@@ -111,16 +111,6 @@ public class SimpleUserEntity extends SimpleGenericEntity<String> implements Use
@Override
public SimpleUserEntity clone() {
SimpleUserEntity target = ((SimpleUserEntity) super.clone());
// target.setId(getId());
// target.setName(getName());
// target.setUsername(getUsername());
// target.setPassword(getPassword());
// target.setCreateTime(getCreateTime());
// target.setCreatorId(getCreatorId());
// target.setEnabled(isEnabled());
// target.setLastLoginTime(getLastLoginTime());
// target.setLastLoginIp(getLastLoginIp());
return target;
return ((SimpleUserEntity) super.clone());
}
}

View File

@@ -38,10 +38,10 @@ public interface UserEntity extends GenericEntity<String>, RecordCreationEntity
void setPassword(String password);
void setSalt(String salt);
String getPassword();
void setSalt(String salt);
String getSalt();
Long getLastLoginTime();

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2016 http://www.hswebframework.org
~
~ Licensed 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.
~
~
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>3.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hsweb-system-authorization-model</artifactId>
<dependencies>
<dependency>
<groupId>org.hswebframework.web</groupId>
<artifactId>hsweb-commons-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hswebframework.web.commons.model.Model;
@ApiModel(description = "操作事件")
public class ActionModel implements Model {
@ApiModelProperty(value = "事件标识", required = true, allowableValues = "query,get,update,delete,add,....", example = "query")
private String action;
@ApiModelProperty("描述")
private String describe;
@ApiModelProperty("是否默认选中")
private boolean defaultCheck;
public ActionModel() {
}
public ActionModel(String action) {
this.action = action;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
public boolean isDefaultCheck() {
return defaultCheck;
}
public void setDefaultCheck(boolean defaultCheck) {
this.defaultCheck = defaultCheck;
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* TODO 完成注释
*
* @author zhouhao
*/
@ApiModel(value = "DataAccessModel",description = "数据级权限控制配置")
public class DataAccessModel {
private String action;
private String describe;
private String type;
private String config;
@ApiModelProperty(value = "触发控制的事件", example = "query", required = true)
public String getAction() {
return this.action;
}
public void setAction(String action) {
this.action = action;
}
@ApiModelProperty("说明")
public String getDescribe() {
return this.describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
@ApiModelProperty(value = "控制的类型", allowableValues = "OWN_CREATED,SCRIPT,CUSTOM", required = true, example = "OWN_CREATED")
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
@ApiModelProperty(value = "控制配置." +
"当控制类型为OWN_CREATED时:可留空." +
"当控制类型为SCRIPT时:值为json string,格式:{\"language\":\"groovy\",\"script\":\"return true;\"}." +
"当控制类型为CUSTOM时,值为一个实现了DataAccessController接口的类")
public String getConfig() {
return this.config;
}
public void setConfig(String config) {
this.config = config;
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.*;
import org.hswebframework.web.commons.model.Model;
import java.util.Collections;
import java.util.List;
/**
* TODO 完成注释
*
* @author zhouhao
*/
@ApiModel(value = "FieldAccessModel", description = "字段级权限控制配置")
public class FieldAccessModel implements Model {
private String field;
private String describe;
private List<ActionModel> actions;
@ApiModelProperty(value = "要控制的字段名", required = true, example = "createTime")
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
@ApiModelProperty("字段说明")
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
@ApiModelProperty(value = "触发控制的事件,表示此字段不能进行{action}操作.",
// example = "[{\"action\":\"query\"}]",
required = true, dataType = "ActionModel")
public List<ActionModel> getActions() {
if (actions == null) actions = Collections.emptyList();
return actions;
}
public void setActions(List<ActionModel> actions) {
this.actions = actions;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hswebframework.web.commons.model.Model;
import java.util.List;
/**
* TODO 完成注释
*
* @author zhouhao
*/
@ApiModel(value = "PermissionRoleModel", description = "权限配置")
public interface PermissionRoleModel extends Model {
//
// @ApiModelProperty(value = "角色ID", required = true, example = "admin")
// String getRoleId();
//
// void setRoleId(String roleId);
@ApiModelProperty(value = "权限ID", required = true, example = "user")
String getPermissionId();
void setPermissionId(String permissionId);
@ApiModelProperty(value = "可操作事件"
// , example = "[\"query\",\"add\"]"
)
List<String> getActions();
void setActions(List<String> actions);
@ApiModelProperty(value = "数据级权限控制配置", dataType = "DataAccessModel")
List<DataAccessModel> getDataAccesses();
@ApiModelProperty(value = "字段级权限控制配置", dataType = "FieldAccessModel")
List<FieldAccessModel> getFieldAccesses();
void setDataAccesses(List<DataAccessModel> dataAccesses);
void setFieldAccesses(List<FieldAccessModel> fieldAccesses);
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hswebframework.web.commons.model.Model;
import java.util.List;
/**
* @author zhouhao
*/
@ApiModel(value = "RoleModel", description = "角色模型")
public interface RoleModel extends Model {
@ApiModelProperty(value = "角色ID", readOnly = true, required = true, example = "admin")
String getId();
void setId(String id);
@ApiModelProperty(value = "角色名", required = true)
String getName();
void setName(String name);
@ApiModelProperty("说明")
String getDescribe();
void setDescribe(String describe);
@ApiModelProperty(value = "权限配置", dataType = "PermissionRoleModel")
List<PermissionRoleModel> getPermissions();
void setPermissions(List<PermissionRoleModel> permissions);
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import java.util.Collections;
import java.util.List;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public class SimplePermissionRoleModel implements PermissionRoleModel {
// private String roleId;
private String permissionId;
private List<String> actions;
private List<DataAccessModel> dataAccesses;
private List<FieldAccessModel> fieldAccesses;
//
// @Override
// public String getRoleId() {
// return roleId;
// }
//
// @Override
// public void setRoleId(String roleId) {
// this.roleId = roleId;
// }
@Override
public String getPermissionId() {
return permissionId;
}
@Override
public void setPermissionId(String permissionId) {
this.permissionId = permissionId;
}
@Override
public List<String> getActions() {
if (this.actions == null) return Collections.emptyList();
return actions;
}
@Override
public void setActions(List<String> actions) {
this.actions = actions;
}
@Override
public List<DataAccessModel> getDataAccesses() {
if (this.dataAccesses == null) return Collections.emptyList();
return this.dataAccesses;
}
@Override
public List<FieldAccessModel> getFieldAccesses() {
if (this.fieldAccesses == null) return Collections.emptyList();
return this.fieldAccesses;
}
@Override
public void setDataAccesses(List<DataAccessModel> dataAccesses) {
this.dataAccesses = dataAccesses;
}
@Override
public void setFieldAccesses(List<FieldAccessModel> fieldAccesses) {
this.fieldAccesses = fieldAccesses;
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import java.util.ArrayList;
import java.util.List;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public class SimpleRoleModel implements RoleModel {
private String id;
private String name;
private String describe;
private List<SimplePermissionRoleModel> permissions;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescribe() {
return describe;
}
public void setDescribe(String describe) {
this.describe = describe;
}
@Override
public List<PermissionRoleModel> getPermissions() {
return new ArrayList<>(permissions);
}
public void setPermissions(List<PermissionRoleModel> permissions) {
this.permissions = ((List) permissions);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import org.hibernate.validator.constraints.NotBlank;
/**
* @author zhouhao
*/
public class SimpleUserModel implements UserModel {
@NotBlank
private String name;
@NotBlank
private String username;
@NotBlank
private String password;
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.model.authorization;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hswebframework.web.commons.model.Model;
/**
* @author zhouhao
*/
@ApiModel(value = "UserModel", description = "用户信息")
public interface UserModel extends Model {
void setName(String name);
@ApiModelProperty(value = "用户登录名", required = true, readOnly = true)
String getUsername();
void setUsername(String username);
@ApiModelProperty(value = "用户姓名", required = true)
String getName();
void setPassword(String password);
@ApiModelProperty(value = "密码", required = true)
String getPassword();
}

View File

@@ -23,7 +23,7 @@ public interface UserService extends
boolean disable(String userId);
void update(UserEntity userBean);
void update(String userId,UserEntity userBean);
UserEntity selectByUsername(String username);

View File

@@ -1,31 +0,0 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.service.authorization;
import java.io.OutputStream;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public interface VerifyCode {
String getCode();
void write(OutputStream outputStream);
}

View File

@@ -1,32 +0,0 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.service.authorization;
/**
* TODO 完成注释
*
* @author zhouhao
*/
public interface VerifyCodeGenerator {
VerifyCode generate(int figures);
default VerifyCode generate() {
return generate(4);
}
}

View File

@@ -25,7 +25,6 @@ import org.hswebframework.web.service.authorization.DataAccessFactory;
import java.io.Serializable;
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**

View File

@@ -23,6 +23,7 @@ import org.hswebframework.web.dao.authorization.RoleDao;
import org.hswebframework.web.entity.authorization.PermissionRoleEntity;
import org.hswebframework.web.entity.authorization.RoleEntity;
import org.hswebframework.web.entity.authorization.bind.BindPermissionRoleEntity;
import org.hswebframework.web.entity.authorization.bind.BindRoleUserEntity;
import org.hswebframework.web.service.AbstractService;
import org.hswebframework.web.service.DefaultDSLQueryService;
import org.hswebframework.web.service.DefaultDSLUpdateService;
@@ -96,8 +97,13 @@ public class SimpleRoleService extends AbstractService<RoleEntity, String>
}
@Override
@SuppressWarnings("unchecked")
public RoleEntity selectByPk(String roleId) {
return createQuery().where(RoleEntity.id, roleId).single();
RoleEntity entity = createQuery().where(RoleEntity.id, roleId).single();
if (entity == null) return null;
BindPermissionRoleEntity<PermissionRoleEntity> bindPermissionRoleEntity = entityFactory.newInstance(BindPermissionRoleEntity.class);
bindPermissionRoleEntity.setPermissions(permissionRoleDao.selectByRoleId(roleId));
return entity;
}
@Override

View File

@@ -130,11 +130,12 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
}
@Override
public void update(UserEntity userEntity) {
public void update(String userId, UserEntity userEntity) {
userEntity.setId(userId);
//判断用户是否存在
boolean userExists = createQuery().where()
.is("username", userEntity.getUsername())
.and().not(GenericEntity.id, userEntity.getId())
.and().not(GenericEntity.id, userId)
.total() > 0;
tryValidateProperty(!userExists, GenericEntity.id, "{username_exists}");
List<String> updateProperties = Arrays.asList("name");

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2016 http://www.hswebframework.org
*
* Licensed 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.hswebframework.web.authorization.starter;
import org.hswebframework.web.authorization.listener.AuthorizationListener;
import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
import org.hswebframework.web.authorization.listener.event.AuthorizationEvent;
import org.hswebframwork.utils.ClassUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* @author zhouhao
*/
@Configuration
public class AuthorizationAutoConfigration {
@Autowired(required = false)
private List<AuthorizationListener> listeners;
@Bean
@SuppressWarnings("unchecked")
public <E extends AuthorizationEvent> AuthorizationListenerDispatcher authorizationListenerDispatcher() {
AuthorizationListenerDispatcher dispatcher = new AuthorizationListenerDispatcher();
if (listeners != null) {
listeners.forEach(listener -> dispatcher.addListener((Class<E>) ClassUtils.getGenericType(listener.getClass()), listener));
}
return dispatcher;
}
}

View File

@@ -56,17 +56,17 @@ public class LoginTests extends SimpleWebApplicationTests {
userEntity.setCreateTimeNow();
userService.insert(userEntity);
//获取publicKey
String publicKey = testGet("/authorize/public-key").exec().resultAsJson().getString("data");
Assert.notNull(publicKey);
RSAPublicEncrypt publicEncrypt = Encrypt.rsa().publicEncrypt(publicKey);
String username = Base64.encodeBase64String(publicEncrypt.encrypt("test".getBytes()));
String password = Base64.encodeBase64String(publicEncrypt.encrypt("password_1234".getBytes()));
// //获取publicKey
// String publicKey = testGet("/authorize/public-key").exec().resultAsJson().getString("result");
// Assert.notNull(publicKey);
// RSAPublicEncrypt publicEncrypt = Encrypt.rsa().publicEncrypt(publicKey);
// String username = Base64.encodeBase64String(publicEncrypt.encrypt("test".getBytes()));
// String password = Base64.encodeBase64String(publicEncrypt.encrypt("password_1234".getBytes()));
JSONObject json = testPost("/authorize/login").setUp((builder) -> {
builder.param("username", username);
builder.param("password", password);
builder.param("username", userEntity.getUsername());
builder.param("password","password_1234");
}).exec().resultAsJson();
System.out.println(json);
org.junit.Assert.assertEquals(json.get("result"), userEntity.getId());
}
}

View File

@@ -112,7 +112,7 @@ public class UserTests extends SimpleWebApplicationTests {
UserEntity newUserEntity = userEntity.clone();
newUserEntity.setUsername("test2");
String antherId = userService.insert(newUserEntity);
String anotherId = userService.insert(newUserEntity);
Assert.assertNotNull(id);
Assert.assertEquals(userEntity.getPassword().length(), 32);
@@ -141,16 +141,16 @@ public class UserTests extends SimpleWebApplicationTests {
entityInDb = userService.selectByUsername(userEntity.getUsername());
Assert.assertEquals(entityInDb.getPassword(), userService.encodePassword("password_2345", entityInDb.getSalt()));
entityInDb.setId(antherId);
entityInDb.setId(anotherId);
entityInDb.setName("新名字");
try {
userService.update(entityInDb);
userService.update(anotherId,entityInDb);
Assert.assertTrue(false);
} catch (ValidationException e) {
Assert.assertEquals(e.getResults().getResults().get(0).getMessage(), "{username_exists}");
}
entityInDb.setId(id);
userService.update(entityInDb);
userService.update(id,entityInDb);
entityInDb = userService.selectByUsername(userEntity.getUsername());
Assert.assertEquals("新名字", entityInDb.getName());

View File

@@ -10,7 +10,4 @@ spring:
hsweb:
app:
name: 权限管理测试
version: 3.0.0
web:
authorize:
rsa: true
version: 3.0.0

View File

@@ -17,6 +17,7 @@
<module>hsweb-system-authorization-service</module>
<module>hsweb-system-authorization-starter</module>
<module>hsweb-system-authorization-controller</module>
<module>hsweb-system-authorization-model</module>
</modules>

View File

@@ -18,6 +18,7 @@
package org.hswebframework.web.controller.config;
import io.swagger.annotations.Api;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.GenericEntityController;
@@ -40,7 +41,8 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("${hsweb.web.mappings.config:config}")
@Authorize(permission = "config")
@AccessLogger("配置管理")
public class ConfigController implements GenericEntityController<ConfigEntity, String, QueryParamEntity> {
@Api(description = "配置管理,用于系统配置信息维护")
public class ConfigController implements GenericEntityController<ConfigEntity, String, QueryParamEntity,ConfigEntity> {
private ConfigService configService;
@@ -54,8 +56,4 @@ public class ConfigController implements GenericEntityController<ConfigEntity, S
return configService;
}
@Override
public ResponseMessage updateByPrimaryKey(@PathVariable String id, @RequestBody ConfigEntity data) {
return GenericEntityController.super.updateByPrimaryKey(id, data);
}
}

View File

@@ -54,11 +54,11 @@ public class ConfigTests extends SimpleWebApplicationTests {
)
.exec().resultAsJson();
//{data:id,code:200}
Assert.assertEquals(jsonObject.getString("data"), configBean.getId());
Assert.assertEquals(jsonObject.getString("result"), configBean.getId());
JSONObject getRes = testGet("/config/" + configBean.getId()).exec().resultAsJson();
Assert.assertEquals(getRes
.getObject("data", SimpleConfigEntity.class)
.getObject("result", SimpleConfigEntity.class)
.get("test")
.getNumber(0).intValue(), 1);
@@ -66,7 +66,7 @@ public class ConfigTests extends SimpleWebApplicationTests {
builder.param("terms[0].column", "id")
.param("terms[0].value", configBean.getId())
).exec().resultAsJson();
Assert.assertEquals(getRes.getJSONObject("data").getJSONArray("data")
Assert.assertEquals(getRes.getJSONObject("result").getJSONArray("data")
.getObject(0, SimpleConfigEntity.class)
.get("test")
.getNumber(0).intValue(), 1);

View File

@@ -1,5 +1,6 @@
## 组织架构管理
提供 地区-机构-职位-人员 的组织架构管理
提供 机构-部门-职位-人员 的组织架构管理
## API
//todo

View File

@@ -36,7 +36,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("${hsweb.web.mappings.department:department}")
@Authorize(permission = "department")
@AccessLogger("部门管理")
public class DepartmentController implements GenericEntityController<DepartmentEntity, String, QueryParamEntity> {
public class DepartmentController implements GenericEntityController<DepartmentEntity, String, QueryParamEntity,DepartmentEntity> {
private DepartmentService departmentService;

View File

@@ -20,6 +20,7 @@ package org.hswebframework.web.controller.organizational;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.GenericEntityController;
import org.hswebframework.web.entity.organizational.DepartmentEntity;
import org.hswebframework.web.entity.organizational.OrganizationalEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.service.organizational.OrganizationalService;
@@ -36,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("${hsweb.web.mappings.organizational:organizational}")
@Authorize(permission = "organizational")
@AccessLogger("组织管理")
public class OrganizationalController implements GenericEntityController<OrganizationalEntity, String, QueryParamEntity> {
public class OrganizationalController implements GenericEntityController<OrganizationalEntity, String, QueryParamEntity,DepartmentEntity> {
private OrganizationalService organizationalService;

View File

@@ -20,6 +20,7 @@ package org.hswebframework.web.controller.organizational;
import org.hswebframework.web.authorization.annotation.Authorize;
import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.GenericEntityController;
import org.hswebframework.web.entity.organizational.DepartmentEntity;
import org.hswebframework.web.entity.organizational.PersonEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.service.organizational.PersonService;
@@ -36,7 +37,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("${hsweb.web.mappings.person:person}")
@Authorize(permission = "person")
@AccessLogger("人员")
public class PersonController implements GenericEntityController<PersonEntity, String, QueryParamEntity> {
public class PersonController implements GenericEntityController<PersonEntity, String, QueryParamEntity,DepartmentEntity> {
private PersonService personService;

View File

@@ -24,6 +24,7 @@ import org.hswebframework.web.commons.entity.param.QueryParamEntity;
import org.hswebframework.web.controller.GenericEntityController;
import org.hswebframework.web.controller.QueryController;
import org.hswebframework.web.controller.message.ResponseMessage;
import org.hswebframework.web.entity.organizational.DepartmentEntity;
import org.hswebframework.web.entity.organizational.PositionEntity;
import org.hswebframework.web.logging.AccessLogger;
import org.hswebframework.web.service.organizational.PositionService;
@@ -40,7 +41,7 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("${hsweb.web.mappings.position:position}")
@Authorize(permission = "position")
@AccessLogger("职位管理")
public class PositionController implements GenericEntityController<PositionEntity, String, QueryParamEntity> {
public class PositionController implements GenericEntityController<PositionEntity, String, QueryParamEntity,DepartmentEntity> {
private PositionService positionService;

View File

@@ -51,18 +51,18 @@ public class DepartmentTests extends SimpleWebApplicationTests {
String requestBody = JSON.toJSONString(entity);
JSONObject result = testPost("/department").setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON).content(requestBody)).exec().resultAsJson();
Assert.assertEquals(200, result.get("status"));
String id = result.getString("data");
String id = result.getString("result");
Assert.assertNotNull(id);
entity.setId(id);
// test get data
result = testGet("/department/" + id).exec().resultAsJson();
entity = result.getObject("data", entityFactory.getInstanceType(DepartmentEntity.class));
entity = result.getObject("result", entityFactory.getInstanceType(DepartmentEntity.class));
Assert.assertEquals(200, result.get("status"));
Assert.assertNotNull(result.getJSONObject("data"));
Assert.assertNotNull(result.getJSONObject("result"));
Assert.assertEquals(fastJsonHttpMessageConverter.converter(entity),
fastJsonHttpMessageConverter.converter(result.getObject("data", entityFactory.getInstanceType(DepartmentEntity.class))));
fastJsonHttpMessageConverter.converter(result.getObject("result", entityFactory.getInstanceType(DepartmentEntity.class))));
//todo 修改测试属性
DepartmentEntity newEntity = entityFactory.newInstance(DepartmentEntity.class);
newEntity.setName("test");
@@ -75,7 +75,7 @@ public class DepartmentTests extends SimpleWebApplicationTests {
Assert.assertEquals(200, result.get("status"));
result = testGet("/department/" + id).exec().resultAsJson();
result = result.getJSONObject("data");
result = result.getJSONObject("result");
Assert.assertNotNull(result);
result = testDelete("/department/" + id).exec().resultAsJson();

View File

@@ -50,18 +50,18 @@ public class OrganizationalTests extends SimpleWebApplicationTests {
String requestBody = JSON.toJSONString(entity);
JSONObject result = testPost("/department").setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON).content(requestBody)).exec().resultAsJson();
Assert.assertEquals(200, result.get("status"));
String id = result.getString("data");
String id = result.getString("result");
Assert.assertNotNull(id);
entity.setId(id);
// test get data
result = testGet("/department/" + id).exec().resultAsJson();
entity = result.getObject("data", entityFactory.getInstanceType(OrganizationalEntity.class));
entity = result.getObject("result", entityFactory.getInstanceType(OrganizationalEntity.class));
Assert.assertEquals(200, result.get("status"));
Assert.assertNotNull(result.getJSONObject("data"));
Assert.assertNotNull(result.getJSONObject("result"));
Assert.assertEquals(fastJsonHttpMessageConverter.converter(entity),
fastJsonHttpMessageConverter.converter(result.getObject("data", entityFactory.getInstanceType(OrganizationalEntity.class))));
fastJsonHttpMessageConverter.converter(result.getObject("result", entityFactory.getInstanceType(OrganizationalEntity.class))));
//todo 修改测试属性
OrganizationalEntity newEntity = entityFactory.newInstance(OrganizationalEntity.class);
newEntity.setName("test");
@@ -74,7 +74,7 @@ public class OrganizationalTests extends SimpleWebApplicationTests {
Assert.assertEquals(200, result.get("status"));
result = testGet("/department/" + id).exec().resultAsJson();
result = result.getJSONObject("data");
result = result.getJSONObject("result");
Assert.assertNotNull(result);
result = testDelete("/department/" + id).exec().resultAsJson();

View File

@@ -50,18 +50,18 @@ public class PersonTests extends SimpleWebApplicationTests {
String requestBody = JSON.toJSONString(entity);
JSONObject result = testPost("/person").setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON).content(requestBody)).exec().resultAsJson();
Assert.assertEquals(200, result.get("status"));
String id = result.getString("data");
String id = result.getString("result");
Assert.assertNotNull(id);
entity.setId(id);
// test get data
result = testGet("/person/" + id).exec().resultAsJson();
entity = result.getObject("data", entityFactory.getInstanceType(PersonEntity.class));
entity = result.getObject("result", entityFactory.getInstanceType(PersonEntity.class));
Assert.assertEquals(200, result.get("status"));
Assert.assertNotNull(result.getJSONObject("data"));
Assert.assertNotNull(result.getJSONObject("result"));
Assert.assertEquals(fastJsonHttpMessageConverter.converter(entity),
fastJsonHttpMessageConverter.converter(result.getObject("data", entityFactory.getInstanceType(PersonEntity.class))));
fastJsonHttpMessageConverter.converter(result.getObject("result", entityFactory.getInstanceType(PersonEntity.class))));
//todo 修改测试属性
PersonEntity newEntity = entityFactory.newInstance(PersonEntity.class);
newEntity.setName("test2");
@@ -74,7 +74,7 @@ public class PersonTests extends SimpleWebApplicationTests {
Assert.assertEquals(200, result.get("status"));
result = testGet("/person/" + id).exec().resultAsJson();
result = result.getJSONObject("data");
result = result.getJSONObject("result");
Assert.assertNotNull(result);
result = testDelete("/person/" + id).exec().resultAsJson();

View File

@@ -48,18 +48,18 @@ public class PositionTests extends SimpleWebApplicationTests {
String requestBody = JSON.toJSONString(entity);
JSONObject result = testPost("/position").setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON).content(requestBody)).exec().resultAsJson();
Assert.assertEquals(200, result.get("status"));
String id = result.getString("data");
String id = result.getString("result");
Assert.assertNotNull(id);
entity.setId(id);
// test get data
result = testGet("/position/" + id).exec().resultAsJson();
entity = result.getObject("data", entityFactory.getInstanceType(PositionEntity.class));
entity = result.getObject("result", entityFactory.getInstanceType(PositionEntity.class));
Assert.assertEquals(200, result.get("status"));
Assert.assertNotNull(result.getJSONObject("data"));
Assert.assertNotNull(result.getJSONObject("result"));
Assert.assertEquals(fastJsonHttpMessageConverter.converter(entity),
fastJsonHttpMessageConverter.converter(result.getObject("data", entityFactory.getInstanceType(PositionEntity.class))));
fastJsonHttpMessageConverter.converter(result.getObject("result", entityFactory.getInstanceType(PositionEntity.class))));
//todo 修改测试属性
PositionEntity newEntity = entityFactory.newInstance(PositionEntity.class);
newEntity.setName("test");
@@ -72,7 +72,7 @@ public class PositionTests extends SimpleWebApplicationTests {
Assert.assertEquals(200, result.get("status"));
result = testGet("/position/" + id).exec().resultAsJson();
result = result.getJSONObject("data");
result = result.getJSONObject("result");
Assert.assertNotNull(result);
result = testDelete("/position/" + id).exec().resultAsJson();