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 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -152,27 +178,27 @@ public class Shiro {
|
|||
* representation in the database the returned {@link Optional} is empty.
|
||||
*
|
||||
* @see #getSubject()
|
||||
* @see #getSystemUser()
|
||||
* @see #getPublicUser()
|
||||
* @see #getSystemUser()
|
||||
* @see #getPublicUser()
|
||||
*/
|
||||
public Optional<User> getUser() {
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue