CCM NG/ccm-cms: Extended test for developing query which takes permissions into acccount when retrieving ContentItems from the database.
git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4699 8810af33-2d31-482b-a856-94f89814c4dfccm-docs
parent
68ae2e8d44
commit
04acd6a974
|
|
@ -47,8 +47,10 @@ import org.libreccm.security.User;
|
||||||
import org.libreccm.tests.categories.IntegrationTest;
|
import org.libreccm.tests.categories.IntegrationTest;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -71,11 +73,12 @@ import static org.junit.Assert.*;
|
||||||
phase = TestExecutionPhase.BEFORE)
|
phase = TestExecutionPhase.BEFORE)
|
||||||
public class ContentItemPermissionTest {
|
public class ContentItemPermissionTest {
|
||||||
|
|
||||||
private static final String QUERY = "SELECT i FROM ContentItem i "
|
private static final String QUERY = "SELECT DISTINCT i FROM ContentItem i "
|
||||||
+ "JOIN i.permissions p "
|
+ "JOIN i.permissions p "
|
||||||
+ "WHERE p.grantee IN :roles "
|
+ "WHERE (p.grantee IN :roles "
|
||||||
+ "AND p.grantedPrivilege = 'view_draft_items' "
|
+ "AND p.grantedPrivilege = 'view_draft_items')"
|
||||||
+ "ORDER BY i.displayName";
|
+ "OR true = :isSystemUser "
|
||||||
|
+ "ORDER BY i.displayName";
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
@ -106,9 +109,9 @@ public class ContentItemPermissionTest {
|
||||||
public static WebArchive createDeployment() {
|
public static WebArchive createDeployment() {
|
||||||
return ShrinkWrap
|
return ShrinkWrap
|
||||||
.create(WebArchive.class,
|
.create(WebArchive.class,
|
||||||
"LibreCCM-org.librecms.contentsection.ContentItemPermissionTest.war")
|
"LibreCCM-org.librecms.contentsection.ContentItemPermissionTest.war") //Classes imported by this class
|
||||||
//Classes imported by this class
|
.
|
||||||
.addClass(Role.class)
|
addClass(Role.class)
|
||||||
.addClass(Shiro.class)
|
.addClass(Shiro.class)
|
||||||
.addClass(User.class)
|
.addClass(User.class)
|
||||||
.addClass(ContentItem.class)
|
.addClass(ContentItem.class)
|
||||||
|
|
@ -232,7 +235,7 @@ public class ContentItemPermissionTest {
|
||||||
.addClass(org.libreccm.core.CcmObjectRepository.class)
|
.addClass(org.libreccm.core.CcmObjectRepository.class)
|
||||||
//Required by org.libreccm.core.CcmObjectRepository
|
//Required by org.libreccm.core.CcmObjectRepository
|
||||||
.addClass(org.libreccm.core.CoreConstants.class)
|
.addClass(org.libreccm.core.CoreConstants.class)
|
||||||
//Dependencies from other modules and resources
|
//Dependencies from other modules and resources
|
||||||
.addAsLibraries(getCcmCoreDependencies())
|
.addAsLibraries(getCcmCoreDependencies())
|
||||||
.addAsResource("test-persistence.xml",
|
.addAsResource("test-persistence.xml",
|
||||||
"META-INF/persistence.xml")
|
"META-INF/persistence.xml")
|
||||||
|
|
@ -270,12 +273,13 @@ public class ContentItemPermissionTest {
|
||||||
.map(membership -> membership.getRole())
|
.map(membership -> membership.getRole())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
roles = new ArrayList<>();
|
roles = Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
||||||
QUERY, ContentItem.class);
|
QUERY, ContentItem.class);
|
||||||
query.setParameter("roles", roles);
|
query.setParameter("roles", roles);
|
||||||
|
query.setParameter("isSystemUser", shiro.isSystemUser());
|
||||||
final List<ContentItem> result = query.getResultList();
|
final List<ContentItem> result = query.getResultList();
|
||||||
|
|
||||||
assertThat(result.isEmpty(), is(true));
|
assertThat(result.isEmpty(), is(true));
|
||||||
|
|
@ -286,6 +290,7 @@ public class ContentItemPermissionTest {
|
||||||
@UsingDataSet("datasets/org/librecms/contentsection/"
|
@UsingDataSet("datasets/org/librecms/contentsection/"
|
||||||
+ "ContentItemPermissionTest/data.xml")
|
+ "ContentItemPermissionTest/data.xml")
|
||||||
public void accessByUser1() {
|
public void accessByUser1() {
|
||||||
|
|
||||||
final UsernamePasswordToken token = new UsernamePasswordToken(
|
final UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
"user1@example.org", "foo123");
|
"user1@example.org", "foo123");
|
||||||
token.setRememberMe(true);
|
token.setRememberMe(true);
|
||||||
|
|
@ -299,6 +304,7 @@ public class ContentItemPermissionTest {
|
||||||
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
||||||
QUERY, ContentItem.class);
|
QUERY, ContentItem.class);
|
||||||
query.setParameter("roles", roles);
|
query.setParameter("roles", roles);
|
||||||
|
query.setParameter("isSystemUser", shiro.isSystemUser());
|
||||||
final List<ContentItem> result = query.getResultList();
|
final List<ContentItem> result = query.getResultList();
|
||||||
|
|
||||||
assertThat(result.size(), is(2));
|
assertThat(result.size(), is(2));
|
||||||
|
|
@ -311,6 +317,7 @@ public class ContentItemPermissionTest {
|
||||||
@UsingDataSet("datasets/org/librecms/contentsection/"
|
@UsingDataSet("datasets/org/librecms/contentsection/"
|
||||||
+ "ContentItemPermissionTest/data.xml")
|
+ "ContentItemPermissionTest/data.xml")
|
||||||
public void accessByUser2() {
|
public void accessByUser2() {
|
||||||
|
|
||||||
final UsernamePasswordToken token = new UsernamePasswordToken(
|
final UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
"user2@example.org", "foo123");
|
"user2@example.org", "foo123");
|
||||||
token.setRememberMe(true);
|
token.setRememberMe(true);
|
||||||
|
|
@ -324,6 +331,7 @@ public class ContentItemPermissionTest {
|
||||||
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
||||||
QUERY, ContentItem.class);
|
QUERY, ContentItem.class);
|
||||||
query.setParameter("roles", roles);
|
query.setParameter("roles", roles);
|
||||||
|
query.setParameter("isSystemUser", shiro.isSystemUser());
|
||||||
final List<ContentItem> result = query.getResultList();
|
final List<ContentItem> result = query.getResultList();
|
||||||
|
|
||||||
assertThat(result.size(), is(1));
|
assertThat(result.size(), is(1));
|
||||||
|
|
@ -335,6 +343,7 @@ public class ContentItemPermissionTest {
|
||||||
@UsingDataSet("datasets/org/librecms/contentsection/"
|
@UsingDataSet("datasets/org/librecms/contentsection/"
|
||||||
+ "ContentItemPermissionTest/data.xml")
|
+ "ContentItemPermissionTest/data.xml")
|
||||||
public void accessByUser3() {
|
public void accessByUser3() {
|
||||||
|
|
||||||
final UsernamePasswordToken token = new UsernamePasswordToken(
|
final UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
"user3@example.org", "foo123");
|
"user3@example.org", "foo123");
|
||||||
token.setRememberMe(true);
|
token.setRememberMe(true);
|
||||||
|
|
@ -348,6 +357,7 @@ public class ContentItemPermissionTest {
|
||||||
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
||||||
QUERY, ContentItem.class);
|
QUERY, ContentItem.class);
|
||||||
query.setParameter("roles", roles);
|
query.setParameter("roles", roles);
|
||||||
|
query.setParameter("isSystemUser", shiro.isSystemUser());
|
||||||
final List<ContentItem> result = query.getResultList();
|
final List<ContentItem> result = query.getResultList();
|
||||||
|
|
||||||
assertThat(result.size(), is(3));
|
assertThat(result.size(), is(3));
|
||||||
|
|
@ -356,4 +366,51 @@ public class ContentItemPermissionTest {
|
||||||
assertThat(result.get(2).getDisplayName(), is(equalTo("article3")));
|
assertThat(result.get(2).getDisplayName(), is(equalTo("article3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@InSequence(500)
|
||||||
|
@UsingDataSet("datasets/org/librecms/contentsection/"
|
||||||
|
+ "ContentItemPermissionTest/data.xml")
|
||||||
|
public void accessBySystemUser() {
|
||||||
|
|
||||||
|
final UsernamePasswordToken token = new UsernamePasswordToken(
|
||||||
|
"user3@example.org", "foo123");
|
||||||
|
token.setRememberMe(true);
|
||||||
|
subject.login(token);
|
||||||
|
|
||||||
|
final List<ContentItem> result = shiro
|
||||||
|
.getSystemUser()
|
||||||
|
.execute(new ItemRetriever());
|
||||||
|
|
||||||
|
assertThat(result.size(), is(4));
|
||||||
|
assertThat(result.get(0).getDisplayName(), is(equalTo("article1")));
|
||||||
|
assertThat(result.get(1).getDisplayName(), is(equalTo("article2")));
|
||||||
|
assertThat(result.get(2).getDisplayName(), is(equalTo("article3")));
|
||||||
|
assertThat(result.get(3).getDisplayName(), is(equalTo("news1")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ItemRetriever implements Callable<List<ContentItem>> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ContentItem> call() throws Exception {
|
||||||
|
|
||||||
|
final Optional<User> user = shiro.getUser();
|
||||||
|
final List<Role> roles;
|
||||||
|
if (user.isPresent()) {
|
||||||
|
roles = shiro.getUser().get().getRoleMemberships()
|
||||||
|
.stream()
|
||||||
|
.map(membership -> membership.getRole())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} else {
|
||||||
|
roles = Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
final TypedQuery<ContentItem> query = entityManager.createQuery(
|
||||||
|
QUERY, ContentItem.class);
|
||||||
|
query.setParameter("roles", roles);
|
||||||
|
query.setParameter("isSystemUser", shiro.isSystemUser());
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,13 +134,39 @@ public class Shiro {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPublicUser() {
|
||||||
|
final Subject subject = getSubject();
|
||||||
|
final Object principal = subject.getPrincipal();
|
||||||
|
|
||||||
|
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
|
||||||
|
return PUBLIC_USER_PRINCIPAL_EMAIL.equals(principal);
|
||||||
|
} else {
|
||||||
|
return PUBLIC_USER_PRINCIPAL_SCREEN_NAME.equals(principal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A virtual user for internal processes which has all permissions.
|
* A virtual user for internal processes which has all permissions.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Subject getSystemUser() {
|
public Subject getSystemUser() {
|
||||||
return buildInternalSubject(SYSTEM_USER_PRINCIPAL_SCREEN_NAME);
|
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
|
||||||
|
return buildInternalSubject(SYSTEM_USER_PRINCIPAL_EMAIL);
|
||||||
|
} else {
|
||||||
|
return buildInternalSubject(SYSTEM_USER_PRINCIPAL_SCREEN_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSystemUser() {
|
||||||
|
final Subject subject = getSubject();
|
||||||
|
final Object principal = subject.getPrincipal();
|
||||||
|
|
||||||
|
if (KernelConfig.getConfig().emailIsPrimaryIdentifier()) {
|
||||||
|
return SYSTEM_USER_PRINCIPAL_EMAIL.equals(principal);
|
||||||
|
} else {
|
||||||
|
return SYSTEM_USER_PRINCIPAL_SCREEN_NAME.equals(principal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -152,27 +178,27 @@ public class Shiro {
|
||||||
* representation in the database the returned {@link Optional} is empty.
|
* representation in the database the returned {@link Optional} is empty.
|
||||||
*
|
*
|
||||||
* @see #getSubject()
|
* @see #getSubject()
|
||||||
* @see #getSystemUser()
|
* @see #getSystemUser()
|
||||||
* @see #getPublicUser()
|
* @see #getPublicUser()
|
||||||
*/
|
*/
|
||||||
public Optional<User> getUser() {
|
public Optional<User> getUser() {
|
||||||
final KernelConfig kernelConfig = KernelConfig.getConfig();
|
final KernelConfig kernelConfig = KernelConfig.getConfig();
|
||||||
if (kernelConfig.emailIsPrimaryIdentifier()) {
|
if (kernelConfig.emailIsPrimaryIdentifier()) {
|
||||||
return userRepository.findByEmailAddress((String) getSubject().
|
return userRepository.findByEmailAddress((String) getSubject().
|
||||||
getPrincipal());
|
getPrincipal());
|
||||||
} else {
|
} else {
|
||||||
return userRepository.findByName((String) getSubject().
|
return userRepository.findByName((String) getSubject().
|
||||||
getPrincipal());
|
getPrincipal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Subject buildInternalSubject(final String userName) {
|
private Subject buildInternalSubject(final String userName) {
|
||||||
final PrincipalCollection principals = new SimplePrincipalCollection(
|
final PrincipalCollection principals = new SimplePrincipalCollection(
|
||||||
userName, "CcmShiroRealm");
|
userName, "CcmShiroRealm");
|
||||||
final Subject internalUser = new Subject.Builder()
|
final Subject internalUser = new Subject.Builder()
|
||||||
.principals(principals)
|
.principals(principals)
|
||||||
.authenticated(true)
|
.authenticated(true)
|
||||||
.buildSubject();
|
.buildSubject();
|
||||||
|
|
||||||
return internalUser;
|
return internalUser;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue