Merge branch 'master' into bug5249

This commit is contained in:
Axel Uhl committed 2020-04-02 23:04:40 +02:00
commit b2f0727f61
30 files changed
+109 -391

No files matched your search

@@ -1,70 +0,0 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2018-09/r/eclipse-ide-eclipse-committers
if [[ $1 == "" ]]; then
echo "You need to specify the Eclipse installation directory"
exit 1
fi
installPath="$1"
installPlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -installIU $2
echo ""
}
updatePlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -uninstallIU $2 -installIU $2
echo ""
}
# Not necessary if using Eclipse for JEE developers
echo "Installing webtools (WTP/WST/JPT) and m2e that are required by the GWT plugin..."
installPlugins http://download.eclipse.org/releases/2018-09/ org.eclipse.wst.web_ui.feature.feature.group,org.eclipse.jst.web_ui.feature.feature.group,org.eclipse.wst.xml_ui.feature.feature.group,org.eclipse.jpt.common.feature.feature.group,org.eclipse.jpt.jpa.feature.feature.group,org.eclipse.m2e.feature.feature.group,org.eclipse.m2e.wtp.feature.feature.group
echo "Installing GWT plugin..."
installPlugins http://storage.googleapis.com/gwt-eclipse-plugin/v3/release com.gwtplugins.eclipse.suite.v3.feature.feature.group
echo "Installing Mission Control plugin..."
installPlugins http://download.oracle.com/technology/products/missioncontrol/updatesites/base/6.0.0/eclipse com.oracle.jmc.feature.ide.feature.group,com.oracle.jmc.feature.flightrecorder.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.console.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.core.feature.group
echo "Installing Android Tools..."
installPlugins https://dl-ssl.google.com/android/eclipse com.android.ide.eclipse.adt.feature.feature.group
echo "Installing GWT SDM debug bridge..."
installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.group
echo "Installing EasyShell..."
installPlugins http://anb0s.github.io/EasyShell de.anbos.eclipse.easyshell.feature.feature.group
echo "Installing BIRT charts (requirement for MAT)..."
installPlugins http://download.eclipse.org/birt/update-site/4.6 org.eclipse.birt.chart.feature.group
echo "Installing Memory Analyzer..."
installPlugins http://download.eclipse.org/releases/2018-09 org.eclipse.mat.feature.feature.group,org.eclipse.mat.chart.feature.feature.group
echo "Installing latest version of Code Recommenders..."
updatePlugins http://download.eclipse.org/recommenders/updates/stable/ org.eclipse.recommenders.rcp.feature.feature.group,org.eclipse.recommenders.mylyn.rcp.feature.feature.group,org.eclipse.recommenders.snipmatch.rcp.feature.feature.group,org.eclipse.recommenders.news.rcp.feature.feature.group
echo "Installing latest version of EGit..."
updatePlugins http://download.eclipse.org/egit/updates org.eclipse.jgit.feature.group,org.eclipse.jgit.http.apache.feature.group,org.eclipse.egit.feature.group,org.eclipse.egit.mylyn.feature.group,org.eclipse.egit.gitflow.feature.feature.group
# Currently not needed because Eclipse Photon already provides current versions
# echo "Installing latest version of Mylyn ..."
# updatePlugins http://download.eclipse.org/mylyn/releases/latest org.eclipse.mylyn_feature.feature.group,org.eclipse.mylyn.bugzilla_feature.feature.group,org.eclipse.mylyn.builds.feature.group,org.eclipse.mylyn.commons.feature.group,org.eclipse.mylyn.commons.identity.feature.group,org.eclipse.mylyn.commons.notifications.feature.group,org.eclipse.mylyn.commons.repositories.feature.group,org.eclipse.mylyn.commons.repositories.http.feature.group,org.eclipse.mylyn.context_feature.feature.group,org.eclipse.mylyn.discovery.feature.group,org.eclipse.mylyn.gerrit.feature.feature.group,org.eclipse.mylyn.git.feature.group,org.eclipse.mylyn.hudson.feature.group,org.eclipse.mylyn.java_feature.feature.group,org.eclipse.mylyn.monitor.feature.group,org.eclipse.mylyn.reviews.feature.feature.group,org.eclipse.mylyn.team_feature.feature.group,org.eclipse.mylyn.versions.feature.group,org.eclipse.mylyn.wikitext_feature.feature.group
echo "Installing SAP JVM Tools (profiler) ..."
installPlugins https://tools.hana.ondemand.com/photon com.sap.jvm.profiling.feature.group
echo "Installing javax.xml.bind for news feed polling (see https://stackoverflow.com/questions/52528693/eclipse-internal-error-polling-news-feeds)..."
installPlugins http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository javax.xml.bind
echo "Installing Java 11 support"
installPlugins http://download.eclipse.org/eclipse/updates/4.9-P-builds org.eclipse.jdt.java11patch.feature.group,org.eclipse.pde.java11patch.feature.group
echo "Installing Java11 Patches..."
installPlugins http://download.eclipse.org/eclipse/updates/4.9-P-builds/ org.eclipse.jdt.java11patch.feature.group
echo "Installation completed!"
@@ -1,54 +0,0 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2019-03/r/eclipse-ide-eclipse-committers
if [[ $1 == "" ]]; then
echo "You need to specify the Eclipse installation directory"
exit 1
fi
installPath="$1"
installPlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -installIU $2
echo ""
}
updatePlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -uninstallIU $2 -installIU $2
echo ""
}
# Not necessary if using Eclipse for JEE developers
echo "Installing webtools (WTP/WST/JPT) and m2e that are required by the GWT plugin..."
installPlugins http://download.eclipse.org/releases/2019-03/ org.eclipse.wst.web_ui.feature.feature.group,org.eclipse.jst.web_ui.feature.feature.group,org.eclipse.wst.xml_ui.feature.feature.group,org.eclipse.jpt.common.feature.feature.group,org.eclipse.jpt.jpa.feature.feature.group,org.eclipse.m2e.feature.feature.group,org.eclipse.m2e.wtp.feature.feature.group
echo "Installing GWT plugin..."
installPlugins http://storage.googleapis.com/gwt-eclipse-plugin/v3/release com.gwtplugins.eclipse.suite.v3.feature.feature.group
echo "Installing Mission Control plugin..."
installPlugins http://download.oracle.com/technology/products/missioncontrol/updatesites/base/6.0.0/eclipse com.oracle.jmc.feature.ide.feature.group,com.oracle.jmc.feature.flightrecorder.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.console.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.core.feature.group
echo "Installing GWT SDM debug bridge..."
installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.group
echo "Installing EasyShell..."
installPlugins http://anb0s.github.io/EasyShell de.anbos.eclipse.easyshell.feature.feature.group
echo "Installing Memory Analyzer..."
installPlugins http://download.eclipse.org/releases/2019-03 org.eclipse.mat.feature.feature.group,org.eclipse.mat.chart.feature.feature.group
echo "Installing SAP JVM Tools (profiler) ..."
installPlugins https://tools.hana.ondemand.com/oxygen com.sap.jvm.profiling.feature.group
echo "Installing UMLet ..."
installPlugins https://www.umlet.com/umlet_latest/repository/ umlet-eclipse-feature.feature.group
echo "Installing javax.xml.bind for news feed polling (see https://stackoverflow.com/questions/52528693/eclipse-internal-error-polling-news-feeds)..."
installPlugins http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository javax.xml.bind
echo "Installing Enhanced Class Decompiler"
installPlugins https://ecd-plugin.github.io/update org.sf.feeling.decompiler.feature.group,org.sf.feeling.decompiler.cfr.feature.group,org.sf.feeling.decompiler.jad.feature.group,org.sf.feeling.decompiler.jd.feature.group,org.sf.feeling.decompiler.procyon.feature.group
echo "Installation completed!"
@@ -1,54 +0,0 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2019-06/r/eclipse-ide-eclipse-committers
if [[ $1 == "" ]]; then
echo "You need to specify the Eclipse installation directory"
exit 1
fi
installPath="$1"
installPlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -installIU $2
echo ""
}
updatePlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -uninstallIU $2 -installIU $2
echo ""
}
# Not necessary if using Eclipse for JEE developers
echo "Installing webtools (WTP/WST/JPT) and m2e that are required by the GWT plugin..."
installPlugins http://download.eclipse.org/releases/2019-06/ org.eclipse.wst.web_ui.feature.feature.group,org.eclipse.jst.web_ui.feature.feature.group,org.eclipse.wst.xml_ui.feature.feature.group,org.eclipse.jpt.common.feature.feature.group,org.eclipse.jpt.jpa.feature.feature.group,org.eclipse.m2e.feature.feature.group,org.eclipse.m2e.wtp.feature.feature.group
echo "Installing GWT plugin..."
installPlugins http://storage.googleapis.com/gwt-eclipse-plugin/v3/release com.gwtplugins.eclipse.suite.v3.feature.feature.group
echo "Installing Mission Control plugin..."
installPlugins http://download.oracle.com/technology/products/missioncontrol/updatesites/base/6.0.0/eclipse com.oracle.jmc.feature.ide.feature.group,com.oracle.jmc.feature.flightrecorder.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.console.feature.group,com.oracle.jmc.feature.core.feature.group,com.oracle.jmc.feature.core.feature.group
echo "Installing GWT SDM debug bridge..."
installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.group
echo "Installing EasyShell..."
installPlugins http://anb0s.github.io/EasyShell de.anbos.eclipse.easyshell.feature.feature.group
echo "Installing Memory Analyzer..."
installPlugins http://download.eclipse.org/releases/2019-06 org.eclipse.mat.feature.feature.group,org.eclipse.mat.chart.feature.feature.group
echo "Installing SAP JVM Tools (profiler) ..."
installPlugins https://tools.hana.ondemand.com/oxygen com.sap.jvm.profiling.feature.group
echo "Installing UMLet ..."
installPlugins https://www.umlet.com/umlet_latest/repository/ umlet-eclipse-feature.feature.group
echo "Installing javax.xml.bind for news feed polling (see https://stackoverflow.com/questions/52528693/eclipse-internal-error-polling-news-feeds)..."
installPlugins http://download.eclipse.org/tools/orbit/downloads/drops/R20180905201904/repository javax.xml.bind
echo "Installing Enhanced Class Decompiler"
installPlugins https://ecd-plugin.github.io/update org.sf.feeling.decompiler.feature.group,org.sf.feeling.decompiler.cfr.feature.group,org.sf.feeling.decompiler.jad.feature.group,org.sf.feeling.decompiler.jd.feature.group,org.sf.feeling.decompiler.procyon.feature.group
echo "Installation completed!"
@@ -1,6 +1,6 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# You need an installation of the 2019-09 release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2019-09/r/eclipse-ide-eclipse-committers
if [[ $1 == "" ]]; then
@@ -1,7 +1,7 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2019-09/r/eclipse-ide-eclipse-committers
# You need an installation of the 2020-03 release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# https://www.eclipse.org/downloads/packages/release/2020-03/r/eclipse-ide-eclipse-committers
if [[ $1 == "" ]]; then
echo "You need to specify the Eclipse installation directory"
@@ -1,58 +0,0 @@
#!/bin/bash
# You need an installation of the Photon release of "Eclipse IDE for Eclipse Committers" matching you OS and JDK (32 vs 64 Bit):
# http://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/photonr
if [[ $1 == "" ]]; then
echo "You need to specify the Eclipse installation directory"
exit 1
fi
installPath="$1"
installPlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -installIU $2
echo ""
}
updatePlugins() {
"$installPath/eclipse" -application org.eclipse.equinox.p2.director -noSplash -roaming -repository $1 -uninstallIU $2 -installIU $2
echo ""
}
# Not necessary if using Eclipse for JEE developers
echo "Installing webtools (WTP/WST/JPT) and m2e that are required by the GWT plugin..."
installPlugins http://download.eclipse.org/releases/photon/ org.eclipse.wst.web_ui.feature.feature.group,org.eclipse.jst.web_ui.feature.feature.group,org.eclipse.wst.xml_ui.feature.feature.group,org.eclipse.jpt.common.feature.feature.group,org.eclipse.jpt.jpa.feature.feature.group,org.eclipse.m2e.feature.feature.group,org.eclipse.m2e.wtp.feature.feature.group
echo "Installing GWT plugin..."
installPlugins http://storage.googleapis.com/gwt-eclipse-plugin/v3/release com.gwtplugins.eclipse.suite.v3.feature.feature.group
echo "Installing Android Tools..."
installPlugins https://dl-ssl.google.com/android/eclipse com.android.ide.eclipse.adt.feature.feature.group
echo "Installing GWT SDM debug bridge..."
installPlugins http://p2.sapsailing.com/p2/sdbg com.github.sdbg.feature.feature.group
echo "Installing EasyShell..."
installPlugins http://anb0s.github.io/EasyShell de.anbos.eclipse.easyshell.feature.feature.group
echo "Installing BIRT charts (requirement for MAT)..."
installPlugins http://download.eclipse.org/birt/update-site/4.6 org.eclipse.birt.chart.feature.group
echo "Installing Memory Analyzer..."
installPlugins http://download.eclipse.org/releases/photon org.eclipse.mat.feature.feature.group,org.eclipse.mat.chart.feature.feature.group
echo "Installing latest version of Code Recommenders..."
updatePlugins http://download.eclipse.org/recommenders/updates/stable/ org.eclipse.recommenders.rcp.feature.feature.group,org.eclipse.recommenders.mylyn.rcp.feature.feature.group,org.eclipse.recommenders.snipmatch.rcp.feature.feature.group,org.eclipse.recommenders.news.rcp.feature.feature.group
echo "Installing latest version of EGit..."
updatePlugins http://download.eclipse.org/egit/updates org.eclipse.jgit.feature.group,org.eclipse.jgit.http.apache.feature.group,org.eclipse.egit.feature.group,org.eclipse.egit.mylyn.feature.group,org.eclipse.egit.gitflow.feature.feature.group
# Currently not needed because Eclipse Photon already provides current versions
# echo "Installing latest version of Mylyn ..."
# updatePlugins http://download.eclipse.org/mylyn/releases/latest org.eclipse.mylyn_feature.feature.group,org.eclipse.mylyn.bugzilla_feature.feature.group,org.eclipse.mylyn.builds.feature.group,org.eclipse.mylyn.commons.feature.group,org.eclipse.mylyn.commons.identity.feature.group,org.eclipse.mylyn.commons.notifications.feature.group,org.eclipse.mylyn.commons.repositories.feature.group,org.eclipse.mylyn.commons.repositories.http.feature.group,org.eclipse.mylyn.context_feature.feature.group,org.eclipse.mylyn.discovery.feature.group,org.eclipse.mylyn.gerrit.feature.feature.group,org.eclipse.mylyn.git.feature.group,org.eclipse.mylyn.hudson.feature.group,org.eclipse.mylyn.java_feature.feature.group,org.eclipse.mylyn.monitor.feature.group,org.eclipse.mylyn.reviews.feature.feature.group,org.eclipse.mylyn.team_feature.feature.group,org.eclipse.mylyn.versions.feature.group,org.eclipse.mylyn.wikitext_feature.feature.group
echo "Installing SAP JVM Tools (profiler) ..."
installPlugins https://tools.hana.ondemand.com/photon com.sap.jvm.profiling.feature.group
echo "Installation completed!"
@@ -322,7 +322,7 @@ public class RaceLogRaceTracker extends AbstractRaceTrackerBaseImpl {
// this wakes up all waiting race handles
} catch (Exception exception) {
logger.log(Level.WARNING,
"Error while creating race " + raceName + " for retatta " + trackedRegatta.getRegatta(), exception);
"Error while creating race " + raceName + " for regatta " + trackedRegatta.getRegatta(), exception);
try {
trackedRegattaRegistry.stopTracker(trackedRegatta.getRegatta(), this);
} catch (Exception e) {
@@ -503,7 +503,7 @@ public class SwissTimingRaceTrackerImpl extends AbstractRaceTrackerImpl
logger.info("Created SwissTiming RaceDefinition and TrackedRace for "+race.getName());
} catch (Exception exception) {
logger.log(Level.WARNING,
"Error while creating race " + raceName + " for retatta " + trackedRegatta.getRegatta(), exception);
"Error while creating race " + raceName + " for regatta " + trackedRegatta.getRegatta(), exception);
try {
if (race == null) {
trackedRegattaRegistry.stopTracker(regatta, this);
@@ -428,7 +428,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
dynamicRaceDefinitionSet.addRaceDefinition(race, trackedRace);
}
} catch (Exception exception) {
logger.log(Level.WARNING, "Error while creating race " + raceName + " for retatta " + regatta, exception);
logger.log(Level.WARNING, "Error while creating race " + raceName + " for regatta " + regatta, exception);
try {
if (tracker != null) {
trackedRegattaRegistry.stopTracker(regatta, getTracker());
@@ -317,10 +317,6 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
* empty results and there is a {@link CompetitorResult} for that competitor coming from the race log, that competitor
* result will be "invalidated" / "revoked" by adding a new {@link CompetitorResult} at the end of the race log that
* has an empty finishing time and zero rank.
*
* TODO bug5154 continue here...
*
* TODO bug5154 this method will also need to be called whenever new results are published on the RaceLog because a "more official" or more recent update may already exist in the TracTrac IRaceCompetitor
*/
public void reconcileCompetitorStatus(IRaceCompetitor raceCompetitor, TrackedRace trackedRace) {
final IRace tractracRace = raceCompetitor.getRace();
@@ -338,12 +334,18 @@ public class RaceAndCompetitorStatusWithRaceLogReconciler {
final RaceCompetitorStatusType competitorStatus = raceCompetitor.getStatus();
final MaxPointsReason officialMaxPointsReason = getMaxPointsReason(competitorStatus);
final MillisecondsTimePoint officialResultTime = new MillisecondsTimePoint(timePointForStatusEvent);
if (resultFromRaceLogAndItsCreationTimePoint == null
// accept even OFFICIAL results only if at least one of officialRank or officialFinishingTime is
// provided:
// Jorge Piera Llodra on 2020-04-01: "If both the finishing time and the rank are not defined means that
// we don’t have these values. In fact, we only have these values for some races of the test event in
// Enoshima last year.
// If the race is OFFICIAL but these values are empty, just ignore them."
if ((officialFinishingTime != 0 || officialRank != 0) && (resultFromRaceLogAndItsCreationTimePoint == null
|| (resultFromRaceLogAndItsCreationTimePoint.getA().getOneBasedRank() != officialRank
|| ((resultFromRaceLogAndItsCreationTimePoint.getA().getFinishingTime() == null) ? 0
: resultFromRaceLogAndItsCreationTimePoint.getA().getFinishingTime().asMillis()) != officialFinishingTime
|| resultFromRaceLogAndItsCreationTimePoint.getA().getMaxPointsReason() != officialMaxPointsReason)
&& resultFromRaceLogAndItsCreationTimePoint.getB().before(officialResultTime)) {
&& resultFromRaceLogAndItsCreationTimePoint.getB().before(officialResultTime))) {
// We have an official statement from TracTrac, rank or finishing time or penalty varies and is newer
// than the last thing we see in the race log (including we may not have anything in the race
// log for the results of that competitor at all yet).
@@ -3,6 +3,7 @@ package com.sap.sailing.domain.leaderboard.impl;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -300,7 +301,8 @@ public class DelegatingRegattaLeaderboardWithCompetitorElimination extends Abstr
}
public Iterable<RaceColumn> getRaceColumns() {
return getFullLeaderboard().getRaceColumns();
final RegattaLeaderboard theFullLeaderboard = getFullLeaderboard();
return theFullLeaderboard == null ? Collections.emptySet() : theFullLeaderboard.getRaceColumns();
}
public RaceColumn getRaceColumnByName(String name) {
@@ -9,6 +9,7 @@ import static com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage.goToP
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.openqa.selenium.WebElement;
@@ -46,6 +47,8 @@ public class AclRevokeAnonymousTest extends AbstractSeleniumTest {
}
@Test
// TODO remove, once we allow denied ACLs again
@Ignore("Bug 5239 deactivates denied actions")
public void test() {
EventConfigurationPanelPO eventPanel = adminConsole.goToEvents();
EventEntryPO eventEntry = eventPanel.getEventEntry(EVENT_NAME);
@@ -55,7 +55,7 @@ consumption of this service simple.</p>
a value for boatclassname becomes mandatory; the regatta will have a "Default" series with a single "Default"
fleet; a regatta leaderboard is created, and if a leaderboard group
was also created, the regatta leaderboard will automatically be added to the new leaderboard group</div>
<div>boatclassname must be provided if createretatta=true; can be the display name or an alias name of a boat class to
<div>boatclassname must be provided if createregatta=true; can be the display name or an alias name of a boat class to
use for the new regatta</div>
<div>numberofraces tells how many races shall be created in the default series; by default the series remains empty</div>
<div>canBoatsOfCompetitorsChangePerRace If true, boats and competitors can change per race, also it is necessary to register them in this case for each race!</div>
@@ -61,28 +61,6 @@ public interface SecurityAccessControlList<G extends SecurityUserGroup<?>> exten
*/
boolean addPermission(G userGroup, String actionToAllow);
/**
* @param actionToDeny
* the action to be denied. The wildcard string {@code "*"} can be used to deny permission for all
* possible actions for the {@code userGroup}. Prefixing the action by an exclamation mark character
* {@code '!'} instead allows the action that follows. Multiple leading exclamation marks toggle
* accordingly.
* @return {@code true} if the denial was added; {@code false} if the denial was already in this ACL and therefore
* didn't need to be added
* @see #addPermission(UserGroupImpl, String)
*/
boolean denyPermission(G userGroup, String actionToDeny);
/**
* Removes a permission denial from those permissions denied for the user group. If the action starts with an
* {@code "!"} exclamation mark, the exclamation mark is stripped, and {@link #removePermission(UserGroupImpl, String)}
* is invoked with the remaining string.
*
* @return {@code true} if the permission was removed; {@code false} if the permission was not in this ACL and
* therefore didn't need to be removed
*/
boolean removeDenial(G userGroup, String substring);
/**
* Removes a permission from those permissions granted to the user group. If the action starts with an {@code "!"}
* exclamation mark, the exclamation mark is stripped, and {@link #removeDenial(UserGroupImpl, String)} is invoked with
@@ -94,5 +72,15 @@ public interface SecurityAccessControlList<G extends SecurityUserGroup<?>> exten
boolean removePermission(G userGroup, String action);
void setPermissions(G userGroup, Set<String> actions);
/**
* When adding an action to a ACL prefixed with ! this is meant to be an explicit denial of that action instead of
* granting that action. This method checks if an action is such a denial.
*
* @return {@code true} if it is a denied action, {@code false} otherwise
*/
static boolean isDeniedAction(String action) {
return action.startsWith("!");
}
}
@@ -111,11 +111,14 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup<?>>
}
return result;
}
private boolean isDeniedAction(String action) {
return SecurityAccessControlList.isDeniedAction(action);
}
@Override
public boolean denyPermission(G userGroup, String action) {
private boolean denyPermission(G userGroup, String action) {
final boolean result;
if (action.startsWith("!")) {
if (isDeniedAction(action)) {
result = addPermission(userGroup, action.substring(1));
} else {
result = Util.addToValueSet(deniedActionsByUserGroup, userGroup, new WildcardPermission(action));
@@ -126,7 +129,7 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup<?>>
@Override
public boolean addPermission(G userGroup, String action) {
final boolean result;
if (action.startsWith("!")) {
if (isDeniedAction(action)) {
result = denyPermission(userGroup, action.substring(1));
} else {
result = Util.addToValueSet(allowedActionsByUserGroup, userGroup, new WildcardPermission(action));
@@ -137,7 +140,7 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup<?>>
@Override
public boolean removePermission(G userGroup, String action) {
final boolean result;
if (action.startsWith("!")) {
if (isDeniedAction(action)) {
result = removeDenial(userGroup, action.substring(1));
} else {
result = Util.removeFromValueSet(allowedActionsByUserGroup, userGroup, new WildcardPermission(action));
@@ -145,10 +148,9 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup<?>>
return result;
}
@Override
public boolean removeDenial(G userGroup, String action) {
private boolean removeDenial(G userGroup, String action) {
final boolean result;
if (action.startsWith("!")) {
if (isDeniedAction(action)) {
result = removeDenial(userGroup, action.substring(1));
} else {
result = Util.removeFromValueSet(deniedActionsByUserGroup, userGroup, new WildcardPermission(action));
@@ -161,7 +163,7 @@ public abstract class AbstractAccessControlList<G extends SecurityUserGroup<?>>
allowedActionsByUserGroup.remove(userGroup);
deniedActionsByUserGroup.remove(userGroup);
for (final String actionAsString : actions) {
if (actionAsString.startsWith("!")) {
if (isDeniedAction(actionAsString)) {
denyPermission(userGroup, actionAsString.substring(1));
} else {
addPermission(userGroup, actionAsString);
@@ -32,10 +32,6 @@ public interface AccessControlStore extends Named {
void removeAclPermission(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action);
void removeAclDenial(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action);
void denyAclPermission(QualifiedObjectIdentifier idOfAccessControlledObject, UserGroup userGroup, String action);
void removeAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject);
Iterable<OwnershipAnnotation> getOwnerships();
@@ -20,6 +20,7 @@ import org.apache.shiro.SecurityUtils;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import com.mongodb.MongoException;
@@ -92,9 +93,10 @@ public class LoginTest {
assertFalse(Util.contains(specialUserGroup1.getUsers(), user));
assertFalse(Util.contains(specialUserGroup2.getUsers(), user));
}
@Test
// FIXME Bug 5239: Negative ACL actions are currently disabled due to bugs
@Ignore
public void testAclAnonUserGroup() throws UserManagementException, MailException, UserGroupManagementException {
final String username = "TheNewUser";
securityService.createSimpleUser(username, "u@a.b", "Humba", username, /* company */ null,
@@ -103,7 +105,7 @@ public class LoginTest {
Map<UserGroup, Set<String>> permissionMap = new HashMap<>();
permissionMap.put(defaultUserGroup, new HashSet<>(Arrays.asList(new String[] { "!READ", "UPDATE" })));
permissionMap.put(null, new HashSet<>(Arrays.asList(new String[] { "!READ", "UPDATE" })));
AccessControlList acl = securityService.updateAccessControlList(
AccessControlList acl = securityService.overrideAccessControlList(
QualifiedObjectIdentifierImpl.fromDBWithoutEscaping("someid/more"), permissionMap);
Map<UserGroup, Set<String>> result = acl.getActionsByUserGroup();
@@ -192,7 +192,7 @@ public class PermissionCheckerTest {
assertTrue(PermissionChecker.isPermitted(eventReadPermission, /* user */ null, /* groups */ new HashSet<>(),
null, null, adminOwnership, acl));
// now deny "public read" permission in ACL which is expected to supersede the granting from above:
acl.denyPermission(null, DefaultActions.READ.name());
acl.addPermission(null, "!"+DefaultActions.READ.name());
assertFalse(PermissionChecker.isPermitted(eventReadPermission, /* user */ null, /* groups */ new HashSet<>(),
null, null, adminOwnership, acl));
}
@@ -42,10 +42,6 @@ public interface UserManagementService extends RemoteService {
AccessControlListAnnotationDTO getAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject)
throws org.apache.shiro.authz.UnauthorizedException;
AccessControlListDTO updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<String, Set<String>> permissionStrings)
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
AccessControlListDTO addToAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
String groupOrTenantIdAsString, String action)
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
@@ -38,9 +38,6 @@ public interface UserManagementServiceAsync {
void getAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, AsyncCallback<AccessControlListAnnotationDTO> callback);
void updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<String, Set<String>> permissionStrings, AsyncCallback<AccessControlListDTO> callback);
void getAccessControlListWithoutPruning(QualifiedObjectIdentifier idOfAccessControlledObject,
AsyncCallback<AccessControlListDTO> updateAclAsyncCallback);
@@ -61,6 +61,8 @@ public class AclEditPanel extends Composite {
interface AclEditPanelUiBinder extends UiBinder<Widget, AclEditPanel> {
}
private static final boolean showDeniedActions = false;
@UiField
FlowPanel userGroupCellListPanelUi;
@@ -126,8 +128,11 @@ public class AclEditPanel extends Composite {
IconResources.INSTANCE.removeIcon(), actionNames, stringMessages.deniedActionName());
deniedActionsEditor.addValueChangeHandler(e -> userGroupsWithDeniedActions
.put(userGroupSelectionModel.getSelectedObject(), toDeniedActionSet(e.getValue())));
permissionsCellListPanelUi.add(deniedActionsContainer = createActionsContainer(stringMessages.deniedActions(),
deniedActionsEditor, AclDialogResources.INSTANCE.css().deniedActionsTable()));
deniedActionsContainer = createActionsContainer(stringMessages.deniedActions(),
deniedActionsEditor, AclDialogResources.INSTANCE.css().deniedActionsTable());
if (showDeniedActions) {
permissionsCellListPanelUi.add(deniedActionsContainer);
}
userGroupSelectionModel.addSelectionChangeHandler(event -> {
StrippedUserGroupDTO userGroup = userGroupSelectionModel.getSelectedObject();
@@ -203,8 +208,10 @@ public class AclEditPanel extends Composite {
deniedActionsContainer.setVisible(userGroupSelected);
if (userGroupSelected) {
allowedActionsEditor.setValue(userGroupsWithAllowedActions.get(selectedUserGroup), false);
deniedActionsEditor.setValue(
removeExclamationMarkFromStrings(userGroupsWithDeniedActions.get(selectedUserGroup)), false);
if (showDeniedActions) {
deniedActionsEditor.setValue(
removeExclamationMarkFromStrings(userGroupsWithDeniedActions.get(selectedUserGroup)), false);
}
}
}
@@ -243,21 +243,6 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
return securityDTOFactory.createAccessControlListAnnotationDTO(getSecurityService().getAccessControlList(idOfAccessControlledObject));
}
@Override
public AccessControlListDTO updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<String, Set<String>> permissionStrings) throws UnauthorizedException {
if (SecurityUtils.getSubject()
.isPermitted(idOfAccessControlledObject.getStringPermission(DefaultActions.CHANGE_ACL))) {
Map<UserGroup, Set<String>> permissionMap = new HashMap<>();
for (String group : permissionStrings.keySet()) {
permissionMap.put(getSecurityService().getUserGroupByName(group), permissionStrings.get(group));
}
return securityDTOFactory.createAccessControlListDTO(getSecurityService().updateAccessControlList(idOfAccessControlledObject, permissionMap));
} else {
throw new UnauthorizedException("Not permitted to grant and revoke permissions for user");
}
}
@Override
public AccessControlListDTO addToAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
String groupIdAsString, String action) throws UnauthorizedException {
@@ -199,21 +199,6 @@ public class AccessControlStoreImpl implements AccessControlStore {
});
}
@Override
public void denyAclPermission(final QualifiedObjectIdentifier idOfAccessControlledObjectAsString,
final UserGroup userGroup, final String action) {
LockUtil.executeWithWriteLock(lockForManagementMappings, new Runnable() {
@Override
public void run() {
final AccessControlListAnnotation acl = getOrCreateAcl(idOfAccessControlledObjectAsString);
if (acl.getAnnotation().denyPermission(userGroup, action)) {
internalMapUserGroupToACL(userGroup, acl);
mongoObjectFactory.storeAccessControlList(acl);
}
}
});
}
private void internalMapUserGroupToACL(final UserGroup userGroup2, final AccessControlListAnnotation acl) {
if (!lockForManagementMappings.isWriteLockedByCurrentThread()) {
throw new IllegalStateException("Current thread has no write lock!");
@@ -246,22 +231,6 @@ public class AccessControlStoreImpl implements AccessControlStore {
}
}
@Override
public void removeAclDenial(final QualifiedObjectIdentifier idOfAccessControlledObject, final UserGroup userGroup2,
final String action) {
final UserGroup userGroup = userGroup2 == null ? NULL_GROUP : userGroup2;
LockUtil.executeWithWriteLock(lockForManagementMappings, new Runnable() {
@Override
public void run() {
final AccessControlListAnnotation acl = getOrCreateAcl(idOfAccessControlledObject);
if (acl.getAnnotation().removeDenial(userGroup, action)) {
internalRemoveUserGroupToACLMapping(userGroup, acl);
mongoObjectFactory.storeAccessControlList(acl);
}
}
});
}
@Override
public void removeAccessControlList(final QualifiedObjectIdentifier idOfAccessControlledObject) {
LockUtil.executeWithWriteLock(lockForManagementMappings, new Runnable() {
@@ -79,19 +79,6 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
AccessControlListAnnotation getAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject);
/**
* @param idOfAccessControlledObject Has to be globally unique
*/
SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject);
/**
* @param id Has to be globally unique
*/
SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject, String displayNameOfAccessControlledObject);
AccessControlList updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<UserGroup, Set<String>> permissionMap);
AccessControlList overrideAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<UserGroup, Set<String>> permissionMap);
+39 -22
View File
@@ -153,6 +153,7 @@ import com.sap.sse.security.shared.PredefinedRoles;
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
import com.sap.sse.security.shared.RoleDefinition;
import com.sap.sse.security.shared.RolePrototype;
import com.sap.sse.security.shared.SecurityAccessControlList;
import com.sap.sse.security.shared.SocialUserAccount;
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
import com.sap.sse.security.shared.UserGroupManagementException;
@@ -176,6 +177,9 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
private static final Logger logger = Logger.getLogger(SecurityServiceImpl.class.getName());
private static final String ADMIN_DEFAULT_PASSWORD = "admin";
// TODO remove, once we allow denied ACLs again
private static final boolean supportDeniedActions = false;
private final Set<String> migratedHasPermissionTypes = new ConcurrentSkipListSet<>();;
@@ -537,13 +541,17 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
return accessControlStore.getAccessControlList(idOfAccessControlledObjectAsString);
}
@Override
public SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString) {
/**
* @param id Has to be globally unique
*/
private SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString) {
return setEmptyAccessControlList(idOfAccessControlledObjectAsString, /* display name of access-controlled object */ null);
}
@Override
public SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString, String displayNameOfAccessControlledObject) {
/**
* @param id Has to be globally unique
*/
private SecurityService setEmptyAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObjectAsString, String displayNameOfAccessControlledObject) {
apply(new SetEmptyAccessControlListOperation(idOfAccessControlledObjectAsString, displayNameOfAccessControlledObject));
return this;
}
@@ -557,38 +565,43 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
@Override
public AccessControlList overrideAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<UserGroup, Set<String>> permissionMap) {
accessControlStore.removeAccessControlList(idOfAccessControlledObject);
return updateAccessControlList(idOfAccessControlledObject, permissionMap);
return overrideAccessControlList(idOfAccessControlledObject, permissionMap, /* displayNameOfAccessControlledObject */ null);
}
@Override
public AccessControlList overrideAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<UserGroup, Set<String>> permissionMap, String displayNameOfAccessControlledObject) {
accessControlStore.removeAccessControlList(idOfAccessControlledObject);
accessControlStore.setEmptyAccessControlList(idOfAccessControlledObject, displayNameOfAccessControlledObject);
return updateAccessControlList(idOfAccessControlledObject, permissionMap);
}
@Override
public AccessControlList updateAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
Map<UserGroup, Set<String>> permissionMap) {
if (getAccessControlList(idOfAccessControlledObject) == null) {
setEmptyAccessControlList(idOfAccessControlledObject);
// TODO remove, once we allow denied ACLs again
if (!supportDeniedActions) {
for (Set<String> actions : permissionMap.values()) {
for (String action : actions) {
if (SecurityAccessControlList.isDeniedAction(action)) {
throw new IllegalArgumentException("Adding denied actions to an ACL is not allowed");
}
}
}
}
setEmptyAccessControlList(idOfAccessControlledObject, displayNameOfAccessControlledObject);
for (Map.Entry<UserGroup, Set<String>> entry : permissionMap.entrySet()) {
final UserGroup userGroup = entry.getKey();
// filter any denied action for anonymous user
Set<String> filteredActions = entry.getValue().stream()
.filter(action -> !(entry.getKey() == null && action != null && action.startsWith("!")))
.collect(Collectors.toSet());
final Set<String> actionsToSet;
if (userGroup == null) {
// filter any denied action for anonymous user
actionsToSet = entry.getValue().stream()
.filter(action -> !SecurityAccessControlList.isDeniedAction(action))
.collect(Collectors.toSet());
} else {
actionsToSet = entry.getValue();
}
final UUID userGroupId = userGroup == null ? null : userGroup.getId();
// avoid the UserGroup object having to be serialized with the operation by using the ID
apply(new AclPutPermissionsOperation(idOfAccessControlledObject, userGroupId, filteredActions));
apply(new AclPutPermissionsOperation(idOfAccessControlledObject, userGroupId, actionsToSet));
}
return accessControlStore.getAccessControlList(idOfAccessControlledObject).getAnnotation();
}
@Override
public Void internalAclPutPermissions(QualifiedObjectIdentifier idOfAccessControlledObject, UUID groupId, Set<String> actions) {
accessControlStore.setAclPermissions(idOfAccessControlledObject, getUserGroup(groupId), actions);
@@ -601,6 +614,10 @@ public class SecurityServiceImpl implements ReplicableSecurityService, ClearStat
@Override
public AccessControlList addToAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
UserGroup group, String action) {
// TODO remove, once we allow denied ACLs again
if (!supportDeniedActions && SecurityAccessControlList.isDeniedAction(action)) {
throw new IllegalArgumentException("Adding denied actions to an ACL is not allowed");
}
if (getAccessControlList(idOfAccessControlledObject) == null) {
setEmptyAccessControlList(idOfAccessControlledObject);
}
+1 -1
View File
@@ -31,7 +31,7 @@
Due to ECJ/JDT bugs it may fail depending on the Eclipse version tycho is based on
(see Bugzilla: https://bugzilla.sapsailing.com/bugzilla/show_bug.cgi?id=3859). -->
<!-- Most likely, serialization/replication will fail with tycho versions based on Eclipse Neon R (4.6.0). -->
<tycho-version>1.0.0</tycho-version>
<tycho-version>1.6.0</tycho-version>
<gwt.version>2.8.2</gwt.version>
<!-- gwt-maven-plugin is typically in sync with the GWT version. But sometimes versions need extra time after a new GWT release. -->
<gwt.plugin.version>2.8.2</gwt.plugin.version>
@@ -95,10 +95,11 @@ public class ManagedRaceListAdapter extends ArrayAdapter<RaceListDataType> imple
viewItemsRaces.put(race, new RaceListDataTypeRace(race, mInflater));
final SeriesBase series = race.getSeries();
RaceState state = race.getState();
boolean draft = state.getFinishPositioningList() != null && state.getFinishPositioningList().hasConflicts();
boolean confirmed = state.getConfirmedFinishPositioningList() != null
&& state.getConfirmedFinishPositioningList().getCompetitorResults().hasConflicts();
boolean hasConflict = draft || confirmed;
CompetitorResults draft = state.getFinishPositioningList();
CompetitorResults confirmed = state.getConfirmedFinishPositioningList().getCompetitorResults();
boolean draftHasConflict = draft != null && draft.hasConflicts();
boolean confirmedHasConflict = confirmed != null && confirmed.hasConflicts();
boolean hasConflict = draftHasConflict || confirmedHasConflict;
if (!viewItemsSeriesHeaders.containsKey(series)) {
viewItemsSeriesHeaders.put(series,
new RaceListDataTypeHeader(new RaceGroupSeries(race), mInflater, hasConflict));
@@ -350,7 +350,7 @@ public class PenaltyFragment extends BaseFragment
}
mConfirmedData.clear();
if (getRaceState().getConfirmedFinishPositioningList() != null) {
if (getRaceState().getConfirmedFinishPositioningList().getCompetitorResults() != null) {
for (CompetitorResult item : getRaceState().getConfirmedFinishPositioningList().getCompetitorResults()) {
mConfirmedData.add(new CompetitorResultImpl(item));
}
@@ -571,7 +571,7 @@ public class TrackingListFragment extends BaseFragment
}
mConfirmedData.clear();
if (getRaceState().getConfirmedFinishPositioningList() != null) {
if (getRaceState().getConfirmedFinishPositioningList().getCompetitorResults() != null) {
for (CompetitorResult item : getRaceState().getConfirmedFinishPositioningList().getCompetitorResults()) {
mConfirmedData.add(new CompetitorResultWithIdImpl(-1, item));
}
+3 -3
View File
@@ -8,7 +8,7 @@ First of all, make sure you've looked at [http://www.amazon.de/Patterns-Elements
#### Installations
1. Eclipse (Eclipse IDE for Eclipse Committers, version 4.13.0 ["2019-09"]https://www.eclipse.org/downloads/packages/release/2019-09/r/eclipse-ide-eclipse-committers)), [http://www.eclipse.org](http://www.eclipse.org)
1. Eclipse (Eclipse IDE for Eclipse Committers, version 4.15.0 ["2020-03"]https://www.eclipse.org/downloads/packages/release/2020-03/r/eclipse-ide-eclipse-committers)), [http://www.eclipse.org](http://www.eclipse.org)
2. Get the content of the git repository (see
Steps to build and run the Race Analysis Suite below)
3. Install the eclipse plugins (see Automatic Eclipse plugin installation below)
@@ -22,9 +22,9 @@ Steps to build and run the Race Analysis Suite below)
#### Automatic Eclipse plugin installation
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers 4.11.0 "2019-09"](https://www.eclipse.org/downloads/packages/release/2019-09/r/eclipse-ide-eclipse-committers) by using the script "configuration/installPluginsForEclipse2019-09.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using your Eclipse installation directory as command line parameter for the script:
The necessary Eclipse plugins described above can be automatically be installed into a newly unzipped version of [Eclipse IDE for Eclipse Committers "2020-03"](https://www.eclipse.org/downloads/packages/release/2020-03/r/eclipse-ide-eclipse-committers) by using the script "configuration/installPluginsForEclipse2020-03.sh". In addition, the script applies some updates to plugins packaged with Eclipse itself. To start the plugin installation, run the following command using your Eclipse installation directory as command line parameter for the script:
./installPluginsForEclipse2019-09.sh "/some/path/on/my/computer/eclipse"
./installPluginsForEclipse2020-03.sh "/some/path/on/my/computer/eclipse"
Be aware that with this script it's not possible to update the plugins to newer versions. Instead you can install a new version by unpacking the base package and executing the script.