diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java index 0decb6201bc..ee8b9ebfff7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/AbstractMapTokenizer.java @@ -18,6 +18,26 @@ public abstract class AbstractMapTokenizer

implements PlaceToke @Override public P getPlace(String token) { + /* + * See bug 6088; the token delivered here as parameter has undergone encoding/decoding using URL.encodeURI; this + * leaves encoded characters with special meaning in the URL untouched, such as '/', '&' or '?', meaning that + * their encoding such as %2F for the '/' character will remain unchanged in the token and will not be replaced + * by '/'. Other characters, such as the '%' character, encoded as '%25', will be decoded. + * + * But we do need to be able to encode special characters in tokens, e.g., for regatta names which may contain + * any UTF character. The problem, though, is that what we receive here as the "token" parameter is already a + * "projection" that cannot be inverted to the original string. For example, when we see "%2F" as the "token" + * value, we cannot tell whether the original URL hash/fragment was "%252F" or just "%2F" as the latter would + * have been returned unchanged. + * + * Alternatively, we could look at Window.Location.getHash() and silently assume that that would be what was + * decoded and then passed to this method; interestingly, the call to here from SwitchingEntryPoint.onModuleLoad() + * passes an non-decoded hash/fragment taken straight from Window.Location.getHash(). + * + * Yet alternatively, we could find an encoding of values in tokens that is guaranteed to never produce the + * offending characters such as '%', '/' or the like. As an extreme case, we could use a Base64 encoding + * of all values and then run a Base64 decoding to obtain the original token again. + */ return getPlaceFromParameters(toParameterMap(token)); } @@ -32,7 +52,6 @@ public abstract class AbstractMapTokenizer

implements PlaceToke private String toToken(Map> parameters) { StringBuilder stringBuilder = new StringBuilder(); - for (Map.Entry> entry : parameters.entrySet()) { if (entry.getValue() == null || entry.getValue().isEmpty()) { continue; @@ -41,31 +60,34 @@ public abstract class AbstractMapTokenizer

implements PlaceToke if (stringBuilder.length() > 0) { stringBuilder.append("&"); } - stringBuilder.append(entry.getKey() + "=" + val); + stringBuilder.append(entry.getKey() + "=" + val); // see bug6088; values must contain only URL-compliant characters, so any encoding must be done by the caller } } - return stringBuilder.toString(); } private Map> toParameterMap(String placeParametersAsToken) { - List list = Arrays.asList(placeParametersAsToken.split("&")); - + final Map> result; + final List list = Arrays.asList(placeParametersAsToken.split("&")); if (list == null || list.size() < 1) { logger.warning("Token empty, no-op"); - Collections.emptyMap(); - } - - Map> result = new HashMap<>(); - for (String listItem : list) { - String[] nvPair = listItem.split("="); - if (nvPair == null || nvPair.length != 2) { - logger.warning("Invalid parameters"); - continue; + result = Collections.emptyMap(); + } else { + result = new HashMap<>(); + for (String listItem : list) { + final int indexOfEquals = listItem.indexOf('='); // don't use "split" because value may contain '=' characters + final String key; + final String value; + if (indexOfEquals < 0) { + key = listItem; + value = null; + } else { + key = listItem.substring(0, indexOfEquals); + value = listItem.substring(indexOfEquals+1); + } + Util.addToValueSet(result, key, value); // see bug6088; values are expected to travel safely through URLs; encoding is the caller's responsibility } - Util.addToValueSet(result, nvPair[0], nvPair[1]); } return result; } - } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/NavigatorUtil.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/NavigatorUtil.java index ef82171a6d5..a7e8bd1407c 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/NavigatorUtil.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/NavigatorUtil.java @@ -7,39 +7,44 @@ import com.sap.sse.gwt.client.Notification.NotificationType; public class NavigatorUtil { /** - * Note that this method will check whether the browser does support the copyToClipboard feature first - * and will display a warning notification if it does not, to prevent JS error messages in the console. - * Please use {@link clientHasNavigatorCopyToClipboardSupport} to check for browser support, - * if case specific handling is required. - * On a successful copy an info notification is displayed. - * @param String text: Text to share. + * Note that this method will check whether the browser does support the copyToClipboard feature first and will + * display a warning notification if it does not, to prevent JS error messages in the console. Please use + * {@link clientHasNavigatorCopyToClipboardSupport} to check for browser support, if case specific handling is + * required. On a successful copy an info notification is displayed. + * + * @param String + * text: Text to share. */ public static void copyToClipboard(String text) { - if(nativeClientHasNavigatorCopyToClipboardSupport()) { + if (nativeClientHasNavigatorCopyToClipboardSupport()) { nativeCopyToClipboard(text); Notification.notify(StringMessages.INSTANCE.sharingLinkCopied(), NotificationType.INFO); - }else { + } else { GWT.log("This browser does not support copying to clipboard"); - Notification.notify(StringMessages.INSTANCE.browserDoesNotSupportCopyToClipboard(), NotificationType.WARNING); + Notification.notify(StringMessages.INSTANCE.browserDoesNotSupportCopyToClipboard(), + NotificationType.WARNING); } } /** - * Note that this method will check whether the browser does support the sharing feature first - * and will display a warning notification if it does not, to prevent JS error messages in the console. - * Please use {@link clientHasNavigatorShareSupport} to check for browser support, if case specific handling is required. - * @param String url: URL to share. - * @param String text: Optional text to share. + * Note that this method will check whether the browser does support the sharing feature first and will display a + * warning notification if it does not, to prevent JS error messages in the console. Please use + * {@link clientHasNavigatorShareSupport} to check for browser support, if case specific handling is required. + * + * @param String + * url: URL to share. + * @param String + * text: Optional text to share. */ public static void shareUrl(String url, String text) { - if(nativeClientHasNavigatorShareSupport()) { - if(text != null) { + if (nativeClientHasNavigatorShareSupport()) { + if (text != null) { nativeShareUrlAndText(url, text); - }else { + } else { nativeShareUrl(url); } - }else { + } else { GWT.log("This browser does not support native sharing"); Notification.notify(StringMessages.INSTANCE.browserDoesNotSupportNativeSharing(), NotificationType.WARNING); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/AbstractEventActivityProxy.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/AbstractEventActivityProxy.java index 7be9079e3ec..1da6a830671 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/AbstractEventActivityProxy.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/AbstractEventActivityProxy.java @@ -1,6 +1,7 @@ package com.sap.sailing.gwt.home.shared.places.event; import java.util.UUID; +import java.util.logging.Logger; import com.google.gwt.activity.shared.Activity; import com.sap.sailing.gwt.home.communication.event.GetEventViewAction; @@ -21,7 +22,8 @@ import com.sap.sse.gwt.client.mvp.AbstractActivityProxy; import com.sap.sse.gwt.client.mvp.ClientFactory; public abstract class AbstractEventActivityProxy extends AbstractActivityProxy implements ProvidesNavigationPath { - + private static final Logger logger = Logger.getLogger(AbstractEventActivityProxy.class.getName()); + private final C clientFactory; private AbstractEventPlace place; private NavigationPathDisplay navigationPathDisplay; @@ -55,7 +57,7 @@ public abstract class AbstractEventActivityProxy extends AbstractMapTokenizer { + /** + * See also {@code TokenizedHomePlaceUrlBuilder.EVENT_ID_PARAM} + */ private final static String PARAM_EVENTID = "eventId"; + + /** + * See also {@code TokenizedHomePlaceUrlBuilder.REGATTA_ID_PARAM}; expected to be a Base64 string that has been URL-encoded, + * so that the optional trailing '=' characters are properly encoded as %3D, for example. + */ private final static String PARAM_REGATTAID = "regattaId"; protected PLACE getPlaceFromParameters(Map> parameters) { + final String encodedRegattaId = extractSingleParameter(parameters, PARAM_REGATTAID); + String decodedRegattaId; + try { + decodedRegattaId = encodedRegattaId==null?null:new String(Base64Utils.fromBase64(encodedRegattaId)); + } catch (Throwable e) { + logger.warning("Error trying to decode regatta ID "+encodedRegattaId+"; trying to use URL decoding to obtain regatta name"); + decodedRegattaId = URL.decodeQueryString(encodedRegattaId); + } + // see bug 6088: regatta names may contain any UTF character and therefore need encoding return getRealPlace(new EventContext().withId(extractSingleParameter(parameters, PARAM_EVENTID)) - .withRegattaId(extractSingleParameter(parameters, PARAM_REGATTAID)), parameters); + .withRegattaId(decodedRegattaId), parameters); } private String extractSingleParameter(Map> parameters, String key) { @@ -63,9 +85,9 @@ public abstract class AbstractEventPlace extends Place implements HasLocationTit Map> parameters = new HashMap<>(); EventContext context = place.getCtx(); Util.addToValueSet(parameters, PARAM_EVENTID, context.getEventId()); - String regattaId = context.getRegattaId(); + String regattaId = context.getRegattaId(); // bug 6088: we assume that a regatta id/name can contain any UTF character and therefore needs encoding if (regattaId != null && !regattaId.isEmpty()) { - Util.addToValueSet(parameters, PARAM_REGATTAID, context.getRegattaId()); + Util.addToValueSet(parameters, PARAM_REGATTAID, Base64Utils.toBase64(context.getRegattaId().getBytes())); } return parameters; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/EventContext.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/EventContext.java index 4c10ca45d17..e179004f2ac 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/EventContext.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/event/EventContext.java @@ -53,13 +53,13 @@ public class EventContext implements ShareablePlaceContext { @Override public String getContextAsPathParameters() { - if(eventId != null) { + if (eventId != null) { String path = "/events/" + eventId; - if(regattaId != null) { - path += "/regattas/" + URLEncoder.encode(regattaId); + if (regattaId != null) { + path += "/regattas/" + URLEncoder.encodeQueryString(regattaId); } return path; - }else { + } else { return null; } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupConfigPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupConfigPanel.java index 58056ef778d..61c24dc9bda 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupConfigPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LeaderboardGroupConfigPanel.java @@ -480,9 +480,9 @@ public class LeaderboardGroupConfigPanel extends AbstractRegattaPanel @Override public SafeHtml getValue(LeaderboardGroupDTO group) { String debugParam = Window.Location.getParameter("gwt.codesvr"); - String link = URLEncoder.encode("/gwt/Spectator.html?leaderboardGroupId=" + group.getId()+"&showRaceDetails=true&" + String link = "/gwt/Spectator.html?leaderboardGroupId=" + group.getId()+"&showRaceDetails=true&" + RaceBoardPerspectiveOwnSettings.PARAM_CAN_REPLAY_DURING_LIVE_RACES + "=true" - + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : "")); + + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + URLEncoder.encodeQueryString(debugParam) : ""); return ANCHORTEMPLATE.cell(UriUtils.fromString(link), group.getName()); } }; diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupOverviewPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupOverviewPanel.java index 7d09bcc6715..0b38a043712 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupOverviewPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/spectator/LeaderboardGroupOverviewPanel.java @@ -362,10 +362,10 @@ public class LeaderboardGroupOverviewPanel extends FormPanel { public SafeHtml getValue(StrippedLeaderboardDTO leaderboard) { LeaderboardGroupDTO selectedGroup = groupsSelectionModel.getSelectedObject(); String debugParam = Window.Location.getParameter("gwt.codesvr"); - String link = URLEncoder.encode("/gwt/Leaderboard.html?name=" + leaderboard.getName() + String link = "/gwt/Leaderboard.html?name=" + URLEncoder.encodeQueryString(leaderboard.getName()) + (showRaceDetails ? "&showRaceDetails=true" : "") + "&root=overview" + "&leaderboardGroupId=" + selectedGroup.getId().toString() - + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : "")); + + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + URLEncoder.encodeQueryString(debugParam) : ""); return ANCHORTEMPLATE.anchor(UriUtils.fromString(link), leaderboard.getName()); } }; @@ -455,11 +455,11 @@ public class LeaderboardGroupOverviewPanel extends FormPanel { StrippedLeaderboardDTO selectedLeaderboard = leaderboardsSelectionModel.getSelectedObject(); RegattaNameAndRaceName raceId = (RegattaNameAndRaceName) race.getRaceIdentifier(fleet); String debugParam = Window.Location.getParameter("gwt.codesvr"); - String link = URLEncoder.encode(RaceBoardPanel.RACEBOARD_PATH+"?leaderboardName=" - + selectedLeaderboard.getName() + "&raceName=" + raceId.getRaceName() + "®attaName=" - + raceId.getRegattaName() + "&leaderboardGroupId=" + selectedGroup.getId().toString() + String link = RaceBoardPanel.RACEBOARD_PATH+"?leaderboardName=" + + URLEncoder.encodeQueryString(selectedLeaderboard.getName()) + "&raceName=" + URLEncoder.encodeQueryString(raceId.getRaceName()) + "®attaName=" + + URLEncoder.encodeQueryString(raceId.getRegattaName()) + "&leaderboardGroupId=" + selectedGroup.getId().toString() + "&root=overview" - + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : "")); + + (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + URLEncoder.encodeQueryString(debugParam) : ""); name = ANCHORTEMPLATE.anchor(UriUtils.fromString(link), raceDisplayName); } else { name = new SafeHtmlBuilder().appendHtmlConstant(raceDisplayName).toSafeHtml(); diff --git a/java/com.sap.sailing.server.gateway/resources/SharedProxy.html b/java/com.sap.sailing.server.gateway/resources/SharedProxy.html index be0ee8e32ad..c31fcfbd261 100644 --- a/java/com.sap.sailing.server.gateway/resources/SharedProxy.html +++ b/java/com.sap.sailing.server.gateway/resources/SharedProxy.html @@ -11,6 +11,6 @@ ${disable_redirect_end} -

In case the redirect fails, please click here.
+
In case the redirect fails, please click here.
diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingResource.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingResource.java index e6ea4c40737..c2686e1a71d 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingResource.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingResource.java @@ -58,7 +58,7 @@ public class HomeSharingResource extends AbstractSailingServerResource { @Path("/events/{eventId}/regattas/{regattaId}") @Produces("text/html") public String getSharedRegatta(@PathParam("eventId") String eventId, @PathParam("regattaId") String regattaId, - @HeaderParam("user-agent") String userAgent) { + @HeaderParam("user-agent") String userAgent) throws UnsupportedEncodingException { RacingEventService eventService = getService(); SecurityService securityService = getSecurityService(); UUID uuid = UUID.fromString(eventId); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingUtils.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingUtils.java index 1aa08a088d8..f329e78231f 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingUtils.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/HomeSharingUtils.java @@ -130,11 +130,14 @@ public class HomeSharingUtils { public static Map createReplacementMap(String title, String description, String imageUrl, String placeUrl, String userAgent) { final Map replacementMap = new HashMap(); - String disabledStart = ""; - String disabledEnd = ""; - if(userAgent != null && userAgent.contains("facebookexternalhit")) { + final String disabledStart; + final String disabledEnd; + if (userAgent != null && userAgent.contains("facebookexternalhit")) { disabledStart = HTML_COMMENT_START; disabledEnd = HTML_COMMENT_END; + } else { + disabledStart = ""; + disabledEnd = ""; } replacementMap.put(REPLACEMENT_KEY_TITLE, title); replacementMap.put(REPLACEMENT_KEY_DESCRIPTION, description); diff --git a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/TokenizedHomePlaceUrlBuilder.java b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/TokenizedHomePlaceUrlBuilder.java index 56e009ad4f0..0774f1e2d3f 100644 --- a/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/TokenizedHomePlaceUrlBuilder.java +++ b/java/com.sap.sailing.server.gateway/src/com/sap/sailing/server/gateway/jaxrs/sharing/TokenizedHomePlaceUrlBuilder.java @@ -6,6 +6,8 @@ import java.net.URL; import javax.ws.rs.core.UriInfo; +import com.sap.sse.common.Base64Utils; + public class TokenizedHomePlaceUrlBuilder { private static final String EVENT_PATH = "/event"; private static final String SERIES_PATH = "/series"; @@ -14,7 +16,15 @@ public class TokenizedHomePlaceUrlBuilder { private static final String HOME_HTML = "/Home.html"; private static final String STARTOFPARAMS = "/:"; private static final String STARTOFTOKENPATH = "#"; + + /** + * See also {@code AbstractEventPlace.Tokenizer.PARAM_EVENTID} + */ private static final String EVENT_ID_PARAM = "eventId"; + + /** + * See also {@code AbstractEventPlace.Tokenizer.PARAM_REGATTAID} + */ private static final String REGATTA_ID_PARAM = "regattaId"; private static final String LEADERBOARD_GROUP_ID_PARAM = "leaderboardGroupId"; @@ -49,7 +59,7 @@ public class TokenizedHomePlaceUrlBuilder { String url = new String(baseUrl.toString()); url += STARTOFTOKENPATH + REGATTA_OVERVIEW_PATH; url += buildToken(eventId, EVENT_ID_PARAM); - url += buildToken(regattaId, REGATTA_ID_PARAM); + url += buildToken(Base64Utils.toBase64(regattaId.getBytes()), REGATTA_ID_PARAM); return url; } diff --git a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/URLEncoder.java b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/URLEncoder.java index 77219290e4c..78ed9c419b8 100644 --- a/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/URLEncoder.java +++ b/java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/URLEncoder.java @@ -4,7 +4,7 @@ import com.google.gwt.http.client.URL; /** * A very basic URL encoder that also works in a GWT environment where java.net.URLEncoder is not available. - * It is based on {@link URL#encode(String)} and adds encoding for the backslash (\) character. + * It is based on {@link URL#encodeQueryString(String)}. * * @author Axel Uhl (D043530) * @@ -13,14 +13,8 @@ public class URLEncoder { private URLEncoder() { } - private final static char[] charsToReplace = { '\'', '(', ')', '"', '[', ']', '{', '}', '<', '>', '|', '+' }; - - public static String encode(String url) { - String nearlyEncoded = URL.encode(url); - for (char c : charsToReplace) { - nearlyEncoded = nearlyEncoded.replaceAll("\\" + Character.toString(c), "%" + Integer.toHexString(c)); - } - return nearlyEncoded; + public static String encodeQueryString(String url) { + return URL.encodeQueryString(url); } } diff --git a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/PermissionConverterTest.java b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/PermissionConverterTest.java index ae3ae1ad7e4..296ca1ef6f4 100755 --- a/java/com.sap.sse.security.test/src/com/sap/sse/security/test/PermissionConverterTest.java +++ b/java/com.sap.sse.security.test/src/com/sap/sse/security/test/PermissionConverterTest.java @@ -51,6 +51,12 @@ public class PermissionConverterTest { com.sap.sse.security.shared.WildcardPermission wp = new PermissionConverter().getWildcardPermission(new org.apache.shiro.authz.permission.WildcardPermission("LEADERBOARD:EDIT:KW2017 Laser Int.", /* case sensitive */ true)); assertEquals("LEADERBOARD:EDIT:KW2017 Laser Int.", wp.toString()); } + + @Test + public void testGetWildcardPermissionWithMultipleObjectsInThirdPart() { + com.sap.sse.security.shared.WildcardPermission wp = new PermissionConverter().getWildcardPermission(new org.apache.shiro.authz.permission.WildcardPermission("LEADERBOARD:EDIT:KW2017 Laser Int.,KW2024 [ILCA7]", /* case sensitive */ true)); + assertEquals("LEADERBOARD:EDIT:KW2017 Laser Int.,KW2024 [ILCA7]", wp.toString()); + } @Test public void testMixedCaseWildcardPermissionWithDedicatedRealm() { diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthorizingRealm.java b/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthorizingRealm.java index 7118e04fd8b..2cf6bd96d6b 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthorizingRealm.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/AbstractCompositeAuthorizingRealm.java @@ -20,6 +20,7 @@ import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; import com.sap.sse.security.impl.Activator; +import com.sap.sse.security.impl.PermissionConverter; import com.sap.sse.security.interfaces.AccessControlStore; import com.sap.sse.security.interfaces.UserStore; import com.sap.sse.security.shared.AccessControlListAnnotation; @@ -169,7 +170,7 @@ public abstract class AbstractCompositeAuthorizingRealm extends AuthorizingRealm public boolean isPermitted(PrincipalCollection principals, Permission perm) { String username = (String) principals.getPrimaryPrincipal(); final User user = getUserStore().getUserByName(username); - final WildcardPermission wildcardPermission = new WildcardPermission(perm.toString().replaceAll("\\[|\\]", "")); + final WildcardPermission wildcardPermission = new PermissionConverter().getWildcardPermission(perm); List> parts = wildcardPermission.getParts(); final boolean result; if (parts.size() > 2 && !parts.get(2).isEmpty()) { diff --git a/java/com.sap.sse.security/src/com/sap/sse/security/impl/PermissionConverter.java b/java/com.sap.sse.security/src/com/sap/sse/security/impl/PermissionConverter.java index f7da671ef64..6491cb7641e 100755 --- a/java/com.sap.sse.security/src/com/sap/sse/security/impl/PermissionConverter.java +++ b/java/com.sap.sse.security/src/com/sap/sse/security/impl/PermissionConverter.java @@ -27,13 +27,11 @@ public class PermissionConverter { private final PermissionToObjectIdConverter poc = new PermissionToObjectIdConverter(); public WildcardPermission getWildcardPermission(Permission permission) { - return new WildcardPermission(getAsString(permission)); + final WildcardPermission result; + result = new WildcardPermission(permission.toString()); + return result; } - private String getAsString(Permission permission) { - return permission.toString().replaceAll("\\[|\\]", ""); // FIXME for multi-subpart parts remove leading blanks after , - } - /** * Splits the permission along ":" occurrences */ diff --git a/java/com.sap.sse.test/src/com/sap/sse/test/URLEncoderTest.java b/java/com.sap.sse.test/src/com/sap/sse/test/URLEncoderTest.java new file mode 100644 index 00000000000..57d41e4c8dd --- /dev/null +++ b/java/com.sap.sse.test/src/com/sap/sse/test/URLEncoderTest.java @@ -0,0 +1,20 @@ +package com.sap.sse.test; + +import static org.junit.Assert.assertEquals; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; + +import org.junit.Test; + +public class URLEncoderTest { + @Test + public void testWithSlash() throws UnsupportedEncodingException { + assertEquals("a%2Fb", URLEncoder.encode("a/b", "UTF-8")); + } + + @Test + public void testWithColon() throws UnsupportedEncodingException { + assertEquals("a%3Ab", URLEncoder.encode("a:b", "UTF-8")); + } +}