From cedc43b654c1256c460a2277335ce0f6544c154b Mon Sep 17 00:00:00 2001 From: FangfangZhao Date: Wed, 31 Oct 2018 00:53:54 +0800 Subject: [PATCH] service obs / bizz view --- .../bizz/privileges/EntityQueryFilter.java | 6 +- .../bizz/privileges/SecurityManager.java | 21 ++++- .../server/helper/cache/CacheTemplate.java | 2 +- .../helper/cache/RecordOwningCache.java | 12 +++ .../rebuild/server/service/AwareContext.java | 86 +++++++++++++++++ .../rebuild/server/service/AwareObserver.java | 93 +++++++++++++++++++ .../rebuild/server/service/BaseService.java | 18 +++- .../service/base/AuditLoggingObserver.java | 35 +++++++ .../service/base/GeneralEntityService.java | 5 + src/main/webapp/admin/bizuser/dept-view.jsp | 7 +- src/main/webapp/admin/bizuser/user-view.jsp | 7 +- 11 files changed, 279 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/rebuild/server/service/AwareContext.java create mode 100644 src/main/java/com/rebuild/server/service/AwareObserver.java create mode 100644 src/main/java/com/rebuild/server/service/base/AuditLoggingObserver.java diff --git a/src/main/java/com/rebuild/server/bizz/privileges/EntityQueryFilter.java b/src/main/java/com/rebuild/server/bizz/privileges/EntityQueryFilter.java index 8b8384655..8f4e94649 100644 --- a/src/main/java/com/rebuild/server/bizz/privileges/EntityQueryFilter.java +++ b/src/main/java/com/rebuild/server/bizz/privileges/EntityQueryFilter.java @@ -90,7 +90,11 @@ public class EntityQueryFilter implements Filter, QueryFilter { @Override public String evaluate(Entity entity) { if (!EntityHelper.hasPrivilegesField(entity)) { - return DENIED.evaluate(null); + if (SecurityManager.isBizz(entity.getEntityCode())) { + return ALLOWED.evaluate(null); + } else { + return DENIED.evaluate(null); + } } Privileges p = user.getOwningRole().getPrivileges(entity.getEntityCode()); diff --git a/src/main/java/com/rebuild/server/bizz/privileges/SecurityManager.java b/src/main/java/com/rebuild/server/bizz/privileges/SecurityManager.java index 66b7ddcc3..a66ce3642 100644 --- a/src/main/java/com/rebuild/server/bizz/privileges/SecurityManager.java +++ b/src/main/java/com/rebuild/server/bizz/privileges/SecurityManager.java @@ -21,6 +21,7 @@ package com.rebuild.server.bizz.privileges; import com.rebuild.server.bizz.RoleService; import com.rebuild.server.bizz.UserService; import com.rebuild.server.helper.cache.RecordOwningCache; +import com.rebuild.server.metadata.EntityHelper; import cn.devezhao.bizz.privileges.DepthEntry; import cn.devezhao.bizz.privileges.Permission; @@ -220,6 +221,10 @@ public class SecurityManager { return true; } + if (action == BizzPermission.READ && isBizz(entity)) { + return true; + } + Privileges priv = role.getPrivileges(entity); return priv.allowed(action); } @@ -245,7 +250,11 @@ public class SecurityManager { return true; } - final int entity = target.getEntityCode(); + int entity = target.getEntityCode(); + + if (action == BizzPermission.READ && isBizz(entity)) { + return true; + } Privileges priv = role.getPrivileges(entity); boolean allowed = priv.allowed(action); @@ -335,4 +344,14 @@ public class SecurityManager { } return new EntityQueryFilter(theUser, action); } + + /** + * TODO 用户/部门全局可读 + * + * @param entity + * @return + */ + public static boolean isBizz(int entity) { + return entity == EntityHelper.User || entity == EntityHelper.Department; + } } diff --git a/src/main/java/com/rebuild/server/helper/cache/CacheTemplate.java b/src/main/java/com/rebuild/server/helper/cache/CacheTemplate.java index a5abeb481..1fdcc2547 100644 --- a/src/main/java/com/rebuild/server/helper/cache/CacheTemplate.java +++ b/src/main/java/com/rebuild/server/helper/cache/CacheTemplate.java @@ -45,7 +45,7 @@ public abstract class CacheTemplate { getCache().put(unityKey(key), value); } - public void evict(String key, V value) { + public void evict(String key) { getCache().evict(unityKey(key)); } diff --git a/src/main/java/com/rebuild/server/helper/cache/RecordOwningCache.java b/src/main/java/com/rebuild/server/helper/cache/RecordOwningCache.java index 6232d4cf2..2d5490ddc 100644 --- a/src/main/java/com/rebuild/server/helper/cache/RecordOwningCache.java +++ b/src/main/java/com/rebuild/server/helper/cache/RecordOwningCache.java @@ -18,6 +18,8 @@ along with this program. If not, see . package com.rebuild.server.helper.cache; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.cache.CacheManager; import com.rebuild.server.metadata.EntityHelper; @@ -35,6 +37,8 @@ import cn.devezhao.persist4j.engine.ID; * @since 10/12/2018 */ public class RecordOwningCache extends CacheTemplate { + + private static final Log LOG = LogFactory.getLog(RecordOwningCache.class); final private PersistManagerFactory aPMFactory; @@ -64,6 +68,7 @@ public class RecordOwningCache extends CacheTemplate { sql = String.format(sql, EntityHelper.owningUser, entity.getName(), entity.getPrimaryField().getName(), record.toLiteral()); Object[] own = aPMFactory.createQuery(sql).unique(); if (own == null) { + LOG.warn("No record found : " + record); return null; } @@ -72,6 +77,13 @@ public class RecordOwningCache extends CacheTemplate { return ownUser; } + /** + * @param record + */ + public void cleanOwningUser(ID record) { + evict(record.toLiteral()); + } + @Override protected String unityKey(Object key) { return "OU__" + super.unityKey(key); diff --git a/src/main/java/com/rebuild/server/service/AwareContext.java b/src/main/java/com/rebuild/server/service/AwareContext.java new file mode 100644 index 000000000..593de7a30 --- /dev/null +++ b/src/main/java/com/rebuild/server/service/AwareContext.java @@ -0,0 +1,86 @@ +/* +rebuild - Building your system freely. +Copyright (C) 2018 devezhao + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package com.rebuild.server.service; + +import cn.devezhao.bizz.privileges.Permission; +import cn.devezhao.persist4j.Record; +import cn.devezhao.persist4j.engine.ID; + +/** + * @author devezhao + * @since 10/31/2018 + */ +public class AwareContext { + + // 操作人 + private ID editor; + // 动作 + private Permission action; + + // 记录 ID + private ID recordId; + // 记录(与记录 ID 两者二选一) + private Record record; + + private AwareContext(ID editor, Permission action, ID recordId) { + super(); + this.editor = editor; + this.action = action; + this.recordId = recordId; + } + + private AwareContext(ID editor, Permission action, Record record) { + super(); + this.editor = editor; + this.action = action; + this.record = record; + } + + public ID getEditor() { + return editor; + } + + public Permission getAction() { + return action; + } + + public ID getRecordId() { + return recordId; + } + + public Record getRecord() { + return record; + } + + @Override + public String toString() { + String astr = "{ Editor: %s, Action: %s, Record: %s }"; + return String.format(astr, getEditor(), getAction().getName(), getRecordId() != null ? getRecordId() : getRecord().getPrimary()); + } + + // -- + + public static AwareContext valueOf(ID editor, Permission action, ID recordId) { + return new AwareContext(editor, action, recordId); + } + + public static AwareContext valueOf(ID editor, Permission action, Record record) { + return new AwareContext(editor, action, record); + } +} diff --git a/src/main/java/com/rebuild/server/service/AwareObserver.java b/src/main/java/com/rebuild/server/service/AwareObserver.java new file mode 100644 index 000000000..064d4fb57 --- /dev/null +++ b/src/main/java/com/rebuild/server/service/AwareObserver.java @@ -0,0 +1,93 @@ +/* +rebuild - Building your system freely. +Copyright (C) 2018 devezhao + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package com.rebuild.server.service; + +import java.util.Observable; +import java.util.Observer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import cn.devezhao.bizz.privileges.impl.BizzPermission; +import cn.devezhao.commons.ThreadPool; + +/** + * + * @author devezhao + * @since 10/31/2018 + */ +public abstract class AwareObserver implements Observer { + + protected static final Log LOG = LogFactory.getLog(AwareObserver.class); + + @Override + public void update(final Observable o, final Object arg) { + final AwareContext ctx = (AwareContext) arg; + if (isAsync()) { + ThreadPool.exec(new Runnable() { + @Override + public void run() { + try { + update(ctx); + } catch (Exception ex) { + LOG.error("AwareContext : " + ctx, ex); + } + } + }); + } else { + update(ctx); + } + } + + private void update(AwareContext ctx) { + if (ctx.getAction() == BizzPermission.CREATE) { + notifyCreate(ctx); + } else if (ctx.getAction() == BizzPermission.UPDATE) { + notifyUpdate(ctx); + } else if (ctx.getAction() == BizzPermission.DELETE) { + notifyDelete(ctx); + } else if (ctx.getAction() == BizzPermission.ASSIGN) { + notifyAssign(ctx); + } else if (ctx.getAction() == BizzPermission.SHARE) { + notifySahre(ctx); + } + } + + /** + * 是否异步 + * + * @return + */ + abstract protected boolean isAsync(); + + public void notifyCreate(final AwareContext context) { + } + + public void notifyUpdate(final AwareContext context) { + } + + public void notifyDelete(final AwareContext context) { + } + + public void notifyAssign(final AwareContext context) { + } + + public void notifySahre(final AwareContext context) { + } +} diff --git a/src/main/java/com/rebuild/server/service/BaseService.java b/src/main/java/com/rebuild/server/service/BaseService.java index 462c7dcc9..8bb16cf06 100644 --- a/src/main/java/com/rebuild/server/service/BaseService.java +++ b/src/main/java/com/rebuild/server/service/BaseService.java @@ -18,6 +18,11 @@ along with this program. If not, see . package com.rebuild.server.service; +import java.util.Observable; + +import com.rebuild.server.Application; + +import cn.devezhao.bizz.privileges.impl.BizzPermission; import cn.devezhao.persist4j.PersistManagerFactory; import cn.devezhao.persist4j.Record; import cn.devezhao.persist4j.engine.ID; @@ -28,7 +33,7 @@ import cn.devezhao.persist4j.engine.ID; * @author zhaofang123@gmail.com * @since 05/21/2017 */ -public abstract class BaseService { +public abstract class BaseService extends Observable { final protected PersistManagerFactory aPMFactory; @@ -42,7 +47,9 @@ public abstract class BaseService { * @return */ public Record create(Record record) { - return aPMFactory.createPersistManager().save(record); + record = aPMFactory.createPersistManager().save(record); + notifyObservers(AwareContext.valueOf(record.getEditor(), BizzPermission.CREATE, record)); + return record; } /** @@ -50,7 +57,9 @@ public abstract class BaseService { * @return */ public Record update(Record record) { - return aPMFactory.createPersistManager().update(record); + record = aPMFactory.createPersistManager().update(record); + notifyObservers(AwareContext.valueOf(record.getEditor(), BizzPermission.UPDATE, record)); + return record; } /** @@ -63,10 +72,11 @@ public abstract class BaseService { /** * @param recordId - * @return 删除记录数量(包括关联的记录) + * @return 删除记录数量。包括关联的记录,自定义实体都选择了 remove-link 级联模式,因此基本不会自动关联删除 */ public int delete(ID recordId) { int affected = aPMFactory.createPersistManager().delete(recordId); + notifyObservers(AwareContext.valueOf(Application.currentCallerUser(), BizzPermission.DELETE, recordId)); return affected; } } diff --git a/src/main/java/com/rebuild/server/service/base/AuditLoggingObserver.java b/src/main/java/com/rebuild/server/service/base/AuditLoggingObserver.java new file mode 100644 index 000000000..7cb6d05d9 --- /dev/null +++ b/src/main/java/com/rebuild/server/service/base/AuditLoggingObserver.java @@ -0,0 +1,35 @@ +/* +rebuild - Building your system freely. +Copyright (C) 2018 devezhao + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +package com.rebuild.server.service.base; + +import com.rebuild.server.service.AwareObserver; + +/** + * TODO 记录审计日志 + * + * @author devezhao + * @since 10/31/2018 + */ +public class AuditLoggingObserver extends AwareObserver { + + @Override + protected boolean isAsync() { + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/rebuild/server/service/base/GeneralEntityService.java b/src/main/java/com/rebuild/server/service/base/GeneralEntityService.java index 07a83c859..4cbef0b63 100644 --- a/src/main/java/com/rebuild/server/service/base/GeneralEntityService.java +++ b/src/main/java/com/rebuild/server/service/base/GeneralEntityService.java @@ -33,6 +33,7 @@ import com.rebuild.server.bizz.privileges.User; import com.rebuild.server.helper.BulkTaskExecutor; import com.rebuild.server.metadata.EntityHelper; import com.rebuild.server.metadata.MetadataHelper; +import com.rebuild.server.service.AwareContext; import com.rebuild.server.service.BaseService; import cn.devezhao.bizz.privileges.Permission; @@ -172,6 +173,8 @@ public class GeneralEntityService extends BaseService { affected += assign(id, to, null); } } + + notifyObservers(AwareContext.valueOf(Application.currentCallerUser(), BizzPermission.ASSIGN, record)); return affected; } @@ -215,6 +218,8 @@ public class GeneralEntityService extends BaseService { affected += share(id, to, null); } } + + notifyObservers(AwareContext.valueOf(Application.currentCallerUser(), BizzPermission.SHARE, record)); return affected; } diff --git a/src/main/webapp/admin/bizuser/dept-view.jsp b/src/main/webapp/admin/bizuser/dept-view.jsp index fb42f3ec9..73ceb6cb9 100644 --- a/src/main/webapp/admin/bizuser/dept-view.jsp +++ b/src/main/webapp/admin/bizuser/dept-view.jsp @@ -24,7 +24,7 @@
@@ -37,9 +37,10 @@