CCM NG: ccm-shortcuts: Secured methods for creating, saving and deleting Shortcuts with the appropriate annoations from ccm-core/org.libreccm.security. Tests for ShortcutManager extended to check if the authorization check works as intented.

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4149 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-06-10 09:35:27 +00:00
parent e7f4e49a15
commit fea14a860e
7 changed files with 221 additions and 52 deletions

View File

@ -18,8 +18,9 @@
*/ */
package org.libreccm.shortcuts; package org.libreccm.shortcuts;
import java.net.URI;
import java.net.URL; import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
@ -46,6 +47,8 @@ public class ShortcutManager {
* @param redirect The URL to which the Shortcut redirects. Can't be null. * @param redirect The URL to which the Shortcut redirects. Can't be null.
* @return the new Shortcut * @return the new Shortcut
*/ */
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
public Shortcut createShortcut(final String url, final String redirect) { public Shortcut createShortcut(final String url, final String redirect) {
if (url == null || url.trim().isEmpty()) { if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

@ -19,6 +19,8 @@
package org.libreccm.shortcuts; package org.libreccm.shortcuts;
import org.libreccm.core.AbstractEntityRepository; import org.libreccm.core.AbstractEntityRepository;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -78,4 +80,17 @@ public class ShortcutRepository extends AbstractEntityRepository<Long, Shortcut>
return query.getResultList(); return query.getResultList();
} }
@Override
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
public void save(final Shortcut shortcut) {
super.save(shortcut);
}
@Override
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
public void delete(final Shortcut shortcut) {
super.delete(shortcut);
}
} }

View File

@ -18,17 +18,19 @@
*/ */
package org.libreccm.shortcuts; package org.libreccm.shortcuts;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.subject.Subject;
import java.io.File; import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import javax.inject.Inject; import javax.inject.Inject;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.ShouldThrowException; import org.jboss.arquillian.container.test.api.ShouldThrowException;
import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.junit.Arquillian;
@ -40,7 +42,6 @@ import org.jboss.arquillian.persistence.UsingDataSet;
import org.jboss.arquillian.transaction.api.annotation.TransactionMode; import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
import org.jboss.arquillian.transaction.api.annotation.Transactional; import org.jboss.arquillian.transaction.api.annotation.Transactional;
import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven; import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage; import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
@ -53,6 +54,7 @@ import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.experimental.categories.Category; import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.libreccm.security.Shiro;
import org.libreccm.tests.categories.IntegrationTest; import org.libreccm.tests.categories.IntegrationTest;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
@ -72,6 +74,12 @@ public class ShortcutManagerTest {
@Inject @Inject
private ShortcutManager shortcutManager; private ShortcutManager shortcutManager;
@Inject
private Shiro shiro;
@Inject
private Subject subject;
@PersistenceContext @PersistenceContext
private EntityManager entityManager; private EntityManager entityManager;
@ -110,8 +118,8 @@ public class ShortcutManagerTest {
dependencies.addDependency(MavenDependencies.createDependency( dependencies.addDependency(MavenDependencies.createDependency(
"org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven", "org.jboss.shrinkwrap.resolver:shrinkwrap-resolver-impl-maven",
ScopeType.RUNTIME, false)); ScopeType.RUNTIME, false));
final File[] libsWithCcmCore = dependencies.resolve().withTransitivity(). final File[] libsWithCcmCore = dependencies.resolve().withTransitivity()
asFile(); .asFile();
final List<File> libsList = new ArrayList<>(libsWithCcmCore.length - 1); final List<File> libsList = new ArrayList<>(libsWithCcmCore.length - 1);
IntStream.range(0, libsWithCcmCore.length).forEach(i -> { IntStream.range(0, libsWithCcmCore.length).forEach(i -> {
@ -132,6 +140,7 @@ public class ShortcutManagerTest {
"LibreCCM-org.libreccm.shortcuts.ShortcutTest-web.war") "LibreCCM-org.libreccm.shortcuts.ShortcutTest-web.war")
.addPackage(org.libreccm.categorization.Categorization.class .addPackage(org.libreccm.categorization.Categorization.class
.getPackage()) .getPackage())
.addPackage(org.libreccm.cdi.utils.CdiUtil.class.getPackage())
.addPackage(org.libreccm.configuration.Configuration.class .addPackage(org.libreccm.configuration.Configuration.class
.getPackage()) .getPackage())
.addPackage(org.libreccm.core.CcmCore.class.getPackage()) .addPackage(org.libreccm.core.CcmCore.class.getPackage())
@ -143,11 +152,13 @@ public class ShortcutManagerTest {
.addPackage(org.libreccm.shortcuts.Shortcuts.class.getPackage()) .addPackage(org.libreccm.shortcuts.Shortcuts.class.getPackage())
.addPackage(org.libreccm.web.CcmApplication.class.getPackage()) .addPackage(org.libreccm.web.CcmApplication.class.getPackage())
.addPackage(org.libreccm.workflow.Workflow.class.getPackage()) .addPackage(org.libreccm.workflow.Workflow.class.getPackage())
.addClass(com.arsdigita.kernel.KernelConfig.class)
.addAsLibraries(libs) .addAsLibraries(libs)
.addAsResource("configs/shiro.ini", "shiro.ini")
.addAsResource("test-persistence.xml", .addAsResource("test-persistence.xml",
"META-INF/persistence.xml") "META-INF/persistence.xml")
.addAsWebInfResource("test-web.xml", "WEB-INF/web.xml") .addAsWebInfResource("test-web.xml", "web.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml"); .addAsResource("test-beans.xml", "META-INF/beans.xml");
} }
@Test @Test
@ -169,7 +180,42 @@ public class ShortcutManagerTest {
value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml", value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml",
excludeColumns = {"shortcut_id"}) excludeColumns = {"shortcut_id"})
@InSequence(100) @InSequence(100)
public void createShortcutStringParams() { public void createShortcutBySystemUser() {
final Subject systemUser = shiro.getSystemUser();
systemUser.execute(() -> {
shortcutManager.createShortcut("datenschutz",
"/ccm/navigation/privacy");
return null;
});
}
@Test
@UsingDataSet(
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldMatchDataSet(
value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml",
excludeColumns = {"shortcut_id"})
@InSequence(110)
public void createShortcutByAuthorizedUser() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut("datenschutz",
"/ccm/navigation/privacy");
subject.logout();
}
@Test(expected = UnauthorizedException.class)
@UsingDataSet(
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(UnauthorizedException.class)
@InSequence(120)
public void createShortcutByUnAuthorizedUser() {
shortcutManager.createShortcut("datenschutz", shortcutManager.createShortcut("datenschutz",
"/ccm/navigation/privacy"); "/ccm/navigation/privacy");
} }
@ -178,9 +224,16 @@ public class ShortcutManagerTest {
@UsingDataSet( @UsingDataSet(
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(IllegalArgumentException.class) @ShouldThrowException(IllegalArgumentException.class)
@InSequence(110) @InSequence(130)
public void createShortcutStringParamsNullUrlKey() { public void createShortcutNullUrlKey() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut(null, "http://www.example.org"); shortcutManager.createShortcut(null, "http://www.example.org");
subject.logout();
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -188,8 +241,15 @@ public class ShortcutManagerTest {
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(IllegalArgumentException.class) @ShouldThrowException(IllegalArgumentException.class)
@InSequence(120) @InSequence(120)
public void createShortcutStringParamsNullRedirect() { public void createShortcutNullRedirect() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut("example", null); shortcutManager.createShortcut("example", null);
subject.logout();
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -197,8 +257,15 @@ public class ShortcutManagerTest {
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(IllegalArgumentException.class) @ShouldThrowException(IllegalArgumentException.class)
@InSequence(140) @InSequence(140)
public void createShortcutStringParamsEmptyUrlKey() { public void createShortcutEmptyUrlKey() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut(" ", "http://www.example.org"); shortcutManager.createShortcut(" ", "http://www.example.org");
subject.logout();
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -206,8 +273,15 @@ public class ShortcutManagerTest {
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(IllegalArgumentException.class) @ShouldThrowException(IllegalArgumentException.class)
@InSequence(150) @InSequence(150)
public void createShortcutStringParamsEmptyRedirect() { public void createShortcutEmptyRedirect() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut("example", " "); shortcutManager.createShortcut("example", " ");
subject.logout();
} }
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
@ -215,8 +289,15 @@ public class ShortcutManagerTest {
"datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml")
@ShouldThrowException(IllegalArgumentException.class) @ShouldThrowException(IllegalArgumentException.class)
@InSequence(160) @InSequence(160)
public void createShortcutStringParamsEmptyParams() { public void createShortcutEmptyParams() {
final UsernamePasswordToken token = new UsernamePasswordToken(
"john.doe@example.org", "foo123");
token.setRememberMe(true);
subject.login(token);
shortcutManager.createShortcut("", ""); shortcutManager.createShortcut("", "");
subject.logout();
} }
// @Test // @Test

View File

@ -0,0 +1,10 @@
[main]
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher.passwordService = $passwordService
ccmRealm = org.libreccm.security.CcmShiroRealm
ccmRealm.credentialsMatcher = $passwordMatcher
securityManager.realms = $ccmRealm

View File

@ -1,5 +1,40 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<dataset> <dataset>
<ccm_core.parties party_id="-100"
name="public-user" />
<ccm_core.parties party_id="-110"
name="jdoe" />
<ccm_core.users party_id="-100"
given_name="public"
family_name="user"
email_address="public-user@localhost"
banned="false"
bouncing="false"
verified="true"
password_reset_required="false" />
<!-- Password is foo123 -->
<ccm_core.users party_id="-110"
given_name="John"
family_name="Doe"
email_address="john.doe@example.org"
password="$shiro1$SHA-512$500000$Y7CnccN1h25sR7KCElMOXg==$CVLWBhetodaEzzhDfGjRcCFZtSW02xOnjH7xhBx0lbxO66grKIt6LWmXoUhLEydce1JZ7cbzNLYOxIwwTeqi5Q=="
banned="false"
bouncing="false"
verified="true"
password_reset_required="false" />
<ccm_core.ccm_roles role_id="-200"
name="shortcuts-manager"/>
<ccm_core.role_memberships membership_id="-300"
role_id="-200"
member_id="-110" />
<ccm_core.permissions permission_id="-400"
granted_privilege="manage_shortcuts"
grantee_id="-200" />
<ccm_shortcuts.shortcuts shortcut_id="-10" <ccm_shortcuts.shortcuts shortcut_id="-10"
url_key="mitglieder" url_key="mitglieder"
redirect="/ccm/navigation/members" /> redirect="/ccm/navigation/members" />

View File

@ -0,0 +1,11 @@
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="annotated">
<interceptors>
<class>org.libreccm.security.AuthorizationInterceptor</class>
</interceptors>
</beans>

View File

@ -6,4 +6,18 @@
version="3.0"> version="3.0">
<display-name>LibreCCM Shortcuts Test</display-name> <display-name>LibreCCM Shortcuts Test</display-name>
<filter>
<filter-name>ShiroFilter</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ShiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
</web-app> </web-app>