Bläddra i källkod

新增 数据级和字段级的权限控制

zhouhao 8 år sedan
förälder
incheckning
0745650e47
90 ändrade filer med 1886 tillägg och 353 borttagningar
  1. 18 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authorization.java
  2. 1 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthorizationHolder.java
  3. 62 3
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Permission.java
  4. 11 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/CustomDataAccess.java
  5. 41 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccess.java
  6. 10 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessController.java
  7. 13 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessHandler.java
  8. 27 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/FieldAccess.java
  9. 12 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/FieldAccessController.java
  10. 9 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/OwnCreatedDataAccess.java
  11. 22 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ParamContext.java
  12. 24 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ScriptDataAccess.java
  13. 1 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Authorize.java
  14. 1 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Logical.java
  15. 54 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresDataAccess.java
  16. 53 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresFieldAccess.java
  17. 34 4
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java
  18. 12 2
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java
  19. 122 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java
  20. 57 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultDataAccessController.java
  21. 70 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java
  22. 87 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/FieldAccessAnnotationMethodInterceptor.java
  23. 33 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/MethodInterceptorHolder.java
  24. 21 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/CustomDataAccessHandler.java
  25. 127 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java
  26. 39 0
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java
  27. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java
  28. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java
  29. 9 0
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/HswebController.java
  30. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java
  31. 1 1
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java
  32. 20 0
      hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/RecordCreationEntity.java
  33. 3 2
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java
  34. 15 3
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java
  35. 1 1
      hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/AopUtils.java
  36. 4 0
      hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java
  37. 4 0
      hsweb-examples/hsweb-examples-simple/pom.xml
  38. 80 1
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java
  39. 82 5
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java
  40. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java
  41. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserController.java
  42. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-api/src/main/java/org/hswebframework/web/dao/authorization/PermissionDao.java
  43. 4 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/PermissionMapper.xml
  44. 2 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/PermissionRoleMapper.xml
  45. 4 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/UserMapper.xml
  46. 51 7
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/ActionEntity.java
  47. 60 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/DataAccessEntity.java
  48. 69 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/FieldAccessEntity.java
  49. 21 4
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionEntity.java
  50. 0 22
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionReadEntity.java
  51. 14 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionRoleEntity.java
  52. 0 19
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionRoleReadEntity.java
  53. 2 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/RoleEntity.java
  54. 0 70
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleActionEntity.java
  55. 32 7
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimplePermissionEntity.java
  56. 31 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimplePermissionRoleEntity.java
  57. 3 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleRoleEntity.java
  58. 33 18
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleUserEntity.java
  59. 14 4
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/UserEntity.java
  60. 0 27
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/UserReadEntity.java
  61. 0 17
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/WebPermissionEntity.java
  62. 3 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/bind/SimpleBindRoleUserEntity.java
  63. 13 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/DataAccessFactory.java
  64. 1 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/PermissionService.java
  65. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/UserService.java
  66. 89 15
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorization.java
  67. 1 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimplePermissionService.java
  68. 4 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleRoleService.java
  69. 11 7
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleUserService.java
  70. 22 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/AbstractDataAccess.java
  71. 45 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleCustomDataAccess.java
  72. 41 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleDataAccessFactory.java
  73. 11 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleOwnCreatedDataAccess.java
  74. 39 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleScriptDataAccess.java
  75. 7 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js
  76. 16 6
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/PermissionTests.java
  77. 9 5
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/UserTests.java
  78. 1 1
      hsweb-system/hsweb-system-config/hsweb-system-config-controller/src/main/java/org/hswebframework/web/controller/config/ConfigController.java
  79. 2 2
      hsweb-system/hsweb-system-config/hsweb-system-config-dao/hsweb-system-config-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/config/ConfigMapper.xml
  80. 4 21
      hsweb-system/hsweb-system-config/hsweb-system-config-entity/src/main/java/org/hswebframework/web/entity/config/ConfigEntity.java
  81. 11 13
      hsweb-system/hsweb-system-config/hsweb-system-config-entity/src/main/java/org/hswebframework/web/entity/config/SimpleConfigEntity.java
  82. 1 2
      hsweb-system/hsweb-system-config/hsweb-system-config-service/hsweb-system-config-service-simple/src/main/java/org/hswebframework/web/service/config/simple/SimpleConfigService.java
  83. 3 2
      hsweb-system/hsweb-system-config/hsweb-system-config-starter/src/main/resources/hsweb-starter.js
  84. 2 2
      hsweb-system/hsweb-system-config/hsweb-system-config-starter/src/test/java/org/hswebframework/web/starter/config/ConfigTests.java
  85. 1 1
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-dao/hsweb-system-explorer-dao-api/src/main/java/org/hswebframework/web/dao/explorer/MenuDao.java
  86. 4 4
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-entity/src/main/java/org/hswebframework/web/entity/explorer/MenuEntity.java
  87. 6 6
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-entity/src/main/java/org/hswebframework/web/entity/explorer/SimpleMenuEntity.java
  88. 3 4
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-service/hsweb-system-explorer-service-api/src/main/java/org/hswebframework/web/service/explorer/simple/MenuService.java
  89. 3 3
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-service/hsweb-system-explorer-service-simple/src/main/java/org/hswebframework/web/service/explorer/simple/SimpleMenuService.java
  90. 6 7
      hsweb-system/hsweb-system-explorer/hsweb-system-explorer-starter/src/test/java/org/hswebframework/web/starter/explorer/MenuTests.java

+ 18 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Authorization.java

@@ -20,6 +20,7 @@ package org.hswebframework.web.authorization;
 import java.io.Serializable;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Supplier;
 
 /**
@@ -34,6 +35,23 @@ public interface Authorization extends Serializable {
 
     List<Permission> getPermissions();
 
+    default Role getRole(String id) {
+        if (null == id) return null;
+        return getRoles().stream()
+                .filter(role -> role.getId().equals(id))
+                .findAny()
+                .orElse(null);
+    }
+
+    default Permission getPermission(String id) {
+        if (null == id) return null;
+        return getPermissions().parallelStream()
+                .filter(permission -> permission.getId().equals(id))
+                .findAny()
+                .orElse(null);
+    }
+
+
     <T extends Serializable> T getAttribute(String name);
 
     <T extends Serializable> T getAttribute(String name, T defaultValue);

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthorizationHolder.java

@@ -8,7 +8,7 @@ package org.hswebframework.web.authorization;
 public final class AuthorizationHolder {
     private static AuthorizationSupplier supplier;
 
-    public Authorization get() {
+    public static Authorization get() {
         return supplier.get();
     }
 

+ 62 - 3
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Permission.java

@@ -17,16 +17,75 @@
 
 package org.hswebframework.web.authorization;
 
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.FieldAccess;
+
 import java.io.Serializable;
-import java.util.List;
+import java.util.Set;
 
 /**
- * TODO 完成注释
+ * 用户持有的权限信息
  *
  * @author zhouhao
  */
 public interface Permission extends Serializable {
+
+    /**
+     * 查询
+     */
+    String ACTION_QUERY  = "query";
+    /**
+     * 获取明细
+     */
+    String ACTION_GET    = "get";
+    /**
+     * 新增
+     */
+    String ACTION_ADD    = "add";
+    /**
+     * 更新
+     */
+    String ACTION_UPDATE = "update";
+    /**
+     * 删除
+     */
+    String ACTION_DELETE = "delete";
+    /**
+     * 导入
+     */
+    String ACTION_IMPORT = "import";
+    /**
+     * 导出
+     */
+    String ACTION_EXPORT = "export";
+
+    /**
+     * 获取权限ID,权限的唯一标识
+     *
+     * @return id
+     */
     String getId();
 
-    List<String> getActions();
+    /**
+     * 获取用户对此权限的可操作事件(按钮)
+     *
+     * @return 操作事件(按钮)集合
+     */
+    Set<String> getActions();
+
+    /**
+     * 获取用户对此权限持有的字段权限信息,用于字段级别的控制
+     *
+     * @return 可操作字段集合
+     * @see FieldAccess
+     */
+    Set<FieldAccess> getFieldAccesses();
+
+    /**
+     * 获取用户对此权限持有的数据权限信息,用于数据级别的控制
+     *
+     * @return 数据权限信息
+     * @see DataAccess
+     */
+    Set<DataAccess> getDataAccesses();
 }

+ 11 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/CustomDataAccess.java

@@ -0,0 +1,11 @@
+package org.hswebframework.web.authorization.access;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ * @see DataAccess.Type#CUSTOM
+ */
+public interface CustomDataAccess extends DataAccess {
+    DataAccessController getController();
+}

+ 41 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccess.java

@@ -0,0 +1,41 @@
+package org.hswebframework.web.authorization.access;
+
+
+import org.hswebframework.web.authorization.Permission;
+
+import java.io.Serializable;
+
+/**
+ * 数据级的权限控制
+ *
+ * @author zhouhao
+ * @see org.hswebframework.web.authorization.access.CustomDataAccess
+ * @see org.hswebframework.web.authorization.access.OwnCreatedDataAccess
+ * @see org.hswebframework.web.authorization.access.ScriptDataAccess
+ */
+public interface DataAccess extends Serializable {
+
+    /**
+     * 对数据的操作事件
+     *
+     * @return 操作时间
+     * @see Permission#ACTION_ADD
+     * @see Permission#ACTION_DELETE
+     * @see Permission#ACTION_GET
+     * @see Permission#ACTION_QUERY
+     * @see Permission#ACTION_UPDATE
+     */
+    String getAction();
+
+    enum Type {
+        OWN_CREATED("自己创建的数据"),
+        SCRIPT("脚本"),
+        CUSTOM("自定义控制器");
+
+        public final String text;
+
+        Type(String text) {
+            this.text = text;
+        }
+    }
+}

+ 10 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessController.java

@@ -0,0 +1,10 @@
+package org.hswebframework.web.authorization.access;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DataAccessController {
+    boolean doAccess(DataAccess access, ParamContext params);
+}

+ 13 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessHandler.java

@@ -0,0 +1,13 @@
+package org.hswebframework.web.authorization.access;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DataAccessHandler {
+
+    boolean isSupport(DataAccess access);
+
+    boolean doAccess(DataAccess access, ParamContext context);
+}

+ 27 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/FieldAccess.java

@@ -0,0 +1,27 @@
+package org.hswebframework.web.authorization.access;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * 字段级别权限控制
+ *
+ * @author zhouhao
+ * @see FieldAccessController
+ */
+public interface FieldAccess extends Serializable {
+    /**
+     * 获取字段名称,字段名称支持嵌套如: user.info.name
+     * 此值为不能操作的字段
+     *
+     * @return 字段名称
+     */
+    String getField();
+
+    /**
+     * 对此字段的操作权限
+     *
+     * @return 操作权限集合
+     */
+    Set<String> getActions();
+}

+ 12 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/FieldAccessController.java

@@ -0,0 +1,12 @@
+package org.hswebframework.web.authorization.access;
+
+import java.util.Set;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface FieldAccessController {
+    boolean doAccess(String action, Set<FieldAccess> accesses, ParamContext params);
+}

+ 9 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/OwnCreatedDataAccess.java

@@ -0,0 +1,9 @@
+package org.hswebframework.web.authorization.access;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface OwnCreatedDataAccess extends DataAccess {
+}

+ 22 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ParamContext.java

@@ -0,0 +1,22 @@
+package org.hswebframework.web.authorization.access;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ParamContext extends Serializable {
+
+    Object getTarget();
+
+    <T> Optional<T> getParameter(String name);
+
+    <T extends Annotation> T getAnnotation();
+
+    Map<String, Object> getParams();
+}

+ 24 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ScriptDataAccess.java

@@ -0,0 +1,24 @@
+package org.hswebframework.web.authorization.access;
+
+/**
+ * 动态脚本数据权限控制
+ *
+ * @author zhouhao
+ */
+public interface ScriptDataAccess extends DataAccess {
+
+    /**
+     * 脚本语言: javascript(js),groovy
+     *
+     * @return 语言
+     */
+    String getScriptLanguage();
+
+    /**
+     * 脚本内容,在进行验证的时候会执行脚本
+     *
+     * @return 脚本
+     */
+    String getScript();
+
+}

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Authorize.java

@@ -41,7 +41,7 @@ public @interface Authorize {
      *
      * @return 进行授权的模块
      */
-    String[] module() default {};
+    String[] permission() default {};
 
     /**
      * 如增删改查等

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Logical.java

@@ -17,7 +17,7 @@
 
 package org.hswebframework.web.authorization.annotation;
 
-enum Logical {
+public enum Logical {
     /**
      * 并集,需要满足所有验证条件
      */

+ 54 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresDataAccess.java

@@ -0,0 +1,54 @@
+/*
+ * 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.annotation;
+
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.Permission;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author zhouhao
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequiresDataAccess {
+
+    /**
+     * @return permission id
+     * @see Permission#getId()
+     */
+    String permission();
+    /**
+     * @return
+     * @see DataAccess#getAction()
+     */
+    String[] action() default {};
+
+    Logical logical() default Logical.OR;
+
+    String controllerBeanName() default "";
+
+    Class<DataAccessController> controllerClass() default DataAccessController.class;
+
+    String idParamName() default "id";
+}

+ 53 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresFieldAccess.java

@@ -0,0 +1,53 @@
+/*
+ * 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.annotation;
+
+import org.hswebframework.web.authorization.access.FieldAccess;
+import org.hswebframework.web.authorization.Permission;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * todo
+ *
+ * @author zhouhao
+ */
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequiresFieldAccess {
+
+    /**
+     * @return permission id
+     * @see Permission#getId()
+     */
+    String permission();
+
+    /**
+     * @return
+     * @see FieldAccess#getActions()
+     */
+    String action();
+
+    Logical logical() default Logical.OR;
+
+    String paramName() default "";
+
+}

+ 34 - 4
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoconfiguration.java

@@ -36,11 +36,17 @@ import org.aspectj.lang.reflect.MethodSignature;
 import org.hswebframework.web.AopUtils;
 import org.hswebframework.web.authorization.Authorization;
 import org.hswebframework.web.authorization.AuthorizationSupplier;
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.access.DataAccessHandler;
+import org.hswebframework.web.authorization.access.FieldAccessController;
 import org.hswebframework.web.authorization.shiro.boost.BoostAuthorizationAttributeSourceAdvisor;
+import org.hswebframework.web.authorization.shiro.boost.DefaultDataAccessController;
+import org.hswebframework.web.authorization.shiro.boost.DefaultFieldAccessController;
 import org.hswebframework.web.authorization.shiro.boost.MethodInterceptorHolder;
 import org.hswebframework.web.authorization.shiro.cache.SpringCacheManagerWrapper;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -55,6 +61,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 
 import java.util.Collections;
+import java.util.List;
 
 /**
  * TODO 完成注释
@@ -121,9 +128,30 @@ public class ShiroAutoconfiguration {
 //        return advisorAutoProxyCreator;
 //    }
 
+    @Autowired(required = false)
+    private List<DataAccessHandler> dataAccessHandlers;
+
+    @Bean
+    @ConditionalOnMissingBean
+    public DefaultDataAccessController defaultDataAccessController() {
+        DefaultDataAccessController accessController = new DefaultDataAccessController();
+        if (dataAccessHandlers != null) {
+            dataAccessHandlers.forEach(accessController::addHandler);
+        }
+        return accessController;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public DefaultFieldAccessController defaultFieldAccessController() {
+        return new DefaultFieldAccessController();
+    }
+
     @Bean
-    public BoostAuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
-        BoostAuthorizationAttributeSourceAdvisor advisor = new BoostAuthorizationAttributeSourceAdvisor();
+    public BoostAuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager,
+                                                                                        DataAccessController dataAccessController,
+                                                                                        FieldAccessController fieldAccessController) {
+        BoostAuthorizationAttributeSourceAdvisor advisor = new BoostAuthorizationAttributeSourceAdvisor(dataAccessController, fieldAccessController);
         advisor.setSecurityManager(securityManager);
         return advisor;
     }
@@ -154,10 +182,12 @@ public class ShiroAutoconfiguration {
     @Aspect
     @Order(Ordered.HIGHEST_PRECEDENCE)
     static class MethodInterceptorHolderAdvisor {
-        @Around(value = "@annotation(org.hswebframework.web.authorization.annotation.RequiresExpression)")
+        @Around(value = "@annotation(org.hswebframework.web.authorization.annotation.RequiresExpression)" +
+                "||@annotation(org.hswebframework.web.authorization.annotation.RequiresDataAccess)" +
+                "||@annotation(org.hswebframework.web.authorization.annotation.Authorize)")
         public Object around(ProceedingJoinPoint pjp) throws Throwable {
             MethodSignature signature = (MethodSignature) pjp.getSignature();
-            String methodName = AopUtils.getMethodName(pjp);
+            String methodName = AopUtils.getMethodBody(pjp);
             String className = pjp.getTarget().getClass().getName();
             String id = DigestUtils.md5Hex(className.concat(methodName));
             new MethodInterceptorHolder(id, signature.getMethod(), pjp.getTarget(), AopUtils.getArgsMap(pjp))

+ 12 - 2
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java

@@ -21,9 +21,14 @@ import org.apache.shiro.authz.annotation.*;
 import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.spring.security.interceptor.AopAllianceAnnotationsAuthorizingMethodInterceptor;
 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.access.FieldAccessController;
 import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
 import org.hswebframework.web.authorization.annotation.RequiresExpression;
+import org.hswebframework.web.authorization.annotation.RequiresFieldAccess;
 import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.annotation.AnnotationUtils;
 
 import java.lang.annotation.Annotation;
@@ -42,7 +47,9 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche
                     RequiresUser.class, RequiresGuest.class, RequiresAuthentication.class,
                     //自定义
                     RequiresExpression.class,
-                    Authorize.class
+                    Authorize.class,
+                    RequiresDataAccess.class,
+                    RequiresFieldAccess.class
             };
 
     protected SecurityManager securityManager = null;
@@ -50,9 +57,12 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche
     /**
      * Create a new AuthorizationAttributeSourceAdvisor.
      */
-    public BoostAuthorizationAttributeSourceAdvisor() {
+    public BoostAuthorizationAttributeSourceAdvisor(DataAccessController dataAccessController,
+                                                    FieldAccessController fieldAccessController) {
         AopAllianceAnnotationsAuthorizingMethodInterceptor interceptor = new AopAllianceAnnotationsAuthorizingMethodInterceptor();
         interceptor.getMethodInterceptors().add(new ExpressionAnnotationMethodInterceptor());
+        interceptor.getMethodInterceptors().add(new DataAccessAnnotationMethodInterceptor(dataAccessController));
+        interceptor.getMethodInterceptors().add(new FieldAccessAnnotationMethodInterceptor(fieldAccessController));
         setAdvice(interceptor);
     }
 

+ 122 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java

@@ -0,0 +1,122 @@
+/*
+ * 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.shiro.boost;
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
+import org.hsweb.expands.script.engine.DynamicScriptEngine;
+import org.hsweb.expands.script.engine.DynamicScriptEngineFactory;
+import org.hswebframework.web.BusinessException;
+import org.hswebframework.web.authorization.Authorization;
+import org.hswebframework.web.authorization.AuthorizationHolder;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.access.ParamContext;
+import org.hswebframework.web.authorization.annotation.Logical;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.authorization.annotation.RequiresExpression;
+import org.hswebframwork.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+
+import java.lang.annotation.Annotation;
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class DataAccessAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
+
+    public DataAccessAnnotationMethodInterceptor(DataAccessController controller) {
+        super(new DataAccessAnnotationHandler(controller));
+    }
+
+    private static final Logger logger = LoggerFactory.getLogger(DataAccessAnnotationMethodInterceptor.class);
+
+    static class DataAccessAnnotationHandler extends AuthorizingAnnotationHandler {
+        protected DataAccessController dataAccessController;
+
+        public DataAccessAnnotationHandler(DataAccessController controller) {
+            super(RequiresDataAccess.class);
+            this.dataAccessController = controller;
+        }
+
+        Map<Class<DataAccessController>, DataAccessController> cache = new HashMap<>();
+
+        @Override
+        public void assertAuthorized(Annotation a) throws AuthorizationException {
+            if (!(a instanceof RequiresDataAccess)) return;
+            MethodInterceptorHolder holder = MethodInterceptorHolder.current();
+            if (null == holder) {
+                logger.warn("MethodInterceptorHolder is null!");
+                return;
+            }
+            RequiresDataAccess accessAnn = ((RequiresDataAccess) a);
+            DataAccessController accessController = dataAccessController;
+            if (DataAccessController.class != accessAnn.controllerClass()) {
+                if (null == (accessController = cache.get(accessAnn.controllerClass()))) {
+                    synchronized (cache) {
+                        if (null == (accessController = cache.get(accessAnn.controllerClass())))
+                            try {
+                                accessController = accessAnn.controllerClass().newInstance();
+                                cache.put(accessAnn.controllerClass(), accessController);
+                            } catch (Exception e) {
+                                throw new RuntimeException(e);
+                            }
+                    }
+                }
+            } else if (StringUtils.isNullOrEmpty(accessAnn.controllerBeanName())) {
+                // TODO: 17-2-8  get controller from spring context
+            }
+            DataAccessController finalAccessController = accessController;
+
+            ParamContext context = holder.createParamContext(accessAnn);
+            Authorization authorization = AuthorizationHolder.get();
+            if (authorization == null) {
+                throw new AuthorizationException("{no_authorization}");
+            }
+            String permission = accessAnn.permission();
+            Permission permissionInfo = authorization.getPermission(permission);
+            List<String> actionList = Arrays.asList(accessAnn.action());
+
+            Set<DataAccess> accesses = permissionInfo
+                    .getDataAccesses()
+                    .stream()
+                    .filter(access -> actionList.contains(access.getAction()))
+                    .collect(Collectors.toSet());
+            if (accesses.isEmpty()) return;
+            Function<Predicate<DataAccess>, Boolean> function =
+                    (accessAnn.logical() == Logical.AND) ?
+                            accesses.stream()::allMatch : accesses.stream()::anyMatch;
+
+            boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, context));
+            if (!isAccess) {
+                throw new AuthorizationException("{access_deny}");
+            }
+        }
+    }
+}

+ 57 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultDataAccessController.java

@@ -0,0 +1,57 @@
+package org.hswebframework.web.authorization.shiro.boost;
+
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.access.DataAccessHandler;
+import org.hswebframework.web.authorization.access.ParamContext;
+import org.hswebframework.web.authorization.shiro.boost.handler.CustomDataAccessHandler;
+import org.hswebframework.web.authorization.shiro.boost.handler.OwnCreatedDataAccessHandler;
+import org.hswebframework.web.authorization.shiro.boost.handler.ScriptDataAccessHandler;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public final class DefaultDataAccessController implements DataAccessController {
+
+    private DataAccessController parent;
+
+    private List<DataAccessHandler> handlers = new LinkedList<>();
+
+    public DefaultDataAccessController() {
+        this(null);
+    }
+
+    public DefaultDataAccessController(DataAccessController parent) {
+        if (parent == this) throw new UnsupportedOperationException();
+        this.parent = parent;
+        addHandler(new CustomDataAccessHandler());
+        addHandler(new OwnCreatedDataAccessHandler());
+        addHandler(new ScriptDataAccessHandler());
+    }
+
+    @Override
+    public boolean doAccess(DataAccess access, ParamContext params) {
+        if (parent != null) parent.doAccess(access, params);
+        return handlers.parallelStream()
+                .filter(handler -> handler.isSupport(access))
+                .anyMatch(handler -> handler.doAccess(access, params));
+    }
+
+    public DefaultDataAccessController addHandler(DataAccessHandler handler) {
+        handlers.add(handler);
+        return this;
+    }
+
+    public void setHandlers(List<DataAccessHandler> handlers) {
+        this.handlers = handlers;
+    }
+
+    public List<DataAccessHandler> getHandlers() {
+        return handlers;
+    }
+}

+ 70 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultFieldAccessController.java

@@ -0,0 +1,70 @@
+package org.hswebframework.web.authorization.shiro.boost;
+
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.FieldAccess;
+import org.hswebframework.web.authorization.access.FieldAccessController;
+import org.hswebframework.web.authorization.access.ParamContext;
+import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class DefaultFieldAccessController implements FieldAccessController {
+
+    private Logger logger = LoggerFactory.getLogger(DefaultFieldAccessController.class);
+
+    @Override
+    public boolean doAccess(String action, Set<FieldAccess> accesses, ParamContext params) {
+        switch (action) {
+            case Permission.ACTION_QUERY:
+                return doQueryAccess(accesses, params);
+            case Permission.ACTION_UPDATE:
+                return doUpdateAccess(accesses, params);
+            default:
+                logger.warn("action {} not support now!", action);
+        }
+        return false;
+    }
+
+    protected boolean doUpdateAccess(Set<FieldAccess> accesses, ParamContext params) {
+        Entity entity = params.getParams().values().stream()
+                .filter(Entity.class::isInstance)
+                .map(Entity.class::cast)
+                .findAny().orElse(null);
+        if (null != entity) {
+            for (FieldAccess access : accesses) {
+                try {
+                    //设置值为null,跳过修改
+                    BeanUtilsBean.getInstance()
+                            .getPropertyUtils()
+                            .setProperty(entity, access.getField(), null);
+                } catch (Exception e) {
+                }
+            }
+        } else {
+            logger.warn("doUpdateAccess skip ,because can not found any entity in param!");
+        }
+        return true;
+    }
+
+    protected boolean doQueryAccess(Set<FieldAccess> accesses, ParamContext params) {
+        QueryParamEntity paramEntity = params.getParams().values().stream()
+                .filter(QueryParamEntity.class::isInstance)
+                .map(QueryParamEntity.class::cast)
+                .findAny().orElse(null);
+        if (paramEntity != null) {
+            paramEntity.excludes(accesses.stream().map(FieldAccess::getField).toArray(String[]::new));
+        } else {
+            logger.warn("doQueryAccess skip ,because can not found any QueryParamEntity in param!");
+        }
+        return true;
+    }
+}

+ 87 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/FieldAccessAnnotationMethodInterceptor.java

@@ -0,0 +1,87 @@
+/*
+ * 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.shiro.boost;
+
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
+import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
+import org.hswebframework.web.authorization.Authorization;
+import org.hswebframework.web.authorization.AuthorizationHolder;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.FieldAccess;
+import org.hswebframework.web.authorization.access.FieldAccessController;
+import org.hswebframework.web.authorization.access.ParamContext;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.authorization.annotation.RequiresFieldAccess;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class FieldAccessAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
+
+    public FieldAccessAnnotationMethodInterceptor(FieldAccessController controller) {
+        super(new DataAccessAnnotationHandler(controller));
+    }
+
+    private static final Logger logger = LoggerFactory.getLogger(FieldAccessAnnotationMethodInterceptor.class);
+
+    static class DataAccessAnnotationHandler extends AuthorizingAnnotationHandler {
+        protected FieldAccessController fieldAccessController;
+
+        public DataAccessAnnotationHandler(FieldAccessController controller) {
+            super(RequiresFieldAccess.class);
+            this.fieldAccessController = controller;
+        }
+
+        @Override
+        public void assertAuthorized(Annotation a) throws AuthorizationException {
+            if (!(a instanceof RequiresFieldAccess)) return;
+            MethodInterceptorHolder holder = MethodInterceptorHolder.current();
+            if (null == holder) {
+                logger.warn("MethodInterceptorHolder is null!");
+                return;
+            }
+            RequiresFieldAccess accessAnn = ((RequiresFieldAccess) a);
+            ParamContext context = holder.createParamContext(accessAnn);
+            Authorization authorization = AuthorizationHolder.get();
+            if (authorization == null) {
+                throw new AuthorizationException("{no_authorization}");
+            }
+            String permission = accessAnn.permission();
+            Permission permissionInfo = authorization.getPermission(permission);
+
+            Set<FieldAccess> accesses = permissionInfo
+                    .getFieldAccesses()
+                    .stream()
+                    .filter(access -> access.getActions().contains(accessAnn.action()))
+                    .collect(Collectors.toSet());
+            boolean isAccess = fieldAccessController.doAccess(accessAnn.action(), accesses, context);
+            if (!isAccess) {
+                throw new AuthorizationException("{access_deny}");
+            }
+        }
+    }
+}

+ 33 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/MethodInterceptorHolder.java

@@ -17,10 +17,14 @@
 
 package org.hswebframework.web.authorization.shiro.boost;
 
+import org.apache.shiro.util.Assert;
 import org.hswebframework.web.ThreadLocalUtils;
+import org.hswebframework.web.authorization.access.ParamContext;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.Map;
+import java.util.Optional;
 
 /**
  * TODO 完成注释
@@ -54,6 +58,10 @@ public class MethodInterceptorHolder {
     }
 
     public MethodInterceptorHolder(String id, Method method, Object target, Map<String, Object> args) {
+        Assert.notNull(id);
+        Assert.notNull(method);
+        Assert.notNull(target);
+        Assert.notNull(args);
         this.id = id;
         this.method = method;
         this.target = target;
@@ -75,4 +83,29 @@ public class MethodInterceptorHolder {
     public Map<String, Object> getArgs() {
         return args;
     }
+
+    public ParamContext createParamContext(final Annotation annotation) {
+        return new ParamContext() {
+            @Override
+            public Object getTarget() {
+                return target;
+            }
+
+            @Override
+            public <T> Optional<T> getParameter(String name) {
+                if (args == null) return Optional.empty();
+                return Optional.of((T) args.get(name));
+            }
+
+            @Override
+            public <T extends Annotation> T getAnnotation() {
+                return (T) annotation;
+            }
+
+            @Override
+            public Map<String, Object> getParams() {
+                return getArgs();
+            }
+        };
+    }
 }

+ 21 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/CustomDataAccessHandler.java

@@ -0,0 +1,21 @@
+package org.hswebframework.web.authorization.shiro.boost.handler;
+
+import org.hswebframework.web.authorization.access.*;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class CustomDataAccessHandler implements DataAccessHandler {
+    @Override
+    public boolean isSupport(DataAccess access) {
+        return access instanceof CustomDataAccess;
+    }
+
+    @Override
+    public boolean doAccess(DataAccess access, ParamContext context) {
+        CustomDataAccess custom = ((CustomDataAccess) access);
+        return custom.getController().doAccess(access, context);
+    }
+}

+ 127 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java

@@ -0,0 +1,127 @@
+package org.hswebframework.web.authorization.shiro.boost.handler;
+
+import org.hsweb.ezorm.core.param.Term;
+import org.hswebframework.web.authorization.AuthorizationHolder;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.DataAccessHandler;
+import org.hswebframework.web.authorization.access.OwnCreatedDataAccess;
+import org.hswebframework.web.authorization.access.ParamContext;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.commons.entity.RecordCreationEntity;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.HswebController;
+import org.hswebframework.web.controller.QueryController;
+import org.hswebframework.web.service.QueryService;
+import org.hswebframwork.utils.ClassUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class OwnCreatedDataAccessHandler implements DataAccessHandler {
+    private static final Logger logger = LoggerFactory.getLogger(OwnCreatedDataAccessHandler.class);
+
+    @Override
+    public boolean isSupport(DataAccess access) {
+        return access instanceof OwnCreatedDataAccess;
+    }
+
+    @Override
+    public boolean doAccess(DataAccess access, ParamContext context) {
+        OwnCreatedDataAccess own = ((OwnCreatedDataAccess) access);
+        Object controller = context.getTarget();
+        if (controller != null) {
+            switch (access.getAction()) {
+                case Permission.ACTION_QUERY:
+                    return doQueryAccess(own, context);
+                case Permission.ACTION_GET:
+                case Permission.ACTION_DELETE:
+                case Permission.ACTION_UPDATE:
+                    return doRWAccess(own, context, controller);
+                case Permission.ACTION_ADD:
+                    //put creator_id to data
+                    return putCreatorId(own, context);
+                default:
+                    logger.warn("action: {} not support now!", access.getAction());
+            }
+        } else {
+            logger.warn("target is not instance of HswebController!");
+        }
+        return true;
+    }
+
+    public boolean putCreatorId(OwnCreatedDataAccess access, ParamContext context) {
+        RecordCreationEntity entity = context.getParams()
+                .values().stream()
+                .filter(RecordCreationEntity.class::isInstance)
+                .map(RecordCreationEntity.class::cast)
+                .findAny().orElse(null);
+        if (entity != null) {
+            entity.setCreatorId(AuthorizationHolder.get().getUser().getId());
+        } else {
+            logger.warn("try put creatorId property,but not found any RecordCreationEntity!");
+        }
+        return true;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected boolean doRWAccess(OwnCreatedDataAccess access, ParamContext context, Object controller) {
+        //获取注解
+        RequiresDataAccess dataAccess = context.getAnnotation();
+        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
+        //通过QueryController获取QueryService
+        //然后调用selectByPk 查询旧的数据,进行对比
+        if (controller instanceof QueryController) {
+            //判断是否满足条件(泛型为 RecordCreationEntity)
+            Class entityType = ClassUtils.getGenericType(controller.getClass(), 0);
+            if (ClassUtils.instanceOf(entityType, RecordCreationEntity.class)) {
+                QueryService<RecordCreationEntity, Object> queryService =
+                        ((QueryController<RecordCreationEntity, Object, Entity>) controller).getService();
+                RecordCreationEntity oldData = queryService.selectByPk(id);
+                if (oldData != null && !AuthorizationHolder.get().getUser().getId().equals(oldData.getCreatorId())) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    protected boolean doQueryAccess(OwnCreatedDataAccess access, ParamContext context) {
+        Entity entity = context.getParams()
+                .values().stream()
+                .filter(Entity.class::isInstance)
+                .map(Entity.class::cast)
+                .findAny().orElse(null);
+        if (entity == null) {
+            logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
+            return true;
+        }
+        if (entity instanceof QueryParamEntity) {
+            QueryParamEntity queryParamEntity = ((QueryParamEntity) entity);
+            //重构查询条件
+            //如: 旧的条件为 where name =? or name = ?
+            //重构后为: where creatorId=? and (name = ? or name = ?)
+            List<Term> oldParam = queryParamEntity.getTerms();
+            //清空旧的查询条件
+            queryParamEntity.setTerms(new ArrayList<>());
+            //添加一个查询条件
+            queryParamEntity
+                    .where("creatorId", AuthorizationHolder.get().getUser().getId())
+                    //客户端提交的参数 作为嵌套参数
+                    .nest().setTerms(oldParam);
+        } else if (entity instanceof RecordCreationEntity) {
+            ((RecordCreationEntity) entity).setCreatorId(AuthorizationHolder.get().getUser().getId());
+        } else {
+            logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
+        }
+        return true;
+    }
+}

+ 39 - 0
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java

@@ -0,0 +1,39 @@
+package org.hswebframework.web.authorization.shiro.boost.handler;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.shiro.authz.AuthorizationException;
+import org.hswebframework.expands.script.engine.DynamicScriptEngine;
+import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
+import org.hswebframework.web.BusinessException;
+import org.hswebframework.web.authorization.access.*;
+import org.hswebframwork.utils.StringUtils;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class ScriptDataAccessHandler implements DataAccessHandler {
+    @Override
+    public boolean isSupport(DataAccess access) {
+        return access instanceof ScriptDataAccess;
+    }
+
+    @Override
+    public boolean doAccess(DataAccess access, ParamContext context) {
+        ScriptDataAccess dataAccess = ((ScriptDataAccess) access);
+        DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(dataAccess.getScriptLanguage());
+        if (engine == null) throw new UnsupportedOperationException(dataAccess.getScriptLanguage() + " {not_support}");
+        String scriptId = DigestUtils.md5Hex(dataAccess.getScript());
+        try {
+            if (!engine.compiled(scriptId)) {
+                engine.compile(scriptId, dataAccess.getScript());
+            }
+            Object success = engine.execute(scriptId, context.getParams()).getIfSuccess();
+            return StringUtils.isTrue(success);
+        } catch (Exception e) {
+            throw new BusinessException("{script_error}", e);
+        }
+    }
+
+}

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/CreateController.java

@@ -33,7 +33,7 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
  *
  * @author zhouhao
  */
-public interface CreateController<E, PK> {
+public interface CreateController<E, PK> extends HswebController {
 
     InsertService<E, PK> getService();
 

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/DeleteController.java

@@ -31,7 +31,7 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
  *
  * @author zhouhao
  */
-public interface DeleteController<PK> {
+public interface DeleteController<PK> extends HswebController {
 
     DeleteService<PK> getService();
 

+ 9 - 0
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/HswebController.java

@@ -0,0 +1,9 @@
+package org.hswebframework.web.controller;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface HswebController {
+}

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/QueryController.java

@@ -33,7 +33,7 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
  *
  * @author zhouhao
  */
-public interface QueryController<E, PK, Q extends Entity> {
+public interface QueryController<E, PK, Q extends Entity> extends HswebController {
 
     <T extends QueryByEntityService<E> & QueryService<E, PK>> T getService();
 

+ 1 - 1
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/UpdateController.java

@@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RequestBody;
  *
  * @author zhouhao
  */
-public interface UpdateController<E, PK> {
+public interface UpdateController<E, PK> extends HswebController {
     @Authorize(action = "update")
     @PutMapping(path = "/{id}")
     @AccessLogger("根据主键修改数据")

+ 20 - 0
hsweb-commons/hsweb-commons-entity/src/main/java/org/hswebframework/web/commons/entity/RecordCreationEntity.java

@@ -0,0 +1,20 @@
+package org.hswebframework.web.commons.entity;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface RecordCreationEntity extends Entity {
+    String getCreatorId();
+
+    void setCreatorId(String creatorId);
+
+    Long getCreateTime();
+
+    void setCreateTime(Long createTime);
+
+    default void setCreateTimeNow() {
+        setCreateTime(System.currentTimeMillis());
+    }
+}

+ 3 - 2
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractService.java

@@ -40,8 +40,9 @@ public abstract class AbstractService<E extends Entity, PK> implements CreateEnt
 
     @SuppressWarnings("unchecked")
     public AbstractService() {
-        primaryKeyType = (Class<PK>) ClassUtils.getGenericType(this.getClass(), 1);
-        entityType = (Class<E>) ClassUtils.getGenericType(this.getClass(), 0);
+        Class userClass = org.springframework.util.ClassUtils.getUserClass(this);
+        primaryKeyType = (Class<PK>) ClassUtils.getGenericType(userClass, 1);
+        entityType = (Class<E>) ClassUtils.getGenericType(userClass, 0);
     }
 
     protected boolean entityFactoryIsEnabled() {

+ 15 - 3
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/GenericEntityService.java

@@ -19,7 +19,9 @@
 package org.hswebframework.web.service;
 
 import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.dao.CrudDao;
+import org.hswebframwork.utils.ClassUtils;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
@@ -44,18 +46,28 @@ public abstract class GenericEntityService<E extends GenericEntity<PK>, PK>
 
     @Override
     public int deleteByPk(PK pk) {
-        return createDelete().where(GenericEntity.id, pk).exec();
+        return createDelete()
+                .where(GenericEntity.id, pk)
+                .exec();
     }
 
     @Override
     public int updateByPk(E entity) {
         tryValidate(entity);
-        return createUpdate(entity).where(GenericEntity.id, entity.getId()).exec();
+        return createUpdate(entity)
+                //如果是RecordCreationEntity则不修改creator_id和creator_time
+                .when(ClassUtils.instanceOf(getEntityType(), RecordCreationEntity.class),
+                        update -> update.and().excludes("creator_id", "creator_time"))
+                .where(GenericEntity.id, entity.getId())
+                .exec();
     }
 
     @Override
     public int updateByPk(List<E> data) {
-        return data.stream().map(this::updateByPk).reduce(Math::addExact).orElse(0);
+        return data.stream()
+                .map(this::updateByPk)
+                .reduce(Math::addExact)
+                .orElse(0);
     }
 
     @Override

+ 1 - 1
hsweb-commons/hsweb-commons-utils/src/main/java/org/hswebframework/web/AopUtils.java

@@ -26,7 +26,7 @@ import java.util.Map;
 
 public class AopUtils {
 
-    public static final String getMethodName(JoinPoint pjp) {
+    public static final String getMethodBody(JoinPoint pjp) {
         StringBuilder methodName = new StringBuilder(pjp.getSignature().getName()).append("(");
         MethodSignature signature = (MethodSignature) pjp.getSignature();
         String[] names = signature.getParameterNames();

+ 4 - 0
hsweb-core/src/main/java/org/hswebframework/web/BusinessException.java

@@ -35,6 +35,10 @@ public class BusinessException extends RuntimeException {
         this.status = status;
     }
 
+    public BusinessException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
     public BusinessException(String message, Throwable cause, int status) {
         super(message, cause);
         this.status = status;

+ 4 - 0
hsweb-examples/hsweb-examples-simple/pom.xml

@@ -49,6 +49,10 @@
         </plugins>
     </build>
     <dependencies>
+        <dependency>
+            <groupId>org.codehaus.groovy</groupId>
+            <artifactId>groovy-all</artifactId>
+        </dependency>
         <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>

+ 80 - 1
hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java

@@ -17,10 +17,23 @@
 
 package org.hswebframework.web.example.simple;
 
+import com.alibaba.fastjson.JSON;
 import org.hsweb.ezorm.rdb.executor.AbstractJdbcSqlExecutor;
 import org.hsweb.ezorm.rdb.executor.SqlExecutor;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.dao.datasource.DataSourceHolder;
 import org.hswebframework.web.dao.datasource.DatabaseType;
+import org.hswebframework.web.entity.authorization.*;
+import org.hswebframework.web.entity.authorization.bind.BindPermissionRoleEntity;
+import org.hswebframework.web.entity.authorization.bind.BindRoleUserEntity;
+import org.hswebframework.web.service.authorization.PermissionService;
+import org.hswebframework.web.service.authorization.RoleService;
+import org.hswebframework.web.service.authorization.UserService;
+import org.hswebframework.web.service.authorization.simple.access.SimpleScriptDataAccess;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -30,9 +43,11 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.jdbc.datasource.DataSourceUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import javax.annotation.PostConstruct;
 import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.Arrays;
 
 /**
  * TODO 完成注释
@@ -43,7 +58,7 @@ import java.sql.SQLException;
 @SpringBootApplication
 @Configuration
 @RequestMapping
-public class SpringBootExample {
+public class SpringBootExample implements CommandLineRunner {
 
     @Bean
     @ConditionalOnMissingBean(SqlExecutor.class)
@@ -60,9 +75,73 @@ public class SpringBootExample {
                 DataSourceUtils.releaseConnection(connection, dataSource);
             }
         };
+
     }
 
+    @Autowired
+    UserService       userService;
+    @Autowired
+    RoleService       roleService;
+    @Autowired
+    PermissionService permissionService;
+    @Autowired
+    EntityFactory     entityFactory;
+
+
     public static void main(String[] args) {
         SpringApplication.run(SpringBootExample.class);
     }
+
+    @Override
+    public void run(String... strings) throws Exception {
+        DataAccessEntity accessEntity = new DataAccessEntity();
+        accessEntity.setType(DataAccess.Type.OWN_CREATED.name());
+        accessEntity.setAction(Permission.ACTION_QUERY);
+
+        DataAccessEntity updateAccessEntity = new DataAccessEntity();
+        updateAccessEntity.setType(DataAccess.Type.OWN_CREATED.name());
+        updateAccessEntity.setAction(Permission.ACTION_UPDATE);
+//        updateAccessEntity.setConfig(JSON.toJSONString(new SimpleScriptDataAccess("" +
+//                "println(id);" +
+//                "println(entity);" +
+//                "println('脚本权限控制');" +
+//                "return true;" +
+//                "","groovy")));
+
+        //password 属性不能读取和修改
+        FieldAccessEntity fieldAccessEntity = new FieldAccessEntity();
+        fieldAccessEntity.setField("password");
+        fieldAccessEntity.setActions(ActionEntity.create(Permission.ACTION_QUERY,Permission.ACTION_UPDATE));
+
+        PermissionEntity permission = entityFactory.newInstance(PermissionEntity.class);
+        permission.setName("测试");
+        permission.setId("test");
+        permission.setActions(ActionEntity.create(Permission.ACTION_QUERY, Permission.ACTION_UPDATE));
+        permission.setDataAccess(Arrays.asList(accessEntity, updateAccessEntity));
+        permission.setFieldAccess(Arrays.asList(fieldAccessEntity));
+        permissionService.insert(permission);
+
+        BindPermissionRoleEntity<PermissionRoleEntity> roleEntity = entityFactory.newInstance(BindPermissionRoleEntity.class);
+        SimplePermissionRoleEntity permissionRoleEntity = new SimplePermissionRoleEntity();
+        permissionRoleEntity.setRoleId("admin");
+        permissionRoleEntity.setPermissionId("test");
+        permissionRoleEntity.setActions(Arrays.asList(Permission.ACTION_QUERY, Permission.ACTION_UPDATE));
+        permissionRoleEntity.setDataAccesses(permission.getDataAccess());
+        permissionRoleEntity.setFieldAccesses(permission.getFieldAccess());
+        roleEntity.setId("admin");
+        roleEntity.setName("test");
+        roleEntity.setPermissions(Arrays.asList(permissionRoleEntity));
+        roleService.insert(roleEntity);
+
+        BindRoleUserEntity userEntity = entityFactory.newInstance(BindRoleUserEntity.class);
+        userEntity.setId("admin");
+        userEntity.setName("admin");
+        userEntity.setCreateTimeNow();
+        userEntity.setCreatorId("admin");
+        userEntity.setUsername("admin");
+        userEntity.setPassword("admin");
+        userEntity.setRoles(Arrays.asList("admin"));
+        userService.insert(userEntity);
+
+    }
 }

+ 82 - 5
hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java

@@ -2,11 +2,24 @@ package org.hswebframework.web.example.simple;
 
 import org.apache.shiro.authz.annotation.RequiresUser;
 import org.hswebframework.web.authorization.Authorization;
+import org.hswebframework.web.authorization.AuthorizationHolder;
+import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.annotation.AuthInfo;
-import org.hswebframework.web.authorization.annotation.RequiresExpression;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.authorization.annotation.RequiresFieldAccess;
+import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.commons.entity.PagerResult;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.QueryController;
 import org.hswebframework.web.controller.message.ResponseMessage;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.hswebframework.web.entity.authorization.SimpleUserEntity;
+import org.hswebframework.web.entity.authorization.UserEntity;
+import org.hswebframework.web.service.QueryByEntityService;
+import org.hswebframework.web.service.QueryService;
+import org.hswebframwork.utils.ClassUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * TODO 完成注释
@@ -14,12 +27,76 @@ import org.springframework.web.bind.annotation.RestController;
  * @author zhouhao
  */
 @RestController
-public class TestController {
+public class TestController implements QueryController<UserEntity, String, QueryParamEntity> {
+
     @GetMapping("/test")
     @RequiresUser
-    @RequiresExpression("#authorization!=null&&#authorization.user.username=='admin'")
     public ResponseMessage testShiro(@AuthInfo Authorization authorization) {
         return ResponseMessage.ok(authorization);
     }
 
+    @GetMapping("/testQuery")
+    @RequiresUser
+    @RequiresDataAccess(permission = "test", action = Permission.ACTION_QUERY)
+    @RequiresFieldAccess(permission = "test", action = Permission.ACTION_QUERY)
+    public ResponseMessage testQuery(QueryParamEntity entity) {
+        return ResponseMessage.ok(entity);
+    }
+
+
+    @PutMapping("/testUpdate/{id}")
+    @RequiresUser
+    @RequiresDataAccess(permission = "test", action = Permission.ACTION_UPDATE)
+    @RequiresFieldAccess(permission = "test", action = Permission.ACTION_UPDATE)
+    public ResponseMessage testUpdate(@PathVariable String id, @RequestBody UserEntity entity) {
+        return ResponseMessage.ok(entity);
+    }
+
+
+    @Override
+    public TestService getService() {
+        return new TestService();
+    }
+
+    public static class TestService implements QueryByEntityService<UserEntity>, QueryService<UserEntity, String> {
+
+        @Override
+        public UserEntity selectByPk(String id) {
+            SimpleUserEntity userEntity = new SimpleUserEntity();
+            // 同一个用户
+            userEntity.setCreatorId(AuthorizationHolder.get().getUser().getId());
+
+            return userEntity;
+        }
+
+        @Override
+        public List<UserEntity> select() {
+            return null;
+        }
+
+        @Override
+        public int count() {
+            return 0;
+        }
+
+        @Override
+        public PagerResult<UserEntity> selectPager(Entity param) {
+            return null;
+        }
+
+        @Override
+        public List<UserEntity> select(Entity param) {
+            return null;
+        }
+
+        @Override
+        public int count(Entity param) {
+            return 0;
+        }
+
+        @Override
+        public UserEntity selectSingle(Entity param) {
+            return null;
+        }
+    }
 }

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java

@@ -140,7 +140,7 @@ public class AuthorizationController {
                 throw new BusinessException("{password_error}", 400);
             }
             // TODO: 17-1-13  获取IP
-            userService.updateLoginInfo(entity.getId(), "", new Date());
+            userService.updateLoginInfo(entity.getId(), "", System.currentTimeMillis());
             // 验证通过
             Authorization authorization = userService.initUserAuthorization(entity.getId());
             listenerAdapter.onAuthorizeSuccess(remember, authorization);

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserController.java

@@ -39,7 +39,7 @@ import static org.hswebframework.web.controller.message.ResponseMessage.*;
  */
 @RestController
 @RequestMapping("${hsweb.web.mappings.user:user}")
-@Authorize(module = "user")
+@Authorize(permission = "user")
 @AccessLogger("用户管理")
 public class UserController implements QueryController<UserEntity, String, QueryParamEntity>, CreateController<UserEntity, String> {
 

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-api/src/main/java/org/hswebframework/web/dao/authorization/PermissionDao.java

@@ -9,5 +9,5 @@ import org.hswebframework.web.entity.authorization.PermissionEntity;
  *
  * @author zhouhao
  */
-public interface PermissionDao extends CrudDao<PermissionEntity<ActionEntity>,String> {
+public interface PermissionDao extends CrudDao<PermissionEntity,String> {
 }

+ 4 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/PermissionMapper.xml

@@ -25,8 +25,11 @@
         <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
         <result property="name" column="name" javaType="string" jdbcType="VARCHAR"/>
         <result property="describe" column="describe" javaType="string" jdbcType="VARCHAR"/>
-        <result property="status" column="status" javaType="byte" jdbcType="NUMERIC"/>
+        <result property="status" column="status" javaType="Byte" jdbcType="NUMERIC"/>
         <result property="actions" column="actions" javaType="java.util.List" jdbcType="VARCHAR"/>
+        <result property="fieldAccess" column="field_access" javaType="java.util.List" jdbcType="CLOB"/>
+        <result property="dataAccess" column="data_access" javaType="java.util.List" jdbcType="CLOB"/>
+
     </resultMap>
 
     <!--用于动态生成sql所需的配置-->

+ 2 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/PermissionRoleMapper.xml

@@ -25,6 +25,8 @@
         <result property="roleId" column="role_id" javaType="string" jdbcType="VARCHAR"/>
         <result property="permissionId" column="permission_id" javaType="string" jdbcType="VARCHAR"/>
         <result property="actions" column="actions" javaType="java.util.List" jdbcType="VARCHAR"/>
+        <result property="fieldAccesses" column="field_access" javaType="java.util.List" jdbcType="CLOB"/>
+        <result property="dataAccesses" column="data_access" javaType="java.util.List" jdbcType="CLOB"/>
     </resultMap>
 
     <!--用于动态生成sql所需的配置-->

+ 4 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-dao/hsweb-system-authorization-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/authorization/UserMapper.xml

@@ -27,10 +27,11 @@
         <result property="username" column="username" javaType="string" jdbcType="VARCHAR"/>
         <result property="password" column="password" javaType="String" jdbcType="VARCHAR"/>
         <result property="salt" column="salt" javaType="String" jdbcType="VARCHAR"/>
-        <result property="enabled" column="enabled" javaType="boolean" jdbcType="NUMERIC"/>
+        <result property="enabled" column="enabled" javaType="Boolean" jdbcType="NUMERIC"/>
         <result property="lastLoginIp" column="last_login_ip" javaType="string" jdbcType="VARCHAR"/>
-        <result property="createDate" column="create_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
-        <result property="lastLoginDate" column="last_login_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="createTime" column="create_time" javaType="Long" jdbcType="NUMERIC"/>
+        <result property="creatorId" column="creator_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="lastLoginTime" column="last_login_time" javaType="Long" jdbcType="NUMERIC"/>
     </resultMap>
 
     <!--用于动态生成sql所需的配置-->

+ 51 - 7
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/ActionEntity.java

@@ -2,16 +2,60 @@ package org.hswebframework.web.entity.authorization;
 
 import org.hswebframework.web.commons.entity.CloneableEntity;
 
-public interface ActionEntity extends CloneableEntity {
-    String getAction();
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
 
-    void setAction(String action);
+public class ActionEntity implements CloneableEntity {
 
-    String getDescribe();
+    private String action;
 
-    void setDescribe(String describe);
+    private String describe;
 
-    boolean isDefaultCheck();
+    private boolean defaultCheck;
+
+    public ActionEntity() {
+    }
+
+    public ActionEntity(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;
+    }
+
+    @Override
+    public ActionEntity clone() {
+        ActionEntity target = new ActionEntity();
+        target.setAction(getAction());
+        target.setDescribe(getDescribe());
+        target.setDefaultCheck(isDefaultCheck());
+        return target;
+    }
+
+    public static List<ActionEntity> create(String... actions) {
+        return Arrays.stream(actions).map(ActionEntity::new).collect(Collectors.toList());
+    }
 
-    void setDefaultCheck(boolean defaultCheck);
 }

+ 60 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/DataAccessEntity.java

@@ -0,0 +1,60 @@
+package org.hswebframework.web.entity.authorization;
+
+import org.hswebframework.web.commons.entity.CloneableEntity;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class DataAccessEntity implements CloneableEntity {
+    private String action;
+
+    private String describe;
+
+    private String type;
+
+    private String config;
+
+    public String getAction() {
+        return this.action;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    public String getDescribe() {
+        return this.describe;
+    }
+
+    public void setDescribe(String describe) {
+        this.describe = describe;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getConfig() {
+        return this.config;
+    }
+
+    public void setConfig(String config) {
+        this.config = config;
+    }
+
+    @Override
+    public DataAccessEntity clone() {
+        DataAccessEntity target = new DataAccessEntity();
+        target.setDescribe(getDescribe());
+        target.setAction(getAction());
+        target.setConfig(getConfig());
+        target.setType(getType());
+        return target;
+    }
+}

+ 69 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/FieldAccessEntity.java

@@ -0,0 +1,69 @@
+package org.hswebframework.web.entity.authorization;
+
+import org.hswebframework.web.commons.entity.CloneableEntity;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class FieldAccessEntity implements CloneableEntity {
+    private String field;
+
+    private String describe;
+
+    private List<ActionEntity> actions;
+
+    private boolean defaultCheck;
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    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;
+    }
+
+    public List<ActionEntity> getActions() {
+        if (actions == null) actions = Collections.emptyList();
+        return actions;
+    }
+
+    public void setActions(List<ActionEntity> actions) {
+        this.actions = actions;
+    }
+
+    @Override
+    public FieldAccessEntity clone() {
+        FieldAccessEntity target = new FieldAccessEntity();
+        target.setField(getField());
+        target.setDescribe(getDescribe());
+        target.setDefaultCheck(isDefaultCheck());
+        if (actions != null) {
+            target.setActions(actions.stream().map(ActionEntity::clone).collect(Collectors.toList()));
+        }
+        return target;
+    }
+
+}

+ 21 - 4
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionEntity.java

@@ -9,14 +9,31 @@ import java.util.List;
  *
  * @author zhouhao
  */
-public interface PermissionEntity<A extends ActionEntity> extends GenericEntity<String>,
-        PermissionReadEntity<A>{
+public interface PermissionEntity extends GenericEntity<String> {
+
+    String getId();
+
+    String getName();
+
+    String getDescribe();
+
+    byte getStatus();
+
     void setName(String name);
 
     void setDescribe(String comment);
 
-    void setStatus(byte status);
+    void setStatus(Byte status);
+
+    List<ActionEntity> getActions();
+
+    void setActions(List<ActionEntity> actions);
+
+    List<DataAccessEntity> getDataAccess();
+
+    List<FieldAccessEntity> getFieldAccess();
 
-    void setActions(List<A> actions);
+    void setDataAccess(List<DataAccessEntity> dataAccess);
 
+    void setFieldAccess(List<FieldAccessEntity> fieldAccess);
 }

+ 0 - 22
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionReadEntity.java

@@ -1,22 +0,0 @@
-package org.hswebframework.web.entity.authorization;
-
-import org.hswebframework.web.commons.entity.Entity;
-
-import java.util.List;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public interface PermissionReadEntity<A extends ActionEntity> extends Entity{
-    String getId();
-
-    String getName();
-
-    String getDescribe();
-
-    byte getStatus();
-
-    List<A> getActions();
-}

+ 14 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionRoleEntity.java

@@ -9,7 +9,7 @@ import java.util.List;
  *
  * @author zhouhao
  */
-public interface PermissionRoleEntity extends PermissionRoleReadEntity, CloneableEntity {
+public interface PermissionRoleEntity extends CloneableEntity {
 
     void setRoleId(String roleId);
 
@@ -17,4 +17,17 @@ public interface PermissionRoleEntity extends PermissionRoleReadEntity, Cloneabl
 
     void setActions(List<String> actions);
 
+    String getRoleId();
+
+    String getPermissionId();
+
+    List<String> getActions();
+
+    List<DataAccessEntity> getDataAccesses();
+
+    List<FieldAccessEntity> getFieldAccesses();
+
+    void setDataAccesses(List<DataAccessEntity> dataAccesses);
+
+    void setFieldAccesses(List<FieldAccessEntity> fieldAccesses);
 }

+ 0 - 19
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/PermissionRoleReadEntity.java

@@ -1,19 +0,0 @@
-package org.hswebframework.web.entity.authorization;
-
-import org.hswebframework.web.commons.entity.Entity;
-
-import java.util.List;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public interface PermissionRoleReadEntity extends Entity {
-
-    String getRoleId();
-
-    String getPermissionId();
-
-    List<String> getActions();
-}

+ 2 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/RoleEntity.java

@@ -17,7 +17,7 @@ public interface RoleEntity extends GenericEntity<String> {
 
     void setDescribe(String describe);
 
-    void setEnabled(boolean enabled);
+    void setEnabled(Boolean enabled);
 
-    boolean isEnabled();
+    Boolean isEnabled();
 }

+ 0 - 70
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleActionEntity.java

@@ -1,70 +0,0 @@
-package org.hswebframework.web.entity.authorization;
-
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public class SimpleActionEntity implements ActionEntity {
-
-    private String action;
-
-    private String describe;
-
-    private boolean defaultCheck;
-
-    public SimpleActionEntity() {
-    }
-
-    public SimpleActionEntity(String action) {
-        this.action = action;
-    }
-
-    @Override
-    public String getAction() {
-        return action;
-    }
-
-    @Override
-    public void setAction(String action) {
-        this.action = action;
-    }
-
-    @Override
-    public String getDescribe() {
-        return describe;
-    }
-
-    @Override
-    public void setDescribe(String describe) {
-        this.describe = describe;
-    }
-
-    @Override
-    public boolean isDefaultCheck() {
-        return defaultCheck;
-    }
-
-    @Override
-    public void setDefaultCheck(boolean defaultCheck) {
-        this.defaultCheck = defaultCheck;
-    }
-
-    @Override
-    public SimpleActionEntity clone() {
-        SimpleActionEntity target = new SimpleActionEntity();
-        target.setAction(getAction());
-        target.setDescribe(getDescribe());
-        target.setDefaultCheck(isDefaultCheck());
-        return target;
-    }
-
-    public static List<ActionEntity> create(String... actions) {
-        return Arrays.stream(actions).map(SimpleActionEntity::new).collect(Collectors.toList());
-    }
-}

+ 32 - 7
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimplePermissionEntity.java

@@ -5,22 +5,27 @@ import org.hswebframework.web.commons.entity.SimpleGenericEntity;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * TODO 完成注释
  *
  * @author zhouhao
  */
-public class SimplePermissionEntity extends SimpleGenericEntity<String> implements PermissionEntity<SimpleActionEntity> {
+public class SimplePermissionEntity extends SimpleGenericEntity<String> implements PermissionEntity {
     @NotBlank
     private String name;
 
     private String describe;
 
-    private byte status = 1;
+    private Byte status = 1;
 
     //可选事件
-    private List<SimpleActionEntity> actions;
+    private List<ActionEntity> actions;
+
+    private List<DataAccessEntity> dataAccess;
+
+    private List<FieldAccessEntity> fieldAccess;
 
     public String getName() {
         return this.name;
@@ -42,26 +47,46 @@ public class SimplePermissionEntity extends SimpleGenericEntity<String> implemen
         return status;
     }
 
-    public void setStatus(byte status) {
+    public void setStatus(Byte status) {
         this.status = status;
     }
 
     @Override
-    public List<SimpleActionEntity> getActions() {
+    public List<ActionEntity> getActions() {
         return actions;
     }
 
     @Override
-    public void setActions(List<SimpleActionEntity> actions) {
+    public void setActions(List<ActionEntity> actions) {
         this.actions = actions;
     }
 
+    @Override
+    public List<DataAccessEntity> getDataAccess() {
+        return this.dataAccess;
+    }
+
+    @Override
+    public List<FieldAccessEntity> getFieldAccess() {
+        return this.fieldAccess;
+    }
+
+    @Override
+    public void setDataAccess(List<DataAccessEntity> dataAccess) {
+        this.dataAccess = dataAccess;
+    }
+
+    @Override
+    public void setFieldAccess(List<FieldAccessEntity> fieldAccess) {
+        this.fieldAccess = fieldAccess;
+    }
+
     @Override
     public SimplePermissionEntity clone() {
         SimplePermissionEntity target = new SimplePermissionEntity();
         target.setId(getId());
         if (actions != null)
-            target.setActions(new ArrayList<>(getActions()));
+            target.setActions(getActions().stream().map(ActionEntity::clone).collect(Collectors.toList()));
         target.setDescribe(getDescribe());
         target.setStatus(getStatus());
         return target;

+ 31 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimplePermissionRoleEntity.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.entity.authorization;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * TODO 完成注释
@@ -15,6 +16,10 @@ public class SimplePermissionRoleEntity implements PermissionRoleEntity {
 
     private List<String> actions;
 
+    private List<DataAccessEntity> dataAccesses;
+
+    private List<FieldAccessEntity> fieldAccesses;
+
     @Override
     public String getRoleId() {
         return roleId;
@@ -45,13 +50,37 @@ public class SimplePermissionRoleEntity implements PermissionRoleEntity {
         this.actions = actions;
     }
 
+    @Override
+    public List<DataAccessEntity> getDataAccesses() {
+        return this.dataAccesses;
+    }
+
+    @Override
+    public List<FieldAccessEntity> getFieldAccesses() {
+        return this.fieldAccesses;
+    }
+
+    @Override
+    public void setDataAccesses(List<DataAccessEntity> dataAccesses) {
+        this.dataAccesses = dataAccesses;
+    }
+
+    @Override
+    public void setFieldAccesses(List<FieldAccessEntity> fieldAccesses) {
+        this.fieldAccesses = fieldAccesses;
+    }
+
     @Override
     public SimplePermissionRoleEntity clone() {
         SimplePermissionRoleEntity target = new SimplePermissionRoleEntity();
-        if (actions != null)
-            target.setActions(new ArrayList<>(getActions()));
         target.setPermissionId(getPermissionId());
         target.setRoleId(getRoleId());
+        if (actions != null)
+            target.setActions(new ArrayList<>(getActions()));
+        if (dataAccesses != null)
+            target.setDataAccesses(dataAccesses.stream().map(DataAccessEntity::clone).collect(Collectors.toList()));
+        if (fieldAccesses != null)
+            target.setFieldAccesses(fieldAccesses.stream().map(FieldAccessEntity::clone).collect(Collectors.toList()));
         return target;
     }
 }

+ 3 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleRoleEntity.java

@@ -12,7 +12,7 @@ public class SimpleRoleEntity extends SimpleGenericEntity<String> implements Rol
 
     private String describe;
 
-    private boolean enabled;
+    private Boolean enabled;
 
     public String getName() {
         return name;
@@ -31,12 +31,12 @@ public class SimpleRoleEntity extends SimpleGenericEntity<String> implements Rol
     }
 
     @Override
-    public boolean isEnabled() {
+    public Boolean isEnabled() {
         return enabled;
     }
 
     @Override
-    public void setEnabled(boolean enabled) {
+    public void setEnabled(Boolean enabled) {
         this.enabled = enabled;
     }
 

+ 33 - 18
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/SimpleUserEntity.java

@@ -2,8 +2,6 @@ package org.hswebframework.web.entity.authorization;
 
 import org.hswebframework.web.commons.entity.SimpleGenericEntity;
 
-import java.util.Date;
-
 /**
  * TODO 完成注释
  *
@@ -18,11 +16,13 @@ public class SimpleUserEntity extends SimpleGenericEntity<String> implements Use
 
     private String salt;
 
-    private Date createDate;
+    private Long createTime;
+
+    private String creatorId;
 
-    private Date lastLoginDate;
+    private Long lastLoginTime;
 
-    private boolean enabled;
+    private Boolean enabled;
 
     private String lastLoginIp;
 
@@ -62,31 +62,45 @@ public class SimpleUserEntity extends SimpleGenericEntity<String> implements Use
         this.salt = salt;
     }
 
-    public Date getCreateDate() {
-        return createDate;
+    @Override
+    public Long getCreateTime() {
+        return createTime;
     }
 
-    public void setCreateDate(Date createDate) {
-        this.createDate = createDate;
+    @Override
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    @Override
+    public String getCreatorId() {
+        return creatorId;
     }
 
-    public Date getLastLoginDate() {
-        return lastLoginDate;
+    @Override
+    public void setCreatorId(String creatorId) {
+        this.creatorId = creatorId;
     }
 
-    public void setLastLoginDate(Date lastLoginDate) {
-        this.lastLoginDate = lastLoginDate;
+    public void setLastLoginTime(Long lastLoginDate) {
+        this.lastLoginTime = lastLoginDate;
     }
 
     @Override
-    public boolean isEnabled() {
-        return enabled;
+    public Long getLastLoginTime() {
+        return lastLoginTime;
     }
 
-    public void setEnabled(boolean enabled) {
+    @Override
+    public void setEnabled(Boolean enabled) {
         this.enabled = enabled;
     }
 
+    @Override
+    public Boolean isEnabled() {
+        return enabled;
+    }
+
     public String getLastLoginIp() {
         return lastLoginIp;
     }
@@ -102,9 +116,10 @@ public class SimpleUserEntity extends SimpleGenericEntity<String> implements Use
         target.setName(getName());
         target.setUsername(getUsername());
         target.setPassword(getPassword());
-        target.setCreateDate(getCreateDate());
+        target.setCreateTime(getCreateTime());
+        target.setCreatorId(getCreatorId());
         target.setEnabled(isEnabled());
-        target.setLastLoginDate(getLastLoginDate());
+        target.setLastLoginTime(getLastLoginTime());
         target.setLastLoginIp(getLastLoginIp());
         return target;
     }

+ 14 - 4
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/UserEntity.java

@@ -19,6 +19,7 @@
 package org.hswebframework.web.entity.authorization;
 
 import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.commons.entity.RecordCreationEntity;
 
 import java.util.Date;
 
@@ -27,11 +28,16 @@ import java.util.Date;
  *
  * @author zhouhao
  */
-public interface UserEntity extends UserReadEntity, GenericEntity<String> {
+public interface UserEntity extends GenericEntity<String>, RecordCreationEntity {
+
     void setName(String name);
 
+    String getUsername();
+
     void setUsername(String username);
 
+    String getName();
+
     void setPassword(String password);
 
     void setSalt(String salt);
@@ -40,11 +46,15 @@ public interface UserEntity extends UserReadEntity, GenericEntity<String> {
 
     String getSalt();
 
-    void setCreateDate(Date createDate);
+    Long getLastLoginTime();
+
+    void setLastLoginTime(Long lastLoginTime);
+
+    Boolean isEnabled();
 
-    void setLastLoginDate(Date lastLoginDate);
+    void setEnabled(Boolean enabled);
 
-    void setEnabled(boolean enabled);
+    String getLastLoginIp();
 
     void setLastLoginIp(String lastLoginIp);
 

+ 0 - 27
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/UserReadEntity.java

@@ -1,27 +0,0 @@
-package org.hswebframework.web.entity.authorization;
-
-import org.hswebframework.web.commons.entity.Entity;
-
-import java.util.Date;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public interface UserReadEntity extends Entity {
-
-    String getId();
-
-    String getName();
-
-    String getUsername();
-
-    Date getCreateDate();
-
-    Date getLastLoginDate();
-
-    boolean isEnabled();
-
-    String getLastLoginIp();
-}

+ 0 - 17
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/WebPermissionEntity.java

@@ -1,17 +0,0 @@
-package org.hswebframework.web.entity.authorization;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public interface WebPermissionEntity<A extends ActionEntity> extends PermissionEntity<A> {
-    String getUri();
-
-    void setUri(String uri);
-
-    String getIcon();
-
-    void setIcon(String icon);
-
-}

+ 3 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-entity/src/main/java/org/hswebframework/web/entity/authorization/bind/SimpleBindRoleUserEntity.java

@@ -29,10 +29,11 @@ public class SimpleBindRoleUserEntity extends SimpleUserEntity implements BindRo
         SimpleBindRoleUserEntity target = new SimpleBindRoleUserEntity();
         target.setId(getId());
         target.setName(getName());
-        target.setCreateDate(getCreateDate());
+        target.setCreateTime(getCreateTime());
+        target.setCreatorId(getCreatorId());
         target.setEnabled(isEnabled());
         target.setLastLoginIp(getLastLoginIp());
-        target.setLastLoginDate(getLastLoginDate());
+        target.setLastLoginTime(getLastLoginTime());
         target.setSalt(getSalt());
         if (roles != null)
             target.setRoles(new ArrayList<>(getRoles()));

+ 13 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/DataAccessFactory.java

@@ -0,0 +1,13 @@
+package org.hswebframework.web.service.authorization;
+
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.entity.authorization.DataAccessEntity;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface DataAccessFactory {
+    DataAccess create(DataAccessEntity entity);
+}

+ 1 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/PermissionService.java

@@ -1,8 +1,6 @@
 package org.hswebframework.web.service.authorization;
 
-import org.hswebframework.web.entity.authorization.ActionEntity;
 import org.hswebframework.web.entity.authorization.PermissionEntity;
-import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.service.CrudService;
 
 /**
@@ -10,6 +8,6 @@ import org.hswebframework.web.service.CrudService;
  *
  * @author zhouhao
  */
-public interface PermissionService extends CrudService<PermissionEntity<ActionEntity>, String> {
+public interface PermissionService extends CrudService<PermissionEntity, String> {
 
 }

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-api/src/main/java/org/hswebframework/web/service/authorization/UserService.java

@@ -30,7 +30,7 @@ public interface UserService extends
 
     String encodePassword(String password, String salt);
 
-    void updateLoginInfo(String userId, String ip, Date loginTime);
+    void updateLoginInfo(String userId, String ip, Long loginTime);
 
     void updatePassword(String userId, String oldPassword, String newPassword);
 

+ 89 - 15
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorization.java

@@ -17,11 +17,11 @@
 
 package org.hswebframework.web.service.authorization.simple;
 
-import org.hswebframework.web.authorization.Authorization;
-import org.hswebframework.web.authorization.Permission;
-import org.hswebframework.web.authorization.Role;
-import org.hswebframework.web.authorization.User;
+import org.hswebframework.web.authorization.*;
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.authorization.access.FieldAccess;
 import org.hswebframework.web.entity.authorization.*;
+import org.hswebframework.web.service.authorization.DataAccessFactory;
 
 import java.io.Serializable;
 import java.util.*;
@@ -47,13 +47,31 @@ public class SimpleAuthorization implements Authorization {
 
     public SimpleAuthorization(UserEntity user,
                                List<RoleEntity> roleEntities,
-                               List<PermissionRoleEntity> permissionRoleEntities) {
+                               List<PermissionRoleEntity> permissionRoleEntities,
+                               DataAccessFactory dataAccessFactory) {
         this.user = new ReadOnlyUser(user.getId(), user.getUsername(), user.getName());
         this.roles = roleEntities.stream()
                 .map(roleEntity -> new ReadOnlyRole(roleEntity.getId(), roleEntity.getDescribe()))
                 .collect(Collectors.toList());
         this.permissions = permissionRoleEntities.stream()
-                .map(permissionRoleEntity -> new ReadOnlyPermission(permissionRoleEntity.getPermissionId(), permissionRoleEntity.getActions()))
+                .map(permissionRoleEntity -> {
+                    ReadOnlyPermission permission = new ReadOnlyPermission(permissionRoleEntity.getPermissionId(), permissionRoleEntity.getActions());
+                    if (null != dataAccessFactory && null != permissionRoleEntity.getDataAccesses()) {
+                        permission.setDataAccesses(permissionRoleEntity
+                                .getDataAccesses()
+                                .stream()
+                                .map(dataAccessFactory::create)
+                                .collect(Collectors.toSet()));
+                    }
+                    if (null != permissionRoleEntity.getFieldAccesses()) {
+                        permission.setFieldAccesses(permissionRoleEntity
+                                .getFieldAccesses()
+                                .stream()
+                                .map(SimpleFieldAccess::of)
+                                .collect(Collectors.toSet()));
+                    }
+                    return permission;
+                })
                 .collect(Collectors.toList());
     }
 
@@ -119,15 +137,17 @@ public class SimpleAuthorization implements Authorization {
     }
 
     public static class ReadOnlyPermission implements Permission {
-        private String       id;
-        private List<String> actions;
+        private String                 id;
+        private Set<String>            actions;
+        private Set<SimpleFieldAccess> fieldAccesses;
+        private Set<DataAccess>        dataAccesses;
 
         public ReadOnlyPermission() {
         }
 
-        public ReadOnlyPermission(String id, List<String> actions) {
+        public ReadOnlyPermission(String id, Collection<String> actions) {
             this.id = id;
-            this.actions = actions;
+            this.actions = new HashSet<>(actions);
         }
 
         @Override
@@ -141,14 +161,68 @@ public class SimpleAuthorization implements Authorization {
         }
 
         @Override
-        public List<String> getActions() {
-            if (actions == null) actions = Collections.emptyList();
-            return new ArrayList<>(actions);
+        public Set<String> getActions() {
+            if (actions == null) actions = Collections.emptySet();
+            return new HashSet<>(actions);
+        }
+
+        @Override
+        public Set<FieldAccess> getFieldAccesses() {
+            if (fieldAccesses == null) fieldAccesses = Collections.emptySet();
+            return new HashSet<>(fieldAccesses);
+        }
+
+        @Override
+        public Set<DataAccess> getDataAccesses() {
+            if (dataAccesses == null) dataAccesses = Collections.emptySet();
+            return new HashSet<>(dataAccesses);
         }
 
-        public void setActions(List<String> actions) {
+        public void setFieldAccesses(Set<SimpleFieldAccess> fieldAccesses) {
+            checkWritable(this.fieldAccesses);
+            this.fieldAccesses = fieldAccesses;
+        }
+
+        public void setDataAccesses(Set<DataAccess> dataAccesses) {
+            checkWritable(this.dataAccesses);
+            this.dataAccesses = dataAccesses;
+        }
+
+        public void setActions(Set<String> actions) {
             checkWritable(this.actions);
-            this.actions = new ArrayList<>(actions);
+            this.actions = new HashSet<>(actions);
+        }
+    }
+
+    public static class SimpleFieldAccess implements FieldAccess {
+        private String      field;
+        private Set<String> actions;
+
+        public static SimpleFieldAccess of(FieldAccessEntity entity) {
+            SimpleFieldAccess access = new SimpleFieldAccess();
+            access.setField(entity.getField());
+            access.setActions(entity.getActions().stream().map(ActionEntity::getAction).collect(Collectors.toSet()));
+            return access;
+        }
+
+        @Override
+        public String getField() {
+            return field;
+        }
+
+        @Override
+        public Set<String> getActions() {
+            return new HashSet<>(actions);
+        }
+
+        public void setField(String field) {
+            checkWritable(this.field);
+            this.field = field;
+        }
+
+        public void setActions(Set<String> actions) {
+            checkWritable(this.actions);
+            this.actions = actions;
         }
     }
 

+ 1 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimplePermissionService.java

@@ -1,7 +1,6 @@
 package org.hswebframework.web.service.authorization.simple;
 
 import org.hswebframework.web.dao.authorization.PermissionDao;
-import org.hswebframework.web.entity.authorization.ActionEntity;
 import org.hswebframework.web.entity.authorization.PermissionEntity;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.authorization.PermissionService;
@@ -14,7 +13,7 @@ import org.springframework.stereotype.Service;
  * @author zhouhao
  */
 @Service("permissionService")
-public class SimplePermissionService extends GenericEntityService<PermissionEntity<ActionEntity>, String>
+public class SimplePermissionService extends GenericEntityService<PermissionEntity, String>
         implements PermissionService {
     @Autowired
     private PermissionDao permissionDao;

+ 4 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleRoleService.java

@@ -64,8 +64,9 @@ public class SimpleRoleService extends AbstractService<RoleEntity, String>
 
     @Override
     public <T extends PermissionRoleEntity> String insert(BindPermissionRoleEntity<T> roleEntity) {
-        tryValidateProperty(!StringUtils.hasLength(roleEntity.getId()), RoleEntity.id, "id {not_be_null}");
-        tryValidateProperty(null != selectByPk(roleEntity.getId()), RoleEntity.id, "{role_exists}");
+        tryValidateProperty(StringUtils.hasLength(roleEntity.getId()), RoleEntity.id, "id {not_be_null}");
+        tryValidateProperty(null == selectByPk(roleEntity.getId()), RoleEntity.id, "{role_exists}");
+        roleEntity.setEnabled(true);
         tryValidate(roleEntity);
         roleDao.insert(roleEntity);
         syncPermissions(roleEntity.getId(), roleEntity.getPermissions());
@@ -89,7 +90,7 @@ public class SimpleRoleService extends AbstractService<RoleEntity, String>
 
     @Override
     public <T extends PermissionRoleEntity> boolean update(BindPermissionRoleEntity<T> roleEntity) {
-        tryValidateProperty(!StringUtils.hasLength(roleEntity.getId()), RoleEntity.id, "id {not_be_null}");
+        tryValidateProperty(StringUtils.hasLength(roleEntity.getId()), RoleEntity.id, "id {not_be_null}");
         tryValidateProperty(null == selectByPk(roleEntity.getId()), RoleEntity.id, "{role_not_exists}");
         tryValidate(roleEntity);
         DefaultDSLUpdateService.createUpdate(roleDao)

+ 11 - 7
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleUserService.java

@@ -10,6 +10,7 @@ import org.hswebframework.web.id.IDGenerator;
 import org.hswebframework.web.service.AbstractService;
 import org.hswebframework.web.service.DefaultDSLQueryService;
 import org.hswebframework.web.service.DefaultDSLUpdateService;
+import org.hswebframework.web.service.authorization.DataAccessFactory;
 import org.hswebframework.web.service.authorization.PasswordStrengthValidator;
 import org.hswebframework.web.service.authorization.UserService;
 import org.hswebframework.web.service.authorization.UsernameValidator;
@@ -55,19 +56,22 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
     @Autowired
     private RoleDao roleDao;
 
+    @Autowired(required = false)
+    private DataAccessFactory dataAccessFactory;
+
     @Override
     public String encodePassword(String password, String salt) {
         return DigestUtils.md5Hex(String.format("hsweb.%s.framework.%s", password, salt));
     }
 
     @Override
-    public void updateLoginInfo(String userId, String ip, Date loginTime) {
+    public void updateLoginInfo(String userId, String ip, Long loginTime) {
         Assert.notNull(userId, "userId:{not_be_null}");
         Assert.notNull(ip, "ip:{not_be_null}");
         Assert.notNull(loginTime, "loginTime:{not_be_null}");
         DefaultDSLUpdateService.createUpdate(getDao())
                 .set("lastLoginIp", ip)
-                .set("lastLoginDate", loginTime)
+                .set("lastLoginTime", loginTime)
                 .where(GenericEntity.id, userId)
                 .exec();
     }
@@ -94,7 +98,7 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
         tryValidateProperty(usernameValidator, "username", userEntity.getUsername());
         //密码强度验证
         tryValidateProperty(passwordStrengthValidator, "password", userEntity.getPassword());
-        userEntity.setCreateDate(new Date());
+        userEntity.setCreateTime(System.currentTimeMillis());
         userEntity.setId(IDGenerator.MD5.generate());
         userEntity.setSalt(IDGenerator.RANDOM.generate());
         userEntity.setEnabled(true);
@@ -194,14 +198,14 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
         //用户持有的角色
         List<UserRoleEntity> roleEntities = userRoleDao.selectByUserId(userId);
         if (ListUtils.isNullOrEmpty(roleEntities)) {
-            return new SimpleAuthorization(userEntity, new ArrayList<>(), new ArrayList<>());
+            return new SimpleAuthorization(userEntity, new ArrayList<>(), new ArrayList<>(), dataAccessFactory);
         }
         List<String> roleIdList = roleEntities.stream().map(UserRoleEntity::getRoleId).collect(Collectors.toList());
 
         List<RoleEntity> roleEntityList = DefaultDSLQueryService.createQuery(roleDao).where().in(GenericEntity.id, roleIdList).noPaging().list();
         //权限角色关联信息
         List<PermissionRoleEntity> permissionRoleEntities = permissionRoleDao.selectByRoleIdList(roleIdList);
-        return new SimpleAuthorization(userEntity, roleEntityList, permissionRoleEntities);
+        return new SimpleAuthorization(userEntity, roleEntityList, permissionRoleEntities, dataAccessFactory);
     }
 
     @Override
@@ -209,7 +213,7 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
         UserEntity userEntity = selectByPk(userId);
         assertNotNull(userEntity);
         //所有权限信息
-        List<PermissionEntity<ActionEntity>> permissionEntities = DefaultDSLQueryService
+        List<PermissionEntity> permissionEntities = DefaultDSLQueryService
                 .createQuery(permissionDao).noPaging().list();
         List<PermissionRoleEntity> permissionRoleEntities = permissionEntities
                 .stream().map(permission -> {
@@ -231,7 +235,7 @@ public class SimpleUserService extends AbstractService<UserEntity, String>
             admin.setName("admin");
             roleEntityList.add(admin);
         }
-        return new SimpleAuthorization(userEntity, roleEntityList, permissionRoleEntities);
+        return new SimpleAuthorization(userEntity, roleEntityList, permissionRoleEntities, dataAccessFactory);
     }
 
 

+ 22 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/AbstractDataAccess.java

@@ -0,0 +1,22 @@
+package org.hswebframework.web.service.authorization.simple.access;
+
+import org.hswebframework.web.authorization.access.DataAccess;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public abstract class AbstractDataAccess implements DataAccess {
+
+    private String action;
+
+    @Override
+    public String getAction() {
+        return action;
+    }
+
+    public void setAction(String action) {
+        this.action = action;
+    }
+}

+ 45 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleCustomDataAccess.java

@@ -0,0 +1,45 @@
+package org.hswebframework.web.service.authorization.simple.access;
+
+import org.hswebframework.web.authorization.access.CustomDataAccess;
+import org.hswebframework.web.authorization.access.DataAccessController;
+
+/**
+ * @author zhouhao
+ */
+public class SimpleCustomDataAccess extends AbstractDataAccess implements CustomDataAccess {
+
+    private String classOrBeanName;
+
+    private transient DataAccessController instance;
+
+    public SimpleCustomDataAccess() {
+    }
+
+    public SimpleCustomDataAccess(String classOrBeanName) {
+        this.classOrBeanName = classOrBeanName;
+    }
+
+    @Override
+    public DataAccessController getController() {
+        if (instance == null) {
+            synchronized (this) {
+                // TODO: 17-2-8  spring bean not support now!
+                if (instance == null)
+                    try {
+                        instance = (DataAccessController) Class.forName(classOrBeanName).newInstance();
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+            }
+        }
+        return instance;
+    }
+
+    public String getClassOrBeanName() {
+        return classOrBeanName;
+    }
+
+    public void setClassOrBeanName(String classOrBeanName) {
+        this.classOrBeanName = classOrBeanName;
+    }
+}

+ 41 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleDataAccessFactory.java

@@ -0,0 +1,41 @@
+package org.hswebframework.web.service.authorization.simple.access;
+
+import com.alibaba.fastjson.JSON;
+import org.hswebframework.web.authorization.access.DataAccess;
+import org.hswebframework.web.entity.authorization.DataAccessEntity;
+import org.hswebframework.web.service.authorization.DataAccessFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Component("simpleDataAccessFactory")
+public class SimpleDataAccessFactory implements DataAccessFactory {
+
+    @Override
+    public DataAccess create(DataAccessEntity entity) {
+        AbstractDataAccess dataAccess = null;
+        try {
+            switch (entity.getType()) {
+                case "custom":
+                case "CUSTOM":
+                    return dataAccess = new SimpleCustomDataAccess(entity.getConfig());
+                case "script":
+                case "SCRIPT":
+                    return dataAccess = JSON.parseObject(entity.getConfig(), SimpleScriptDataAccess.class);
+                case "own_created":
+                case "OWN_CREATED":
+                    return dataAccess = new SimpleOwnCreatedDataAccess();
+            }
+        } finally {
+            if (null != dataAccess) dataAccess.setAction(entity.getAction());
+        }
+        return createOtherType(entity);
+    }
+
+    protected DataAccess createOtherType(DataAccessEntity entity) {
+        return null;
+    }
+}

+ 11 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleOwnCreatedDataAccess.java

@@ -0,0 +1,11 @@
+package org.hswebframework.web.service.authorization.simple.access;
+
+import org.hswebframework.web.authorization.access.OwnCreatedDataAccess;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleOwnCreatedDataAccess extends AbstractDataAccess implements OwnCreatedDataAccess {
+}

+ 39 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/access/SimpleScriptDataAccess.java

@@ -0,0 +1,39 @@
+package org.hswebframework.web.service.authorization.simple.access;
+
+import org.hswebframework.web.authorization.access.ScriptDataAccess;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class SimpleScriptDataAccess extends AbstractDataAccess implements ScriptDataAccess {
+    private String script;
+
+    private String scriptLanguage;
+
+    public SimpleScriptDataAccess() {
+    }
+
+    public SimpleScriptDataAccess(String script, String scriptLanguage) {
+        this.script = script;
+        this.scriptLanguage = scriptLanguage;
+    }
+
+    @Override
+    public String getScriptLanguage() {
+        return scriptLanguage;
+    }
+
+    public void setScriptLanguage(String scriptLanguage) {
+        this.scriptLanguage = scriptLanguage;
+    }
+
+    public String getScript() {
+        return script;
+    }
+
+    public void setScript(String script) {
+        this.script = script;
+    }
+}

+ 7 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js

@@ -43,9 +43,10 @@ function install(context) {
         .addColumn().name("password").varchar(128).notNull().comment("密码").commit()
         .addColumn().name("salt").varchar(128).notNull().comment("密码盐").commit()
         .addColumn().name("enabled").number(1).notNull().comment("是否启用").commit()
-        .addColumn().name("create_date").datetime().notNull().comment("创建时间").commit()
         .addColumn().name("last_login_ip").varchar(128).comment("上一次登录的ip地址").commit()
-        .addColumn().name("last_login_date").datetime().comment("上一次登录时间").commit()
+        .addColumn().name("last_login_time").number(32).comment("上一次登录时间").commit()
+        .addColumn().name("creator_id").varchar(32).notNull().comment("创建者ID").commit()
+        .addColumn().name("create_time").number(32).notNull().comment("创建时间").commit()
         .comment("用户表").commit();
 
     database.createOrAlter("s_role")
@@ -61,18 +62,21 @@ function install(context) {
         .addColumn().name("describe").varchar(128).comment("说明").commit()
         .addColumn().name("status").number(4).notNull().comment("状态").commit()
         .addColumn().name("actions").clob().notNull().comment("可选操作(按钮)").commit()
+        .addColumn().name("data_access").clob().notNull().comment("数据级控制配置").commit()
+        .addColumn().name("field_access").clob().notNull().comment("字段级控制配置").commit()
         .comment("权限表").commit();
 
     database.createOrAlter("s_permission_role")
         .addColumn().name("role_id").varchar(32).notNull().comment("角色ID").commit()
         .addColumn().name("permission_id").varchar(32).notNull().comment("权限ID").commit()
         .addColumn().name("actions").clob().notNull().comment("可选操作").commit()
+        .addColumn().name("data_access").clob().notNull().comment("数据级控制配置").commit()
+        .addColumn().name("field_access").clob().notNull().comment("字段级控制配置").commit()
         .comment("权限与角色关联表").commit();
 
     database.createOrAlter("s_user_role")
         .addColumn().name("role_id").varchar(32).notNull().comment("角色ID").commit()
         .addColumn().name("user_id").varchar(32).notNull().comment("用户ID").commit()
-        .addColumn().name("actions").clob().notNull().comment("可选操作").commit()
         .comment("用户与角色关联表").commit();
 
 }

+ 16 - 6
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/PermissionTests.java

@@ -18,10 +18,11 @@
 package org.hswebframework.web.starter.authorization;
 
 import org.hsweb.ezorm.rdb.executor.SqlExecutor;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.access.DataAccess;
 import org.hswebframework.web.entity.authorization.ActionEntity;
+import org.hswebframework.web.entity.authorization.DataAccessEntity;
 import org.hswebframework.web.entity.authorization.PermissionEntity;
-import org.hswebframework.web.entity.authorization.SimpleActionEntity;
 import org.hswebframework.web.service.authorization.PermissionService;
 import org.hswebframework.web.tests.SimpleWebApplicationTests;
 import org.junit.After;
@@ -54,22 +55,31 @@ public class PermissionTests extends SimpleWebApplicationTests {
     public void testCRUD() throws Exception {
         Assert.assertTrue(sqlExecutor.tableExists("s_permission"));
 
-        PermissionEntity<ActionEntity> entity = permissionService.createEntity();
+        DataAccessEntity dataAccessEntity = new DataAccessEntity();
+        dataAccessEntity.setType(DataAccess.Type.OWN_CREATED.name());
+        dataAccessEntity.setAction(Permission.ACTION_QUERY);
+        dataAccessEntity.setDescribe("只能查询自己创建的数据");
+
+        PermissionEntity entity = permissionService.createEntity();
         entity.setStatus((byte) 1);
         entity.setName("测试");
-        entity.setActions(Arrays.asList(new SimpleActionEntity("C")));
+        entity.setActions(Arrays.asList(new ActionEntity("C")));
         entity.setId("test");
+        entity.setDataAccess(Arrays.asList(dataAccessEntity));
         String id = permissionService.insert(entity);
         Assert.assertNotNull(id);
 
-        PermissionEntity<ActionEntity> data = permissionService.selectByPk("test");
+        PermissionEntity data = permissionService.selectByPk("test");
         Assert.assertEquals(data.getId(), entity.getId());
         Assert.assertEquals(data.getName(), entity.getName());
         Assert.assertEquals(data.getStatus(), entity.getStatus());
+        Assert.assertNotNull(data.getDataAccess());
+        Assert.assertEquals(data.getDataAccess().get(0).getAction(),dataAccessEntity.getAction());
+        Assert.assertEquals(data.getDataAccess().get(0).getType(),dataAccessEntity.getType());
 
         data.setName("测试修改");
         permissionService.updateByPk(data);
-        PermissionEntity<ActionEntity> data2 = permissionService.selectByPk("test");
+        PermissionEntity data2 = permissionService.selectByPk("test");
         Assert.assertEquals(data2.getName(), data.getName());
 
         permissionService.deleteByPk("test");

+ 9 - 5
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/UserTests.java

@@ -77,6 +77,8 @@ public class UserTests extends SimpleWebApplicationTests {
         userEntity.setName("测试");
         userEntity.setUsername("test");
         userEntity.setPassword("password_1234");
+        userEntity.setCreateTimeNow();
+        userEntity.setCreatorId("admin");
         userService.insert(userEntity);
         return userEntity;
     }
@@ -98,6 +100,8 @@ public class UserTests extends SimpleWebApplicationTests {
         userEntity.setName("测试");
         userEntity.setUsername("test");
         userEntity.setPassword("123");
+        userEntity.setCreatorId("admin");
+        userEntity.setCreateTimeNow();
         try {
             userService.insert(userEntity);
             Assert.assertTrue(false);
@@ -116,17 +120,17 @@ public class UserTests extends SimpleWebApplicationTests {
 
         UserEntity entityInDb = userService.selectByUsername(userEntity.getUsername());
         Assert.assertEquals(entityInDb.isEnabled(), true);
-        Assert.assertNotNull(entityInDb.getCreateDate());
-        Assert.assertTrue(entityInDb.getLastLoginDate() == null);
+        Assert.assertNotNull(entityInDb.getCreateTime());
+        Assert.assertTrue(entityInDb.getLastLoginTime() == null);
         Assert.assertTrue(entityInDb.getLastLoginIp() == null);
 
         Assert.assertEquals(entityInDb.getPassword(), userService.encodePassword("password_1234", entityInDb.getSalt()));
 
-        userService.updateLoginInfo(id, "127.0.0.1", new Date());
+        userService.updateLoginInfo(id, "127.0.0.1", System.currentTimeMillis());
         entityInDb = userService.selectByUsername(userEntity.getUsername());
         Assert.assertEquals(entityInDb.isEnabled(), true);
-        Assert.assertNotNull(entityInDb.getCreateDate());
-        Assert.assertNotNull(entityInDb.getLastLoginDate());
+        Assert.assertNotNull(entityInDb.getCreateTime());
+        Assert.assertNotNull(entityInDb.getLastLoginTime());
         Assert.assertNotNull(entityInDb.getLastLoginIp());
         try {
             userService.updatePassword(id, "test", "test");

+ 1 - 1
hsweb-system/hsweb-system-config/hsweb-system-config-controller/src/main/java/org/hswebframework/web/controller/config/ConfigController.java

@@ -35,7 +35,7 @@ import org.springframework.web.bind.annotation.RestController;
  */
 @RestController
 @RequestMapping("${hsweb.web.mappings.config:config}")
-@Authorize(module = "config")
+@Authorize(permission = "config")
 @AccessLogger("配置管理")
 public class ConfigController implements GenericEntityController<ConfigEntity, String, QueryParamEntity> {
 

+ 2 - 2
hsweb-system/hsweb-system-config/hsweb-system-config-dao/hsweb-system-config-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/config/ConfigMapper.xml

@@ -8,8 +8,8 @@
         <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
         <result property="remark" column="remark" javaType="String" jdbcType="VARCHAR"/>
         <result property="content" column="content" javaType="java.util.List" jdbcType="CLOB"/>
-        <result property="createDate" column="create_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
-        <result property="updateDate" column="update_date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
+        <result property="createTime" column="create_time" javaType="Long" jdbcType="NUMERIC"/>
+        <result property="updateTime" column="update_time" javaType="Long" jdbcType="NUMERIC"/>
         <result property="classifiedId" column="classified_id" javaType="String" jdbcType="VARCHAR"/>
         <result property="creatorId" column="creator_id" javaType="String" jdbcType="VARCHAR"/>
     </resultMap>

+ 4 - 21
hsweb-system/hsweb-system-config/hsweb-system-config-entity/src/main/java/org/hswebframework/web/entity/config/ConfigEntity.java

@@ -20,6 +20,7 @@ package org.hswebframework.web.entity.config;
 
 
 import org.hswebframework.web.commons.entity.GenericEntity;
+import org.hswebframework.web.commons.entity.RecordCreationEntity;
 
 import java.util.Date;
 import java.util.List;
@@ -29,11 +30,7 @@ import java.util.List;
  *
  * @author zhouhao
  */
-public interface ConfigEntity extends GenericEntity<String> {
-
-    String getCreatorId();
-
-    void setCreatorId(String creatorId);
+public interface ConfigEntity extends GenericEntity<String>,RecordCreationEntity {
 
     /**
      * 获取 备注
@@ -63,33 +60,19 @@ public interface ConfigEntity extends GenericEntity<String> {
      */
     void setContent(List<ConfigContent> content);
 
-    /**
-     * 获取 创建日期
-     *
-     * @return {@link Date} 创建日期
-     */
-    Date getCreateDate();
-
-    /**
-     * 设置 创建日期
-     *
-     * @param createDate 创建日期
-     */
-    void setCreateDate(Date createDate);
-
     /**
      * 获取 最后一次修改日期
      *
      * @return java.util.Date 最后一次修改日期
      */
-    Date getUpdateDate();
+    Long getUpdateTime();
 
     /**
      * 设置 最后一次修改日期
      *
      * @param updateDate 最后一次修改日期
      */
-    void setUpdateDate(Date updateDate);
+    void setUpdateTime(Long updateDate);
 
     /**
      * 获取分类ID

+ 11 - 13
hsweb-system/hsweb-system-config/hsweb-system-config-entity/src/main/java/org/hswebframework/web/entity/config/SimpleConfigEntity.java

@@ -40,10 +40,10 @@ public class SimpleConfigEntity extends SimpleGenericEntity<String> implements C
 
     //创建日期
     @NotNull
-    private java.util.Date createDate;
+    private Long createTime;
 
     //最后一次修改日期
-    private java.util.Date updateDate;
+    private Long updateTime;
 
     //配置分类ID
     private String classifiedId;
@@ -107,23 +107,21 @@ public class SimpleConfigEntity extends SimpleGenericEntity<String> implements C
     }
 
     @Override
-    public Date getCreateDate() {
-        return createDate;
+    public Long getCreateTime() {
+        return createTime;
     }
 
-    @Override
-    public void setCreateDate(Date createDate) {
-        this.createDate = createDate;
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
     }
 
     @Override
-    public Date getUpdateDate() {
-        return updateDate;
+    public Long getUpdateTime() {
+        return updateTime;
     }
 
-    @Override
-    public void setUpdateDate(Date updateDate) {
-        this.updateDate = updateDate;
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
     }
 
     @Override
@@ -141,7 +139,7 @@ public class SimpleConfigEntity extends SimpleGenericEntity<String> implements C
         SimpleConfigEntity cloned = new SimpleConfigEntity();
         cloned.setId(getId());
         cloned.setCreatorId(getCreatorId());
-        cloned.setCreateDate(getCreateDate());
+        this.setCreateTime(getCreateTime());
         cloned.content = getContent().stream().map(ConfigContent::clone).collect(Collectors.toList());
         return cloned;
     }

+ 1 - 2
hsweb-system/hsweb-system-config/hsweb-system-config-service/hsweb-system-config-service-simple/src/main/java/org/hswebframework/web/service/config/simple/SimpleConfigService.java

@@ -18,9 +18,8 @@
 
 package org.hswebframework.web.service.config.simple;
 
-import org.hswebframework.web.entity.config.ConfigEntity;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.dao.config.ConfigDao;
+import org.hswebframework.web.entity.config.ConfigEntity;
 import org.hswebframework.web.service.GenericEntityService;
 import org.hswebframework.web.service.config.ConfigService;
 import org.springframework.beans.factory.annotation.Autowired;

+ 3 - 2
hsweb-system/hsweb-system-config/hsweb-system-config-starter/src/main/resources/hsweb-starter.js

@@ -41,8 +41,9 @@ function install(context) {
         .addColumn().name("u_id").varchar(32).notNull().primaryKey().comment("uid").commit()
         .addColumn().name("content").clob().notNull().comment("配置内容").commit()
         .addColumn().name("remark").varchar(512).comment("备注").commit()
-        .addColumn().name("create_date").datetime().notNull().comment("创建日期").commit()
-        .addColumn().name("update_date").datetime().comment("修改日期").commit()
+        .addColumn().name("creator_id").varchar(32).notNull().comment("创建人").commit()
+        .addColumn().name("create_time").number(32).notNull().comment("创建日期").commit()
+        .addColumn().name("update_time").number(32).comment("修改日期").commit()
         .addColumn().name("classified_id").varchar(32).comment("分类id").commit()
         .addColumn().name("creator_id").varchar(32).comment("创建者ID").commit()
         .comment("系统配置文件表").commit()

+ 2 - 2
hsweb-system/hsweb-system-config/hsweb-system-config-starter/src/test/java/org/hswebframework/web/starter/config/ConfigTests.java

@@ -43,7 +43,7 @@ public class ConfigTests extends SimpleWebApplicationTests {
         Assert.assertEquals(configBean.getClass(), SimpleConfigEntity.class);
         configBean.setId(IDGenerator.RANDOM.generate());
         configBean.addContent("test", 1, "测试");
-        configBean.setCreateDate(new Date());
+        configBean.setCreateTime(System.currentTimeMillis());
         configBean.setCreatorId("test");
         String jsonStr = JSON.toJSONString(configBean);
 
@@ -82,7 +82,7 @@ public class ConfigTests extends SimpleWebApplicationTests {
         Assert.assertEquals(configBean.getClass(), SimpleConfigEntity.class);
         configBean.setId(IDGenerator.RANDOM.generate());
         configBean.addContent("test", 1, "测试");
-        configBean.setCreateDate(new Date());
+        configBean.setCreateTime(System.currentTimeMillis());
         configBean.setCreatorId("test");
         //test insert
         configService.insert(configBean);

+ 1 - 1
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-dao/hsweb-system-explorer-dao-api/src/main/java/org/hswebframework/web/dao/explorer/MenuDao.java

@@ -26,5 +26,5 @@ import org.hswebframework.web.entity.explorer.MenuEntity;
  *
  * @author zhouhao
  */
-public interface MenuDao extends CrudDao<MenuEntity<MenuEntity, ActionEntity>, String> {
+public interface MenuDao extends CrudDao<MenuEntity<MenuEntity>, String> {
 }

+ 4 - 4
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-entity/src/main/java/org/hswebframework/web/entity/explorer/MenuEntity.java

@@ -28,7 +28,7 @@ import java.util.Map;
  *
  * @author zhouhao
  */
-public interface MenuEntity<C extends MenuEntity, A extends ActionEntity>
+public interface MenuEntity<C extends MenuEntity>
         extends TreeSortSupportEntity<String> {
     String getName();
 
@@ -66,9 +66,9 @@ public interface MenuEntity<C extends MenuEntity, A extends ActionEntity>
 
     void setEnabled(boolean enabled);
 
-    List<A> getActions();
+    List<ActionEntity> getActions();
 
-    void setActions(List<A> actions);
+    void setActions(List<ActionEntity> actions);
 
     void setChildren(List<C> children);
 
@@ -76,5 +76,5 @@ public interface MenuEntity<C extends MenuEntity, A extends ActionEntity>
     @SuppressWarnings("unchecked")
     List<C> getChildren();
 
-    MenuEntity<C, A> clone();
+    MenuEntity<C> clone();
 }

+ 6 - 6
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-entity/src/main/java/org/hswebframework/web/entity/explorer/SimpleMenuEntity.java

@@ -19,7 +19,7 @@ package org.hswebframework.web.entity.explorer;
 
 import org.hswebframework.web.commons.entity.CloneableEntity;
 import org.hswebframework.web.commons.entity.SimpleTreeSortSupportEntity;
-import org.hswebframework.web.entity.authorization.SimpleActionEntity;
+import org.hswebframework.web.entity.authorization.ActionEntity;
 
 import java.util.List;
 import java.util.Map;
@@ -31,7 +31,7 @@ import java.util.stream.Collectors;
  * @author zhouhao
  */
 public class SimpleMenuEntity extends SimpleTreeSortSupportEntity<String>
-        implements MenuEntity<SimpleMenuEntity, SimpleActionEntity> {
+        implements MenuEntity<SimpleMenuEntity> {
 
     //菜单名称
     private String name;
@@ -64,13 +64,13 @@ public class SimpleMenuEntity extends SimpleTreeSortSupportEntity<String>
     private List<SimpleMenuEntity> children;
 
     //可选操作(按钮)
-    private List<SimpleActionEntity> actions;
+    private List<ActionEntity> actions;
 
-    public List<SimpleActionEntity> getActions() {
+    public List<ActionEntity> getActions() {
         return actions;
     }
 
-    public void setActions(List<SimpleActionEntity> actions) {
+    public void setActions(List<ActionEntity> actions) {
         this.actions = actions;
     }
 
@@ -185,7 +185,7 @@ public class SimpleMenuEntity extends SimpleTreeSortSupportEntity<String>
                             })));
         }
         if (null != getActions()) {
-            target.setActions(getActions().stream().map(SimpleActionEntity::clone).collect(Collectors.toList()));
+            target.setActions(getActions().stream().map(ActionEntity::clone).collect(Collectors.toList()));
         }
         if (null != getChildren()) {
             target.setChildren(getChildren().stream().map(SimpleMenuEntity::clone).collect(Collectors.toList()));

+ 3 - 4
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-service/hsweb-system-explorer-service-api/src/main/java/org/hswebframework/web/service/explorer/simple/MenuService.java

@@ -17,7 +17,6 @@
 
 package org.hswebframework.web.service.explorer.simple;
 
-import org.hswebframework.web.entity.authorization.ActionEntity;
 import org.hswebframework.web.entity.explorer.MenuEntity;
 import org.hswebframework.web.service.CrudService;
 
@@ -29,9 +28,9 @@ import java.util.List;
  * @author zhouhao
  */
 public interface MenuService
-        extends CrudService<MenuEntity<MenuEntity, ActionEntity>, String> {
-    MenuEntity<MenuEntity, ActionEntity> getByPermissionId(String permissionId);
+        extends CrudService<MenuEntity<MenuEntity>, String> {
+    MenuEntity<MenuEntity> getByPermissionId(String permissionId);
 
-    List<MenuEntity<MenuEntity, ActionEntity>> getByPermissionId(List<String> permissionId);
+    List<MenuEntity<MenuEntity>> getByPermissionId(List<String> permissionId);
 
 }

+ 3 - 3
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-service/hsweb-system-explorer-service-simple/src/main/java/org/hswebframework/web/service/explorer/simple/SimpleMenuService.java

@@ -34,7 +34,7 @@ import java.util.List;
  */
 @Service("menuService")
 public class SimpleMenuService
-        extends AbstractTreeSortService<MenuEntity<MenuEntity, ActionEntity>, String>
+        extends AbstractTreeSortService<MenuEntity<MenuEntity>, String>
         implements MenuService {
 
     //dao api
@@ -56,12 +56,12 @@ public class SimpleMenuService
     }
 
     @Override
-    public List<MenuEntity<MenuEntity, ActionEntity>> getByPermissionId(List<String> permissionId) {
+    public List<MenuEntity<MenuEntity>> getByPermissionId(List<String> permissionId) {
         return createQuery().noPaging().where().in("permissionId", permissionId).list();
     }
 
     @Override
-    public MenuEntity<MenuEntity, ActionEntity> getByPermissionId(String permissionId) {
+    public MenuEntity<MenuEntity> getByPermissionId(String permissionId) {
         return createQuery().noPaging().where().is("permissionId", permissionId).single();
     }
 }

+ 6 - 7
hsweb-system/hsweb-system-explorer/hsweb-system-explorer-starter/src/test/java/org/hswebframework/web/starter/explorer/MenuTests.java

@@ -19,7 +19,6 @@ package org.hswebframework.web.starter.explorer;
 
 import com.alibaba.fastjson.JSON;
 import org.hswebframework.web.entity.authorization.ActionEntity;
-import org.hswebframework.web.entity.authorization.SimpleActionEntity;
 import org.hswebframework.web.entity.explorer.MenuEntity;
 import org.hswebframework.web.service.explorer.simple.MenuService;
 import org.hswebframework.web.tests.SimpleWebApplicationTests;
@@ -48,19 +47,19 @@ public class MenuTests extends SimpleWebApplicationTests {
         sqlExecutor.delete("delete from s_menu");
     }
 
-    public MenuEntity<MenuEntity, ActionEntity> createMenu(String name, String... actions) {
-        MenuEntity<MenuEntity, ActionEntity> menuEntity = menuService.createEntity();
+    public MenuEntity<MenuEntity> createMenu(String name, String... actions) {
+        MenuEntity<MenuEntity> menuEntity = menuService.createEntity();
         menuEntity.setName(name);
-        menuEntity.setActions(SimpleActionEntity.create(actions));
+        menuEntity.setActions(ActionEntity.create(actions));
         return menuEntity;
     }
 
     @Test
     public void testCrud() throws Exception {
-        MenuEntity<MenuEntity, ActionEntity> menuEntity = createMenu("测试1", "C", "R");
+        MenuEntity<MenuEntity> menuEntity = createMenu("测试1", "C", "R");
         menuEntity.setSortIndex(1);
-        MenuEntity<MenuEntity, ActionEntity> child1 = createMenu("测试2", "C", "R");
-        MenuEntity<MenuEntity, ActionEntity> child3 = createMenu("测试2", "C", "R");
+        MenuEntity<MenuEntity> child1 = createMenu("测试2", "C", "R");
+        MenuEntity<MenuEntity> child3 = createMenu("测试2", "C", "R");
         menuEntity.setChildren(Arrays.asList(child1, child3));
 
         String id = menuService.insert(menuEntity);