diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java b/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java index d5f3ebd86..fccbecc92 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/ContentType.java @@ -25,11 +25,13 @@ import static org.librecms.CmsConstants.*; import org.libreccm.core.CcmObject; import org.libreccm.l10n.LocalizedString; +import org.libreccm.security.InheritsPermissions; import org.libreccm.workflow.WorkflowTemplate; import org.librecms.lifecycle.LifecycleDefinition; import java.io.Serializable; import java.util.Objects; +import java.util.Optional; import javax.persistence.AssociationOverride; import javax.persistence.Column; @@ -69,7 +71,8 @@ import javax.persistence.Table; + "WHERE i.contentType = :type" ) }) -public class ContentType extends CcmObject implements Serializable { +public class ContentType extends CcmObject implements InheritsPermissions, + Serializable { private static final long serialVersionUID = -2708659750560382851L; @@ -190,6 +193,11 @@ public class ContentType extends CcmObject implements Serializable { protected void setDefaultWorkflow(final WorkflowTemplate defaultWorkflow) { this.defaultWorkflow = defaultWorkflow; } + + @Override + public Optional getParent() { + return Optional.of(contentSection); + } @Override public int hashCode() { diff --git a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java index e85111620..3c927c1c6 100644 --- a/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java +++ b/ccm-cms/src/main/java/org/librecms/contentsection/Folder.java @@ -24,10 +24,14 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import org.libreccm.categorization.Category; +import org.libreccm.core.CcmObject; +import org.libreccm.security.InheritsPermissions; +import java.io.Serializable; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Collectors; import javax.persistence.Column; @@ -55,7 +59,8 @@ import static org.librecms.CmsConstants.*; name = "Folder.findByName", query = "SELECT f FROM Folder f WHERE f.name = :name") }) -public class Folder extends Category { +public class Folder extends Category implements InheritsPermissions, + Serializable { private static final long serialVersionUID = 1L; @@ -87,6 +92,15 @@ public class Folder extends Category { protected void setType(final FolderType type) { this.type = type; } + + @Override + public Optional getParent() { + if (getParentFolder() == null) { + return Optional.of(section); + } else { + return Optional.of(getParentFolder()); + } + } /** * A convenient method for getting all sub folders of folder. diff --git a/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java b/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java index c6c9e853a..9041e7f89 100644 --- a/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java +++ b/ccm-cms/src/test/java/org/librecms/contentsection/ContentTypeRepositoryTest.java @@ -20,6 +20,7 @@ package org.librecms.contentsection; import static org.libreccm.testutils.DependenciesHelpers.*; +import org.apache.shiro.authz.UnauthorizedException; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.ShouldThrowException; import org.jboss.arquillian.junit.Arquillian; @@ -31,7 +32,6 @@ import org.jboss.arquillian.persistence.UsingDataSet; import org.jboss.arquillian.transaction.api.annotation.TransactionMode; import org.jboss.arquillian.transaction.api.annotation.Transactional; import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.EmptyAsset; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.After; import org.junit.AfterClass; @@ -39,6 +39,7 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.libreccm.security.Shiro; import org.libreccm.tests.categories.IntegrationTest; import org.librecms.contenttypes.Article; import org.librecms.contenttypes.News; @@ -69,6 +70,9 @@ public class ContentTypeRepositoryTest { @Inject private ContentSectionRepository contentSectionRepo; + @Inject + private Shiro shiro; + public ContentTypeRepositoryTest() { } @@ -139,8 +143,10 @@ public class ContentTypeRepositoryTest { .addAsLibraries(getCcmCoreDependencies()) .addAsResource("test-persistence.xml", "META-INF/persistence.xml") - .addAsWebInfResource("test-web.xml", "WEB-INF/web.xml") - .addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml"); + .addAsWebInfResource("test-web.xml", "web.xml") + .addAsResource("configs/shiro.ini", "shiro.ini") + .addAsResource("META-INF/beans.xml", "META-INF/beans.xml"); + //.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml"); } /** @@ -151,6 +157,7 @@ public class ContentTypeRepositoryTest { public void checkInjection() { assertThat(contentTypeRepo, is(not(nullValue()))); assertThat(contentSectionRepo, is(not(nullValue()))); + assertThat(shiro, is(not(nullValue()))); } /** @@ -170,12 +177,12 @@ public class ContentTypeRepositoryTest { assertThat(types, is(not(nullValue()))); assertThat(types.isEmpty(), is(false)); assertThat(types.size(), is(2)); - + assertThat(types.get(0).getContentItemClass(), is(equalTo(Article.class.getName()))); assertThat(types.get(0).getContentSection().getDisplayName(), is(equalTo("info"))); - + assertThat(types.get(1).getContentItemClass(), is(equalTo(News.class.getName()))); assertThat(types.get(1).getContentSection().getDisplayName(), @@ -369,6 +376,26 @@ public class ContentTypeRepositoryTest { .findByContentSectionAndClass(section, News.class); assertThat(newsType.isPresent(), is(true)); + shiro.getSystemUser() + .execute(() -> contentTypeRepo.delete(newsType.get())); + } + + /** + * Verifies that an unused content type can be deleted. + */ + @Test(expected = UnauthorizedException.class) + @InSequence(2000) + @UsingDataSet("datasets/org/librecms/contentsection/" + + "ContentTypeRepositoryTest/data.xml") + @ShouldMatchDataSet("datasets/org/librecms/contentsection/" + + "ContentTypeRepositoryTest/data.xml") + @ShouldThrowException(UnauthorizedException.class) + public void deleteUnusedContentTypeUnauthorized() { + final ContentSection section = contentSectionRepo.findById(-1001L); + final Optional newsType = contentTypeRepo + .findByContentSectionAndClass(section, News.class); + assertThat(newsType.isPresent(), is(true)); + contentTypeRepo.delete(newsType.get()); } @@ -377,7 +404,7 @@ public class ContentTypeRepositoryTest { * Verifies that content types which are in use can't be deleted. */ @Test(expected = IllegalArgumentException.class) - @InSequence(2000) + @InSequence(2200) @UsingDataSet("datasets/org/librecms/contentsection/" + "ContentTypeRepositoryTest/data.xml") @ShouldMatchDataSet("datasets/org/librecms/contentsection/" @@ -389,7 +416,8 @@ public class ContentTypeRepositoryTest { .findByContentSectionAndClass(section, Article.class); assertThat(articleType.isPresent(), is(true)); - contentTypeRepo.delete(articleType.get()); + shiro.getSystemUser() + .execute(() -> contentTypeRepo.delete(articleType.get())); } } diff --git a/ccm-cms/src/test/resources/datasets/org/librecms/contentsection/ContentTypeRepositoryTest/data.xml b/ccm-cms/src/test/resources/datasets/org/librecms/contentsection/ContentTypeRepositoryTest/data.xml index d36057f89..acb15e123 100644 --- a/ccm-cms/src/test/resources/datasets/org/librecms/contentsection/ContentTypeRepositoryTest/data.xml +++ b/ccm-cms/src/test/resources/datasets/org/librecms/contentsection/ContentTypeRepositoryTest/data.xml @@ -146,6 +146,18 @@ category_index="false" type="folder" /> + + + + assertThat( - oneTimeAuthManager.validTokenExistsForUser( - user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION), - is(true))); + () -> { + assertThat( + oneTimeAuthManager.validTokenExistsForUser( + user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION), + is(true)); + }); } @Test @@ -288,10 +290,12 @@ public class OneTimeAuthManagerTest { final User user = userRepository.findByName("mmuster"); shiro.getSystemUser().execute( - () -> assertThat( - oneTimeAuthManager.validTokenExistsForUser( - user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION), - is(false))); + () -> { + assertThat( + oneTimeAuthManager.validTokenExistsForUser( + user, OneTimeAuthTokenPurpose.EMAIL_VERIFICATION), + is(false)); + }); } @Test(expected = IllegalArgumentException.class) @@ -338,8 +342,10 @@ public class OneTimeAuthManagerTest { }); assertThat(result, is(not(empty()))); shiro.getSystemUser().execute( - () -> assertThat(oneTimeAuthManager.isValid(result.get(0)), - is(true))); + () -> { + assertThat(oneTimeAuthManager.isValid(result.get(0)), + is(true)); + }); } @Test @@ -363,7 +369,9 @@ public class OneTimeAuthManagerTest { token.setValidUntil(Date.from(date.toInstant(ZoneOffset.UTC))); shiro.getSystemUser().execute( - () -> assertThat(oneTimeAuthManager.isValid(token), is(false))); + () -> { + assertThat(oneTimeAuthManager.isValid(token), is(false)); + }); }