关联操作过滤无权限实体

This commit is contained in:
devezhao 2020-10-22 20:46:24 +08:00
parent fbee726293
commit 035df48aa2
8 changed files with 70 additions and 23 deletions

View file

@ -10,7 +10,7 @@
</parent> </parent>
<groupId>com.rebuild</groupId> <groupId>com.rebuild</groupId>
<artifactId>rebuild</artifactId> <artifactId>rebuild</artifactId>
<version>2.0.0</version> <version>2.1.0-dev</version>
<name>rebuild</name> <name>rebuild</name>
<description>RB V2 use SpringBoot</description> <description>RB V2 use SpringBoot</description>
<!-- UNCOMMENT USE TOMCAT --> <!-- UNCOMMENT USE TOMCAT -->

View file

@ -65,7 +65,7 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
/** /**
* Rebuild Version * Rebuild Version
*/ */
public static final String VER = "2.0.0"; public static final String VER = "2.1.0-dev";
/** /**
* Rebuild Build * Rebuild Build
*/ */

View file

@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.metadata; package com.rebuild.core.metadata;
import cn.devezhao.bizz.privileges.impl.BizzPermission;
import cn.devezhao.persist4j.Entity; import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field; import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.dialect.FieldType; import cn.devezhao.persist4j.dialect.FieldType;
@ -17,7 +18,10 @@ import com.rebuild.core.metadata.impl.DisplayType;
import com.rebuild.core.metadata.impl.EasyMeta; import com.rebuild.core.metadata.impl.EasyMeta;
import java.text.Collator; import java.text.Collator;
import java.util.*; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
/** /**
* 元数据辅助类注意此类返回的数据会过滤和排序 * 元数据辅助类注意此类返回的数据会过滤和排序
@ -39,7 +43,7 @@ public class MetadataSorter {
} }
/** /**
* 用户权限内可用实体 * 用户权限内*可读*实体
* *
* @param user * @param user
* @param usesBizz 是否包括内建 BIZZ 实体 * @param usesBizz 是否包括内建 BIZZ 实体
@ -57,7 +61,7 @@ public class MetadataSorter {
if (user == null || !MetadataHelper.hasPrivilegesField(e)) { if (user == null || !MetadataHelper.hasPrivilegesField(e)) {
entities.add(e); entities.add(e);
} else if (Application.getPrivilegesManager().allowRead(user, e.getEntityCode())) { } else if (Application.getPrivilegesManager().allow(user, e.getEntityCode(), BizzPermission.READ)) {
entities.add(e); entities.add(e);
} }
} }

View file

@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.core.privileges; package com.rebuild.core.privileges;
import cn.devezhao.bizz.BizzException;
import cn.devezhao.bizz.privileges.DepthEntry; import cn.devezhao.bizz.privileges.DepthEntry;
import cn.devezhao.bizz.privileges.Permission; import cn.devezhao.bizz.privileges.Permission;
import cn.devezhao.bizz.privileges.Privileges; import cn.devezhao.bizz.privileges.Privileges;
@ -471,4 +472,30 @@ public class PrivilegesManager {
} }
return new RoleBaseQueryFilter(theUser, action); return new RoleBaseQueryFilter(theUser, action);
} }
// --
// 权限动作集合
private static final Permission[] RB_PERMISSIONS = new Permission[] {
BizzPermission.CREATE,
BizzPermission.DELETE,
BizzPermission.UPDATE,
BizzPermission.READ,
BizzPermission.ASSIGN,
BizzPermission.SHARE,
EntityService.UNSHARE
};
/**
* @param name
* @return
*/
public static Permission parse(String name) {
for (Permission p : RB_PERMISSIONS) {
if (p.getName().equalsIgnoreCase(name)) {
return p;
}
}
throw new BizzException("Unknown Permission : " + name);
}
} }

View file

@ -7,16 +7,19 @@ See LICENSE and COMMERCIAL in the project root for license information.
package com.rebuild.web.commons; package com.rebuild.web.commons;
import cn.devezhao.bizz.privileges.Permission;
import cn.devezhao.persist4j.Entity; import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Field; import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.dialect.FieldType; import cn.devezhao.persist4j.dialect.FieldType;
import cn.devezhao.persist4j.engine.ID; import cn.devezhao.persist4j.engine.ID;
import cn.devezhao.persist4j.metadata.BaseMeta; import cn.devezhao.persist4j.metadata.BaseMeta;
import com.rebuild.core.Application;
import com.rebuild.core.metadata.EntityHelper; import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper; import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.MetadataSorter; import com.rebuild.core.metadata.MetadataSorter;
import com.rebuild.core.metadata.impl.DisplayType; import com.rebuild.core.metadata.impl.DisplayType;
import com.rebuild.core.metadata.impl.EasyMeta; import com.rebuild.core.metadata.impl.EasyMeta;
import com.rebuild.core.privileges.PrivilegesManager;
import com.rebuild.core.support.state.StateHelper; import com.rebuild.core.support.state.StateHelper;
import com.rebuild.web.BaseController; import com.rebuild.web.BaseController;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -116,11 +119,18 @@ public class MetadataGetting extends BaseController {
// 哪些实体引用了指定实体 // 哪些实体引用了指定实体
@GetMapping("references") @GetMapping("references")
public List<String[]> references(HttpServletRequest request) { public List<String[]> references(HttpServletRequest request) {
String entity = getParameterNotNull(request, "entity"); final ID user = getRequestUser(request);
Entity entityMeta = MetadataHelper.getEntity(entity);
Entity entity = MetadataHelper.getEntity(getParameterNotNull(request, "entity"));
String permission = getParameter(request, "permission");
Permission checkPermission = null;
if (permission != null) {
checkPermission = PrivilegesManager.parse(permission);
}
Set<Entity> references = new HashSet<>(); Set<Entity> references = new HashSet<>();
for (Field field : entityMeta.getReferenceToFields()) { for (Field field : entity.getReferenceToFields()) {
Entity own = field.getOwnEntity(); Entity own = field.getOwnEntity();
if (!(own.getMainEntity() != null || field.getType() == FieldType.ANY_REFERENCE)) { if (!(own.getMainEntity() != null || field.getType() == FieldType.ANY_REFERENCE)) {
references.add(own); references.add(own);
@ -129,8 +139,11 @@ public class MetadataGetting extends BaseController {
List<String[]> data = new ArrayList<>(); List<String[]> data = new ArrayList<>();
for (Entity e : references) { for (Entity e : references) {
EasyMeta easy = new EasyMeta(e); if (checkPermission == null
data.add(new String[] { easy.getName(), easy.getLabel() }); || Application.getPrivilegesManager().allow(user, e.getEntityCode(), checkPermission)) {
EasyMeta easy = new EasyMeta(e);
data.add(new String[] { easy.getName(), easy.getLabel() });
}
} }
return data; return data;
} }

View file

@ -11,30 +11,30 @@ class DlgAssign extends RbModalHandler {
constructor(props) { constructor(props) {
super(props) super(props)
this.onView = !!window.RbViewPage this.onView = !!window.RbViewPage
this.specs = ['assign', 'Assign'] this._Props = ['assign', 'Assign', 'A']
} }
render() { render() {
return ( return (
<RbModal title={$L(this.specs[1])} ref={(c) => (this._dlg = c)}> <RbModal title={$L(this._Props[1])} ref={(c) => (this._dlg = c)}>
<div className="form"> <div className="form">
{this.onView === true ? null : ( {this.onView === true ? null : (
<div className="form-group row pb-0"> <div className="form-group row pb-0">
<label className="col-sm-3 col-form-label text-sm-right">{$L('SomeWhichRecords,' + this.specs[1])}</label> <label className="col-sm-3 col-form-label text-sm-right">{$L('SomeWhichRecords,' + this._Props[1])}</label>
<div className="col-sm-7"> <div className="col-sm-7">
<div className="form-control-plaintext">{`${$L('DatasSelected')} (${$L('XItem').replace('%d', this.state.ids.length)})`}</div> <div className="form-control-plaintext">{`${$L('DatasSelected')} (${$L('XItem').replace('%d', this.state.ids.length)})`}</div>
</div> </div>
</div> </div>
)} )}
<div className="form-group row"> <div className="form-group row">
<label className="col-sm-3 col-form-label text-sm-right">{$L('SomeToWho,' + this.specs[1])}</label> <label className="col-sm-3 col-form-label text-sm-right">{$L('SomeToWho,' + this._Props[1])}</label>
<div className="col-sm-7">{this._useUserSelector()}</div> <div className="col-sm-7">{this._useUserSelector()}</div>
</div> </div>
{this.state.cascadesShow !== true ? ( {this.state.cascadesShow !== true ? (
<div className="form-group row"> <div className="form-group row">
<div className="col-sm-7 offset-sm-3"> <div className="col-sm-7 offset-sm-3">
<a href="#" onClick={this._showCascade}> <a href="#" onClick={this._showCascade}>
{$L('SameSomeRelatedRecords,' + this.specs[1])} {$L('SameSomeRelatedRecords,' + this._Props[1])}
</a> </a>
</div> </div>
</div> </div>
@ -71,14 +71,17 @@ class DlgAssign extends RbModalHandler {
_showCascade = () => { _showCascade = () => {
event && event.preventDefault() event && event.preventDefault()
$.get(`/commons/metadata/references?entity=${this.props.entity}`, (res) => { $.get(`/commons/metadata/references?entity=${this.props.entity}&permission=${this._Props[2]}`, (res) => {
this.setState({ cascadesShow: true, cascadesEntity: res.data }, () => { this.setState({ cascadesShow: true, cascadesEntity: res.data }, () => {
const defaultSelected = []
res.data.forEach((item) => defaultSelected.push(item[0]))
$(this._cascades) $(this._cascades)
.select2({ .select2({
multiple: true, multiple: true,
placeholder: $L('SelectCasEntity'), placeholder: $L('SelectCasEntity'),
}) })
.val(null) .val(defaultSelected)
.trigger('change') .trigger('change')
}) })
}) })
@ -91,21 +94,21 @@ class DlgAssign extends RbModalHandler {
post() { post() {
let users = this._UserSelector.val() let users = this._UserSelector.val()
if (!users || users.length === 0) { if (!users || users.length === 0) {
RbHighbar.create($L('PlsSelectSomeToWho,' + this.specs[1])) RbHighbar.create($L('PlsSelectSomeToWho,' + this._Props[1]))
return return
} }
if ($.type(users) === 'array') users = users.join(',') if ($.type(users) === 'array') users = users.join(',')
const cass = this.state.cascadesShow === true ? $(this._cascades).val().join(',') : '' const cass = this.state.cascadesShow === true ? $(this._cascades).val().join(',') : ''
const $btns = $(this._btns).find('.btn').button('loading') const $btns = $(this._btns).find('.btn').button('loading')
$.post(`/app/entity/record-${this.specs[0]}?id=${this.state.ids.join(',')}&cascades=${cass}&to=${users}`, (res) => { $.post(`/app/entity/record-${this._Props[0]}?id=${this.state.ids.join(',')}&cascades=${cass}&to=${users}`, (res) => {
if (res.error_code === 0) { if (res.error_code === 0) {
this.setState({ cascadesShow: false }) this.setState({ cascadesShow: false })
this._UserSelector.clearSelection() this._UserSelector.clearSelection()
$(this._cascades).val(null).trigger('change') $(this._cascades).val(null).trigger('change')
this.hide() this.hide()
RbHighbar.success($L('SomeSuccess,' + this.specs[1])) RbHighbar.success($L('SomeSuccess,' + this._Props[1]))
setTimeout(() => { setTimeout(() => {
if (window.RbListPage) RbListPage._RbList.reload() if (window.RbListPage) RbListPage._RbList.reload()
@ -136,7 +139,7 @@ class DlgAssign extends RbModalHandler {
class DlgShare extends DlgAssign { class DlgShare extends DlgAssign {
constructor(props) { constructor(props) {
super(props) super(props)
this.specs = ['share', 'Share'] this._Props = ['share', 'Share', 'S']
} }
_useUserSelector() { _useUserSelector() {

View file

@ -1726,7 +1726,7 @@ class DeleteConfirm extends RbAlert {
enableCascade() { enableCascade() {
this.setState({ enableCascade: !this.state.enableCascade }) this.setState({ enableCascade: !this.state.enableCascade })
if (!this.state.cascadesEntity) { if (!this.state.cascadesEntity) {
$.get('/commons/metadata/references?entity=' + this.props.entity, (res) => { $.get(`/commons/metadata/references?entity=${this.props.entity}&permission=D`, (res) => {
this.setState({ cascadesEntity: res.data }, () => { this.setState({ cascadesEntity: res.data }, () => {
this.__select2 = $(this._cascades) this.__select2 = $(this._cascades)
.select2({ .select2({

View file

@ -76,7 +76,7 @@ class ContentAutoAssign extends ActionContentSpec {
} }
const cascades = content.cascades ? content.cascades.split(',') : [] const cascades = content.cascades ? content.cascades.split(',') : []
$.get('/commons/metadata/references?entity=' + this.props.sourceEntity, (res) => { $.get(`/commons/metadata/references?entity=${this.props.sourceEntity}`, (res) => {
this.setState({ cascadesEntity: res.data }, () => { this.setState({ cascadesEntity: res.data }, () => {
this.__select2 = $(this._cascades) this.__select2 = $(this._cascades)
.select2({ .select2({