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-94f89814c4df

Former-commit-id: 76a1e0f10b
pull/2/head
jensp 2017-05-02 09:02:36 +00:00
parent 4503775b6d
commit 8e70f29f3a
2 changed files with 101 additions and 18 deletions

View File

@ -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();
}
}
} }

View File

@ -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);
}
} }
/** /**
@ -159,20 +185,20 @@ public class Shiro {
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;
} }