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
jensp 2017-05-02 09:02:36 +00:00
parent 9e3b58914d
commit 76a1e0f10b
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 java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import javax.inject.Inject;
@ -71,11 +73,12 @@ import static org.junit.Assert.*;
phase = TestExecutionPhase.BEFORE)
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 "
+ "WHERE p.grantee IN :roles "
+ "AND p.grantedPrivilege = 'view_draft_items' "
+ "ORDER BY i.displayName";
+ "WHERE (p.grantee IN :roles "
+ "AND p.grantedPrivilege = 'view_draft_items')"
+ "OR true = :isSystemUser "
+ "ORDER BY i.displayName";
@Inject
private EntityManager entityManager;
@ -106,9 +109,9 @@ public class ContentItemPermissionTest {
public static WebArchive createDeployment() {
return ShrinkWrap
.create(WebArchive.class,
"LibreCCM-org.librecms.contentsection.ContentItemPermissionTest.war")
//Classes imported by this class
.addClass(Role.class)
"LibreCCM-org.librecms.contentsection.ContentItemPermissionTest.war") //Classes imported by this class
.
addClass(Role.class)
.addClass(Shiro.class)
.addClass(User.class)
.addClass(ContentItem.class)
@ -232,7 +235,7 @@ public class ContentItemPermissionTest {
.addClass(org.libreccm.core.CcmObjectRepository.class)
//Required by org.libreccm.core.CcmObjectRepository
.addClass(org.libreccm.core.CoreConstants.class)
//Dependencies from other modules and resources
//Dependencies from other modules and resources
.addAsLibraries(getCcmCoreDependencies())
.addAsResource("test-persistence.xml",
"META-INF/persistence.xml")
@ -270,12 +273,13 @@ public class ContentItemPermissionTest {
.map(membership -> membership.getRole())
.collect(Collectors.toList());
} else {
roles = new ArrayList<>();
roles = Collections.emptyList();
}
final TypedQuery<ContentItem> query = entityManager.createQuery(
QUERY, ContentItem.class);
query.setParameter("roles", roles);
query.setParameter("isSystemUser", shiro.isSystemUser());
final List<ContentItem> result = query.getResultList();
assertThat(result.isEmpty(), is(true));
@ -286,6 +290,7 @@ public class ContentItemPermissionTest {
@UsingDataSet("datasets/org/librecms/contentsection/"
+ "ContentItemPermissionTest/data.xml")
public void accessByUser1() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"user1@example.org", "foo123");
token.setRememberMe(true);
@ -299,6 +304,7 @@ public class ContentItemPermissionTest {
final TypedQuery<ContentItem> query = entityManager.createQuery(
QUERY, ContentItem.class);
query.setParameter("roles", roles);
query.setParameter("isSystemUser", shiro.isSystemUser());
final List<ContentItem> result = query.getResultList();
assertThat(result.size(), is(2));
@ -311,6 +317,7 @@ public class ContentItemPermissionTest {
@UsingDataSet("datasets/org/librecms/contentsection/"
+ "ContentItemPermissionTest/data.xml")
public void accessByUser2() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"user2@example.org", "foo123");
token.setRememberMe(true);
@ -324,6 +331,7 @@ public class ContentItemPermissionTest {
final TypedQuery<ContentItem> query = entityManager.createQuery(
QUERY, ContentItem.class);
query.setParameter("roles", roles);
query.setParameter("isSystemUser", shiro.isSystemUser());
final List<ContentItem> result = query.getResultList();
assertThat(result.size(), is(1));
@ -335,6 +343,7 @@ public class ContentItemPermissionTest {
@UsingDataSet("datasets/org/librecms/contentsection/"
+ "ContentItemPermissionTest/data.xml")
public void accessByUser3() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"user3@example.org", "foo123");
token.setRememberMe(true);
@ -348,6 +357,7 @@ public class ContentItemPermissionTest {
final TypedQuery<ContentItem> query = entityManager.createQuery(
QUERY, ContentItem.class);
query.setParameter("roles", roles);
query.setParameter("isSystemUser", shiro.isSystemUser());
final List<ContentItem> result = query.getResultList();
assertThat(result.size(), is(3));
@ -356,4 +366,51 @@ public class ContentItemPermissionTest {
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.
*
* @return
*/
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();
if (kernelConfig.emailIsPrimaryIdentifier()) {
return userRepository.findByEmailAddress((String) getSubject().
getPrincipal());
getPrincipal());
} else {
return userRepository.findByName((String) getSubject().
getPrincipal());
getPrincipal());
}
}
private Subject buildInternalSubject(final String userName) {
final PrincipalCollection principals = new SimplePrincipalCollection(
userName, "CcmShiroRealm");
userName, "CcmShiroRealm");
final Subject internalUser = new Subject.Builder()
.principals(principals)
.authenticated(true)
.buildSubject();
.principals(principals)
.authenticated(true)
.buildSubject();
return internalUser;
}