Skip to content

Commit

Permalink
Merge branch 'master1264'
Browse files Browse the repository at this point in the history
  • Loading branch information
dofs197 committed Aug 30, 2019
2 parents 86e8fe6 + 4517773 commit 397be9d
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.mysema.commons.lang.CloseableIterator;
import com.querydsl.core.Tuple;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.JPQLQuery;
import com.querydsl.jpa.hibernate.HibernateDeleteClause;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import lombok.val;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -133,6 +135,7 @@ public List<Permission> getIssuedPermissions(User user, Executor performer, Secu
return permissionDao.getIssuedPermissions(performer, securedObject);
}


/**
* Exports permissions to xml, see: manage_datafile, ExportDataFileAction.
* <p>
Expand All @@ -153,7 +156,7 @@ public void exportDataFile(User user, Document script) {
singletonTypes.add(t);
}
}
exportDataFileImpl(parentElement, queryFactory.select(pm.permission, e.name, pm.objectType)
exportDataFilePermissions(parentElement, queryFactory.select(pm.permission, e.name, pm.objectType)
.from(pm, e)
.where(pm.objectType.in(singletonTypes).and(pm.objectId.eq(0L)).and(pm.executor.eq(e)))
.orderBy(pm.objectType.asc(), e.name.asc(), pm.permission.asc()));
Expand All @@ -162,59 +165,142 @@ public void exportDataFile(User user, Document script) {
// Export ACTOR and GROUP permissions.
{
QExecutor e2 = new QExecutor("e2"); // same table as `e`, but different alias
exportDataFileImpl(parentElement, queryFactory.select(pm.permission, e.name, pm.objectType, e2.name)
exportDataFilePermissions(parentElement, queryFactory.select(pm.permission, e.name, pm.objectType, e2.name)
.from(pm, e, e2)
.where(pm.objectType.eq(EXECUTOR).and(pm.objectId.eq(e2.id)).and(pm.executor.eq(e)))
.orderBy(pm.objectType.asc(), e2.name.asc(), e.name.asc(), pm.permission.asc()));
}

// Export DEFINITION permissions.
{
// ********************************************************************************************************************************
// ***** !!!!! DON'T MERGE THIS INTO develop !!!!! This is temporary solution, before table BPM_PROCESS_DEFINITION_VER was created.
// ********************************************************************************************************************************

// Table PERMISSION_MAPPING (PM) for TYPE='DEFINITION' stores OBJECT_ID = Deployment.getIdentifiableId() which is name hash.
// So we cannot join on (PM.OBJECT_ID = BPM_PROCESS_DEFINITION.ID) on SQL side.
val definitionNamesByIdentifiableIds = new HashMap<Long, String>();
QDeployment d = QDeployment.deployment;
exportDataFileImpl(parentElement, queryFactory.select(pm.permission, e.name, pm.objectType, d.name)
.from(pm, e, d)
for (val name : queryFactory.selectDistinct(d.name).from(d).fetch()) {
definitionNamesByIdentifiableIds.put((long) name.hashCode(), name);
}

val tuples = queryFactory.select(pm.permission, e.name, pm.objectType, pm.objectId)
.from(pm, e)
.where(pm.objectType.eq(DEFINITION).and(pm.executor.eq(e)))
.orderBy(d.name.asc(), e.name.asc(), pm.permission.asc()));
// exportDataFilePermissions() requires that rows are ordered by (object, executor) first, permission last.
.orderBy(pm.objectId.asc(), e.name.asc(), pm.permission.asc())
.fetch();
val rows = new ArrayList<ExportDataFilePermissionRow>(tuples.size());
for (val t : tuples) {
val objectName = definitionNamesByIdentifiableIds.get(t.get(3, Long.class));
if (objectName != null) {
rows.add(new ExportDataFilePermissionRow(t, objectName));
}
}

exportDataFilePermissions(parentElement, rows);
}
}

// ********************************************************************************************************************************
// ***** !!!!! DON'T MERGE THIS INTO develop !!!!! This is temporary solution, before table BPM_PROCESS_DEFINITION_VER was created.
// ********************************************************************************************************************************
private static class ExportDataFilePermissionRow {
final Permission permission;
final String executorName;
final SecuredObjectType objectType;
String objectName;

ExportDataFilePermissionRow(Tuple t) {
this(t, t.size() == 4 ? t.get(3, String.class) : null);
}

ExportDataFilePermissionRow(Tuple t, String objectName) {
permission = t.get(0, Permission.class);
executorName = t.get(1, String.class);
objectType = t.get(2, SecuredObjectType.class);
this.objectName = objectName;
}
}

/**
*
* @param parentElement Parent for "addPermissions" elements.
* @param query Must return fields in order: permission, executorName, objectType, [objectName].
*/
private void exportDataFileImpl(Element parentElement, JPQLQuery<Tuple> query) {
// ********************************************************************************************************************************
// ***** !!!!! DON'T MERGE THIS INTO develop !!!!! This is temporary solution, before table BPM_PROCESS_DEFINITION_VER was created.
// ********************************************************************************************************************************
private void exportDataFilePermissions(Element parentElement, JPQLQuery<Tuple> query) {
try (final CloseableIterator<Tuple> it = query.iterate()) {
exportDataFilePermissionsImpl(parentElement, new CloseableIterator<ExportDataFilePermissionRow>() {
@Override
public void close() {
it.close();
}

@Override
public boolean hasNext() {
return it.hasNext();
}

@Override
public ExportDataFilePermissionRow next() {
return new ExportDataFilePermissionRow(it.next());
}
});
}
}

// ********************************************************************************************************************************
// ***** !!!!! DON'T MERGE THIS INTO develop !!!!! This is temporary solution, before table BPM_PROCESS_DEFINITION_VER was created.
// ********************************************************************************************************************************
private void exportDataFilePermissions(Element parentElement, ArrayList<ExportDataFilePermissionRow> rows) {
val it = rows.iterator();
exportDataFilePermissionsImpl(parentElement, new CloseableIterator<ExportDataFilePermissionRow>() {
@Override
public void close() {
}

@Override
public boolean hasNext() {
return it.hasNext();
}

@Override
public ExportDataFilePermissionRow next() {
return it.next();
}
});
}

private void exportDataFilePermissionsImpl(Element parentElement, CloseableIterator<ExportDataFilePermissionRow> it) {
SecuredObjectType lastObjectType = null;
String lastObjectName = null;
String lastExecutorName = null;
Element addPermissionsElement = null;

try (CloseableIterator<Tuple> i = query.iterate()) {
while (i.hasNext()) {
Tuple t = i.next();
Permission permission = t.get(0, Permission.class);
String executorName = t.get(1, String.class);
SecuredObjectType objectType = t.get(2, SecuredObjectType.class);
String objectName = t.size() == 4 ? t.get(3, String.class) : null;

// Manually group by objectType, objectName, executorName.
if (objectType != lastObjectType || !Objects.equals(objectName, lastObjectName) || !Objects.equals(executorName, lastExecutorName)) {
lastObjectType = objectType;
lastObjectName = objectName;
lastExecutorName = executorName;

addPermissionsElement = parentElement.addElement("addPermissions", XmlUtils.RUNA_NAMESPACE);
//noinspection ConstantConditions
addPermissionsElement.addAttribute("type", objectType.getName());
if (objectName != null) {
addPermissionsElement.addAttribute("name", objectName);
}
addPermissionsElement.addAttribute("executor", executorName);
}
while (it.hasNext()) {
val row = it.next();

// Manually group by objectType, objectName, executorName.
if (row.objectType != lastObjectType || !Objects.equals(row.objectName, lastObjectName) || !Objects.equals(row.executorName,
lastExecutorName)) {
lastObjectType = row.objectType;
lastObjectName = row.objectName;
lastExecutorName = row.executorName;

addPermissionsElement = parentElement.addElement("addPermissions", XmlUtils.RUNA_NAMESPACE);
//noinspection ConstantConditions
addPermissionsElement.addElement("permission", XmlUtils.RUNA_NAMESPACE).addAttribute("name", permission.getName());
addPermissionsElement.addAttribute("type", row.objectType.getName());
if (row.objectName != null) {
addPermissionsElement.addAttribute("name", row.objectName);
}
addPermissionsElement.addAttribute("executor", row.executorName);
}

//noinspection ConstantConditions
addPermissionsElement.addElement("permission", XmlUtils.RUNA_NAMESPACE).addAttribute("name", row.permission.getName());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import ru.runa.common.web.html.PermissionTableBuilder;
import ru.runa.common.web.tag.SecuredObjectFormTag2;
import ru.runa.wfe.security.Permission;
import ru.runa.wfe.security.SecuredSingleton;
import ru.runa.wfe.service.delegate.Delegates;

@org.tldgen.annotations.Tag(bodyContent = BodyContent.JSP, name = "managePermissionsForm")
Expand Down

0 comments on commit 397be9d

Please sign in to comment.