mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 03:38:33 +08:00
PL-8064 Define access group constraints on @MappedSuperclasses
This commit is contained in:
parent
f72984e0b1
commit
63d8dde501
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2017 Haulmont.
|
||||
*
|
||||
* 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 com.haulmont.cuba.security;
|
||||
|
||||
import com.haulmont.cuba.core.EntityManager;
|
||||
import com.haulmont.cuba.core.Transaction;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.security.app.LoginWorker;
|
||||
import com.haulmont.cuba.security.entity.*;
|
||||
import com.haulmont.cuba.security.global.LoginException;
|
||||
import com.haulmont.cuba.security.global.UserSession;
|
||||
import com.haulmont.cuba.testsupport.TestContainer;
|
||||
import com.haulmont.cuba.testsupport.TestUserSessionSource;
|
||||
import org.junit.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public class ParentClassConstraintTest {
|
||||
|
||||
@ClassRule
|
||||
public static TestContainer cont = TestContainer.Common.INSTANCE;
|
||||
|
||||
private Group parentGroup;
|
||||
private Group constraintGroup1, constraintGroup2, constraintGroup3;
|
||||
private Constraint constraint1, constraint2, constraint3, constraint4;
|
||||
private User constraintUser1, constraintUser2, constraintUser3;
|
||||
private SearchFolder searchFolder1, searchFolder2;
|
||||
private PasswordEncryption passwordEncryption;
|
||||
|
||||
private static final String PASSWORD = "1";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
passwordEncryption = AppBeans.get(PasswordEncryption.class);
|
||||
|
||||
Transaction tx = cont.persistence().createTransaction();
|
||||
try {
|
||||
EntityManager em = cont.persistence().getEntityManager();
|
||||
|
||||
parentGroup = new Group();
|
||||
parentGroup.setName("parentGroup");
|
||||
em.persist(parentGroup);
|
||||
|
||||
constraintGroup1 = new Group();
|
||||
constraintGroup1.setName("constraintGroup1");
|
||||
em.persist(constraintGroup1);
|
||||
|
||||
constraint1 = new Constraint();
|
||||
constraint1.setEntityName("sys$Folder");
|
||||
constraint1.setCheckType(ConstraintCheckType.DATABASE);
|
||||
constraint1.setOperationType(ConstraintOperationType.READ);
|
||||
constraint1.setWhereClause("{E}.name = 'folder1'");
|
||||
constraint1.setGroup(constraintGroup1);
|
||||
em.persist(constraint1);
|
||||
|
||||
constraintGroup2 = new Group();
|
||||
constraintGroup2.setName("constraintGroup2");
|
||||
em.persist(constraintGroup2);
|
||||
|
||||
constraint2 = new Constraint();
|
||||
constraint2.setEntityName("sys$Folder");
|
||||
constraint2.setCheckType(ConstraintCheckType.DATABASE);
|
||||
constraint2.setOperationType(ConstraintOperationType.READ);
|
||||
constraint2.setWhereClause("{E}.name = 'folder1'");
|
||||
constraint2.setGroup(constraintGroup2);
|
||||
em.persist(constraint2);
|
||||
|
||||
constraint3 = new Constraint();
|
||||
constraint3.setEntityName("sec$SearchFolder");
|
||||
constraint3.setCheckType(ConstraintCheckType.DATABASE);
|
||||
constraint3.setOperationType(ConstraintOperationType.READ);
|
||||
constraint3.setWhereClause("{E}.name = 'folder2'");
|
||||
constraint3.setGroup(constraintGroup2);
|
||||
em.persist(constraint3);
|
||||
|
||||
constraintGroup3 = new Group();
|
||||
constraintGroup3.setName("constraintGroup3");
|
||||
em.persist(constraintGroup3);
|
||||
|
||||
constraint4 = new Constraint();
|
||||
constraint4.setEntityName("sys$StandardEntity");
|
||||
constraint4.setCheckType(ConstraintCheckType.DATABASE);
|
||||
constraint4.setOperationType(ConstraintOperationType.READ);
|
||||
constraint4.setWhereClause("{E}.createTs is null");
|
||||
constraint4.setGroup(constraintGroup3);
|
||||
em.persist(constraint4);
|
||||
|
||||
constraintUser1 = new User();
|
||||
constraintUser1.setLogin("constraintUser1");
|
||||
constraintUser1.setPassword(passwordEncryption.getPasswordHash(constraintUser1.getId(), PASSWORD));
|
||||
constraintUser1.setGroup(constraintGroup1);
|
||||
em.persist(constraintUser1);
|
||||
|
||||
constraintUser2 = new User();
|
||||
constraintUser2.setLogin("constraintUser2");
|
||||
constraintUser2.setPassword(passwordEncryption.getPasswordHash(constraintUser2.getId(), PASSWORD));
|
||||
constraintUser2.setGroup(constraintGroup2);
|
||||
em.persist(constraintUser2);
|
||||
|
||||
constraintUser3 = new User();
|
||||
constraintUser3.setLogin("constraintUser3");
|
||||
constraintUser3.setPassword(passwordEncryption.getPasswordHash(constraintUser3.getId(), PASSWORD));
|
||||
constraintUser3.setGroup(constraintGroup3);
|
||||
em.persist(constraintUser3);
|
||||
|
||||
searchFolder1 = new SearchFolder();
|
||||
searchFolder1.setName("folder1");
|
||||
em.persist(searchFolder1);
|
||||
|
||||
searchFolder2 = new SearchFolder();
|
||||
searchFolder2.setName("folder2");
|
||||
em.persist(searchFolder2);
|
||||
|
||||
tx.commit();
|
||||
} finally {
|
||||
tx.end();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintsOnParentClass() throws LoginException {
|
||||
DataManager dataManager = AppBeans.get(DataManager.NAME);
|
||||
LoadContext<SearchFolder> loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
List resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(2, resultList.size());
|
||||
|
||||
LoginWorker lw = AppBeans.get(LoginWorker.NAME);
|
||||
|
||||
UserSession userSession = lw.login("constraintUser1", passwordEncryption.getPlainHash(PASSWORD), Locale.getDefault());
|
||||
assertNotNull(userSession);
|
||||
|
||||
UserSessionSource uss = AppBeans.get(UserSessionSource.class);
|
||||
UserSession savedUserSession = uss.getUserSession();
|
||||
((TestUserSessionSource) uss).setUserSession(userSession);
|
||||
try {
|
||||
dataManager = AppBeans.get(DataManager.NAME);
|
||||
dataManager = dataManager.secure();
|
||||
loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(1, resultList.size());
|
||||
} finally {
|
||||
((TestUserSessionSource) uss).setUserSession(savedUserSession);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintsOnParentAndCurrentMetaClass() throws LoginException {
|
||||
DataManager dataManager = AppBeans.get(DataManager.NAME);
|
||||
LoadContext<SearchFolder> loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
List resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(2, resultList.size());
|
||||
|
||||
LoginWorker lw = AppBeans.get(LoginWorker.NAME);
|
||||
|
||||
UserSession userSession = lw.login("constraintUser2", passwordEncryption.getPlainHash(PASSWORD), Locale.getDefault());
|
||||
assertNotNull(userSession);
|
||||
|
||||
UserSessionSource uss = AppBeans.get(UserSessionSource.class);
|
||||
UserSession savedUserSession = uss.getUserSession();
|
||||
((TestUserSessionSource) uss).setUserSession(userSession);
|
||||
try {
|
||||
dataManager = AppBeans.get(DataManager.NAME);
|
||||
dataManager = dataManager.secure();
|
||||
loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(0, resultList.size());
|
||||
} finally {
|
||||
((TestUserSessionSource) uss).setUserSession(savedUserSession);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstraintsOnMappedSuperClass() throws LoginException {
|
||||
DataManager dataManager = AppBeans.get(DataManager.NAME);
|
||||
LoadContext<SearchFolder> loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
List resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(2, resultList.size());
|
||||
|
||||
LoginWorker lw = AppBeans.get(LoginWorker.NAME);
|
||||
|
||||
UserSession userSession = lw.login("constraintUser3", passwordEncryption.getPlainHash(PASSWORD), Locale.getDefault());
|
||||
assertNotNull(userSession);
|
||||
|
||||
UserSessionSource uss = AppBeans.get(UserSessionSource.class);
|
||||
UserSession savedUserSession = uss.getUserSession();
|
||||
((TestUserSessionSource) uss).setUserSession(userSession);
|
||||
try {
|
||||
dataManager = AppBeans.get(DataManager.NAME);
|
||||
dataManager = dataManager.secure();
|
||||
loadContext = new LoadContext<>(SearchFolder.class).setView(View.LOCAL);
|
||||
loadContext.setQueryString("select f from sec$SearchFolder f");
|
||||
resultList = dataManager.loadList(loadContext);
|
||||
assertEquals(0, resultList.size());
|
||||
} finally {
|
||||
((TestUserSessionSource) uss).setUserSession(savedUserSession);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
cont.deleteRecord("SEC_USER", constraintUser1.getId(), constraintUser2.getId(), constraintUser3.getId());
|
||||
cont.deleteRecord("SEC_CONSTRAINT", constraint1.getId(), constraint2.getId(), constraint3.getId(), constraint4.getId());
|
||||
cont.deleteRecord("SEC_GROUP", parentGroup.getId(), constraintGroup1.getId(), constraintGroup2.getId(), constraintGroup3.getId());
|
||||
cont.deleteRecord("SEC_SEARCH_FOLDER", "FOLDER_ID", searchFolder1.getId(), searchFolder2.getId());
|
||||
cont.deleteRecord("SYS_FOLDER", searchFolder1.getId(), searchFolder2.getId());
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ import javax.inject.Inject;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.haulmont.cuba.security.entity.ConstraintOperationType.ALL;
|
||||
import static com.haulmont.cuba.security.entity.ConstraintOperationType.CUSTOM;
|
||||
@ -171,26 +172,35 @@ public class SecurityImpl implements Security {
|
||||
|
||||
@Override
|
||||
public boolean hasConstraints(MetaClass metaClass) {
|
||||
UserSession userSession = userSessionSource.getUserSession();
|
||||
String mainMetaClassName = extendedEntities.getOriginalOrThisMetaClass(metaClass).getName();
|
||||
return userSession.hasConstraints(mainMetaClassName);
|
||||
List<ConstraintData> constraints = getConstraints(metaClass);
|
||||
return !constraints.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInMemoryConstraints(MetaClass metaClass, ConstraintOperationType... operationTypes) {
|
||||
UserSession userSession = userSessionSource.getUserSession();
|
||||
String mainMetaClassName = extendedEntities.getOriginalOrThisMetaClass(metaClass).getName();
|
||||
List<ConstraintData> constraints = userSession.getConstraints(mainMetaClassName, constraint ->
|
||||
constraint.getCheckType().memory() && constraint.getOperationType() != null
|
||||
&& Arrays.asList(operationTypes).contains(constraint.getOperationType())
|
||||
List<ConstraintData> constraints = getConstraints(metaClass, constraint ->
|
||||
constraint.getCheckType().memory() && constraint.getOperationType() != null
|
||||
&& Arrays.asList(operationTypes).contains(constraint.getOperationType())
|
||||
);
|
||||
return !constraints.isEmpty();
|
||||
}
|
||||
|
||||
protected List<ConstraintData> getConstraints(MetaClass metaClass, Predicate<ConstraintData> predicate) {
|
||||
return getConstraints(metaClass).stream()
|
||||
.filter(predicate)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected List<ConstraintData> getConstraints(MetaClass metaClass) {
|
||||
UserSession userSession = userSessionSource.getUserSession();
|
||||
String mainMetaClassName = extendedEntities.getOriginalOrThisMetaClass(metaClass).getName();
|
||||
return userSession.getConstraints(mainMetaClassName, predicate);
|
||||
MetaClass mainMetaClass = extendedEntities.getOriginalOrThisMetaClass(metaClass);
|
||||
|
||||
List<ConstraintData> constraints = new ArrayList<>();
|
||||
constraints.addAll(userSession.getConstraints(mainMetaClass.getName()));
|
||||
for (MetaClass parent : mainMetaClass.getAncestors()) {
|
||||
constraints.addAll(userSession.getConstraints(parent.getName()));
|
||||
}
|
||||
return constraints;
|
||||
}
|
||||
|
||||
protected boolean isPermitted(Entity entity, Predicate<ConstraintData> predicate) {
|
||||
@ -216,7 +226,7 @@ public class SecurityImpl implements Security {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("An error occurred while applying constraint's Groovy script. The entity has been filtered out." +
|
||||
"Entity class [{}]. Entity [{}].", metaClassName, entity.getId(), e);
|
||||
"Entity class [{}]. Entity [{}].", metaClassName, entity.getId(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -236,7 +246,7 @@ public class SecurityImpl implements Security {
|
||||
/**
|
||||
* Override if you need specific context variables in Groovy constraints.
|
||||
*
|
||||
* @param context passed to Groovy evaluator
|
||||
* @param context passed to Groovy evaluator
|
||||
*/
|
||||
protected void fillGroovyConstraintsContext(Map<String, Object> context) {
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ package com.haulmont.cuba.gui.app.security.constraint.edit;
|
||||
import com.google.common.base.Strings;
|
||||
import com.haulmont.bali.util.Dom4j;
|
||||
import com.haulmont.chile.core.model.MetaClass;
|
||||
import com.haulmont.cuba.core.entity.BaseGenericIdEntity;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
import com.haulmont.cuba.core.global.filter.GroovyGenerator;
|
||||
import com.haulmont.cuba.core.global.filter.SecurityJpqlGenerator;
|
||||
@ -131,8 +132,8 @@ public class ConstraintEditor extends AbstractEditor<Constraint> {
|
||||
Map<String, Object> options = new TreeMap<>();
|
||||
MessageTools messageTools = AppBeans.get(MessageTools.NAME);
|
||||
entities = new HashMap<>();
|
||||
for (MetaClass metaClass : metadata.getTools().getAllPersistentMetaClasses()) {
|
||||
if (extendedEntities.getExtendedClass(metaClass) == null) {
|
||||
for (MetaClass metaClass : metadata.getSession().getClasses()) {
|
||||
if (extendedEntities.getExtendedClass(metaClass) == null && BaseGenericIdEntity.class.isAssignableFrom(metaClass.getJavaClass())) {
|
||||
MetaClass mainMetaClass = extendedEntities.getOriginalOrThisMetaClass(metaClass);
|
||||
String originalName = mainMetaClass.getName();
|
||||
options.put(messageTools.getEntityCaption(metaClass) + " (" + metaClass.getName() + ")", originalName);
|
||||
|
Loading…
Reference in New Issue
Block a user