diff --git a/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__.java b/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__.java
index 2b66e9eaf..5d99732f2 100644
--- a/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__.java
+++ b/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__.java
@@ -7,7 +7,7 @@ import static ${package}.${typeName}Constants.*;
import org.hibernate.envers.Audited;
-import org.libreccm.cms.contentsection.ContentItem;
+import org.libreccm.contentsection.ContentItem;
import java.io.Serializable;
diff --git a/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__Module.java b/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__Module.java
index 7e839c91f..03624b7f4 100644
--- a/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__Module.java
+++ b/ccm-cms-archetype-contenttype/src/main/resources/archetype-resources/src/main/java/__typeName__Module.java
@@ -12,7 +12,7 @@ import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
@Module(packageName="${package}",
- requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore)})
+ requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore.class)})
public class ${typeName}Module implements CcmModule {
@Override
diff --git a/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/Externallink.java b/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/Externallink.java
index 8231ca1e7..4bf1cc4be 100644
--- a/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/Externallink.java
+++ b/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/Externallink.java
@@ -7,7 +7,7 @@ import static org.librecms.contenttypes.externallink.ExternallinkConstants.*;
import org.hibernate.envers.Audited;
-import org.libreccm.cms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItem;
import java.io.Serializable;
diff --git a/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/ExternallinkModule.java b/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/ExternallinkModule.java
index 5a3c72f13..698b5c0b0 100644
--- a/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/ExternallinkModule.java
+++ b/ccm-cms-types-externallink/src/main/java/org/librecms/contenttypes/externallink/ExternallinkModule.java
@@ -11,8 +11,9 @@ import org.libreccm.modules.RequiredModule;
import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
-@Module(packageName="org.librecms.contenttypes.externallink",
- requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore)})
+@Module(packageName = "org.librecms.contenttypes.externallink",
+ requiredModules = {
+ @RequiredModule(module = org.libreccm.core.CcmCore.class)})
public class ExternallinkModule implements CcmModule {
@Override
@@ -23,7 +24,7 @@ public class ExternallinkModule implements CcmModule {
@Override
public void init(final InitEvent event) {
//ToDo Add initialisation logic necessary for your module
- }
+ }
@Override
public void shutdown(final ShutdownEvent event) {
@@ -35,5 +36,4 @@ public class ExternallinkModule implements CcmModule {
//ToDo Remove module data
}
-
}
diff --git a/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitem.java b/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitem.java
index 3e7104199..2515a6caf 100644
--- a/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitem.java
+++ b/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitem.java
@@ -3,17 +3,16 @@
*/
package org.librecms.contenttypes.faqitem;
-import static org.librecms.contenttypes.faqitem.FAQitemConstants.*;
-
import org.hibernate.envers.Audited;
-
-import org.libreccm.cms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItem;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Table;
+import static org.librecms.contenttypes.faqitem.FAQitemConstants.*;
+
@Entity
@Audited
@Table(name = "${type_name}", schema = DB_SCHEMA)
diff --git a/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitemModule.java b/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitemModule.java
index edfa0a57a..2d2fad4a5 100644
--- a/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitemModule.java
+++ b/ccm-cms-types-faqitem/src/main/java/org/librecms/contenttypes/faqitem/FAQitemModule.java
@@ -11,8 +11,9 @@ import org.libreccm.modules.RequiredModule;
import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
-@Module(packageName="org.librecms.contenttypes.faqitem",
- requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore)})
+@Module(packageName = "org.librecms.contenttypes.faqitem",
+ requiredModules = {
+ @RequiredModule(module = org.libreccm.core.CcmCore.class)})
public class FAQitemModule implements CcmModule {
@Override
@@ -23,7 +24,7 @@ public class FAQitemModule implements CcmModule {
@Override
public void init(final InitEvent event) {
//ToDo Add initialisation logic necessary for your module
- }
+ }
@Override
public void shutdown(final ShutdownEvent event) {
@@ -35,5 +36,4 @@ public class FAQitemModule implements CcmModule {
//ToDo Remove module data
}
-
}
diff --git a/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/Glossaryitem.java b/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/Glossaryitem.java
index ba0c14ab3..2d6ce5a1f 100644
--- a/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/Glossaryitem.java
+++ b/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/Glossaryitem.java
@@ -6,8 +6,7 @@ package org.librecms.contenttypes.glossaryitem;
import static org.librecms.contenttypes.glossaryitem.GlossaryitemConstants.*;
import org.hibernate.envers.Audited;
-
-import org.libreccm.cms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItem;
import java.io.Serializable;
diff --git a/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/GlossaryitemModule.java b/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/GlossaryitemModule.java
index af3e1a083..35a2e2454 100644
--- a/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/GlossaryitemModule.java
+++ b/ccm-cms-types-glossaryitem/src/main/java/org/librecms/contenttypes/glossaryitem/GlossaryitemModule.java
@@ -12,7 +12,7 @@ import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
@Module(packageName="org.librecms.contenttypes.glossaryitem",
- requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore)})
+ requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore.class)})
public class GlossaryitemModule implements CcmModule {
@Override
diff --git a/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/Newsitem.java b/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/Newsitem.java
index 215e9027f..06c9ce067 100644
--- a/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/Newsitem.java
+++ b/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/Newsitem.java
@@ -7,7 +7,7 @@ import static org.librecms.contenttypes.newsitem.NewsitemConstants.*;
import org.hibernate.envers.Audited;
-import org.libreccm.cms.contentsection.ContentItem;
+import org.librecms.contentsection.ContentItem;
import java.io.Serializable;
diff --git a/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/NewsitemModule.java b/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/NewsitemModule.java
index 600d29afd..0637c7a79 100644
--- a/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/NewsitemModule.java
+++ b/ccm-cms-types-newsitem/src/main/java/org/librecms/contenttypes/newsitem/NewsitemModule.java
@@ -12,7 +12,7 @@ import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
@Module(packageName="org.librecms.contenttypes.newsitem",
- requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore)})
+ requiredModules = {@RequiredModule(module = org.libreccm.core.CcmCore.class)})
public class NewsitemModule implements CcmModule {
@Override
diff --git a/ccm-core/src/main/java/org/libreccm/security/AuthorizationInterceptor.java b/ccm-core/src/main/java/org/libreccm/security/AuthorizationInterceptor.java
new file mode 100644
index 000000000..9d80d2655
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/security/AuthorizationInterceptor.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.shiro.subject.Subject;
+import org.libreccm.core.CcmObject;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import javax.inject.Inject;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+import org.libreccm.security.PermissionChecker;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@AuthorizationRequired
+@Interceptor
+public class AuthorizationInterceptor {
+
+ private static final Logger LOGGER = LogManager.getLogger(
+ AuthorizationInterceptor.class);
+
+ @Inject
+ private Subject subject;
+
+ @Inject
+ private PermissionChecker permissionChecker;
+
+ @AroundInvoke
+ public Object intercept(final InvocationContext context) throws Exception {
+ LOGGER.debug("Intercepting method invocation");
+
+ final Method method = context.getMethod();
+ if (method == null) {
+ throw new IllegalArgumentException(
+ "The authoriziation interceptor can only be used for method");
+ }
+
+ if (method.isAnnotationPresent(RequiresRole.class)) {
+ final String requiredRole = method.getAnnotation(RequiresRole.class)
+ .value();
+ subject.checkRoles(requiredRole);
+ }
+
+ if (method.isAnnotationPresent(RequiresPrivilege.class)) {
+ final String requiredPrivilege = method.getAnnotation(
+ RequiresPrivilege.class).value();
+ permissionChecker.checkPermission(requiredPrivilege);
+ }
+
+ final Annotation[][] annotations = method.getParameterAnnotations();
+ final Object[] parameters = context.getParameters();
+ if (parameters != null && parameters.length > 0
+ && annotations != null && annotations.length > 0) {
+ for (int i = 0; i < parameters.length; i++) {
+ checkParameterPermission(parameters[i], annotations[i]);
+ }
+ }
+
+ return context.proceed();
+ }
+
+ private void checkParameterPermission(final Object parameter,
+ final Annotation[] annotations) {
+ if (parameter instanceof CcmObject
+ && annotations != null
+ && annotations.length > 0) {
+ final CcmObject object = (CcmObject) parameter;
+
+ String requiredPrivilege = null;
+ for(Annotation annotation : annotations) {
+ if (annotation instanceof RequiresPrivilege) {
+ requiredPrivilege = ((RequiresPrivilege) annotation).value();
+ break;
+ }
+ }
+
+ if (requiredPrivilege != null && !requiredPrivilege.isEmpty()) {
+ permissionChecker.checkPermission(requiredPrivilege, object);
+ }
+ }
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/security/AuthorizationRequired.java b/ccm-core/src/main/java/org/libreccm/security/AuthorizationRequired.java
new file mode 100644
index 000000000..f456accfd
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/security/AuthorizationRequired.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.interceptor.InterceptorBinding;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Inherited
+@Target({ElementType.TYPE, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@InterceptorBinding
+public @interface AuthorizationRequired {
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/security/RequiresPrivilege.java b/ccm-core/src/main/java/org/libreccm/security/RequiresPrivilege.java
new file mode 100644
index 000000000..8765b0321
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/security/RequiresPrivilege.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Inherited
+@Target({ElementType.METHOD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequiresPrivilege {
+
+ String value();
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/security/RequiresRole.java b/ccm-core/src/main/java/org/libreccm/security/RequiresRole.java
new file mode 100644
index 000000000..6030f18f8
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/security/RequiresRole.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Inherited
+@Target({ElementType.METHOD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RequiresRole {
+
+ String value();
+
+}
diff --git a/ccm-core/src/main/resources/META-INF/beans.xml b/ccm-core/src/main/resources/META-INF/beans.xml
new file mode 100644
index 000000000..d45765d18
--- /dev/null
+++ b/ccm-core/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,11 @@
+
+
+
+ org.libreccm.security.AuthorizationInterceptor
+
+
+
diff --git a/ccm-core/src/test/java/org/libreccm/security/AuthorizationInterceptorTest.java b/ccm-core/src/test/java/org/libreccm/security/AuthorizationInterceptorTest.java
new file mode 100644
index 000000000..a847c52fa
--- /dev/null
+++ b/ccm-core/src/test/java/org/libreccm/security/AuthorizationInterceptorTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security;
+
+import com.arsdigita.kernel.KernelConfig;
+import com.arsdigita.kernel.security.SecurityConfig;
+import com.arsdigita.runtime.AbstractConfig;
+import com.arsdigita.util.UncheckedWrapperException;
+import com.arsdigita.util.parameter.AbstractParameterContext;
+import com.arsdigita.web.CCMApplicationContextListener;
+import com.arsdigita.xml.XML;
+import com.arsdigita.xml.formatters.DateTimeFormatter;
+
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.authz.AuthorizationException;
+import org.apache.shiro.subject.Subject;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.ShouldThrowException;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.junit.InSequence;
+import org.jboss.arquillian.persistence.CreateSchema;
+import org.jboss.arquillian.persistence.PersistenceTest;
+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.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.libreccm.categorization.Categorization;
+import org.libreccm.core.CcmObject;
+import org.libreccm.core.CcmObjectRepository;
+import org.libreccm.jpa.EntityManagerProducer;
+import org.libreccm.jpa.utils.MimeTypeConverter;
+import org.libreccm.l10n.LocalizedString;
+import org.libreccm.security.authorization.LabBean;
+import org.libreccm.tests.categories.IntegrationTest;
+
+import org.libreccm.testutils.EqualsVerifier;
+import org.libreccm.web.CcmApplication;
+
+import java.io.File;
+
+import javax.inject.Inject;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Category(IntegrationTest.class)
+@RunWith(Arquillian.class)
+@PersistenceTest
+@Transactional(TransactionMode.COMMIT)
+@CreateSchema({"create_ccm_core_schema.sql"})
+public class AuthorizationInterceptorTest {
+
+ @Inject
+ private Subject subject;
+
+ @Inject
+ private CcmObjectRepository objectRepository;
+
+ @Inject
+ private LabBean labBean;
+
+ public AuthorizationInterceptorTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Deployment
+ public static WebArchive createDeployment() {
+ final PomEquippedResolveStage pom = Maven
+ .resolver()
+ .loadPomFromFile("pom.xml");
+ final PomEquippedResolveStage dependencies = pom.
+ importCompileAndRuntimeDependencies();
+ final File[] libs = dependencies.resolve().withTransitivity().asFile();
+
+ for (File lib : libs) {
+ System.err.printf("Adding file '%s' to test archive...%n",
+ lib.getName());
+ }
+
+ return ShrinkWrap
+ .create(WebArchive.class,
+ "LibreCCM-org.libreccm.security.PermissionCheckerTest.war")
+ .addPackage(User.class.getPackage())
+ .addPackage(CcmObject.class.getPackage())
+ .addPackage(Categorization.class.getPackage())
+ .addPackage(LocalizedString.class.getPackage())
+ .addPackage(CcmApplication.class.getPackage())
+ .addPackage(EntityManagerProducer.class.getPackage())
+ .addPackage(MimeTypeConverter.class.getPackage())
+ .addPackage(EqualsVerifier.class.getPackage())
+ .addPackage(IntegrationTest.class.getPackage())
+ .addPackage(KernelConfig.class.getPackage())
+ .addPackage(SecurityConfig.class.getPackage())
+ .addPackage(AbstractConfig.class.getPackage())
+ .addPackage(AbstractParameterContext.class.getPackage())
+ .addPackage(UncheckedWrapperException.class.getPackage())
+ .addPackage(CCMApplicationContextListener.class.getPackage())
+ .addPackage(XML.class.getPackage())
+ .addPackage(DateTimeFormatter.class.getPackage())
+ .addPackage(LabBean.class.getPackage())
+ .addAsLibraries(libs)
+ .addAsResource("test-persistence.xml",
+ "META-INF/persistence.xml")
+ .addAsResource("com/arsdigita/kernel/"
+ + "KernelConfig_parameter.properties",
+ "com/arsdigita/kernel/"
+ + "KernelConfig_parameter.properties")
+ .addAsResource("com/arsdigita/kernel/security/"
+ + "SecurityConfig_parameter.properties",
+ "com/arsdigita/kernel/security/"
+ + "SecurityConfig_parameter.properties")
+ .addAsWebInfResource(
+ "configs/org/libreccm/security/UserManagerTest/"
+ + "registry.properties",
+ "conf/registry/registry.properties")
+ .addAsResource(
+ "configs/org/libreccm/security/UserManagerTest/ccm-core.config",
+ "ccm-core.config")
+ .addAsResource(
+ "configs/org/libreccm/security/ShiroTest/shiro.ini",
+ "shiro.ini")
+ .addAsResource(
+ "configs/org/libreccm/security/ShiroTest/log4j2.xml",
+ "log4j2.xml")
+ .addAsWebInfResource(
+ "configs/org/libreccm/security/ShiroTest/"
+ + "kernel.properties",
+ "conf/registry/ccm-core/kernel.properties")
+ .addAsWebInfResource(
+ "configs/org/libreccm//security/ShiroTest/"
+ + "security.properties",
+ "conf/registry/ccm-core/security.properties")
+ .addAsWebInfResource("test-web.xml", "web.xml")
+ .addAsWebInfResource("META-INF/beans.xml", "beans.xml");
+ }
+
+ @Test
+ @InSequence(10)
+ public void labBeanIsInjected() {
+ assertThat(labBean, is(not(nullValue())));
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @InSequence(100)
+ public void checkRequiresRoleAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("mmuster",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ labBean.doSomethingWhichRequiresRole();
+ }
+
+ @Test(expected = AuthorizationException.class)
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @ShouldThrowException(AuthorizationException.class)
+ @InSequence(200)
+ public void checkRequiresRoleNotAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("jdoe",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ labBean.doSomethingWhichRequiresRole();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @InSequence(300)
+ public void checkRequiresPermissionAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("mmuster",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ labBean.doSomethingWhichRequiresPermission();
+ }
+
+ @Test(expected = AuthorizationException.class)
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @ShouldThrowException(AuthorizationException.class)
+ @InSequence(400)
+ public void checkRequiresPermissionNotAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("jdoe",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ labBean.doSomethingWhichRequiresPermission();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @InSequence(500)
+ public void checkRequiresPermissionOnObjectAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("mmuster",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ final CcmObject object1 = objectRepository.findById(-20001L);
+
+ labBean.doSomethingWhichRequiresPermissionOnObject(object1);
+ }
+
+ @Test(expected = AuthorizationException.class)
+ @UsingDataSet("datasets/org/libreccm/security/ShiroTest/data.yml")
+ @ShouldThrowException(AuthorizationException.class)
+ @InSequence(600)
+ public void checkRequiresPermissionOnObjectNotAuthorized() {
+ final UsernamePasswordToken token = new UsernamePasswordToken("jdoe",
+ "foo123");
+ token.setRememberMe(true);
+ subject.login(token);
+
+ final CcmObject object1 = objectRepository.findById(-20001L);
+
+ labBean.doSomethingWhichRequiresPermissionOnObject(object1);
+ }
+
+}
diff --git a/ccm-core/src/test/java/org/libreccm/security/authorization/LabBean.java b/ccm-core/src/test/java/org/libreccm/security/authorization/LabBean.java
new file mode 100644
index 000000000..30ad99e7f
--- /dev/null
+++ b/ccm-core/src/test/java/org/libreccm/security/authorization/LabBean.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.security.authorization;
+
+import org.apache.shiro.subject.Subject;
+import org.libreccm.core.CcmObject;
+import org.libreccm.security.AuthorizationInterceptorTest;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.security.RequiresRole;
+
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+/**
+ * A simple bean used by the {@link AuthorizationInterceptorTest}.
+ *
+ * @author Jens Pelzetter
+ */
+@RequestScoped
+public class LabBean {
+
+ @Inject
+ private Subject subject;
+
+ @AuthorizationRequired
+ @RequiresRole("role1")
+ public void doSomethingWhichRequiresRole() {
+ assertThat(subject.hasRole("role1"), is(true));
+ }
+
+ @AuthorizationRequired
+ @RequiresPrivilege("privilege1")
+ public void doSomethingWhichRequiresPermission() {
+ assertThat(subject.isPermitted("privilege1"), is(true));
+ }
+
+ @AuthorizationRequired
+ public void doSomethingWhichRequiresPermissionOnObject(
+ @RequiresPrivilege("privilege2")
+ final CcmObject object) {
+ assertThat(subject.isPermitted(
+ String.format("privilege2:%d", object.getObjectId())),
+ is(true));
+ }
+}
diff --git a/pom.xml b/pom.xml
index fc1a6efab..240b5d918 100644
--- a/pom.xml
+++ b/pom.xml
@@ -53,11 +53,11 @@
ccm-cms-types-event
ccm-cms-types-minutes
ccm-cms-types-decisiontree
- ccm-cms-types-mparticle
- ccm-cms-types-glossaryitem
- ccm-cms-types-faqitem
- ccm-cms-types-externallink
- ccm-cms-types-newsitem
+ ccm-cms-types-mparticle
+ ccm-cms-types-glossaryitem
+ ccm-cms-types-faqitem
+ ccm-cms-types-externallink
+ ccm-cms-types-newsitem