diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutFilter.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutFilter.java new file mode 100644 index 000000000..991c71ad3 --- /dev/null +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutFilter.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 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.shortcuts; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.Optional; + +import javax.inject.Inject; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * @author Jens Pelzetter + */ +public class ShortcutFilter implements Filter { + + private final static Logger LOGGER = LogManager.getLogger( + ShortcutFilter.class); + + @Inject + private ShortcutRepository shortcutRepository; + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + //Nothing + } + + @Override + public void doFilter(final ServletRequest request, + final ServletResponse response, + final FilterChain chain) + throws IOException, ServletException { + + if (request instanceof HttpServletRequest + && response instanceof HttpServletResponse) { + + final HttpServletRequest httpRequest = (HttpServletRequest) request; + + final String path = httpRequest.getRequestURI(); + LOGGER.debug( + "Request path into: '{}', path translated: '{}', URI: '{}'", + httpRequest.getPathInfo(), + httpRequest.getPathTranslated(), + httpRequest.getRequestURI()); + + if (path == null || path.isEmpty()) { + LOGGER.debug("No path, passing off to next filter."); + + chain.doFilter(request, response); + return; + } + + final Optional shortcut = shortcutRepository.findByUrlKey( + path); + + if (shortcut.isPresent()) { + LOGGER.debug("Found Shortcut for path {}: {}", + path, + shortcut.toString()); + final StringBuffer targetBuffer = new StringBuffer(shortcut + .get() + .getRedirect()); + + final String queryString = httpRequest.getQueryString(); + if (queryString != null && !queryString.isEmpty()) { + LOGGER.debug("Request URL has query parameters. Appending " + + "then to target URL."); + + targetBuffer.append('?'); + targetBuffer.append(queryString); + } + + final String target = targetBuffer.toString(); + LOGGER.debug("Redirecting to {}...", target); + + ((HttpServletResponse) response).sendRedirect(target); + } else { + LOGGER.debug( + "No Shortcut for {} found. Passing off to next filter.", + path); + chain.doFilter(request, response); + } + + } else { + LOGGER.debug("Request is not a HttpServletRequest. Passing off " + + "to next filter."); + chain.doFilter(request, response); + } + } + + @Override + public void destroy() { + //Nothing + } + +} diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutManager.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutManager.java index a07974ea8..61174ca93 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutManager.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutManager.java @@ -18,7 +18,6 @@ */ package org.libreccm.shortcuts; - import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; @@ -41,10 +40,12 @@ public class ShortcutManager { private ShortcutRepository shortcutRepository; /** - * Creates a Shortcut + * Creates a new Shortcut. The Shortcut is automatically saved to the + * database. * - * @param url The URL of the Shortcut. Can't be null. + * @param url The URL of the Shortcut. Can't be null. * @param redirect The URL to which the Shortcut redirects. Can't be null. + * * @return the new Shortcut */ @AuthorizationRequired @@ -52,25 +53,29 @@ public class ShortcutManager { public Shortcut createShortcut(final String url, final String redirect) { if (url == null || url.trim().isEmpty()) { throw new IllegalArgumentException( - "The URL key of a Shortcut can't be empty"); + "The URL key of a Shortcut can't be empty"); } if (redirect == null || redirect.trim().isEmpty()) { throw new IllegalArgumentException( - "The redirect target of a Shortcut can't be empty"); + "The redirect target of a Shortcut can't be empty"); } Shortcut shortcut = new Shortcut(); shortcut.setUrlKey(url); shortcut.setRedirect(redirect); + + shortcutRepository.save(shortcut); + return shortcut; } /** * Creates a Shortcut * - * @param url The URL of the Shortcut. Can't be null. + * @param url The URL of the Shortcut. Can't be null. * @param redirect The URL to which the Shortcut redirects. Can't be null. + * * @return the new Shortcut */ // public Shortcut createShortcut(final URL url, final URL redirect) { @@ -89,12 +94,12 @@ public class ShortcutManager { // shortcut.setRedirect(redirect.toString()); // return shortcut; // } - /** * Creates a Shortcut * - * @param uri The URI of the Shortcut. Can't be null. + * @param uri The URI of the Shortcut. Can't be null. * @param redirect The URI to which the Shortcut redirects. Can't be null. + * * @return the new Shortcut */ // public Shortcut createShortcut(final URI uri, final URI redirect) { @@ -113,7 +118,6 @@ public class ShortcutManager { // shortcut.setRedirect(redirect.toString()); // return shortcut; // } - /** * checks if the Shortcut exists. * @@ -128,8 +132,9 @@ public class ShortcutManager { * checks if the given URL is valid * * @param url the URL you want to validate + * * @return true if you can successfully connect to the url, therefore is - * valid. + * valid. */ private boolean validateURL(final String url) { //TODO diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutRepository.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutRepository.java index 8fd287d19..dad6a40b2 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutRepository.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/ShortcutRepository.java @@ -18,6 +18,8 @@ */ package org.libreccm.shortcuts; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.core.AbstractEntityRepository; import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.RequiresPrivilege; @@ -36,6 +38,9 @@ import javax.persistence.TypedQuery; @RequestScoped public class ShortcutRepository extends AbstractEntityRepository { + private static final Logger LOGGER = LogManager.getLogger( + ShortcutRepository.class); + @Override public Class getEntityClass() { return Shortcut.class; @@ -54,9 +59,11 @@ public class ShortcutRepository extends AbstractEntityRepository * @return The shortcut with the specified {@code urlKey} if there is any. */ public Optional findByUrlKey(final String urlKey) { + LOGGER.debug("Trying to find Shortcut for urlKey {}", + cleanUrlKey(urlKey)); final TypedQuery query = getEntityManager().createNamedQuery( "Shortcut.findByUrlKey", Shortcut.class); - query.setParameter("urlKey", urlKey); + query.setParameter("urlKey", cleanUrlKey(urlKey)); try { final Shortcut result = query.getSingleResult(); @@ -65,18 +72,19 @@ public class ShortcutRepository extends AbstractEntityRepository return Optional.empty(); } } - + /** * Finds all shortcuts which redirect to the provided target. * * @param redirect the wanted redirect + * * @return a List of Shortcuts with the specified {@code redirect} */ public List findByRedirect(final String redirect) { final TypedQuery query = getEntityManager().createNamedQuery( "Shortcut.findByRedirect", Shortcut.class); query.setParameter("redirect", redirect); - + return query.getResultList(); } @@ -84,13 +92,33 @@ public class ShortcutRepository extends AbstractEntityRepository @AuthorizationRequired @RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE) public void save(final Shortcut shortcut) { + //Cleanup the URL key + shortcut.setUrlKey(cleanUrlKey(shortcut.getUrlKey())); + super.save(shortcut); } - + @Override @AuthorizationRequired @RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE) public void delete(final Shortcut shortcut) { super.delete(shortcut); } + + private String cleanUrlKey(final String urlKey) { + final StringBuffer result = new StringBuffer(urlKey.length()); + + if (!urlKey.startsWith("/")) { + result.append('/'); + } + + result.append(urlKey); + + if (!urlKey.endsWith("/")) { + result.append('/'); + } + + return result.toString(); + } + } diff --git a/ccm-shortcuts/src/test/java/org/libreccm/shortcuts/ShortcutManagerTest.java b/ccm-shortcuts/src/test/java/org/libreccm/shortcuts/ShortcutManagerTest.java index 13f11253c..da070fcf9 100644 --- a/ccm-shortcuts/src/test/java/org/libreccm/shortcuts/ShortcutManagerTest.java +++ b/ccm-shortcuts/src/test/java/org/libreccm/shortcuts/ShortcutManagerTest.java @@ -177,7 +177,7 @@ public class ShortcutManagerTest { @UsingDataSet( "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") @ShouldMatchDataSet( - value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml", + value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml", excludeColumns = {"shortcut_id"}) @InSequence(100) public void createShortcutBySystemUser() { @@ -195,7 +195,7 @@ public class ShortcutManagerTest { @UsingDataSet( "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml") @ShouldMatchDataSet( - value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml", + value = "datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml", excludeColumns = {"shortcut_id"}) @InSequence(110) public void createShortcutByAuthorizedUser() { diff --git a/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml b/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml index 4d6919d68..53da6deef 100644 --- a/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml +++ b/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/after-create.xml @@ -1,19 +1,54 @@ + + + + + + + + + + + + + diff --git a/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml b/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml index c9384f3af..ce70d54f0 100644 --- a/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml +++ b/ccm-shortcuts/src/test/resources/datasets/org/libreccm/shortcuts/ShortcutManagerTest/data.xml @@ -36,15 +36,15 @@ grantee_id="-200" />