java/com.google.gwt.dev/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,2 +0,0 @@
1
-//gwtVersion_/com.google.gwt.dev/lib=2.12.2
2
-eclipse.preferences.version=1
java/com.google.gwt.servlet/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,2 +0,0 @@
1
-//gwtVersion_/com.google.gwt.servlet/lib=
2
-eclipse.preferences.version=1
java/com.sap.sailing.aiagent.gateway/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.dashboards.gwt/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,5 +1,5 @@
1 1
//gwtVersion_/com.google.gwt.servlet/lib=
2
-//gwtVersion_/com.google.gwt.user/lib=
2
+//gwtVersion_/com.google.gwt.user/lib=2.11.1
3 3
//gwtVersion_/opt/gwt-2.11.0=2.11.0
4 4
//gwtVersion_/opt/gwt-2.11.1=2.11.1
5 5
//gwtVersion_/opt/gwt-2.12.2=2.12.2
java/com.sap.sailing.dashboards.gwt/src/main/resources/shiro.ini
... ...
@@ -22,7 +22,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
22 22
securityManager.sessionManager.globalSessionTimeout = 31536000000
23 23
cacheManager = com.sap.sse.security.SessionCacheManager
24 24
securityManager.cacheManager = $cacheManager
25
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
25
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
26 26
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
27 27
28 28
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/BoatClassMasterdata.java
... ...
@@ -56,7 +56,6 @@ public enum BoatClassMasterdata {
56 56
ELLIOTT_6M ("Elliott 6m", true, 6.0, 2.35, BoatHullType.MONOHULL, true, "Elliott6m"),
57 57
EUROPE_INT ("Europe Int.", true, 3.35, 1.35, BoatHullType.MONOHULL, false, "Europe"),
58 58
F_18 ("Formula 18", true, 6.85, 2.25, BoatHullType.CATAMARAN, true, "F18", "F-18"),
59
- FAREAST28R ("Fareast 28R", true, 9.07, 2.75, BoatHullType.MONOHULL, true, "FE28R", "F28R"),
60 59
FARR_30 ("Farr 30", true, 9.42, 3.08, BoatHullType.MONOHULL, true, "F30", "F-30", "Farr-30"),
61 60
FARR_280 ("Farr 280", true, 8.72, 2.87, BoatHullType.MONOHULL, true, "F280", "F-280", "Farr-280"),
62 61
FINN ("Finn", true, 4.50, 1.51, BoatHullType.MONOHULL, false),
java/com.sap.sailing.domain.igtimiadapter.gateway/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/OfflineSerializationTest.java
... ...
@@ -47,11 +47,11 @@ import com.sap.sse.common.Color;
47 47
import com.sap.sse.common.Duration;
48 48
import com.sap.sse.common.Util;
49 49
import com.sap.sse.common.impl.MillisecondsTimePoint;
50
-import com.sap.sse.common.impl.TimedLockImpl;
51 50
import com.sap.sse.security.SecurityService;
52 51
import com.sap.sse.security.interfaces.UserStore;
53 52
import com.sap.sse.security.shared.UserGroupManagementException;
54 53
import com.sap.sse.security.shared.UserManagementException;
54
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
55 55
import com.sap.sse.security.shared.impl.User;
56 56
import com.sap.sse.security.shared.impl.UserGroup;
57 57
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
... ...
@@ -111,7 +111,7 @@ public class OfflineSerializationTest extends AbstractSerializationTest {
111 111
UserStore userStore = new UserStoreImpl("defaultTenant");
112 112
userStore.clear();
113 113
UserGroup defaultTenant = userStore.createUserGroup(UUID.randomUUID(), "admin"+SecurityService.TENANT_SUFFIX);
114
- User user = userStore.createUser("admin", "", new TimedLockImpl());
114
+ User user = userStore.createUser("admin", "", new LockingAndBanningImpl());
115 115
defaultTenant.add(user);
116 116
userStore.updateUserGroup(defaultTenant);
117 117
user.getDefaultTenantMap().put("testserver", defaultTenant);
java/com.sap.sailing.domain/src/com/sap/sailing/domain/markpassingcalculation/MarkPassingCalculator.java
... ...
@@ -11,6 +11,7 @@ import java.util.Map;
11 11
import java.util.Map.Entry;
12 12
import java.util.Set;
13 13
import java.util.concurrent.Callable;
14
+import java.util.concurrent.CountDownLatch;
14 15
import java.util.concurrent.ExecutorService;
15 16
import java.util.concurrent.LinkedBlockingQueue;
16 17
import java.util.logging.Level;
... ...
@@ -63,8 +64,8 @@ public class MarkPassingCalculator {
63 64
private CandidateChooser chooser;
64 65
private static final Logger logger = Logger.getLogger(MarkPassingCalculator.class.getName());
65 66
private final MarkPassingUpdateListener listener;
66
- private final static ExecutorService executor = ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor();
67
- private final static ExecutorService initializationExecutor = ThreadPoolUtil.INSTANCE.createBackgroundTaskThreadPoolExecutor("MarkPassingCalculator initializations");
67
+ private final static ExecutorService executor = ThreadPoolUtil.INSTANCE
68
+ .getDefaultBackgroundTaskThreadPoolExecutor();
68 69
private final LinkedBlockingQueue<StorePositionUpdateStrategy> queue;
69 70
70 71
/**
... ...
@@ -149,7 +150,7 @@ public class MarkPassingCalculator {
149 150
} else {
150 151
listen = null;
151 152
}
152
- final Runnable waitForInitialization = () -> {
153
+ Thread t = new Thread(() -> {
153 154
final Set<Callable<Void>> tasks = new HashSet<>();
154 155
for (Competitor c : race.getRace().getCompetitors()) {
155 156
tasks.add(race.getTrackedRegatta().cpuMeterCallable(() -> {
... ...
@@ -173,11 +174,11 @@ public class MarkPassingCalculator {
173 174
}
174 175
}
175 176
}
176
- };
177
+ }, "MarkPassingCalculator for race " + race.getRaceIdentifier() + " initialization");
177 178
if (waitForInitialMarkPassingCalculation) {
178
- waitForInitialization.run();
179
+ t.run();
179 180
} else {
180
- initializationExecutor.submit(waitForInitialization);
181
+ t.start();
181 182
}
182 183
}
183 184
... ...
@@ -460,6 +461,8 @@ public class MarkPassingCalculator {
460 461
fixesForCompetitor.addAll(competitorEntry.getValue());
461 462
}
462 463
if (!newMarkFixes.isEmpty()) {
464
+ // FIXME bug 2745 use new mark fixes to invalidate chooser's mark position and mutual mark/waypoint
465
+ // distance cache
463 466
for (Entry<Competitor, List<GPSFixMoving>> fixesAffectedByNewMarkFixes : finder
464 467
.calculateFixesAffectedByNewMarkFixes(newMarkFixes).entrySet()) {
465 468
Collection<GPSFixMoving> fixes = combinedCompetitorFixesFinderConsidersAffected
... ...
@@ -590,6 +593,7 @@ public class MarkPassingCalculator {
590 593
suspended = false;
591 594
} else {
592 595
suspended = false;
596
+ final CountDownLatch latchForRunningListenRun = new CountDownLatch(1);
593 597
enqueueUpdate(new StorePositionUpdateStrategy() {
594 598
@Override
595 599
public void storePositionUpdate(Map<Competitor, List<GPSFixMoving>> competitorFixes,
... ...
@@ -601,16 +605,25 @@ public class MarkPassingCalculator {
601 605
List<Pair<Competitor, Integer>> suppressedMarkPassings,
602 606
List<Competitor> unSuppressedMarkPassings, CandidateFinder candidateFinder,
603 607
CandidateChooser candidateChooser) {
604
- if (markPassingRaceFingerprintRegistry != null) {
605
- initializationExecutor.submit(()->{
606
- final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
607
- markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
608
- MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
609
- markPassings, race.getRace().getCourse());
610
- });
611
- }
608
+ latchForRunningListenRun.countDown();
609
+ assert latchForRunningListenRun.getCount() == 0;
612 610
}
613 611
});
612
+ if (markPassingRaceFingerprintRegistry != null) {
613
+ new Thread(()->{
614
+ try {
615
+ latchForRunningListenRun.await();
616
+ final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
617
+ markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
618
+ MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
619
+ markPassings, race.getRace().getCourse());
620
+ } catch (InterruptedException e) {
621
+ logger.log(Level.SEVERE, "Exception while waiting for Listen.run() to start processing in MarkPassingCalculator for "+
622
+ race.getName(), e);
623
+ }
624
+ }, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
625
+ .start();
626
+ }
614 627
}
615 628
}
616 629
} finally {
... ...
@@ -667,4 +680,4 @@ public class MarkPassingCalculator {
667 680
public String toString() {
668 681
return getClass().getName() + " for " + race + " / " + race.getTrackedRegatta().getRegatta() + " with chooser " + chooser;
669 682
}
670
-}
683
+}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/GWT Sailing SDM ManagementConsole.launch
... ...
@@ -3,7 +3,7 @@
3 3
<booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/>
4 4
<stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/>
5 5
<booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
6
- <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9879"/>
6
+ <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9876"/>
7 7
<listAttribute key="com.gwtplugins.gwt.eclipse.core.ENTRY_POINT_MODULES">
8 8
<listEntry value="com.sap.sailing.gwt.ui.AdminConsole"/>
9 9
<listEntry value="com.sap.sailing.gwt.home.Home"/>
... ...
@@ -104,7 +104,7 @@
104 104
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
105 105
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
106 106
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sailing.gwt.ui"/>
107
- <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-style PRETTY -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9879 -startupUrl /gwt/Home.html -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole"/>
107
+ <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-style PRETTY -incremental -war &quot;${project_loc:com.sap.sailing.gwt.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9876 -startupUrl /gwt/Home.html -startupUrl /gwt/AdminConsole.html com.sap.sailing.gwt.home.Home com.sap.sailing.gwt.ui.AdminConsole"/>
108 108
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sailing.gwt.ui"/>
109 109
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:+UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
110 110
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/>
java/com.sap.sailing.gwt.ui/pom.xml
... ...
@@ -12,9 +12,9 @@
12 12
<packaging>eclipse-plugin</packaging>
13 13
14 14
<dependencies>
15
- <!-- The following dependency needs re-declaration with the desired version
16
- because gwt-maps-api declares it with no version specifier which may be resolved
17
- to an incorrect version. -->
15
+ <!-- The following dependency needs re-declaration with the desired version
16
+ because gwt-maps-api declares it with no version specifier which may be resolved
17
+ to an incorrect version. -->
18 18
<dependency>
19 19
<groupId>org.gwtproject</groupId>
20 20
<artifactId>gwt-user</artifactId>
... ...
@@ -165,13 +165,7 @@
165 165
<execution>
166 166
<configuration>
167 167
<!-- <userAgents>chrome</userAgents> -->
168
- <!-- Uncomment this if you'd like to attach a debugger to the GWT build:
169
- <extraJvmArgs>
170
- -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8003
171
- </extraJvmArgs>
172
- -->
173 168
<modules>
174
- <!-- Comment all modules but DataMining when chasing GWT issue-10181: -->
175 169
<module>com.sap.sailing.gwt.home.Home</module>
176 170
<module>com.sap.sailing.gwt.autoplay.AutoPlay</module>
177 171
<module>com.sap.sailing.gwt.ui.AdminConsole</module>
... ...
@@ -181,26 +175,20 @@
181 175
<module>com.sap.sailing.gwt.ui.RaceBoard</module>
182 176
<module>com.sap.sailing.gwt.ui.EmbeddedMapAndWindChart</module>
183 177
<module>com.sap.sailing.gwt.ui.Spectator</module>
184
- <!-- -->
185 178
<module>com.sap.sailing.gwt.ui.DataMining</module>
186
- <!-- Comment all modules but DataMining when chasing GWT issue-10181: -->
187 179
<module>com.sap.sailing.gwt.ui.VideoPopup</module>
188 180
<module>com.sap.sailing.gwt.ui.YoutubePopup</module>
189 181
<module>com.sap.sailing.gwt.ui.Simulator</module>
190 182
<module>com.sap.sailing.gwt.ui.PairingList</module>
191 183
<module>com.sap.sailing.gwt.regattaoverview.RegattaOverview</module>
192
- <!-- -->
193 184
</modules>
194
- <!-- uncomment the following for PRETTY-printed, non-obfuscated output format
195
- <style>PRETTY</style>
196
- -->
185
+ <!-- uncomment the following for PRETTY-printed, non-obfuscated output
186
+ format <style>PRETTY</style> -->
197 187
<gen>${basedir}/.generated</gen>
198 188
<webappDirectory>${basedir}</webappDirectory>
199 189
<warSourceDirectory>${basedir}/src/main/resources</warSourceDirectory>
200 190
<!-- Uncomment the following to obtain details split-point reports
201
- <compileReport>true</compileReport>
202
- <detailedSoyc>true</detailedSoyc>
203
- -->
191
+ <compileReport>true</compileReport> <detailedSoyc>true</detailedSoyc> -->
204 192
</configuration>
205 193
<goals>
206 194
<goal>compile</goal>
java/com.sap.sailing.gwt.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/security/ui/shared/IpToTimedLockDTO_CustomFieldSerializer.java
... ...
@@ -1,48 +0,0 @@
1
-package com.google.gwt.user.client.rpc.core.com.sap.sse.security.ui.shared;
2
-
3
-import com.google.gwt.user.client.rpc.CustomFieldSerializer;
4
-import com.google.gwt.user.client.rpc.SerializationException;
5
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
6
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
7
-import com.sap.sse.common.TimedLock;
8
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
9
-
10
-public class IpToTimedLockDTO_CustomFieldSerializer extends CustomFieldSerializer<IpToTimedLockDTO> {
11
- @Override
12
- public void serializeInstance(SerializationStreamWriter streamWriter, IpToTimedLockDTO instance)
13
- throws SerializationException {
14
- serialize(streamWriter, instance);
15
- }
16
-
17
- public static void serialize(SerializationStreamWriter streamWriter, IpToTimedLockDTO instance)
18
- throws SerializationException {
19
- streamWriter.writeString(instance.getIp());
20
- streamWriter.writeObject(instance.getTimedLock());
21
- }
22
-
23
- @Override
24
- public boolean hasCustomInstantiateInstance() {
25
- return true;
26
- }
27
-
28
- @Override
29
- public IpToTimedLockDTO instantiateInstance(SerializationStreamReader streamReader)
30
- throws SerializationException {
31
- return instantiate(streamReader);
32
- }
33
-
34
- public static IpToTimedLockDTO instantiate(SerializationStreamReader streamReader)
35
- throws SerializationException {
36
- return new IpToTimedLockDTO(streamReader.readString(), (TimedLock) streamReader.readObject());
37
- }
38
-
39
- @Override
40
- public void deserializeInstance(SerializationStreamReader streamReader, IpToTimedLockDTO instance)
41
- throws SerializationException {
42
- deserialize(streamReader, instance);
43
- }
44
-
45
- public static void deserialize(SerializationStreamReader streamReader, IpToTimedLockDTO instance) {
46
- // Done by instantiateInstance
47
- }
48
-}
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResolver.java
... ...
@@ -72,7 +72,6 @@ public class BoatClassImageResolver {
72 72
boatClassIconsMap.put(BoatClassMasterdata.D_35.getDisplayName(), imageResources.D35Icon());
73 73
boatClassIconsMap.put(BoatClassMasterdata.F_16.getDisplayName(), imageResources.F16Icon());
74 74
boatClassIconsMap.put(BoatClassMasterdata.F_18.getDisplayName(), imageResources.F18Icon());
75
- boatClassIconsMap.put(BoatClassMasterdata.FAREAST28R.getDisplayName(), imageResources.Fareast28RIcon());
76 75
boatClassIconsMap.put(BoatClassMasterdata.FARR_30.getDisplayName(), imageResources.Farr30Icon());
77 76
boatClassIconsMap.put(BoatClassMasterdata.FARR_280.getDisplayName(), imageResources.Farr280Icon());
78 77
boatClassIconsMap.put(BoatClassMasterdata.FINN.getDisplayName(), imageResources.FinnIcon());
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/common/client/BoatClassImageResources.java
... ...
@@ -188,10 +188,6 @@ public interface BoatClassImageResources extends ClientBundle {
188 188
@ImageOptions(preventInlining = true)
189 189
ImageResource F18Icon();
190 190
191
- @Source("com/sap/sailing/gwt/ui/client/images/boatclass/Fareast28R.png")
192
- @ImageOptions(preventInlining = true)
193
- ImageResource Fareast28RIcon();
194
-
195 191
@Source("com/sap/sailing/gwt/ui/client/images/boatclass/FARR_30.png")
196 192
@ImageOptions(preventInlining = true)
197 193
ImageResource Farr30Icon();
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/desktop/places/whatsnew/resources/SailingAnalyticsNotes.html
... ...
@@ -5,10 +5,6 @@
5 5
<div id="mainContent">
6 6
<h4 class="articleHeadline" id="sailingAnalyticsHeadline">What's New - Sailing Analytics</h4>
7 7
<div class="innerContent">
8
- <h5 class="articleSubheadline">December 2025</h5>
9
- <ul class="bulletList">
10
- <li>Added boat class Fareast 28R.</li>
11
- </ul>
12 8
<h5 class="articleSubheadline">October 2025</h5>
13 9
<ul class="bulletList">
14 10
<li>Bug fix: the "Edit Mark Passings" panel showed only up to 15 waypoints.</li>
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/partials/checkboxList/CheckboxListEntryModel.java
... ...
@@ -1,48 +0,0 @@
1
-package com.sap.sailing.gwt.home.shared.partials.checkboxList;
2
-
3
-import java.util.function.Consumer;
4
-
5
-public class CheckboxListEntryModel {
6
- final String label;
7
- final boolean initialValue;
8
- final ChangeHandler changeHandler;
9
-
10
- public static class ChangeHandler {
11
- final Consumer<Boolean> onEntryValueChanged;
12
- final boolean isAsync;
13
- final String successMessage;
14
- final String failureMessage;
15
-
16
- public ChangeHandler(final Consumer<Boolean> onEntryValueChanged, final boolean isAsync,
17
- final String successMessage, final String failureMessage) {
18
- this.onEntryValueChanged = onEntryValueChanged;
19
- this.isAsync = isAsync;
20
- this.successMessage = successMessage;
21
- this.failureMessage = failureMessage;
22
- }
23
- }
24
-
25
- @Override
26
- public int hashCode() {
27
- return label.hashCode();
28
- }
29
-
30
- @Override
31
- public boolean equals(Object obj) {
32
- return obj != null && obj.getClass() == getClass() && (((CheckboxListEntryModel) obj).label) == label;
33
- }
34
-
35
- /**
36
- * @param changeHandler
37
- * to disable checkbox, pass null here
38
- */
39
- public CheckboxListEntryModel(final String label, final boolean initialValue, final ChangeHandler changeHandler) {
40
- this.label = label;
41
- this.initialValue = initialValue;
42
- this.changeHandler = changeHandler;
43
- }
44
-
45
- boolean getValue() {
46
- return initialValue;
47
- }
48
-}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/partials/checkboxList/CheckboxListUI.java
... ...
@@ -1,57 +0,0 @@
1
-package com.sap.sailing.gwt.home.shared.partials.checkboxList;
2
-
3
-import java.util.Set;
4
-
5
-import com.google.gwt.core.client.GWT;
6
-import com.google.gwt.dom.client.SpanElement;
7
-import com.google.gwt.uibinder.client.UiBinder;
8
-import com.google.gwt.uibinder.client.UiField;
9
-import com.google.gwt.user.client.ui.Composite;
10
-import com.google.gwt.user.client.ui.FlowPanel;
11
-import com.google.gwt.user.client.ui.Widget;
12
-import com.sap.sailing.gwt.home.shared.partials.multiselection.SuggestedMultiSelectionNotificationToggle;
13
-import com.sap.sse.gwt.client.Notification;
14
-import com.sap.sse.gwt.client.Notification.NotificationType;
15
-
16
-public class CheckboxListUI extends Composite {
17
- interface Binder extends UiBinder<Widget, CheckboxListUI> {
18
- }
19
-
20
- private static final Binder binder = GWT.create(Binder.class);
21
-
22
- /* tiles are label + checkbox */
23
- @UiField
24
- FlowPanel tileList;
25
- @UiField
26
- SpanElement title;
27
-
28
- public CheckboxListUI(final String title, final Set<CheckboxListEntryModel> entries) {
29
- initWidget(binder.createAndBindUi(this));
30
- this.title.setInnerText(title);
31
- for (CheckboxListEntryModel e : entries) {
32
- tileList.add(generateTile(e));
33
- }
34
- }
35
-
36
- private SuggestedMultiSelectionNotificationToggle generateTile(CheckboxListEntryModel e) {
37
- final SuggestedMultiSelectionNotificationToggle tile = new SuggestedMultiSelectionNotificationToggle(e.label);
38
- tile.setValue(e.initialValue);
39
- tile.setEnabled(e.changeHandler != null);
40
- tile.addValueChangeHandler(ev -> {
41
- final Boolean newValue = ev.getValue();
42
- try {
43
- e.changeHandler.onEntryValueChanged.accept(newValue);
44
- final String msg = e.changeHandler.successMessage;
45
- if (msg != null && msg.length() != 0) {
46
- Notification.notify(msg, NotificationType.SUCCESS);
47
- }
48
- } catch (Exception e2) {
49
- final String msg = e.changeHandler.failureMessage;
50
- if (msg != null && msg.length() != 0) {
51
- Notification.notify(msg, NotificationType.ERROR);
52
- }
53
- }
54
- });
55
- return tile;
56
- }
57
-}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/partials/checkboxList/CheckboxListUI.ui.xml
... ...
@@ -1,23 +0,0 @@
1
-<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
2
-<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
3
- xmlns:g="urn:import:com.google.gwt.user.client.ui"
4
- xmlns:sp="urn:import:com.sap.sailing.gwt.home.shared.partials">
5
- <ui:with field="i18n"
6
- type="com.sap.sailing.gwt.ui.client.StringMessages" />
7
- <ui:with field="res"
8
- type="com.sap.sailing.gwt.common.client.SharedResources" />
9
- <ui:with field="local_res"
10
- type="com.sap.sailing.gwt.home.shared.partials.multiselection.SuggestedMultiSelectionResources" />
11
-
12
- <g:HTMLPanel addStyleNames="{local_res.css.suggestions}">
13
- <div class="{local_res.css.suggestionsHeader}">
14
- <span class="{local_res.css.suggestionsHeaderTitle}"
15
- ui:field="title" />
16
- </div>
17
- <div class="{local_res.css.suggestionsContent}">
18
- <g:FlowPanel ui:field="tileList" />
19
- <div ui:field="contentSeparatorUi"
20
- class="{local_res.css.suggestionsContentSeparator}"></div>
21
- </div>
22
- </g:HTMLPanel>
23
-</ui:UiBinder>
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/home/shared/places/user/profile/preferences/MiscellaneousAlertsPresenter.java
... ...
@@ -1,31 +0,0 @@
1
-package com.sap.sailing.gwt.home.shared.places.user.profile.preferences;
2
-
3
-import java.util.Arrays;
4
-import java.util.HashSet;
5
-import java.util.Set;
6
-
7
-import com.sap.sailing.gwt.home.shared.partials.checkboxList.CheckboxListEntryModel;
8
-
9
-public class MiscellaneousAlertsPresenter {
10
- public Set<CheckboxListEntryModel> composeEntries() {
11
- final CheckboxListEntryModel passwordReset = new CheckboxListEntryModel("Password Reset", true, null);
12
- final CheckboxListEntryModel.ChangeHandler securityAlertsSubscriptionChangeHandler = new CheckboxListEntryModel.ChangeHandler(
13
- this::setSecurityAlertsSubscription, true, "Successfully changed ", "fail");
14
- final CheckboxListEntryModel securityAlerts = new CheckboxListEntryModel("Security Alerts", true,
15
- securityAlertsSubscriptionChangeHandler);
16
- final CheckboxListEntryModel.ChangeHandler newsletterSubscriptionChangeHandler = new CheckboxListEntryModel.ChangeHandler(
17
- this::setNewsletterSubscription, true, "succ", "fail");
18
- final CheckboxListEntryModel newsletter = new CheckboxListEntryModel("Newsletter", false,
19
- newsletterSubscriptionChangeHandler);
20
- final Set<CheckboxListEntryModel> entries = new HashSet<>(
21
- Arrays.asList(passwordReset, securityAlerts, newsletter));
22
- new CheckboxListEntryModel(null, false, newsletterSubscriptionChangeHandler);
23
- return entries;
24
- }
25
-
26
- private void setSecurityAlertsSubscription(final boolean value) {
27
- }
28
-
29
- private void setNewsletterSubscription(final boolean value) {
30
- }
31
-}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/IPBlocklistTableWrapper.java
... ...
@@ -1,172 +0,0 @@
1
-package com.sap.sailing.gwt.ui.adminconsole;
2
-
3
-import java.util.ArrayList;
4
-import java.util.Comparator;
5
-import java.util.List;
6
-
7
-import com.google.gwt.event.dom.client.ClickEvent;
8
-import com.google.gwt.event.dom.client.ClickHandler;
9
-import com.google.gwt.user.cellview.client.AbstractCellTable;
10
-import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
11
-import com.google.gwt.user.client.rpc.AsyncCallback;
12
-import com.google.gwt.user.client.ui.Button;
13
-import com.google.gwt.user.client.ui.HasVerticalAlignment;
14
-import com.google.gwt.user.client.ui.HorizontalPanel;
15
-import com.google.gwt.user.client.ui.Label;
16
-import com.google.gwt.user.client.ui.Widget;
17
-import com.sap.sailing.gwt.ui.client.SailingServiceWriteAsync;
18
-import com.sap.sailing.gwt.ui.client.StringMessages;
19
-import com.sap.sse.gwt.client.ErrorReporter;
20
-import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
21
-import com.sap.sse.gwt.client.celltable.RefreshableSelectionModel;
22
-import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
23
-import com.sap.sse.security.shared.HasPermissions.DefaultActions;
24
-import com.sap.sse.security.shared.WildcardPermission;
25
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
26
-import com.sap.sse.security.ui.client.UserService;
27
-import com.sap.sse.security.ui.client.component.SelectedElementsCountingButton;
28
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
29
-
30
-abstract class IPBlocklistTableWrapper
31
- extends TableWrapper<IpToTimedLockDTO, RefreshableSelectionModel<IpToTimedLockDTO>> {
32
- private final UserService userService;
33
- private final LabeledAbstractFilterablePanel<IpToTimedLockDTO> filterField;
34
- private final String errorMessageOnDataFailureString;
35
-
36
- protected abstract void fetchData(AsyncCallback<ArrayList<IpToTimedLockDTO>> callback);
37
-
38
- protected abstract void unlockIP(String ip, AsyncCallback<Void> asyncCallback);
39
-
40
- public IPBlocklistTableWrapper(final SailingServiceWriteAsync sailingServiceWrite, final UserService userService,
41
- final String errorMessageOnDataFailureString, final StringMessages stringMessages,
42
- final ErrorReporter errorReporter) {
43
- super(sailingServiceWrite, stringMessages, errorReporter, true, true,
44
- new EntityIdentityComparator<IpToTimedLockDTO>() {
45
- @Override
46
- public boolean representSameEntity(IpToTimedLockDTO dto1, IpToTimedLockDTO dto2) {
47
- return dto1.getIp().equals(dto2.getIp());
48
- }
49
-
50
- @Override
51
- public int hashCode(IpToTimedLockDTO t) {
52
- return t.getIp().hashCode();
53
- }
54
- });
55
- this.userService = userService;
56
- this.errorMessageOnDataFailureString = errorMessageOnDataFailureString;
57
- this.filterField = composeFilterField();
58
- this.asWidget().ensureDebugId("wrappedTable");
59
- this.table.ensureDebugId("cellTable");
60
- configureDataColumns();
61
- setButtonsAndFilterOnMainPanel();
62
- loadDataAndPopulateTable();
63
- }
64
-
65
- private void setButtonsAndFilterOnMainPanel() {
66
- final HorizontalPanel searchPanel = new HorizontalPanel();
67
- searchPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
68
- searchPanel.setSpacing(5);
69
- final Label label = new Label(getStringMessages().filterIpAddresses() + ": ");
70
- searchPanel.add(label);
71
- searchPanel.add(filterField.getTextBox());
72
- // inserted with indices to put them above the table
73
- mainPanel.insert(searchPanel, 0);
74
- mainPanel.insert(composeButtonPanel(), 1);
75
- mainPanel.setSpacing(5);
76
- }
77
-
78
- private Widget composeButtonPanel() {
79
- final HorizontalPanel buttonPanel = new HorizontalPanel();
80
- buttonPanel.setSpacing(5);
81
- final Button refreshButton = new Button(getStringMessages().refresh(), new ClickHandler() {
82
- @Override
83
- public void onClick(ClickEvent event) {
84
- loadDataAndPopulateTable();
85
- }
86
- });
87
- refreshButton.ensureDebugId("refreshButton");
88
- buttonPanel.add(refreshButton);
89
- if (hasUnlockPermission()) {
90
- final Button unlockButton = composeUnlockButton();
91
- unlockButton.ensureDebugId("unlockButton");
92
- buttonPanel.add(unlockButton);
93
- }
94
- return buttonPanel;
95
- }
96
-
97
- private boolean hasUnlockPermission() {
98
- final WildcardPermission unlockIpPermission = SecuredSecurityTypes.LOCKED_IP
99
- .getPermission(DefaultActions.DELETE);
100
- return userService.hasPermission(unlockIpPermission, userService.getServerInfo().getOwnership());
101
- }
102
-
103
- private SelectedElementsCountingButton<IpToTimedLockDTO> composeUnlockButton() {
104
- return new SelectedElementsCountingButton<IpToTimedLockDTO>(getStringMessages().unlock(), getSelectionModel(),
105
- new ClickHandler() {
106
- @Override
107
- public void onClick(ClickEvent event) {
108
- for (IpToTimedLockDTO e : getSelectionModel().getSelectedSet()) {
109
- unlockIP(e.getIp(), new AsyncCallback<Void>() {
110
- @Override
111
- public void onFailure(Throwable caught) {
112
- errorReporter.reportError(errorMessageOnDataFailureString);
113
- }
114
-
115
- @Override
116
- public void onSuccess(Void result) {
117
- filterField.remove(e);
118
- }
119
- });
120
- }
121
- }
122
- });
123
- }
124
-
125
- private void loadDataAndPopulateTable() {
126
- final AsyncCallback<ArrayList<IpToTimedLockDTO>> dataInitializationCallback = new AsyncCallback<ArrayList<IpToTimedLockDTO>>() {
127
- @Override
128
- public void onFailure(Throwable caught) {
129
- errorReporter.reportError(errorMessageOnDataFailureString);
130
- }
131
-
132
- @Override
133
- public void onSuccess(ArrayList<IpToTimedLockDTO> result) {
134
- filterField.clear();
135
- clear();
136
- filterField.addAll(result);
137
- }
138
- };
139
- fetchData(dataInitializationCallback);
140
- }
141
-
142
- private void configureDataColumns() {
143
- final ListHandler<IpToTimedLockDTO> columnListHandler = getColumnSortHandler();
144
- addColumn(record -> record.getIp(), getStringMessages().ipAddress());
145
- final Comparator<IpToTimedLockDTO> expiryComparator = (o1, o2) -> {
146
- return o1.getTimedLock().getLockedUntil().compareTo(o2.getTimedLock().getLockedUntil());
147
- };
148
- addColumn(record -> record.getTimedLock().getLockedUntil().toString(), getStringMessages().lockedUntil(),
149
- expiryComparator);
150
- table.addColumnSortHandler(columnListHandler);
151
- }
152
-
153
- private LabeledAbstractFilterablePanel<IpToTimedLockDTO> composeFilterField() {
154
- final LabeledAbstractFilterablePanel<IpToTimedLockDTO> filterField = new LabeledAbstractFilterablePanel<IpToTimedLockDTO>(
155
- new Label(getStringMessages().filterIpAddresses()), new ArrayList<>(), getDataProvider(),
156
- getStringMessages()) {
157
- @Override
158
- public Iterable<String> getSearchableStrings(IpToTimedLockDTO dto) {
159
- final List<String> string = new ArrayList<String>();
160
- string.add(dto.getIp());
161
- return string;
162
- }
163
-
164
- @Override
165
- public AbstractCellTable<IpToTimedLockDTO> getCellTable() {
166
- return table;
167
- }
168
- };
169
- registerSelectionModelOnNewDataProvider(filterField.getAllListDataProvider());
170
- return filterField;
171
- }
172
-}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/adminconsole/LocalServerManagementPanel.java
... ...
@@ -52,7 +52,6 @@ import com.sap.sse.security.ui.client.UserStatusEventHandler;
52 52
import com.sap.sse.security.ui.client.component.AccessControlledButtonPanel;
53 53
import com.sap.sse.security.ui.client.component.EditOwnershipDialog;
54 54
import com.sap.sse.security.ui.client.component.editacl.EditACLDialog;
55
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
56 55
57 56
public class LocalServerManagementPanel extends SimplePanel {
58 57
private final SailingServiceWriteAsync sailingService;
... ...
@@ -88,8 +87,6 @@ public class LocalServerManagementPanel extends SimplePanel {
88 87
mainPanel.add(this.buttonPanel = createServerActionsUi(userService));
89 88
mainPanel.add(createServerInfoUI());
90 89
mainPanel.add(createServerConfigurationUI());
91
- mainPanel.add(createBearerTokenAbusePanel());
92
- mainPanel.add(createUserCreationAbusePanel());
93 90
refreshServerConfiguration();
94 91
if (userService.hasServerPermission(ServerActions.CONFIGURE_CORS_FILTER)) {
95 92
mainPanel.add(createCORSFilterConfigurationUI());
... ...
@@ -160,44 +157,6 @@ public class LocalServerManagementPanel extends SimplePanel {
160 157
return captionPanel;
161 158
}
162 159
163
- private Widget createBearerTokenAbusePanel() {
164
- final ServerDataCaptionPanel panel = new ServerDataCaptionPanel(stringMessages.ipsLockedForBearerTokenAbuse(), 3);
165
- panel.ensureDebugId("bearerTokenAbusePanel");
166
- final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
167
- stringMessages.unableToLoadIpsBlockedForBearerTokenAbuse(), stringMessages, errorReporter) {
168
- @Override
169
- protected void fetchData(AsyncCallback<ArrayList<IpToTimedLockDTO>> callback) {
170
- userService.getUserManagementService().getClientIPBasedTimedLocksForBearerTokenAbuse(callback);
171
- }
172
-
173
- @Override
174
- protected void unlockIP(String ip, AsyncCallback<Void> asyncCallback) {
175
- userService.getUserManagementWriteService().releaseBearerTokenLockOnIp(ip, asyncCallback);
176
- }
177
- };
178
- panel.setContentWidget(table.asWidget());
179
- return panel;
180
- }
181
-
182
- private Widget createUserCreationAbusePanel() {
183
- final ServerDataCaptionPanel panel = new ServerDataCaptionPanel(stringMessages.ipsLockedForUserCreationAbuse(), 3);
184
- panel.ensureDebugId("userCreationAbusePanel");
185
- final IPBlocklistTableWrapper table = new IPBlocklistTableWrapper(sailingService, userService,
186
- stringMessages.unableToLoadIpsBlockedForUserCreationAbuse(), stringMessages, errorReporter) {
187
- @Override
188
- protected void fetchData(AsyncCallback<ArrayList<IpToTimedLockDTO>> callback) {
189
- userService.getUserManagementService().getClientIPBasedTimedLocksForUserCreation(callback);
190
- }
191
-
192
- @Override
193
- protected void unlockIP(String ip, AsyncCallback<Void> asyncCallback) {
194
- userService.getUserManagementWriteService().releaseUserCreationLockOnIp(ip, asyncCallback);
195
- }
196
- };
197
- panel.setContentWidget(table.asWidget());
198
- return panel;
199
- }
200
-
201 160
private Widget createCORSFilterConfigurationUI() {
202 161
final ServerDataCaptionPanel captionPanel = new ServerDataCaptionPanel(stringMessages.corsAndCSPFilterConfiguration(), 4);
203 162
captionPanel.addWidget("", new Label(stringMessages.corsAndCSPFilterConfigurationHint()));
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.java
... ...
@@ -2547,11 +2547,4 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
2547 2547
String strategySimulatorReadMore();
2548 2548
String testConnection();
2549 2549
String tracTracConnectionTestFailed(String message);
2550
- String ipsLockedForBearerTokenAbuse();
2551
- String unableToLoadIpsBlockedForBearerTokenAbuse();
2552
- String ipAddress();
2553
- String filterIpAddresses();
2554
- String unlock();
2555
- String ipsLockedForUserCreationAbuse();
2556
- String unableToLoadIpsBlockedForUserCreationAbuse();
2557 2550
}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages.properties
... ...
@@ -2582,11 +2582,4 @@ exportTWAHistogramToCsv=Export True Wind Angle histogram to CSV
2582 2582
exportWindSpeedHistogramToCsv=Export Wind Speed histogram to CSV
2583 2583
optionalBearerTokenForWindImport=Optional bearer token for wind import
2584 2584
testConnection=Test Connection
2585
-tracTracConnectionTestFailed=TracTrac connection test failed: {0}
2586
-ipsLockedForBearerTokenAbuse=IPs locked for Bearer Token abuse
2587
-unableToLoadIpsBlockedForBearerTokenAbuse=Unable to load IPs blocked for bearer token abuse
2588
-ipAddress=IP Address
2589
-filterIpAddresses=Filter IP Addresses
2590
-unlock=Unlock
2591
-ipsLockedForUserCreationAbuse=IPs Locked for User Creation Abuse
2592
-unableToLoadIpsBlockedForUserCreationAbuse=Unable to load IPs Blocked for User Creation Abuse
2585
+tracTracConnectionTestFailed=TracTrac connection test failed: {0}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/StringMessages_de.properties
... ...
@@ -2576,11 +2576,4 @@ exportTWAHistogramToCsv=Histogramm der wahren Windwinkel in CSV exportieren
2576 2576
exportWindSpeedHistogramToCsv=Histogramm der wahren Windgeschwindigkeiten in CSV exportieren
2577 2577
optionalBearerTokenForWindImport=Optionales Bearer Token für Wind-Import
2578 2578
testConnection=Verbindung testen
2579
-tracTracConnectionTestFailed=TracTrac-Verbindungstest fehlgeschlagen: {0}
2580
-ipsLockedForBearerTokenAbuse=IPs wegen Missbrauchs von Bearer-Token gesperrt
2581
-unableToLoadIpsBlockedForBearerTokenAbuse=Aufgrund von Missbrauch des Inhabertokens blockierte IPs können nicht geladen werden
2582
-ipAddress=IP-Addresse
2583
-filterIpAddresses=IP-Adressen filtern
2584
-unlock=Entsperren
2585
-ipsLockedForUserCreationAbuse=Wegen Missbrauchs bei der Benutzererstellung gesperrte IPs
2586
-unableToLoadIpsBlockedForUserCreationAbuse=Wegen Missbrauchs der Benutzererstellung blockierte IPs können nicht geladen werden
2579
+tracTracConnectionTestFailed=TracTrac-Verbindungstest fehlgeschlagen: {0}
... ...
\ No newline at end of file
java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/FAREAST28R.png
... ...
Binary files a/java/com.sap.sailing.gwt.ui/src/main/resources/com/sap/sailing/gwt/ui/client/images/boatclass/FAREAST28R.png and /dev/null differ
java/com.sap.sailing.gwt.ui/src/main/resources/shiro.ini
... ...
@@ -22,7 +22,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
22 22
securityManager.sessionManager.globalSessionTimeout = 31536000000
23 23
cacheManager = com.sap.sse.security.SessionCacheManager
24 24
securityManager.cacheManager = $cacheManager
25
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
25
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
26 26
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
27 27
28 28
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
java/com.sap.sailing.hanaexport/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.landscape.gateway/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.landscape.ui/resources/shiro.ini
... ...
@@ -24,7 +24,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
24 24
securityManager.sessionManager.globalSessionTimeout = 31536000000
25 25
cacheManager = com.sap.sse.security.SessionCacheManager
26 26
securityManager.cacheManager = $cacheManager
27
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
27
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
28 28
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
29 29
30 30
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/LandscapeManagementPanel.java
... ...
@@ -1561,7 +1561,7 @@ public class LandscapeManagementPanel extends SimplePanel {
1561 1561
new AsyncCallback<Void>() {
1562 1562
@Override
1563 1563
public void onSuccess(Void result) {
1564
- Notification.notify(stringMessages.unlockedSuccessfully(), NotificationType.SUCCESS);
1564
+ Notification.notify(stringMessages.success(), NotificationType.SUCCESS);
1565 1565
proxiesTableBusy.setBusy(false);
1566 1566
refreshProxiesTable();
1567 1567
}
java/com.sap.sailing.landscape.ui/src/com/sap/sailing/landscape/ui/client/i18n/StringMessages.java
... ...
@@ -172,7 +172,7 @@ com.sap.sse.gwt.adminconsole.StringMessages {
172 172
String successfullyRotatedHttpdLogsOnInstance(String instance);
173 173
String invalidOperationForThisProxy();
174 174
String pleaseProvideNonEmptyNameAndAZ();
175
- String unlockedSuccessfully();
175
+ String success();
176 176
String availabilityZone();
177 177
String runOnExisting();
178 178
String publicIp();
java/com.sap.sailing.polars/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/api/core/ApiContext.java
... ...
@@ -30,7 +30,6 @@ public class ApiContext {
30 30
public static final String SECURITY_CONTEXT = "security"; //$NON-NLS-1$
31 31
public static final String ADMIN_USERNAME = "admin"; //$NON-NLS-1$
32 32
public static final String ADMIN_PASSWORD = "admin"; //$NON-NLS-1$
33
- public static final String INVALID_TOKEN_SAMPLE = "INVALID_TOKEN_SAMPLE";
34 33
35 34
private static final Logger logger = Logger.getLogger(ApiContext.class.getName());
36 35
... ...
@@ -76,19 +75,6 @@ public class ApiContext {
76 75
}
77 76
78 77
/**
79
- * Creates an ApiContext with an invalid token. Useful for testing.
80
- *
81
- * @param contextRoot
82
- * server instance
83
- * @param context
84
- * web application context
85
- * @return ApiContext with invalid token
86
- */
87
- public static ApiContext createApiContextWithInvalidToken(String contextRoot, String context) {
88
- return new ApiContext(contextRoot, context, INVALID_TOKEN_SAMPLE);
89
- }
90
-
91
- /**
92 78
* Creates an ApiContext with administrator privileges.
93 79
*
94 80
* @param contextRoot
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/core/SeleniumTestInvocationProvider.java
... ...
@@ -18,10 +18,9 @@ import com.sap.sailing.selenium.test.AbstractSeleniumTest;
18 18
* Used to extend the {@link SeleniumTestCase} annotation which in turn is used to mark the test methods of all Selenium
19 19
* tests declared in subclasses of {@link AbstractSeleniumTest}. This provider produces test invocation contexts, one
20 20
* for each {@link TestEnvironmentConfiguration#getDriverDefinitions() driver definition} found in the test environment
21
- * configuration. These contexts provide a test instance-specific extension of type
22
- * {@link SeleniumTestEnvironmentInjector} which is in particular a {@link TestInstancePostProcessor} that creates and
23
- * injects a {@link TestEnvironment} created for the driver definition known by the parameter resolver.
24
- * <p>
21
+ * configuration. These contexts provide a test instance-specific extension of type {@link SeleniumTestEnvironmentInjector}
22
+ * which is in particular a {@link TestInstancePostProcessor} that creates and injects a {@link TestEnvironment} created
23
+ * for the driver definition known by the parameter resolver.<p>
25 24
*
26 25
* @author Axel Uhl (d043530)
27 26
*
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/ActionsHelper.java
... ...
@@ -23,9 +23,8 @@ public class ActionsHelper {
23 23
public static final String UNLINK_RACE_ACTION = "ACTION_UNLINK";
24 24
public static final String REFRESH_RACE_ACTION = "ACTION_REFRESH_RACE";
25 25
public static final String SET_START_TIME_ACTION = "ACTION_SET_STARTTIME";
26
-
26
+
27 27
public static final String UPDATE_ACTION = "UPDATE";
28
- public static final String UNLOCK_ACTION = "MANAGE_LOCK";
29 28
public static final String DELETE_ACTION = "DELETE";
30 29
public static final String CHANGE_OWNERSHIP_ACTION = "CHANGE_OWNERSHIP";
31 30
... ...
@@ -60,10 +59,6 @@ public class ActionsHelper {
60 59
public static WebElement findUpdateAction(SearchContext context) {
61 60
return context.findElement(By.xpath(String.format(ACTION_XPATH, UPDATE_ACTION)));
62 61
}
63
-
64
- public static WebElement findUnlockAction(SearchContext context) {
65
- return context.findElement(By.xpath(String.format(ACTION_XPATH, UNLOCK_ACTION)));
66
- }
67 62
68 63
public static WebElement findDeleteAction(SearchContext context) {
69 64
return context.findElement(By.xpath(String.format(ACTION_XPATH, DELETE_ACTION)));
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/advanced/IpBlocklistPanelPO.java
... ...
@@ -1,75 +0,0 @@
1
-package com.sap.sailing.selenium.pages.adminconsole.advanced;
2
-
3
-import org.openqa.selenium.WebDriver;
4
-import org.openqa.selenium.WebElement;
5
-
6
-import com.sap.sailing.selenium.core.BySeleniumId;
7
-import com.sap.sailing.selenium.core.FindBy;
8
-import com.sap.sailing.selenium.pages.PageArea;
9
-import com.sap.sailing.selenium.pages.gwt.CellTablePO;
10
-import com.sap.sailing.selenium.pages.gwt.DataEntryPO;
11
-
12
-public class IpBlocklistPanelPO extends PageArea {
13
- static class IPBlocklistTablePO extends CellTablePO<IPLockEntry> {
14
- public IPBlocklistTablePO(WebDriver driver, WebElement element) {
15
- super(driver, element);
16
- }
17
-
18
- @Override
19
- protected IPLockEntry createDataEntry(WebElement element) {
20
- return new IPLockEntry(this, element);
21
- }
22
-
23
- }
24
-
25
- public static class IPLockEntry extends DataEntryPO {
26
- private static final String IP_COLUMN = "IP Address";
27
- private static final String LOCKED_UNTIL_COLUMN = "Locked until";
28
-
29
- protected IPLockEntry(CellTablePO<IPLockEntry> table, WebElement element) {
30
- super(table, element);
31
- }
32
-
33
- @Override
34
- public String getIdentifier() {
35
- return getIp();
36
- }
37
-
38
- public String getIp() {
39
- return getColumnContent(IP_COLUMN);
40
- }
41
-
42
- public String getLockedUntil() {
43
- return getColumnContent(LOCKED_UNTIL_COLUMN);
44
- }
45
- }
46
-
47
- public IpBlocklistPanelPO(WebDriver driver, WebElement element) {
48
- super(driver, element);
49
- final WebElement cellTableWebElement = this.findElementBySeleniumId("cellTable");
50
- this.cellTable = new IPBlocklistTablePO(driver, cellTableWebElement);
51
- }
52
-
53
- @FindBy(how = BySeleniumId.class, using = "refreshButton")
54
- private WebElement refreshButton;
55
-
56
- @FindBy(how = BySeleniumId.class, using = "unlockButton")
57
- private WebElement unlockButton;
58
-
59
- private final IPBlocklistTablePO cellTable;
60
-
61
- public void refresh() {
62
- refreshButton.click();
63
- }
64
-
65
- public boolean isIpInTable(final String ip) {
66
- final IPLockEntry entry = cellTable.getEntry(ip);
67
- final boolean wasFound = entry != null;
68
- return wasFound;
69
- }
70
-
71
- public void unblockIP(String ip) {
72
- cellTable.getEntry(ip).select();
73
- unlockButton.click();
74
- }
75
-}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/advanced/LocalServerPO.java
... ...
@@ -15,28 +15,12 @@ public class LocalServerPO extends PageArea {
15 15
16 16
@FindBy(how = BySeleniumId.class, using = "isSelfServiceServerCheckbox-input")
17 17
private WebElement isSelfServiceServerCheckbox;
18
-
18
+
19 19
@FindBy(how = BySeleniumId.class, using = "isPublicServerCheckbox-input")
20 20
private WebElement isPublicServerCheckbox;
21
-
21
+
22 22
@FindBy(how = BySeleniumId.class, using = "isStandaloneServerCheckbox-input")
23 23
private WebElement isStandaloneServerCheckbox;
24
-
25
- @FindBy(how = BySeleniumId.class, using = "bearerTokenAbusePanel")
26
- private WebElement bearerTokenAbusePanel;
27
-
28
- @FindBy(how = BySeleniumId.class, using = "userCreationAbusePanel")
29
- private WebElement userCreationAbusePanel;
30
-
31
- public IpBlocklistPanelPO getBearerTokenAbusePO() {
32
- final WebElement wrappedTable = bearerTokenAbusePanel.findElement(new BySeleniumId("wrappedTable"));
33
- return new IpBlocklistPanelPO(this.driver, wrappedTable);
34
- }
35
-
36
- public IpBlocklistPanelPO getUserCreationAbusePO() {
37
- final WebElement wrappedTable = userCreationAbusePanel.findElement(new BySeleniumId("wrappedTable"));
38
- return new IpBlocklistPanelPO(this.driver, wrappedTable);
39
- }
40 24
41 25
public void setSelfServiceServer(boolean selfService) {
42 26
if (selfService != isSelfServiceServerCheckbox.isSelected()) {
... ...
@@ -44,14 +28,14 @@ public class LocalServerPO extends PageArea {
44 28
awaitServerConfigurationUpdated();
45 29
}
46 30
}
47
-
31
+
48 32
public void setPublicServer(boolean publicServer) {
49 33
if (publicServer != isPublicServerCheckbox.isSelected()) {
50 34
isPublicServerCheckbox.click();
51 35
awaitServerConfigurationUpdated();
52 36
}
53 37
}
54
-
38
+
55 39
public void setStandaloneServer(boolean standalone) {
56 40
if (standalone != isStandaloneServerCheckbox.isSelected()) {
57 41
isStandaloneServerCheckbox.click();
... ...
@@ -68,4 +52,5 @@ public class LocalServerPO extends PageArea {
68 52
final String updating = isSelfServiceServerCheckbox.getAttribute("updating");
69 53
return "true".equals(updating);
70 54
}
55
+
71 56
}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/regatta/RegattaDetailsCompositePO.java
... ...
@@ -72,8 +72,8 @@ public class RegattaDetailsCompositePO extends PageArea {
72 72
if (entry != null) {
73 73
WebElement removeAction = ActionsHelper.findRemoveAction(entry.getWebElement());
74 74
removeAction.click();
75
- ActionsHelper.acceptAlert(this.driver);
76
- waitForAjaxRequests();
75
+ ActionsHelper.acceptAlert(this.driver);
76
+ waitForAjaxRequests();
77 77
}
78 78
}
79 79
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/adminconsole/usermanagement/UserManagementPanelPO.java
... ...
@@ -30,10 +30,7 @@ public class UserManagementPanelPO extends PageArea {
30 30
private WebElement createUserButton;
31 31
32 32
@FindBy(how = BySeleniumId.class, using = "DeleteUserButton")
33
- private WebElement deleteUserButton;
34
-
35
- @FindBy(how = BySeleniumId.class, using = "UnlockUserButton")
36
- private WebElement unlockUserButton;
33
+ private WebElement deleteUserButton;
37 34
38 35
@FindBy(how = BySeleniumId.class, using = "UserNameTextbox")
39 36
private WebElement userNameTextbox;
... ...
@@ -155,43 +152,6 @@ public class UserManagementPanelPO extends PageArea {
155 152
deleteUserButton.click();
156 153
}
157 154
158
- public void unlockSelectedUsers() {
159
- final List<DataEntryPO> selection = getUserTable().getSelectedEntries();
160
- final List<String> selectedUsersNames = new ArrayList<String>();
161
- for (DataEntryPO dataEntryPO : selection) {
162
- final String username = dataEntryPO.getColumnContent("User name");
163
- selectedUsersNames.add(username);
164
- }
165
- unlockUserButton.click();
166
- // confirmation dialog
167
- waitForAlertAndAccept();
168
- // response dialog
169
- waitForAlertAndAccept();
170
- // wait until all locked untils of previously selected then unlocked users are blanked out
171
- waitUntil(() -> {
172
- for (String selectedUsersName : selectedUsersNames) {
173
- final String lockedUntilVal = findUser(selectedUsersName).getColumnContent("Locked until");
174
- if (!lockedUntilVal.equals("")) {
175
- return false;
176
- }
177
- }
178
- return true;
179
- });
180
-
181
- }
182
-
183
- public void unlockUser(String name) {
184
- selectUser(name);
185
- final DataEntryPO entry = findUser(name);
186
- if (entry != null) {
187
- final WebElement action = ActionsHelper.findUnlockAction(entry.getWebElement());
188
- action.click();
189
- }
190
- waitUntilAlertIsPresent();
191
- driver.switchTo().alert().accept();
192
- waitForAjaxRequests();
193
- }
194
-
195 155
public void waitUntilUserFound(String userName) {
196 156
waitUntil(() -> findUser(userName) != null);
197 157
}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/pages/authentication/AuthenticationMenuPO.java
... ...
@@ -7,32 +7,29 @@ import com.sap.sailing.selenium.pages.PageArea;
7 7
import com.sap.sailing.selenium.pages.common.AttributeHelper;
8 8
9 9
public class AuthenticationMenuPO extends PageArea {
10
-
10
+
11 11
public AuthenticationMenuPO(WebDriver driver, WebElement element) {
12 12
super(driver, element);
13 13
}
14
-
14
+
15 15
public boolean isOpen() {
16 16
return AttributeHelper.isEnabled(getWebElement(), "data-open");
17 17
}
18
-
18
+
19 19
public boolean isLoggedIn() {
20 20
return AttributeHelper.isEnabled(getWebElement(), "data-auth");
21 21
}
22
-
23
- public boolean attemptLogin(String username, String password) {
22
+
23
+ public void doLogin(String username, String password) {
24 24
AuthenticationViewPO authenticationView = showAuthenticationView();
25 25
authenticationView.getSignInView().doLogin(username, password);
26
- waitForAjaxRequests();
27
- return isLoggedIn();
26
+ waitUntil(this::isLoggedIn);
28 27
}
29
-
28
+
30 29
private AuthenticationViewPO showAuthenticationView() {
31
- if (!this.isOpen()) {
32
- getWebElement().click();
33
- }
30
+ getWebElement().click();
34 31
waitUntil(this::isOpen);
35 32
return getPO(AuthenticationViewPO::new, "authenticationView");
36 33
}
37
-
34
+
38 35
}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/TestIpLocking.java
... ...
@@ -1,113 +0,0 @@
1
-package com.sap.sailing.selenium.test.adminconsole;
2
-
3
-import static org.junit.jupiter.api.Assertions.assertFalse;
4
-import static org.junit.jupiter.api.Assertions.assertTrue;
5
-
6
-import java.util.HashMap;
7
-import java.util.Map;
8
-
9
-import org.junit.jupiter.api.BeforeEach;
10
-
11
-import com.sap.sailing.selenium.api.core.ApiContext;
12
-import com.sap.sailing.selenium.api.core.HttpException.Unauthorized;
13
-import com.sap.sailing.selenium.api.event.PreferencesApi;
14
-import com.sap.sailing.selenium.api.event.SecurityApi;
15
-import com.sap.sailing.selenium.core.SeleniumTestCase;
16
-import com.sap.sailing.selenium.pages.adminconsole.AdminConsolePage;
17
-import com.sap.sailing.selenium.pages.adminconsole.advanced.IpBlocklistPanelPO;
18
-import com.sap.sailing.selenium.pages.adminconsole.advanced.LocalServerPO;
19
-import com.sap.sailing.selenium.test.AbstractSeleniumTest;
20
-
21
-public class TestIpLocking extends AbstractSeleniumTest {
22
- @Override
23
- @BeforeEach
24
- public void setUp() {
25
- clearState(getContextRoot());
26
- super.setUp();
27
- }
28
-
29
- @SeleniumTestCase
30
- public void testUnlockingForBearerTokenAbuser() throws InterruptedException {
31
- final AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
32
- final LocalServerPO localServerPanel = adminConsole.goToLocalServerPanel();
33
- IpBlocklistPanelPO tablePO = localServerPanel.getBearerTokenAbusePO();
34
- attemptBearerTokenAbuse(4);
35
- tablePO.refresh();
36
- final String ip = "127.0.0.1";
37
- assertTrue(tablePO.isIpInTable(ip));
38
- tablePO.unblockIP(ip);
39
- // reference was getting stale otherwise
40
- tablePO = localServerPanel.getBearerTokenAbusePO();
41
- assertFalse(tablePO.isIpInTable(ip));
42
- attemptValidBearerTokenUse();
43
- }
44
-
45
- private void attemptValidBearerTokenUse() {
46
- // prepare api
47
- final ApiContext ctx = ApiContext.createAdminApiContext(getContextRoot(), ApiContext.SECURITY_CONTEXT);
48
- final Map<String, String> prefObjectAttr = new HashMap<String, String>();
49
- prefObjectAttr.put("key1", "value1");
50
- PreferencesApi preferencesApi = new PreferencesApi();
51
- preferencesApi.createPreference(ctx, "pref1", prefObjectAttr);
52
- }
53
-
54
- private void attemptBearerTokenAbuse(final int attempts) throws InterruptedException {
55
- // prepare api
56
- final ApiContext wrongCtx = ApiContext.createApiContextWithInvalidToken(getContextRoot(),
57
- ApiContext.SECURITY_CONTEXT);
58
- final Map<String, String> prefObjectAttr = new HashMap<String, String>();
59
- prefObjectAttr.put("key1", "value1");
60
- final PreferencesApi preferencesApi = new PreferencesApi();
61
- for (int i = 0; i < attempts; i++) {
62
- // call api
63
- try {
64
- preferencesApi.createPreference(wrongCtx, "pref1", prefObjectAttr);
65
- } catch (Unauthorized e) {
66
- // do nothing as this is expected
67
- }
68
- // wait for lock to expire
69
- long lockDuration = (long) Math.pow(2, i) * 1000;
70
- boolean isFinalAttempt = i == (attempts - 1);
71
- if (!isFinalAttempt) {
72
- Thread.sleep(lockDuration);
73
- }
74
- }
75
- }
76
-
77
- @SeleniumTestCase
78
- public void testUnlockingForUserCreationAbuser() throws InterruptedException {
79
- final AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
80
- final LocalServerPO localServerPanel = adminConsole.goToLocalServerPanel();
81
- IpBlocklistPanelPO tablePO = localServerPanel.getUserCreationAbusePO();
82
- spamUserCreation(4);
83
- tablePO.refresh();
84
- final String ip = "127.0.0.1";
85
- assertTrue(tablePO.isIpInTable(ip));
86
- tablePO.unblockIP(ip);
87
- // reference was getting stale otherwise
88
- tablePO = localServerPanel.getUserCreationAbusePO();
89
- assertFalse(tablePO.isIpInTable(ip));
90
- attemptValidBearerTokenUse();
91
- }
92
-
93
- private void spamUserCreation(final int attempts) throws InterruptedException {
94
- for (int i = 0; i < attempts; i++) {
95
- attemptUserCreation(String.valueOf(i));
96
- // wait for lock to expire
97
- final long lockDuration = (long) Math.pow(2, i) * 1000;
98
- final boolean isFinalAttempt = i == (attempts - 1);
99
- if (!isFinalAttempt) {
100
- Thread.sleep(lockDuration);
101
- }
102
- }
103
- }
104
-
105
- private boolean attemptUserCreation(String seed) {
106
- try {
107
- SecurityApi.createUser("USERNAME" + seed, "PASSWORD").run();
108
- return true;
109
- } catch (Exception e) {
110
- return false;
111
- }
112
- }
113
-}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/adminconsole/usermanagement/TestUserManagement.java
... ...
@@ -1,9 +1,7 @@
1 1
package com.sap.sailing.selenium.test.adminconsole.usermanagement;
2 2
3
-import static org.junit.jupiter.api.Assertions.assertFalse;
4 3
import static org.junit.jupiter.api.Assertions.assertNotNull;
5 4
import static org.junit.jupiter.api.Assertions.assertNull;
6
-import static org.junit.jupiter.api.Assertions.assertTrue;
7 5
8 6
import org.junit.jupiter.api.BeforeEach;
9 7
... ...
@@ -15,7 +13,6 @@ import com.sap.sailing.selenium.pages.adminconsole.usermanagement.EditUserDialog
15 13
import com.sap.sailing.selenium.pages.adminconsole.usermanagement.UserManagementPanelPO;
16 14
import com.sap.sailing.selenium.pages.adminconsole.usermanagement.UserRoleDefinitionPanelPO;
17 15
import com.sap.sailing.selenium.pages.adminconsole.usermanagement.WildcardPermissionPanelPO;
18
-import com.sap.sailing.selenium.pages.authentication.AuthenticationMenuPO;
19 16
import com.sap.sailing.selenium.test.AbstractSeleniumTest;
20 17
21 18
public class TestUserManagement extends AbstractSeleniumTest {
... ...
@@ -58,7 +55,7 @@ public class TestUserManagement extends AbstractSeleniumTest {
58 55
assertNull(userRolesPO.findRole(TEST_ROLE));
59 56
createRole(userRolesPO);
60 57
userManagementPanel.selectUser(TEST_USER_NAME);
61
- assertNotNull(userRolesPO.findRole(TEST_ROLE + ":" + TEST_GROUP + ":" + TEST_USER_NAME));
58
+ assertNotNull(userRolesPO.findRole(TEST_ROLE + ":"+ TEST_GROUP + ":" + TEST_USER_NAME));
62 59
}
63 60
64 61
private void createRole(final UserRoleDefinitionPanelPO userRolesPO) {
... ...
@@ -104,63 +101,6 @@ public class TestUserManagement extends AbstractSeleniumTest {
104 101
}
105 102
106 103
@SeleniumTestCase
107
- public void testUnlockUser() throws InterruptedException {
108
- // at admin
109
- UserManagementPanelPO userManagementPanel = goToUserManagementPanel();
110
- createUser(userManagementPanel);
111
- // logout so test user can login
112
- AuthenticationMenuPO authenticationMenu = logoutAndGoToAdminConsolePage().getAuthenticationMenu();
113
- attemptAbusiveLogins(TEST_USER_NAME, "wrongPassword", 6, authenticationMenu);
114
- // 16s lock window in place now, sufficient to log into admin, unlock user
115
- // and return till test user can login, within the erstwhile lock window
116
- assertTrue(authenticationMenu.attemptLogin("admin", "admin"));
117
- userManagementPanel = goToUserManagementPanel();
118
- userManagementPanel.unlockUser(TEST_USER_NAME);
119
- // logout and correct login within now-unlocked lock window
120
- authenticationMenu = logoutAndGoToAdminConsolePage().getAuthenticationMenu();
121
- assertTrue(
122
- authenticationMenu.attemptLogin(
123
- TEST_USER_NAME, TEST_USER_PASSWORD + UserManagementPanelPO.PASSWORD_COMPLEXITY_SALT));
124
- }
125
-
126
- @SeleniumTestCase
127
- public void testUnlockSelectionOfUsers() throws InterruptedException {
128
- // at admin
129
- UserManagementPanelPO userManagementPanel = goToUserManagementPanel();
130
- createUser(userManagementPanel);
131
- // logout so test user can login
132
- AuthenticationMenuPO authenticationMenu = logoutAndGoToAdminConsolePage().getAuthenticationMenu();
133
- attemptAbusiveLogins(TEST_USER_NAME, "wrongPassword", 5, authenticationMenu);
134
- // 16s lock window in place now, sufficient to log into admin, unlock user
135
- // and return till test user can login, within the erstwhile lock window
136
- assertTrue(authenticationMenu.attemptLogin("admin", "admin"));
137
- userManagementPanel = goToUserManagementPanel();
138
- userManagementPanel.selectUser(TEST_USER_NAME);
139
- userManagementPanel.unlockSelectedUsers();
140
- // logout and correct login within now-unlocked lock window
141
- authenticationMenu = logoutAndGoToAdminConsolePage().getAuthenticationMenu();
142
- assertTrue(
143
- authenticationMenu.attemptLogin(
144
- TEST_USER_NAME, TEST_USER_PASSWORD + UserManagementPanelPO.PASSWORD_COMPLEXITY_SALT));
145
- }
146
-
147
- private void attemptAbusiveLogins(final String username, final String wrongPassword, final int attempts, AuthenticationMenuPO authenticationMenu)
148
- throws InterruptedException {
149
- // logout so test user can login
150
- for (int i = 0; i < attempts; i++) {
151
- // attempt login with wrong password
152
- boolean didSucceed = authenticationMenu.attemptLogin(username, wrongPassword);
153
- assertFalse(didSucceed);
154
- // wait for lock to pass
155
- long lockDuration = (long) Math.pow(2, i) * 1000;
156
- boolean isFinalAttempt = i == (attempts - 1);
157
- if (!isFinalAttempt) {
158
- Thread.sleep(lockDuration);
159
- }
160
- }
161
- }
162
-
163
- @SeleniumTestCase
164 104
public void testRemoveUserPermission() {
165 105
final UserManagementPanelPO userManagementPanel = goToUserManagementPanel();
166 106
createUser(userManagementPanel);
... ...
@@ -188,9 +128,4 @@ public class TestUserManagement extends AbstractSeleniumTest {
188 128
final AdminConsolePage adminConsole = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
189 129
return adminConsole.goToUserManagement();
190 130
}
191
-
192
- private AdminConsolePage logoutAndGoToAdminConsolePage() {
193
- getWebDriver().manage().deleteCookieNamed("JSESSIONID");
194
- return AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
195
- }
196 131
}
java/com.sap.sailing.selenium.test/src/com/sap/sailing/selenium/test/authentication/TestAuthenticationSignIn.java
... ...
@@ -18,44 +18,16 @@ public class TestAuthenticationSignIn extends AbstractSeleniumTest {
18 18
clearState(getContextRoot());
19 19
getWebDriver().manage().deleteCookieNamed("JSESSIONID");
20 20
}
21
-
21
+
22 22
@SeleniumTestCase
23 23
public void testSignInWithExistingUserAdmin() {
24 24
AdminConsolePage adminConsolePage = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
25 25
AuthenticationMenuPO authenticationMenu = adminConsolePage.getAuthenticationMenu();
26 26
assertFalse(authenticationMenu.isOpen());
27 27
assertFalse(authenticationMenu.isLoggedIn());
28
- final boolean didSucceed = authenticationMenu.attemptLogin("admin", "admin");
29
- assertTrue(didSucceed);
30
- }
31
-
32
- // test logic is brittle, it is expected that
33
- // login in test environment takes reliably under
34
- // 4 seconds
35
- @SeleniumTestCase
36
- public void testOffendingSignInWithTimedLock() throws InterruptedException {
37
- AdminConsolePage adminConsolePage = AdminConsolePage.goToPage(getWebDriver(), getContextRoot());
38
- AuthenticationMenuPO authenticationMenu = adminConsolePage.getAuthenticationMenu();
39
- assertFalse(authenticationMenu.isOpen());
40
- assertFalse(authenticationMenu.isLoggedIn());
41
- // wrong login 1
42
- boolean didSucceed = authenticationMenu.attemptLogin("admin", "wrongPassword");
43
- assertFalse(didSucceed);
44
- Thread.sleep(2000); // wait for 2s lock to pass
45
- didSucceed = authenticationMenu.attemptLogin("admin", "wrongPassword");
46
- assertFalse(didSucceed);
47
- Thread.sleep(4000); // wait for 4s lock to pass
48
- didSucceed = authenticationMenu.attemptLogin("admin", "wrongPassword");
49
- assertFalse(didSucceed);
50
- // 4s lock window in place now
51
- // we assert that even correct credentials
52
- // attempted within this lock window will fail.
53
- didSucceed = authenticationMenu.attemptLogin("admin", "admin");
54
- assertFalse(didSucceed);
55
- Thread.sleep(8000); // wait for 8s lock to pass (inefficient, but correct)
56
- // correct credentials should work after lock window lapses
57
- didSucceed = authenticationMenu.attemptLogin("admin", "admin");
58
- assertTrue(didSucceed);
28
+ authenticationMenu.doLogin("admin", "admin");
29
+ assertTrue(authenticationMenu.isOpen());
30
+ assertTrue(authenticationMenu.isLoggedIn());
59 31
}
60 32
61 33
}
java/com.sap.sailing.server.gateway.test.support/resources/shiro.ini
... ...
@@ -32,7 +32,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
32 32
securityManager.sessionManager.globalSessionTimeout = 31536000000
33 33
cacheManager = com.sap.sse.security.SessionCacheManager
34 34
securityManager.cacheManager = $cacheManager
35
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
35
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
36 36
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
37 37
38 38
# Authentication Filter Configurations
java/com.sap.sailing.server.gateway.test/src/com/sap/sailing/server/gateway/test/jaxrs/RegattasResourceTest.java
... ...
@@ -49,11 +49,11 @@ import com.sap.sailing.domain.ranking.OneDesignRankingMetric;
49 49
import com.sap.sse.common.Color;
50 50
import com.sap.sse.common.TimePoint;
51 51
import com.sap.sse.common.impl.MillisecondsTimePoint;
52
-import com.sap.sse.common.impl.TimedLockImpl;
53 52
import com.sap.sse.rest.StreamingOutputUtil;
54 53
import com.sap.sse.security.SecurityService;
55 54
import com.sap.sse.security.interfaces.UserImpl;
56 55
import com.sap.sse.security.shared.Account;
56
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
57 57
import com.sap.sse.security.shared.impl.User;
58 58
59 59
public class RegattasResourceTest extends AbstractJaxRsApiTest {
... ...
@@ -160,7 +160,7 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
160 160
public void testCompetitorRegistrationByAdmin() throws Exception {
161 161
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
162 162
doReturn(true).when(securityService).hasCurrentUserUpdatePermission(Mockito.any());
163
- User user = new UserImpl("admin", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new TimedLockImpl());
163
+ User user = new UserImpl("admin", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new LockingAndBanningImpl());
164 164
setUser(user);
165 165
when(securityService.getCurrentUser()).thenReturn(user);
166 166
Response response = regattasResource.createAndAddCompetitor(closedRegattaName, boatClassName, null, "GER",
... ...
@@ -218,7 +218,7 @@ public class RegattasResourceTest extends AbstractJaxRsApiTest {
218 218
@Test
219 219
public void testCompetitorRegistrationAuthenticatedOnOpenRegatta() throws Exception {
220 220
doReturn(securityService).when(regattasResource).getService(SecurityService.class);
221
- User user = new UserImpl("max", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new TimedLockImpl());
221
+ User user = new UserImpl("max", "noreply@sapsailing.com", null, new ArrayList<Account>(0), null, new LockingAndBanningImpl());
222 222
setUser(user);
223 223
Regatta regatta = racingEventService.getRegattaByName(openRegattaName);
224 224
Response response = regattasResource.createAndAddCompetitor(openRegattaName, boatClassName, null, "GER", "#F00",
java/com.sap.sailing.server.gateway/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.server.replication.test/src/com/sap/sailing/server/replication/test/MediaReplicationTest.java
... ...
@@ -57,7 +57,6 @@ import com.sap.sse.common.TimePoint;
57 57
import com.sap.sse.common.Util;
58 58
import com.sap.sse.common.impl.MillisecondsDurationImpl;
59 59
import com.sap.sse.common.impl.MillisecondsTimePoint;
60
-import com.sap.sse.common.impl.TimedLockImpl;
61 60
import com.sap.sse.common.media.MimeType;
62 61
import com.sap.sse.mongodb.MongoDBConfiguration;
63 62
import com.sap.sse.mongodb.MongoDBService;
... ...
@@ -65,6 +64,7 @@ import com.sap.sse.replication.FullyInitializedReplicableTracker;
65 64
import com.sap.sse.security.SecurityService;
66 65
import com.sap.sse.security.interfaces.UserImpl;
67 66
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
67
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
68 68
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.PublicReadableActions;
69 69
import com.sap.sse.security.shared.impl.SecuredSecurityTypes.ServerActions;
70 70
import com.sap.sse.security.shared.impl.User;
... ...
@@ -248,7 +248,7 @@ public class MediaReplicationTest extends AbstractServerReplicationTest {
248 248
@Test
249 249
public void testMasterDataImportForMediaTracks() throws Exception {
250 250
UserGroupImpl defaultTenant = new UserGroupImpl(new UUID(0, 1), "defaultTenant");
251
- User currentUser = new UserImpl("test", "email@test", Collections.emptyMap(), null, new TimedLockImpl());
251
+ User currentUser = new UserImpl("test", "email@test", Collections.emptyMap(), null, new LockingAndBanningImpl());
252 252
SecurityService securityService = Mockito.mock(SecurityService.class);
253 253
Mockito.doReturn(defaultTenant).when(securityService).getServerGroup();
254 254
Mockito.doReturn(currentUser).when(securityService).getCurrentUser();
java/com.sap.sailing.shared.server.gateway/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.windestimation/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sailing.www/release_notes_admin.html
... ...
@@ -23,19 +23,6 @@
23 23
<div class="mainContent">
24 24
<h2 class="releaseHeadline">Release Notes - Administration Console</h2>
25 25
<div class="innerContent">
26
- <h2 class="articleSubheadline">December 2025</h2>
27
- <ul class="bulletList">
28
- <li>Added boat class Fareast 28R.</li>
29
- <li>Added support for unlocking users under Admin Console >
30
- Advanced > User Management. The lock referred to here is that
31
- placed for multiple unsuccessful login attempts, resembling a
32
- brute force attack, onto an account identified by the used email
33
- address or username, for a duration of time.</li>
34
- <li>Added support for unlocking IP addresses under Admin
35
- Console > Advanced > Local Server. The lock referred to here is
36
- that placed for multiple create account API hits or multiple API
37
- hits using an invalid bearer token for a duration of time.</li>
38
- </ul>
39 26
<h2 class="articleSubheadline">November 2025</h2>
40 27
<ul class="bulletList">
41 28
<li>The Landscape Management panel as well as the <tt>refreshInstance.sh</tt> shell script
java/com.sap.sailing.www/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sse.common.test/src/com/sap/sse/common/impl/test/TimedLockImplTest.java
... ...
@@ -1,63 +0,0 @@
1
-/**
2
- *
3
- */
4
-package com.sap.sse.common.impl.test;
5
-
6
-import static org.junit.jupiter.api.Assertions.*;
7
-
8
-import org.junit.jupiter.api.BeforeEach;
9
-import org.junit.jupiter.api.Test;
10
-
11
-import com.sap.sse.common.Duration;
12
-import com.sap.sse.common.TimePoint;
13
-import com.sap.sse.common.impl.TimedLockImpl;
14
-
15
-/**
16
- *
17
- */
18
-class TimedLockImplTest {
19
-
20
- /**
21
- * @throws java.lang.Exception
22
- */
23
- @BeforeEach
24
- void setUp() throws Exception {
25
- }
26
-
27
- /**
28
- * Test method for {@link com.sap.sse.common.impl.TimedLockImpl#extendLockDuration()}.
29
- */
30
- @Test
31
- void testExtendLockDuration() {
32
- final TimedLockImpl lock = new TimedLockImpl();
33
- final Duration firstLockingDelay = lock.getNextLockingDelay();
34
- // initial locking delay should be greater than 0
35
- assertTrue(firstLockingDelay.compareTo(Duration.NULL) > 0);
36
- assertTrue(firstLockingDelay.compareTo(Duration.ofMillis(0)) > 0);
37
- final TimePoint expectedLockedUntil = TimePoint.now().plus(firstLockingDelay);
38
- // locking delay should be applied to lockedUntil
39
- lock.extendLockDuration();
40
- assertEquals(lock.getLockedUntil(), expectedLockedUntil);
41
- // locking delay should double
42
- final Duration secondLockingDelay = firstLockingDelay.plus(firstLockingDelay);
43
- assertEquals(lock.getNextLockingDelay(), secondLockingDelay);
44
- // double locking delay should be applied to lockedUntil
45
- lock.extendLockDuration();
46
- assertEquals(lock.getLockedUntil(), TimePoint.now().plus(secondLockingDelay));
47
- }
48
-
49
- /**
50
- * Test method for {@link com.sap.sse.common.impl.TimedLockImpl#resetLock()}.
51
- */
52
- @Test
53
- void testResetLock() {
54
- final TimedLockImpl lock = new TimedLockImpl();
55
- lock.extendLockDuration();
56
- lock.extendLockDuration();
57
- lock.extendLockDuration();
58
- assertTrue(lock.isLocked());
59
- lock.resetLock();
60
- assertFalse(lock.isLocked());
61
- }
62
-
63
-}
java/com.sap.sse.common/src/com/sap/sse/common/TimedLock.java
... ...
@@ -1,33 +0,0 @@
1
-package com.sap.sse.common;
2
-
3
-import java.io.Serializable;
4
-
5
-/**
6
- * Holds information about a user's log-on history which is then used to decide whether the user account should be
7
- * locked temporarily or permanently for certain forms of authentication.
8
- * <p>
9
- *
10
- * For example, failed password authentication requests shall be logged by the realm using calls to
11
- * {@link #extendLockDuration()}, successful ones with {@link #resetLock()}. Using the
12
- * {@link #isLocked()} method, a realm can determine if the user account to which this object belongs
13
- * shall currently accept password authentication.
14
- * <p>
15
- *
16
- * A possible strategy for an implementation could be to add an increasing delay for each failed password
17
- * authentication, but reduce or clear the delay after a successful password authentication.
18
- *
19
- * @author Axel Uhl (d043530)
20
- *
21
- */
22
-public interface TimedLock extends Serializable {
23
- void extendLockDuration();
24
-
25
- /**
26
- * @return {@code true} if this locking and banning record changed due to this call
27
- */
28
- boolean resetLock();
29
-
30
- boolean isLocked();
31
-
32
- TimePoint getLockedUntil();
33
-}
java/com.sap.sse.common/src/com/sap/sse/common/impl/RenamableImpl.java
... ...
@@ -25,4 +25,5 @@ public class RenamableImpl implements Renamable {
25 25
public void setName(String newName) {
26 26
this.name = newName;
27 27
}
28
+
28 29
}
java/com.sap.sse.common/src/com/sap/sse/common/impl/TimedLockImpl.java
... ...
@@ -1,83 +0,0 @@
1
-package com.sap.sse.common.impl;
2
-
3
-import com.sap.sse.common.Duration;
4
-import com.sap.sse.common.TimePoint;
5
-import com.sap.sse.common.TimedLock;
6
-import com.sap.sse.common.Util;
7
-
8
-public class TimedLockImpl implements TimedLock {
9
- private static final long serialVersionUID = 3547356744366236677L;
10
-
11
- public static final Duration DEFAULT_INITIAL_LOCKING_DELAY = Duration.ONE_SECOND;
12
-
13
- /**
14
- * An always valid time point which may be in the past. If it is in the future,
15
- * {@link #isLocked()} will return {@code true}.
16
- */
17
- private TimePoint lockedUntil;
18
-
19
- /**
20
- * An always valid, non-zero duration that indicates for how long into the future the {@link #lockedUntil} time
21
- * point will be set in case a {@link #extendLockDuration() failed password authentication} is notified.
22
- */
23
- private Duration nextLockingDelay;
24
-
25
- /**
26
- * Creates an instance that is unlocked and has a "last locking delay" of one second
27
- */
28
- public TimedLockImpl() {
29
- this(TimePoint.BeginningOfTime, DEFAULT_INITIAL_LOCKING_DELAY);
30
- }
31
-
32
- public TimedLockImpl(TimePoint lockedUntil, Duration nextLockingDelay) {
33
- super();
34
- this.lockedUntil = lockedUntil;
35
- this.nextLockingDelay = nextLockingDelay;
36
- }
37
-
38
- /**
39
- * Locks for the {@link #nextLockingDelay} and doubles the delay for the next failed attempt.
40
- */
41
- @Override
42
- public void extendLockDuration() {
43
- lockedUntil = TimePoint.now().plus(nextLockingDelay);
44
- nextLockingDelay = nextLockingDelay.times(2);
45
- }
46
-
47
- @Override
48
- public boolean resetLock() {
49
- final Duration oldLockingDelay = nextLockingDelay;
50
- nextLockingDelay = DEFAULT_INITIAL_LOCKING_DELAY;
51
- final TimePoint oldLockedUntil = lockedUntil;
52
- lockedUntil = TimePoint.BeginningOfTime;
53
- return !Util.equalsWithNull(oldLockingDelay, nextLockingDelay) || !Util.equalsWithNull(oldLockedUntil, lockedUntil);
54
- }
55
-
56
- @Override
57
- public boolean isLocked() {
58
- return TimePoint.now().before(lockedUntil);
59
- }
60
-
61
- @Override
62
- public TimePoint getLockedUntil() {
63
- return lockedUntil;
64
- }
65
-
66
- public Duration getNextLockingDelay() {
67
- return nextLockingDelay;
68
- }
69
-
70
- @Override
71
- public String toString() {
72
- final StringBuilder result = new StringBuilder();
73
- if (isLocked()) {
74
- result.append("locked until ");
75
- result.append(getLockedUntil());
76
- } else {
77
- result.append("unlocked");
78
- }
79
- result.append(", next locking duration: ");
80
- result.append(getNextLockingDelay());
81
- return result.toString();
82
- }
83
-}
java/com.sap.sse.gwt.test/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,4 +1,4 @@
1
-//gwtVersion_/com.google.gwt.user/lib=
1
+//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
java/com.sap.sse.gwt/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,4 +1,4 @@
1
-//gwtVersion_/com.google.gwt.user/lib=
1
+//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
java/com.sap.sse.gwt/GWT xdStorage Sample SDM.launch
... ...
@@ -3,14 +3,13 @@
3 3
<booleanAttribute key="com.gwtplugins.gdt.eclipse.core.RUN_SERVER" value="false"/>
4 4
<stringAttribute key="com.gwtplugins.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/>
5 5
<booleanAttribute key="com.gwtplugins.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
6
- <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9878"/>
6
+ <stringAttribute key="com.gwtplugins.gwt.eclipse.core.CLASSIC_DEVMODE_CODE_SERVER_PORT" value="9877"/>
7 7
<listAttribute key="com.gwtplugins.gwt.eclipse.core.ENTRY_POINT_MODULES">
8 8
<listEntry value="com.sap.sse.gwt.StorageMessagingTest"/>
9 9
<listEntry value="com.sap.sse.gwt.StorageMessaging"/>
10 10
</listAttribute>
11 11
<booleanAttribute key="com.gwtplugins.gwt.eclipse.core.SUPERDEVMODE_ENABLED" value="true"/>
12 12
<stringAttribute key="com.gwtplugins.gwt.eclipse.core.URL" value="/gwt-base/StorageMessagingTest.html"/>
13
- <booleanAttribute key="org.eclipse.debug.core.ATTR_FORCE_SYSTEM_CONSOLE_ENCODING" value="false"/>
14 13
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
15 14
<listEntry value="/com.sap.sse.gwt"/>
16 15
</listAttribute>
... ...
@@ -23,8 +22,6 @@
23 22
</listAttribute>
24 23
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
25 24
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
26
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
27
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
28 25
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
29 26
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
30 27
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sse.gwt&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#13;&#10;"/>
... ...
@@ -52,10 +49,9 @@
52 49
</listAttribute>
53 50
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/>
54 51
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
55
- <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
56 52
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
57 53
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sse.gwt"/>
58
- <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-style PRETTY -incremental -workDir &quot;${project_loc:com.sap.sse.gwt}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.gwt}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9878 -startupUrl /gwt-base/StorageMessagingTest.html -startupUrl /gwt-base/StorageMessaging.html com.sap.sse.gwt.StorageMessaging com.sap.sse.gwt.StorageMessagingTest"/>
54
+ <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-style PRETTY -incremental -workDir &quot;${project_loc:com.sap.sse.gwt}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.gwt}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9877 -startupUrl /gwt-base/StorageMessagingTest.html -startupUrl /gwt-base/StorageMessaging.html com.sap.sse.gwt.StorageMessaging com.sap.sse.gwt.StorageMessagingTest"/>
59 55
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sse.gwt"/>
60 56
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:-UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
61 57
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/>
java/com.sap.sse.gwt/resources/com/sap/sse/gwt/client/images/unlock.png
... ...
Binary files a/java/com.sap.sse.gwt/resources/com/sap/sse/gwt/client/images/unlock.png and /dev/null differ
java/com.sap.sse.gwt/src/com/sap/sse/gwt/client/IconResources.java
... ...
@@ -11,9 +11,6 @@ public interface IconResources extends ClientBundle {
11 11
@Source("images/change-acl.png")
12 12
ImageResource changeACLIcon();
13 13
14
- @Source("images/unlock.png")
15
- ImageResource resetLockIcon();
16
-
17 14
@Source("images/change-ownership.png")
18 15
ImageResource changeOwnershipIcon();
19 16
java/com.sap.sse.landscape.aws/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sse.replication/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/BasicUserStore.java
... ...
@@ -5,8 +5,8 @@ import java.util.Set;
5 5
import java.util.UUID;
6 6
7 7
import com.sap.sse.common.Named;
8
-import com.sap.sse.common.TimedLock;
9 8
import com.sap.sse.common.Util.Pair;
9
+import com.sap.sse.security.shared.impl.LockingAndBanning;
10 10
import com.sap.sse.security.shared.impl.Ownership;
11 11
import com.sap.sse.security.shared.impl.Role;
12 12
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
... ...
@@ -60,7 +60,7 @@ public interface BasicUserStore extends UserGroupProvider, Named {
60 60
61 61
User getUserByAccessToken(String accessToken);
62 62
63
- User createUser(String name, String email, TimedLock timedLock, Account... accounts)
63
+ User createUser(String name, String email, LockingAndBanning lockingAndBanning, Account... accounts)
64 64
throws UserManagementException;
65 65
66 66
void addUser(User user) throws UserManagementException;
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/IPAddress.java
... ...
@@ -1,28 +0,0 @@
1
-package com.sap.sse.security.shared;
2
-
3
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
4
-
5
-public class IPAddress implements WithQualifiedObjectIdentifier {
6
- private static final long serialVersionUID = 8016397230668484898L;
7
- private final String ipAddress;
8
-
9
- public IPAddress(final String ipAddress) {
10
- this.ipAddress = ipAddress;
11
- }
12
-
13
- @Override
14
- public String getName() {
15
- return ipAddress;
16
- }
17
-
18
- @Override
19
- public QualifiedObjectIdentifier getIdentifier() {
20
- return getPermissionType().getQualifiedObjectIdentifier(new TypeRelativeObjectIdentifier(ipAddress));
21
- }
22
-
23
- @Override
24
- public HasPermissions getPermissionType() {
25
- return SecuredSecurityTypes.LOCKED_IP;
26
- }
27
-
28
-}
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/dto/UserDTO.java
... ...
@@ -32,7 +32,7 @@ public class UserDTO extends
32 32
private SecurityInformationDTO securityInformation = new SecurityInformationDTO();
33 33
private StrippedUserGroupDTO defaultTenantForCurrentServer;
34 34
35
- private Set<RoleWithSecurityDTO> roles; // TODO turn to HashSet to reduce number of serializers to generate
35
+ private Set<RoleWithSecurityDTO> roles;
36 36
37 37
@Deprecated // gwt only
38 38
UserDTO() {
... ...
@@ -62,22 +62,7 @@ public class UserDTO extends
62 62
Util.addAll(roles, this.getRolesInternal());
63 63
this.lockedUntil = lockedUntil;
64 64
}
65
-
66
- public UserDTO copyWithTimePoint(TimePoint lockedUntil) {
67
- final List<AccountDTO> accountsCopy = new ArrayList<AccountDTO>();
68
- Util.addAll(this.accounts, accountsCopy);
69
- final HashSet<RoleWithSecurityDTO> rolesCopy = new HashSet<>();
70
- Util.addAll(this.roles, rolesCopy);
71
- final List<WildcardPermissionWithSecurityDTO> permissionsCopy = new ArrayList<WildcardPermissionWithSecurityDTO>();
72
- for (WildcardPermission wp : this.getPermissions()) {
73
- permissionsCopy.add((WildcardPermissionWithSecurityDTO) wp);
74
- }
75
- final List<StrippedUserGroupDTO> groupsCopy = new ArrayList<StrippedUserGroupDTO>();
76
- Util.addAll(this.groups, groupsCopy);
77
- return new UserDTO(this.getName(), this.email, this.fullName, this.company, this.locale, this.emailValidated,
78
- accountsCopy, rolesCopy, this.defaultTenantForCurrentServer, permissionsCopy, groupsCopy, lockedUntil);
79
- }
80
-
65
+
81 66
@Override
82 67
protected Set<RoleWithSecurityDTO> getRolesInternal() {
83 68
return roles;
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/LockingAndBanning.java
... ...
@@ -0,0 +1,35 @@
1
+package com.sap.sse.security.shared.impl;
2
+
3
+import java.io.Serializable;
4
+
5
+import com.sap.sse.common.TimePoint;
6
+
7
+/**
8
+ * Holds information about a user's log-on history which is then used to decide whether the user account should be
9
+ * locked temporarily or permanently for certain forms of authentication.
10
+ * <p>
11
+ *
12
+ * For example, failed password authentication requests shall be logged by the realm using calls to
13
+ * {@link #failedPasswordAuthentication()}, successful ones with {@link #successfulPasswordAuthentication()}. Using the
14
+ * {@link #isAuthenticationLocked()} method, a realm can determine if the user account to which this object belongs
15
+ * shall currently accept password authentication.
16
+ * <p>
17
+ *
18
+ * A possible strategy for an implementation could be to add an increasing delay for each failed password
19
+ * authentication, but reduce or clear the delay after a successful password authentication.
20
+ *
21
+ * @author Axel Uhl (d043530)
22
+ *
23
+ */
24
+public interface LockingAndBanning extends Serializable {
25
+ void failedPasswordAuthentication();
26
+
27
+ /**
28
+ * @return {@code true} if this locking and banning record changed due to this call
29
+ */
30
+ boolean successfulPasswordAuthentication();
31
+
32
+ boolean isAuthenticationLocked();
33
+
34
+ TimePoint getLockedUntil();
35
+}
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/LockingAndBanningImpl.java
... ...
@@ -0,0 +1,82 @@
1
+package com.sap.sse.security.shared.impl;
2
+
3
+import com.sap.sse.common.Duration;
4
+import com.sap.sse.common.TimePoint;
5
+import com.sap.sse.common.Util;
6
+
7
+public class LockingAndBanningImpl implements LockingAndBanning {
8
+ private static final long serialVersionUID = 3547356744366236677L;
9
+
10
+ public static final Duration DEFAULT_INITIAL_LOCKING_DELAY = Duration.ONE_SECOND;
11
+
12
+ /**
13
+ * An always valid time point which may be in the past. If it is in the future,
14
+ * {@link #isAuthenticationLocked()} will return {@code true}.
15
+ */
16
+ private TimePoint lockedUntil;
17
+
18
+ /**
19
+ * An always valid, non-zero duration that indicates for how long into the future the {@link #lockedUntil} time
20
+ * point will be set in case a {@link #failedPasswordAuthentication() failed password authentication} is notified.
21
+ */
22
+ private Duration nextLockingDelay;
23
+
24
+ /**
25
+ * Creates an instance that is unlocked and has a "last locking delay" of one second
26
+ */
27
+ public LockingAndBanningImpl() {
28
+ this(TimePoint.BeginningOfTime, DEFAULT_INITIAL_LOCKING_DELAY);
29
+ }
30
+
31
+ public LockingAndBanningImpl(TimePoint lockedUntil, Duration nextLockingDelay) {
32
+ super();
33
+ this.lockedUntil = lockedUntil;
34
+ this.nextLockingDelay = nextLockingDelay;
35
+ }
36
+
37
+ /**
38
+ * Locks for the {@link #nextLockingDelay} and doubles the delay for the next failed attempt.
39
+ */
40
+ @Override
41
+ public void failedPasswordAuthentication() {
42
+ lockedUntil = TimePoint.now().plus(nextLockingDelay);
43
+ nextLockingDelay = nextLockingDelay.times(2);
44
+ }
45
+
46
+ @Override
47
+ public boolean successfulPasswordAuthentication() {
48
+ final Duration oldLockingDelay = nextLockingDelay;
49
+ nextLockingDelay = DEFAULT_INITIAL_LOCKING_DELAY;
50
+ final TimePoint oldLockedUntil = lockedUntil;
51
+ lockedUntil = TimePoint.BeginningOfTime;
52
+ return !Util.equalsWithNull(oldLockingDelay, nextLockingDelay) || !Util.equalsWithNull(oldLockedUntil, lockedUntil);
53
+ }
54
+
55
+ @Override
56
+ public boolean isAuthenticationLocked() {
57
+ return TimePoint.now().before(lockedUntil);
58
+ }
59
+
60
+ @Override
61
+ public TimePoint getLockedUntil() {
62
+ return lockedUntil;
63
+ }
64
+
65
+ public Duration getNextLockingDelay() {
66
+ return nextLockingDelay;
67
+ }
68
+
69
+ @Override
70
+ public String toString() {
71
+ final StringBuilder result = new StringBuilder();
72
+ if (isAuthenticationLocked()) {
73
+ result.append("locked until ");
74
+ result.append(getLockedUntil());
75
+ } else {
76
+ result.append("unlocked");
77
+ }
78
+ result.append(", next locking duration: ");
79
+ result.append(getNextLockingDelay());
80
+ return result.toString();
81
+ }
82
+}
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/SecuredSecurityTypes.java
... ...
@@ -5,7 +5,6 @@ import java.util.HashSet;
5 5
import java.util.Set;
6 6
7 7
import com.sap.sse.security.shared.HasPermissions;
8
-import com.sap.sse.security.shared.IPAddress;
9 8
import com.sap.sse.security.shared.RoleDefinition;
10 9
11 10
/**
... ...
@@ -42,20 +41,14 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
42 41
43 42
public static enum UserActions implements Action {
44 43
/** Update a user's password without knowing the old password. */
45
- FORCE_OVERWRITE_PASSWORD, ADD_SUBSCRIPTION, BE_PREMIUM, MANAGE_LOCK
44
+ FORCE_OVERWRITE_PASSWORD, ADD_SUBSCRIPTION, BE_PREMIUM
46 45
};
47 46
/**
48 47
* type-relative identifier is the {@link User#getName() username}.
49 48
*/
50 49
public static final HasPermissions USER = new SecuredSecurityTypes("USER", DefaultActions
51 50
.plus(UserActions.FORCE_OVERWRITE_PASSWORD, PublicReadableActions.READ_PUBLIC,
52
- UserActions.ADD_SUBSCRIPTION, UserActions.BE_PREMIUM, UserActions.MANAGE_LOCK));
53
-
54
-
55
- /**
56
- * type-relative identifier is the {@link IPAddress#getName() ip address as String}.
57
- */
58
- public static final HasPermissions LOCKED_IP = new SecuredSecurityTypes("LOCKED_IP", DefaultActions.values());
51
+ UserActions.ADD_SUBSCRIPTION, UserActions.BE_PREMIUM));
59 52
60 53
/**
61 54
* type-relative identifier is the {@link RoleDefinition#getId() role ID's} string representation
... ...
@@ -122,8 +115,8 @@ public class SecuredSecurityTypes extends HasPermissionsImpl {
122 115
private static final Action[] ALL_ACTIONS = new Action[] { CONFIGURE_FILE_STORAGE, CONFIGURE_LOCAL_SERVER,
123 116
CONFIGURE_REMOTE_INSTANCES, CREATE_OBJECT, CAN_IMPORT_MASTERDATA, CAN_EXPORT_MASTERDATA, DATA_MINING,
124 117
REPLICATE, START_REPLICATION, READ_REPLICATOR, THREADS, CONFIGURE_AI_AGENT, CONFIGURE_CORS_FILTER,
125
- DefaultActions.CHANGE_OWNERSHIP, DefaultActions.CHANGE_ACL, DefaultActions.CREATE,
126
- DefaultActions.DELETE, DefaultActions.READ, DefaultActions.UPDATE };
118
+ DefaultActions.CHANGE_OWNERSHIP, DefaultActions.CHANGE_ACL, DefaultActions.CREATE, DefaultActions.DELETE,
119
+ DefaultActions.READ, DefaultActions.UPDATE };
127 120
}
128 121
129 122
/**
java/com.sap.sse.security.common/src/com/sap/sse/security/shared/impl/User.java
... ...
@@ -4,7 +4,6 @@ import java.util.Locale;
4 4
import java.util.Map;
5 5
6 6
import com.sap.sse.common.Named;
7
-import com.sap.sse.common.TimedLock;
8 7
import com.sap.sse.common.WithID;
9 8
import com.sap.sse.security.shared.Account;
10 9
import com.sap.sse.security.shared.Account.AccountType;
... ...
@@ -130,5 +129,5 @@ public interface User extends SecurityUser<RoleDefinition, Role, UserGroup> {
130 129
131 130
Subscription getSubscriptionById(String subscriptionId);
132 131
133
- TimedLock getTimedLock();
132
+ LockingAndBanning getLockingAndBanning();
134 133
}
java/com.sap.sse.security.interface/src/com/sap/sse/security/interfaces/UserImpl.java
... ...
@@ -19,12 +19,12 @@ import java.util.Set;
19 19
20 20
import org.apache.shiro.crypto.hash.Sha256Hash;
21 21
22
-import com.sap.sse.common.TimedLock;
23 22
import com.sap.sse.security.shared.Account;
24 23
import com.sap.sse.security.shared.Account.AccountType;
25 24
import com.sap.sse.security.shared.RoleDefinition;
26 25
import com.sap.sse.security.shared.UserGroupProvider;
27 26
import com.sap.sse.security.shared.WildcardPermission;
27
+import com.sap.sse.security.shared.impl.LockingAndBanning;
28 28
import com.sap.sse.security.shared.impl.Ownership;
29 29
import com.sap.sse.security.shared.impl.Role;
30 30
import com.sap.sse.security.shared.impl.SecurityUserImpl;
... ...
@@ -103,26 +103,26 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
103 103
104 104
private Subscription[] subscriptions;
105 105
106
- private final TimedLock timedLock;
106
+ private final LockingAndBanning lockingAndBanning;
107 107
108 108
public UserImpl(String name, String email, Map<String, UserGroup> defaultTenantForServer,
109
- UserGroupProvider userGroupProvider, TimedLock timedLock, Account... accounts) {
110
- this(name, email, defaultTenantForServer, Arrays.asList(accounts), userGroupProvider, timedLock);
109
+ UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning, Account... accounts) {
110
+ this(name, email, defaultTenantForServer, Arrays.asList(accounts), userGroupProvider, lockingAndBanning);
111 111
}
112 112
113 113
public UserImpl(String name, String email, Map<String, UserGroup> defaultTenantForServer,
114
- Collection<Account> accounts, UserGroupProvider userGroupProvider, TimedLock timedLock) {
114
+ Collection<Account> accounts, UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning) {
115 115
this(name, email, /* fullName */ null, /* company */ null, /* locale */ null, /* is email validated */ false,
116 116
/* did opt out of marketing emails */ null, /* password reset secret */ null, /* validation secret */ null,
117
- userGroupProvider, timedLock);
117
+ defaultTenantForServer, accounts, userGroupProvider, lockingAndBanning);
118 118
}
119 119
120 120
public UserImpl(String name, String email, String fullName, String company, Locale locale, Boolean emailValidated,
121 121
Boolean didOptOutOfMarketingEmails, String passwordResetSecret, String validationSecret,
122
- Collection<Account> accounts, UserGroupProvider userGroupProvider, TimedLock timedLock) {
122
+ Map<String, UserGroup> defaultTenantForServer, Collection<Account> accounts,
123 123
UserGroupProvider userGroupProvider, LockingAndBanning lockingAndBanning) {
124 124
super(name);
125
- this.timedLock = timedLock;
125
+ this.lockingAndBanning = lockingAndBanning;
126 126
this.defaultTenantForServer = defaultTenantForServer;
127 127
this.fullName = fullName;
128 128
this.company = company;
... ...
@@ -481,8 +481,8 @@ public class UserImpl extends SecurityUserImpl<RoleDefinition, Role, UserGroup,
481 481
}
482 482
483 483
@Override
484
- public TimedLock getTimedLock() {
485
- return timedLock;
484
+ public LockingAndBanning getLockingAndBanning() {
485
+ return lockingAndBanning;
486 486
}
487 487
488 488
@Override
java/com.sap.sse.security.replication.test/src/com/sap/sse/security/replication/test/SimpleSecurityReplicationTest.java
... ...
@@ -99,7 +99,7 @@ public class SimpleSecurityReplicationTest extends AbstractSecurityReplicationTe
99 99
assertEquals(ERNIE, replicatedErnie.getName());
100 100
assertFalse(replica.checkPassword(ERNIE, BERT_MY_FRIEND));
101 101
// checking with incorrect password locks user for some time; wait long enough before retrying with correct password
102
- final TimePoint lockedUntil = replicatedErnie.getTimedLock().getLockedUntil();
102
+ final TimePoint lockedUntil = replicatedErnie.getLockingAndBanning().getLockedUntil();
103 103
Thread.sleep(Math.max(0, TimePoint.now().until(lockedUntil).asMillis()+10));
104 104
assertTrue(replica.checkPassword(ERNIE, newPassword));
105 105
}
java/com.sap.sse.security.storemerging.test/src/com/sap/sse/security/storemerging/TestGroupIdentity.java
... ...
@@ -10,9 +10,9 @@ import java.util.UUID;
10 10
11 11
import org.junit.jupiter.api.Test;
12 12
13
-import com.sap.sse.common.impl.TimedLockImpl;
14 13
import com.sap.sse.security.SecurityService;
15 14
import com.sap.sse.security.interfaces.UserImpl;
15
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
16 16
import com.sap.sse.security.shared.impl.User;
17 17
import com.sap.sse.security.shared.impl.UserGroup;
18 18
import com.sap.sse.security.shared.impl.UserGroupImpl;
... ...
@@ -51,7 +51,7 @@ public class TestGroupIdentity {
51 51
final UUID uuid2 = UUID.randomUUID();
52 52
final String username = "user";
53 53
final UserGroup g1 = new UserGroupImpl(uuid1, username+SecurityService.TENANT_SUFFIX);
54
- final User user = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
54
+ final User user = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
55 55
g1.add(user);
56 56
final UserGroup g2 = new UserGroupImpl(uuid2, username+SecurityService.TENANT_SUFFIX);
57 57
assertFalse(SecurityStoreMerger.considerGroupsIdentical(g1, g2, Collections.emptyMap()));
... ...
@@ -63,10 +63,10 @@ public class TestGroupIdentity {
63 63
final UUID uuid2 = UUID.randomUUID();
64 64
final String username = "user";
65 65
final UserGroup g1 = new UserGroupImpl(uuid1, username+SecurityService.TENANT_SUFFIX);
66
- final User user1 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
66
+ final User user1 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
67 67
g1.add(user1);
68 68
final UserGroup g2 = new UserGroupImpl(uuid2, username+SecurityService.TENANT_SUFFIX);
69
- final User user2 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new TimedLockImpl());
69
+ final User user2 = new UserImpl(username, /* email */ null, (Map<String, UserGroup>) /* defaultTenantForServer */ null, /* userGroupProvider */ null, new LockingAndBanningImpl());
70 70
g2.add(user2);
71 71
final Map<User, User> userMap = new HashMap<>();
72 72
userMap.put(user2, user1); // user2 assumed to get merged with user1
java/com.sap.sse.security.test/src/com/sap/sse/security/test/AccessControlStoreTest.java
... ...
@@ -18,7 +18,6 @@ import org.junit.jupiter.api.Test;
18 18
19 19
import com.mongodb.MongoException;
20 20
import com.mongodb.client.MongoDatabase;
21
-import com.sap.sse.common.impl.TimedLockImpl;
22 21
import com.sap.sse.mongodb.MongoDBConfiguration;
23 22
import com.sap.sse.mongodb.MongoDBService;
24 23
import com.sap.sse.security.interfaces.AccessControlStore;
... ...
@@ -30,6 +29,7 @@ import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
30 29
import com.sap.sse.security.shared.UserGroupManagementException;
31 30
import com.sap.sse.security.shared.UserStoreManagementException;
32 31
import com.sap.sse.security.shared.WildcardPermission;
32
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
33 33
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
34 34
import com.sap.sse.security.shared.impl.User;
35 35
import com.sap.sse.security.shared.impl.UserGroup;
... ...
@@ -69,7 +69,7 @@ public class AccessControlStoreTest {
69 69
Map<String, UserGroup> defaultTenantForUser = new HashMap<>();
70 70
defaultTenantForUser.put("dummyServer", adminTenant);
71 71
testOwner = new UserImpl("admin", "admin@sapsailing.com", defaultTenantForUser,
72
- /* userGroupProvider */ null, new TimedLockImpl());
72
+ /* userGroupProvider */ null, new LockingAndBanningImpl());
73 73
}
74 74
75 75
private void newStores() {
java/com.sap.sse.security.test/src/com/sap/sse/security/test/LoginTest.java
... ...
@@ -8,13 +8,11 @@ import static org.junit.jupiter.api.Assertions.assertNull;
8 8
import static org.junit.jupiter.api.Assertions.assertSame;
9 9
import static org.junit.jupiter.api.Assertions.assertTrue;
10 10
11
-import java.io.IOException;
12 11
import java.net.UnknownHostException;
13 12
import java.util.Arrays;
14 13
import java.util.Collections;
15 14
import java.util.HashMap;
16 15
import java.util.HashSet;
17
-import java.util.Locale;
18 16
import java.util.Map;
19 17
import java.util.Set;
20 18
import java.util.UUID;
... ...
@@ -27,7 +25,6 @@ import org.junit.jupiter.api.Test;
27 25
import com.mongodb.MongoException;
28 26
import com.mongodb.client.MongoDatabase;
29 27
import com.sap.sse.common.Util;
30
-import com.sap.sse.common.impl.TimedLockImpl;
31 28
import com.sap.sse.common.mail.MailException;
32 29
import com.sap.sse.mongodb.MongoDBConfiguration;
33 30
import com.sap.sse.mongodb.MongoDBService;
... ...
@@ -47,6 +44,7 @@ import com.sap.sse.security.shared.UserStoreManagementException;
47 44
import com.sap.sse.security.shared.WildcardPermission;
48 45
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
49 46
import com.sap.sse.security.shared.impl.AccessControlList;
47
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
50 48
import com.sap.sse.security.shared.impl.Ownership;
51 49
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
52 50
import com.sap.sse.security.shared.impl.Role;
... ...
@@ -244,7 +242,7 @@ public class LoginTest {
244 242
245 243
@Test
246 244
public void rolesTest() throws UserStoreManagementException {
247
- userStore.createUser("me", "me@sap.com", new TimedLockImpl());
245
+ userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
248 246
RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole",
249 247
Collections.emptySet());
250 248
final Role testRole = new Role(testRoleDefinition, true);
... ...
@@ -256,7 +254,7 @@ public class LoginTest {
256 254
@Test
257 255
public void roleWithQualifiersTest() throws UserStoreManagementException {
258 256
UserGroupImpl userDefaultTenant = userStore.createUserGroup(UUID.randomUUID(), "me-tenant");
259
- User meUser = userStore.createUser("me", "me@sap.com", new TimedLockImpl());
257
+ User meUser = userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
260 258
RoleDefinition testRoleDefinition = userStore.createRoleDefinition(UUID.randomUUID(), "testRole",
261 259
Collections.emptySet());
262 260
final Role testRole = new Role(testRoleDefinition, userDefaultTenant, meUser, true);
... ...
@@ -270,7 +268,7 @@ public class LoginTest {
270 268
271 269
@Test
272 270
public void permissionsTest() throws UserStoreManagementException {
273
- userStore.createUser("me", "me@sap.com", new TimedLockImpl());
271
+ userStore.createUser("me", "me@sap.com", new LockingAndBanningImpl());
274 272
userStore.addPermissionForUser("me", new WildcardPermission("a:b:c"));
275 273
UserStoreImpl store2 = createAndLoadUserStore();
276 274
User allUser = userStore.getUserByName(SecurityService.ALL_USERNAME);
... ...
@@ -278,46 +276,6 @@ public class LoginTest {
278 276
assertTrue(PermissionChecker.isPermitted(new WildcardPermission("a:b:c"), user, allUser, null, null));
279 277
}
280 278
281
- @Test
282
- public void testUnlockBearerTokenAbuser() throws UserStoreManagementException, IOException, InterruptedException {
283
- final String localhost = "127.0.0.1";
284
- final int attempts = 4;
285
- for(int i = 0; i < attempts; i++) {
286
- securityService.failedBearerTokenAuthentication(localhost);
287
- final long lockDuration = (long) Math.pow(2, i) * 1000;
288
- final boolean isFinalAttempt = i == (attempts - 1);
289
- if (!isFinalAttempt) {
290
- Thread.sleep(lockDuration);
291
- }
292
- }
293
- assertTrue(securityService.isClientIPLockedForBearerTokenAuthentication(localhost));
294
- securityService.releaseBearerTokenLockOnIp(localhost);
295
- assertFalse(securityService.isClientIPLockedForBearerTokenAuthentication(localhost));
296
- }
297
-
298
- @Test
299
- public void testUnlockUserCreationAbuser() throws UserStoreManagementException, IOException, InterruptedException, MailException {
300
- final String localhost = "127.0.0.1";
301
- final int attempts = 4;
302
- for(int i = 0; i < attempts; i++) {
303
- try {
304
- securityService.createSimpleUser("USERNAME" + i, "a@b.c", "PASSWORD", "The User", "SAP SE",
305
- /* validation URL */ Locale.ENGLISH, null, null, /* clientIP */ localhost,
306
- /* enforce strong password */ false);
307
- } catch (UserManagementException e) {
308
- // do nothing, expected due to lock
309
- }
310
- final long lockDuration = (long) Math.pow(2, i) * 1000;
311
- final boolean isFinalAttempt = i == (attempts - 1);
312
- if (!isFinalAttempt) {
313
- Thread.sleep(lockDuration);
314
- }
315
- }
316
- assertTrue(securityService.isUserCreationLockedForClientIP(localhost));
317
- securityService.releaseUserCreationLockOnIp(localhost);
318
- assertFalse(securityService.isUserCreationLockedForClientIP(localhost));
319
- }
320
-
321 279
private UserStoreImpl createAndLoadUserStore() throws UserStoreManagementException {
322 280
final UserStoreImpl store = new UserStoreImpl(DEFAULT_TENANT_NAME);
323 281
store.loadAndMigrateUsers();
java/com.sap.sse.security.test/src/com/sap/sse/security/test/PermissionCheckerTest.java
... ...
@@ -21,7 +21,6 @@ import org.junit.jupiter.api.BeforeEach;
21 21
import org.junit.jupiter.api.Test;
22 22
23 23
import com.sap.sailing.domain.common.security.SecuredDomainType;
24
-import com.sap.sse.common.impl.TimedLockImpl;
25 24
import com.sap.sse.security.AbstractCompositeAuthorizingRealm;
26 25
import com.sap.sse.security.UsernamePasswordRealm;
27 26
import com.sap.sse.security.interfaces.AccessControlStore;
... ...
@@ -40,6 +39,7 @@ import com.sap.sse.security.shared.UserManagementException;
40 39
import com.sap.sse.security.shared.WildcardPermission;
41 40
import com.sap.sse.security.shared.impl.AccessControlList;
42 41
import com.sap.sse.security.shared.impl.HasPermissionsImpl;
42
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
43 43
import com.sap.sse.security.shared.impl.Ownership;
44 44
import com.sap.sse.security.shared.impl.Role;
45 45
import com.sap.sse.security.shared.impl.User;
... ...
@@ -94,7 +94,7 @@ public class PermissionCheckerTest {
94 94
userStore.deleteUser("jonas");
95 95
}
96 96
userTenant = userStore.createUserGroup(userTenantId, "jonas-tenant");
97
- user = userStore.createUser("jonas", "jonas@dann.io", new TimedLockImpl());
97
+ user = userStore.createUser("jonas", "jonas@dann.io", new LockingAndBanningImpl());
98 98
userTenant.add(user);
99 99
userStore.updateUserGroup(userTenant);
100 100
ownership = new Ownership(user, userTenant);
java/com.sap.sse.security.test/src/com/sap/sse/security/test/PreferenceObjectBasedNotificationSetTest.java
... ...
@@ -18,7 +18,6 @@ import org.junit.jupiter.api.Test;
18 18
import com.mongodb.MongoException;
19 19
import com.mongodb.client.MongoDatabase;
20 20
import com.sap.sse.common.Util;
21
-import com.sap.sse.common.impl.TimedLockImpl;
22 21
import com.sap.sse.mongodb.MongoDBConfiguration;
23 22
import com.sap.sse.mongodb.MongoDBService;
24 23
import com.sap.sse.security.PreferenceObjectBasedNotificationSet;
... ...
@@ -26,6 +25,7 @@ import com.sap.sse.security.interfaces.UserImpl;
26 25
import com.sap.sse.security.interfaces.UserStore;
27 26
import com.sap.sse.security.shared.UserGroupManagementException;
28 27
import com.sap.sse.security.shared.UserManagementException;
28
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
29 29
import com.sap.sse.security.shared.impl.User;
30 30
import com.sap.sse.security.shared.impl.UserGroup;
31 31
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
... ...
@@ -191,7 +191,7 @@ public class PreferenceObjectBasedNotificationSetTest {
191 191
192 192
@Test
193 193
public void userWithNonVerifiedEmailIsSkippedTest() throws UserManagementException, UserGroupManagementException {
194
- store.createUser(user1, mail, new TimedLockImpl());
194
+ store.createUser(user1, mail, new LockingAndBanningImpl());
195 195
store.registerPreferenceConverter(prefKey, prefConverter);
196 196
store.setPreferenceObject(user1, prefKey, values1);
197 197
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
... ...
@@ -238,7 +238,7 @@ public class PreferenceObjectBasedNotificationSetTest {
238 238
*/
239 239
@Test
240 240
public void deleteUserWithMappingTest() throws UserManagementException, UserGroupManagementException {
241
- store.createUser(user1, mail, new TimedLockImpl());
241
+ store.createUser(user1, mail, new LockingAndBanningImpl());
242 242
store.registerPreferenceConverter(prefKey, prefConverter);
243 243
store.setPreferenceObject(user1, prefKey, values1);
244 244
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
... ...
@@ -250,7 +250,7 @@ public class PreferenceObjectBasedNotificationSetTest {
250 250
251 251
@Test
252 252
public void removePreferenceConverterTest() throws UserManagementException, UserGroupManagementException {
253
- store.createUser(user1, mail, new TimedLockImpl());
253
+ store.createUser(user1, mail, new LockingAndBanningImpl());
254 254
store.registerPreferenceConverter(prefKey, prefConverter);
255 255
store.setPreferenceObject(user1, prefKey, values1);
256 256
PreferenceObjectBasedNotificationSetImpl notificationSet = new PreferenceObjectBasedNotificationSetImpl(prefKey, store);
... ...
@@ -272,9 +272,9 @@ public class PreferenceObjectBasedNotificationSetTest {
272 272
UserGroup defaultTenantForSingleServer = store.createUserGroup(UUID.randomUUID(), username + "-tenant");
273 273
Map<String, UserGroup> defaultTenantForServer = new ConcurrentHashMap<>();
274 274
defaultTenantForServer.put(serverName, defaultTenantForSingleServer);
275
- store.createUser(username, email, new TimedLockImpl());
275
+ store.createUser(username, email, new LockingAndBanningImpl());
276 276
store.updateUser(new UserImpl(username, email, null, null, null, true, false, null, null, defaultTenantForServer,
277
- Collections.emptySet(), /* userGroupProvider */ null, new TimedLockImpl()));
277
+ Collections.emptySet(), /* userGroupProvider */ null, new LockingAndBanningImpl()));
278 278
}
279 279
280 280
private static class PreferenceObjectBasedNotificationSetImpl extends PreferenceObjectBasedNotificationSet<HashSet<String>, String> {
java/com.sap.sse.security.test/src/com/sap/sse/security/test/PrivilegeEscalationTest.java
... ...
@@ -11,7 +11,6 @@ import org.junit.jupiter.api.AfterEach;
11 11
import org.junit.jupiter.api.BeforeEach;
12 12
import org.junit.jupiter.api.Test;
13 13
14
-import com.sap.sse.common.impl.TimedLockImpl;
15 14
import com.sap.sse.security.SecurityService;
16 15
import com.sap.sse.security.impl.SecurityServiceImpl;
17 16
import com.sap.sse.security.shared.HasPermissions;
... ...
@@ -27,6 +26,7 @@ import com.sap.sse.security.shared.UserStoreManagementException;
27 26
import com.sap.sse.security.shared.WildcardPermission;
28 27
import com.sap.sse.security.shared.impl.AccessControlList;
29 28
import com.sap.sse.security.shared.impl.HasPermissionsImpl;
29
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
30 30
import com.sap.sse.security.shared.impl.Ownership;
31 31
import com.sap.sse.security.shared.impl.Role;
32 32
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
... ...
@@ -65,8 +65,8 @@ public class PrivilegeEscalationTest {
65 65
PersistenceFactory.INSTANCE.getDefaultMongoObjectFactory(), TEST_DEFAULT_TENANT);
66 66
userStore.ensureDefaultRolesExist();
67 67
userStore.loadAndMigrateUsers();
68
- user = userStore.createUser(USER_USERNAME, null, new TimedLockImpl());
69
- user2 = userStore.createUser(USER2_USERNAME, null, new TimedLockImpl());
68
+ user = userStore.createUser(USER_USERNAME, null, new LockingAndBanningImpl());
69
+ user2 = userStore.createUser(USER2_USERNAME, null, new LockingAndBanningImpl());
70 70
userGroup = userStore.createUserGroup(USER_GROUP_UUID, USER_USERNAME+"-tenant");
71 71
userGroup.add(user);
72 72
userGroup.add(user2);
java/com.sap.sse.security.test/src/com/sap/sse/security/test/RoleDefinitionsTest.java
... ...
@@ -8,11 +8,11 @@ import java.util.UUID;
8 8
import org.junit.jupiter.api.BeforeEach;
9 9
import org.junit.jupiter.api.Test;
10 10
11
-import com.sap.sse.common.impl.TimedLockImpl;
12 11
import com.sap.sse.security.interfaces.UserStore;
13 12
import com.sap.sse.security.shared.RoleDefinition;
14 13
import com.sap.sse.security.shared.UserManagementException;
15 14
import com.sap.sse.security.shared.UserStoreManagementException;
15
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
16 16
import com.sap.sse.security.shared.impl.Role;
17 17
import com.sap.sse.security.shared.impl.User;
18 18
import com.sap.sse.security.shared.impl.UserGroup;
... ...
@@ -37,7 +37,7 @@ public class RoleDefinitionsTest {
37 37
@BeforeEach
38 38
public void doBefore() throws UserStoreManagementException {
39 39
userStore.clear();
40
- user = userStore.createUser(username, email, new TimedLockImpl());
40
+ user = userStore.createUser(username, email, new LockingAndBanningImpl());
41 41
roleDefinition = userStore.createRoleDefinition(testRoleUUID, TEST_ROLE, Collections.emptySet());
42 42
userGroup = userStore.createUserGroup(testGroupUUID, groupName);
43 43
}
java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserPreferenceObjectAndConverterTest.java
... ...
@@ -9,11 +9,11 @@ import org.junit.jupiter.api.Test;
9 9
10 10
import com.mongodb.MongoException;
11 11
import com.mongodb.client.MongoDatabase;
12
-import com.sap.sse.common.impl.TimedLockImpl;
13 12
import com.sap.sse.mongodb.MongoDBConfiguration;
14 13
import com.sap.sse.mongodb.MongoDBService;
15 14
import com.sap.sse.security.shared.UserGroupManagementException;
16 15
import com.sap.sse.security.shared.UserManagementException;
16
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
17 17
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
18 18
import com.sap.sse.security.userstore.mongodb.impl.CollectionNames;
19 19
... ...
@@ -115,7 +115,7 @@ public class UserPreferenceObjectAndConverterTest {
115 115
*/
116 116
@Test
117 117
public void deleteUserWithPreferenceObjectTest() throws UserManagementException, UserGroupManagementException {
118
- store.createUser(user1, email, new TimedLockImpl());
118
+ store.createUser(user1, email, new LockingAndBanningImpl());
119 119
store.registerPreferenceConverter(prefKey1, prefConverter);
120 120
store.setPreferenceObject(user1, prefKey1, pref1);
121 121
store.deleteUser(user1);
... ...
@@ -124,7 +124,7 @@ public class UserPreferenceObjectAndConverterTest {
124 124
125 125
@Test
126 126
public void removeConverterTest() throws UserManagementException, UserGroupManagementException {
127
- store.createUser(user1, email, new TimedLockImpl());
127
+ store.createUser(user1, email, new LockingAndBanningImpl());
128 128
store.registerPreferenceConverter(prefKey1, prefConverter);
129 129
store.setPreference(user1, prefKey1, serializedPref1);
130 130
store.removePreferenceConverter(prefKey1);
java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreTest.java
... ...
@@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.assertNull;
6 6
import org.junit.jupiter.api.BeforeEach;
7 7
import org.junit.jupiter.api.Test;
8 8
9
-import com.sap.sse.common.impl.TimedLockImpl;
10 9
import com.sap.sse.security.interfaces.UserStore;
11 10
import com.sap.sse.security.shared.UserGroupManagementException;
12 11
import com.sap.sse.security.shared.UserManagementException;
12
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
13 13
import com.sap.sse.security.userstore.mongodb.UserStoreImpl;
14 14
15 15
public class UserStoreTest {
... ...
@@ -26,7 +26,7 @@ public class UserStoreTest {
26 26
27 27
@BeforeEach
28 28
public void setUp() throws UserManagementException, UserGroupManagementException {
29
- userStore.createUser(username, email, new TimedLockImpl());
29
+ userStore.createUser(username, email, new LockingAndBanningImpl());
30 30
userStore.setAccessToken(username, accessToken);
31 31
userStore.setPreference(username, prefKey, prefValue);
32 32
}
java/com.sap.sse.security.test/src/com/sap/sse/security/test/UserStoreWithPersistenceTest.java
... ...
@@ -24,7 +24,6 @@ import com.mongodb.MongoException;
24 24
import com.mongodb.client.MongoDatabase;
25 25
import com.sap.sse.common.Util;
26 26
import com.sap.sse.common.Util.Pair;
27
-import com.sap.sse.common.impl.TimedLockImpl;
28 27
import com.sap.sse.mongodb.MongoDBConfiguration;
29 28
import com.sap.sse.mongodb.MongoDBService;
30 29
import com.sap.sse.security.interfaces.UserImpl;
... ...
@@ -35,6 +34,7 @@ import com.sap.sse.security.shared.SecurityUser;
35 34
import com.sap.sse.security.shared.UserGroupManagementException;
36 35
import com.sap.sse.security.shared.UserManagementException;
37 36
import com.sap.sse.security.shared.UserStoreManagementException;
37
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
38 38
import com.sap.sse.security.shared.impl.Ownership;
39 39
import com.sap.sse.security.shared.impl.Role;
40 40
import com.sap.sse.security.shared.impl.User;
... ...
@@ -93,7 +93,7 @@ public class UserStoreWithPersistenceTest {
93 93
94 94
@Test
95 95
public void testCreateUser() throws UserManagementException {
96
- store.createUser(username, email, new TimedLockImpl());
96
+ store.createUser(username, email, new LockingAndBanningImpl());
97 97
assertNotNull(store.getUserByName(username));
98 98
assertNotNull(store.getUserByEmail(email));
99 99
... ...
@@ -104,12 +104,12 @@ public class UserStoreWithPersistenceTest {
104 104
105 105
@Test
106 106
public void testMasterdataIsSaved() throws UserStoreManagementException {
107
- store.createUser(username, email, new TimedLockImpl());
107
+ store.createUser(username, email, new LockingAndBanningImpl());
108 108
UserGroupImpl defaultTenant = createUserGroup();
109 109
HashMap<String, UserGroup> defaultTenantForServers = new HashMap<>();
110 110
defaultTenantForServers.put(serverName, defaultTenant);
111 111
store.updateUser(new UserImpl(username, email, fullName, company, Locale.GERMAN, false,
112
- defaultTenantForServers, Collections.emptySet(), /* userGroupProvider */ null, new TimedLockImpl()));
112
+ didOptOutOfMarketingEmails, null, null, defaultTenantForServers, Collections.emptySet(),
113 113
/* userGroupProvider */ null, new LockingAndBanningImpl()));
114 114
newStore();
115 115
User savedUser = store.getUserByName(username);
... ...
@@ -125,7 +125,7 @@ public class UserStoreWithPersistenceTest {
125 125
*/
126 126
@Test
127 127
public void testDeleteUser() throws UserManagementException {
128
- store.createUser(username, email, new TimedLockImpl());
128
+ store.createUser(username, email, new LockingAndBanningImpl());
129 129
store.deleteUser(username);
130 130
assertNull(store.getUserByName(username));
131 131
assertNull(store.getUserByEmail(email));
... ...
@@ -137,7 +137,7 @@ public class UserStoreWithPersistenceTest {
137 137
138 138
@Test
139 139
public void testSetPreferences() throws UserManagementException {
140
- store.createUser(username, email, new TimedLockImpl());
140
+ store.createUser(username, email, new LockingAndBanningImpl());
141 141
store.setPreference(username, prefKey, prefValue);
142 142
assertEquals(prefValue, store.getPreference(username, prefKey));
143 143
newStore();
... ...
@@ -146,7 +146,7 @@ public class UserStoreWithPersistenceTest {
146 146
147 147
@Test
148 148
public void testUnsetPreferences() throws UserManagementException {
149
- store.createUser(username, email, new TimedLockImpl());
149
+ store.createUser(username, email, new LockingAndBanningImpl());
150 150
store.setPreference(username, prefKey, prefValue);
151 151
store.unsetPreference(username, prefKey);
152 152
assertNull(store.getPreference(username, prefKey));
... ...
@@ -159,7 +159,7 @@ public class UserStoreWithPersistenceTest {
159 159
*/
160 160
@Test
161 161
public void testDeleteUserWithPreferences() throws UserManagementException {
162
- store.createUser(username, email, new TimedLockImpl());
162
+ store.createUser(username, email, new LockingAndBanningImpl());
163 163
store.setPreference(username, prefKey, prefValue);
164 164
store.deleteUser(username);
165 165
assertNull(store.getPreference(username, prefKey));
... ...
@@ -169,7 +169,7 @@ public class UserStoreWithPersistenceTest {
169 169
170 170
@Test
171 171
public void testCreateUserGroup() throws UserGroupManagementException, UserManagementException {
172
- final User user = store.createUser(username, email, new TimedLockImpl());
172
+ final User user = store.createUser(username, email, new LockingAndBanningImpl());
173 173
UserGroupImpl createUserGroup = createUserGroup();
174 174
createUserGroup.add(user);
175 175
store.updateUserGroup(createUserGroup);
... ...
@@ -198,7 +198,7 @@ public class UserStoreWithPersistenceTest {
198 198
@Test
199 199
public void testTenantUsers() throws UserManagementException, UserGroupManagementException {
200 200
UserGroupImpl defaultTenant = createUserGroup();
201
- final User user = store.createUser(username, email, new TimedLockImpl());
201
+ final User user = store.createUser(username, email, new LockingAndBanningImpl());
202 202
defaultTenant.add(user);
203 203
store.updateUserGroup(defaultTenant);
204 204
user.getDefaultTenantMap().put(serverName, defaultTenant);
... ...
@@ -220,7 +220,7 @@ public class UserStoreWithPersistenceTest {
220 220
221 221
@Test
222 222
public void testUserGroups() throws UserManagementException, UserGroupManagementException {
223
- final User user = store.createUser(username, email, new TimedLockImpl());
223
+ final User user = store.createUser(username, email, new LockingAndBanningImpl());
224 224
final String GROUP_NAME = "group";
225 225
final UserGroupImpl group = store.createUserGroup(UUID.randomUUID(), GROUP_NAME);
226 226
group.add(user);
... ...
@@ -244,7 +244,7 @@ public class UserStoreWithPersistenceTest {
244 244
@Test
245 245
public void testGetExistingQualificationsForRoleDefinition()
246 246
throws UserManagementException, UserGroupManagementException {
247
- User user = store.createUser("def", "d@test.de", new TimedLockImpl());
247
+ User user = store.createUser("def", "d@test.de", new LockingAndBanningImpl());
248 248
RoleDefinitionImpl roleDefinition = new RoleDefinitionImpl(UUID.randomUUID(), "My-Test-Role");
249 249
store.createRoleDefinition(roleDefinition.getId(), roleDefinition.getName(), new ArrayList<>());
250 250
UserGroupImpl userGroup = store.createUserGroup(UUID.randomUUID(), "Test-Usergroup");
java/com.sap.sse.security.ui/.settings/com.gwtplugins.gwt.eclipse.core.prefs
... ...
@@ -1,4 +1,4 @@
1
-//gwtVersion_/com.google.gwt.user/lib=
1
+//gwtVersion_/com.google.gwt.user/lib=2.11.1
2 2
//gwtVersion_/opt/gwt-2.11.0=2.11.0
3 3
//gwtVersion_/opt/gwt-2.11.1=2.11.1
4 4
//gwtVersion_/opt/gwt-2.12.2=2.12.2
java/com.sap.sse.security.ui/GWT Security SDM.launch
... ...
@@ -27,8 +27,6 @@
27 27
</listAttribute>
28 28
<booleanAttribute key="org.eclipse.jdt.debug.ui.CONSIDER_INHERITED_MAIN" value="true"/>
29 29
<booleanAttribute key="org.eclipse.jdt.debug.ui.INCLUDE_EXTERNAL_JARS" value="true"/>
30
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
31
- <booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
32 30
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
33 31
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
34 32
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry containerPath=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8&quot; javaProject=&quot;com.sap.sailing.gwt.ui&quot; path=&quot;1&quot; type=&quot;4&quot;/&gt;&#10;"/>
... ...
@@ -103,14 +101,12 @@
103 101
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10; &lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;com.sap.sailing.gwt.ui&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
104 102
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;com.sap.sse.common&quot; type=&quot;1&quot;/&gt;&#10;"/>
105 103
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.landscape.aws.common/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
106
- <listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry internalArchive=&quot;/com.sap.sse.branding/src&quot; path=&quot;3&quot; type=&quot;2&quot;/&gt;&#10;"/>
107 104
</listAttribute>
108 105
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.gwtplugins.gwt.eclipse.core.moduleClasspathProvider"/>
109 106
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
110
- <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/"/>
111 107
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
112 108
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="com.sap.sse.security.ui"/>
113
- <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-incremental -workDir &quot;${project_loc:com.sap.sse.security.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.security.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -bindAddress 0.0.0.0 -logLevel INFO -codeServerPort 9877 -startupUrl /security/ui/Login.html -startupUrl /security/ui/EditProfile.html -startupUrl /security/ui/EmailValidation.html -startupUrl /security/ui/UserManagement.html -startupUrl /security/ui/Register.html -startupUrl /security/ui/Login.html com.sap.sse.security.ui.EditProfile com.sap.sse.security.ui.EmailValidation com.sap.sse.security.ui.OAuthLogin com.sap.sse.security.ui.UserManagementEntryPoint com.sap.sse.security.ui.Register com.sap.sse.security.ui.Login"/>
109
+ <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-incremental -workDir &quot;${project_loc:com.sap.sse.security.ui}/.tmp/gwt-work&quot; -war &quot;${project_loc:com.sap.sse.security.ui}&quot; -noserver -remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -logLevel INFO -codeServerPort 9877 -startupUrl /security/ui/Login.html -startupUrl /security/ui/EditProfile.html -startupUrl /security/ui/EmailValidation.html -startupUrl /security/ui/UserManagement.html -startupUrl /security/ui/Register.html -startupUrl /security/ui/Login.html com.sap.sse.security.ui.EditProfile com.sap.sse.security.ui.EmailValidation com.sap.sse.security.ui.OAuthLogin com.sap.sse.security.ui.UserManagementEntryPoint com.sap.sse.security.ui.Register com.sap.sse.security.ui.Login"/>
114 110
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="com.sap.sse.security.ui"/>
115 111
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+UseG1GC -XX:-UseStringDeduplication -Dgwt.watchFileChanges=false -Xmx2048m -Dgwt-usearchives=false -Dgwt.persistentunitcache=false"/>
116 112
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.sap.sailing.gwt.ui}/.tmp/gwt-work"/>
java/com.sap.sse.security.ui/pom.xml
... ...
@@ -77,19 +77,9 @@
77 77
<!-- GWT version detected from dependencyManagement -->
78 78
<execution>
79 79
<configuration>
80
- <!-- for debugger attachment: -->
81
- <!--
82
- <extraJvmArgs>
83
- -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8003
84
- </extraJvmArgs>
85
- <extraJvmArgsCompiler>
86
- -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8003
87
- </extraJvmArgsCompiler>
88
- <logLevel>DEBUG</logLevel>
89
- -->
90 80
<!-- <userAgents>chrome</userAgents> -->
91 81
<modules>
92
- <module>com.sap.sse.security.ui.UserManagement</module>
82
+ <module>com.sap.sse.security.ui.UserManagement</module>
93 83
<module>com.sap.sse.security.ui.UserManagementEntryPoint</module>
94 84
<module>com.sap.sse.security.ui.Login</module>
95 85
<module>com.sap.sse.security.ui.OAuthLogin</module>
java/com.sap.sse.security.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/common/impl/MillisecondsDurationImpl_CustomFieldSerializer.java
... ...
@@ -1,48 +0,0 @@
1
-package com.google.gwt.user.client.rpc.core.com.sap.sse.common.impl;
2
-
3
-import com.google.gwt.user.client.rpc.CustomFieldSerializer;
4
-import com.google.gwt.user.client.rpc.SerializationException;
5
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
6
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
7
-import com.sap.sse.common.impl.MillisecondsDurationImpl;
8
-
9
-public class MillisecondsDurationImpl_CustomFieldSerializer extends CustomFieldSerializer<MillisecondsDurationImpl> {
10
-
11
- @Override
12
- public void serializeInstance(SerializationStreamWriter streamWriter, MillisecondsDurationImpl instance)
13
- throws SerializationException {
14
- serialize(streamWriter, instance);
15
- }
16
-
17
- public static void serialize(SerializationStreamWriter streamWriter, MillisecondsDurationImpl instance)
18
- throws SerializationException {
19
- streamWriter.writeLong(instance.asMillis());
20
- }
21
-
22
- @Override
23
- public boolean hasCustomInstantiateInstance() {
24
- return true;
25
- }
26
-
27
- @Override
28
- public MillisecondsDurationImpl instantiateInstance(SerializationStreamReader streamReader)
29
- throws SerializationException {
30
- return instantiate(streamReader);
31
- }
32
-
33
- public static MillisecondsDurationImpl instantiate(SerializationStreamReader streamReader)
34
- throws SerializationException {
35
- return new MillisecondsDurationImpl(streamReader.readLong());
36
- }
37
-
38
- @Override
39
- public void deserializeInstance(SerializationStreamReader streamReader, MillisecondsDurationImpl instance)
40
- throws SerializationException {
41
- deserialize(streamReader, instance);
42
- }
43
-
44
- public static void deserialize(SerializationStreamReader streamReader, MillisecondsDurationImpl instance) {
45
- // Done by instantiateInstance
46
- }
47
-
48
-}
java/com.sap.sse.security.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/common/impl/SecondsDurationImpl_CustomFieldSerializer.java
... ...
@@ -1,48 +0,0 @@
1
-package com.google.gwt.user.client.rpc.core.com.sap.sse.common.impl;
2
-
3
-import com.google.gwt.user.client.rpc.CustomFieldSerializer;
4
-import com.google.gwt.user.client.rpc.SerializationException;
5
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
6
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
7
-import com.sap.sse.common.impl.SecondsDurationImpl;
8
-
9
-public class SecondsDurationImpl_CustomFieldSerializer extends CustomFieldSerializer<SecondsDurationImpl> {
10
-
11
- @Override
12
- public void serializeInstance(SerializationStreamWriter streamWriter, SecondsDurationImpl instance)
13
- throws SerializationException {
14
- serialize(streamWriter, instance);
15
- }
16
-
17
- public static void serialize(SerializationStreamWriter streamWriter, SecondsDurationImpl instance)
18
- throws SerializationException {
19
- streamWriter.writeDouble(instance.asSeconds());
20
- }
21
-
22
- @Override
23
- public boolean hasCustomInstantiateInstance() {
24
- return true;
25
- }
26
-
27
- @Override
28
- public SecondsDurationImpl instantiateInstance(SerializationStreamReader streamReader)
29
- throws SerializationException {
30
- return instantiate(streamReader);
31
- }
32
-
33
- public static SecondsDurationImpl instantiate(SerializationStreamReader streamReader)
34
- throws SerializationException {
35
- return new SecondsDurationImpl(streamReader.readDouble());
36
- }
37
-
38
- @Override
39
- public void deserializeInstance(SerializationStreamReader streamReader, SecondsDurationImpl instance)
40
- throws SerializationException {
41
- deserialize(streamReader, instance);
42
- }
43
-
44
- public static void deserialize(SerializationStreamReader streamReader, SecondsDurationImpl instance) {
45
- // Done by instantiateInstance
46
- }
47
-
48
-}
java/com.sap.sse.security.ui/src/main/java/com/google/gwt/user/client/rpc/core/com/sap/sse/security/ui/shared/IpToTimedLockDTO_CustomFieldSerializer.java
... ...
@@ -1,48 +0,0 @@
1
-package com.google.gwt.user.client.rpc.core.com.sap.sse.security.ui.shared;
2
-
3
-import com.google.gwt.user.client.rpc.CustomFieldSerializer;
4
-import com.google.gwt.user.client.rpc.SerializationException;
5
-import com.google.gwt.user.client.rpc.SerializationStreamReader;
6
-import com.google.gwt.user.client.rpc.SerializationStreamWriter;
7
-import com.sap.sse.common.TimedLock;
8
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
9
-
10
-public class IpToTimedLockDTO_CustomFieldSerializer extends CustomFieldSerializer<IpToTimedLockDTO> {
11
- @Override
12
- public void serializeInstance(SerializationStreamWriter streamWriter, IpToTimedLockDTO instance)
13
- throws SerializationException {
14
- serialize(streamWriter, instance);
15
- }
16
-
17
- public static void serialize(SerializationStreamWriter streamWriter, IpToTimedLockDTO instance)
18
- throws SerializationException {
19
- streamWriter.writeString(instance.getIp());
20
- streamWriter.writeObject(instance.getTimedLock());
21
- }
22
-
23
- @Override
24
- public boolean hasCustomInstantiateInstance() {
25
- return true;
26
- }
27
-
28
- @Override
29
- public IpToTimedLockDTO instantiateInstance(SerializationStreamReader streamReader)
30
- throws SerializationException {
31
- return instantiate(streamReader);
32
- }
33
-
34
- public static IpToTimedLockDTO instantiate(SerializationStreamReader streamReader)
35
- throws SerializationException {
36
- return new IpToTimedLockDTO(streamReader.readString(), (TimedLock) streamReader.readObject());
37
- }
38
-
39
- @Override
40
- public void deserializeInstance(SerializationStreamReader streamReader, IpToTimedLockDTO instance)
41
- throws SerializationException {
42
- deserialize(streamReader, instance);
43
- }
44
-
45
- public static void deserialize(SerializationStreamReader streamReader, IpToTimedLockDTO instance) {
46
- // Done by instantiateInstance
47
- }
48
-}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/SerializationDummy.java
... ...
@@ -1,14 +1,12 @@
1 1
package com.sap.sse.security.ui.client;
2 2
3 3
import com.google.gwt.user.client.rpc.IsSerializable;
4
-import com.sap.sse.common.TimedLock;
5 4
import com.sap.sse.landscape.aws.common.shared.SecuredAwsLandscapeType;
6 5
import com.sap.sse.security.shared.HasPermissions;
7 6
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
8 7
9 8
public class SerializationDummy implements IsSerializable {
10
- TypeRelativeObjectIdentifier typeRelativeObjectIdentifier;
11
- HasPermissions hasPermissions;
12
- SecuredAwsLandscapeType securedAwsLandscapeType;
13
- TimedLock timedLock;
9
+ public TypeRelativeObjectIdentifier typeRelativeObjectIdentifier;
10
+ public HasPermissions hasPermissions;
11
+ public SecuredAwsLandscapeType securedAwsLandscapeType;
14 12
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementService.java
... ...
@@ -24,7 +24,6 @@ import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
24 24
import com.sap.sse.security.shared.dto.UserDTO;
25 25
import com.sap.sse.security.shared.dto.UserGroupDTO;
26 26
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
27
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
28 27
import com.sap.sse.security.ui.shared.SecurityServiceSharingDTO;
29 28
import com.sap.sse.security.ui.shared.SuccessInfo;
30 29
... ...
@@ -34,7 +33,7 @@ public interface UserManagementService extends RemoteService {
34 33
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
35 34
36 35
Collection<UserGroupDTO> getUserGroups() throws org.apache.shiro.authz.UnauthorizedException;
37
-
36
+
38 37
UserGroupDTO getUserGroupByName(String userGroupName)
39 38
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
40 39
... ...
@@ -95,8 +94,4 @@ public interface UserManagementService extends RemoteService {
95 94
Pair<Boolean, ArrayList<String>> getCORSFilterConfiguration();
96 95
97 96
String getBrandingConfigurationId();
98
-
99
- ArrayList<IpToTimedLockDTO> getClientIPBasedTimedLocksForUserCreation() throws UnauthorizedException;
100
-
101
- ArrayList<IpToTimedLockDTO> getClientIPBasedTimedLocksForBearerTokenAbuse() throws UnauthorizedException;
102 97
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementServiceAsync.java
... ...
@@ -22,7 +22,6 @@ import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
22 22
import com.sap.sse.security.shared.dto.UserDTO;
23 23
import com.sap.sse.security.shared.dto.UserGroupDTO;
24 24
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
25
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
26 25
import com.sap.sse.security.ui.shared.SecurityServiceSharingDTO;
27 26
import com.sap.sse.security.ui.shared.SuccessInfo;
28 27
... ...
@@ -108,8 +107,4 @@ public interface UserManagementServiceAsync {
108 107
void getCORSFilterConfiguration(AsyncCallback<Pair<Boolean, ArrayList<String>>> callback);
109 108
110 109
void getBrandingConfigurationId(AsyncCallback<String> callback);
111
-
112
- void getClientIPBasedTimedLocksForUserCreation(AsyncCallback<ArrayList<IpToTimedLockDTO>> callback);
113
-
114
- void getClientIPBasedTimedLocksForBearerTokenAbuse(AsyncCallback<ArrayList<IpToTimedLockDTO>> callback);
115 110
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementWriteService.java
... ...
@@ -78,11 +78,6 @@ public interface UserManagementWriteService extends UserManagementService {
78 78
throws UserManagementException, org.apache.shiro.authz.UnauthorizedException;
79 79
80 80
SuccessInfo deleteUser(String username) throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
81
-
82
- SuccessInfo unlockUser(String username) throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
83
-
84
- Set<SuccessInfo> unlockUsers(Set<String> usernames)
85
- throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
86 81
87 82
Set<SuccessInfo> deleteUsers(Set<String> usernames)
88 83
throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
... ...
@@ -141,9 +136,4 @@ public interface UserManagementWriteService extends UserManagementService {
141 136
142 137
AccessControlListDTO overrideAccessControlList(QualifiedObjectIdentifier idOfAccessControlledObject,
143 138
AccessControlListDTO acl) throws UnauthorizedException, org.apache.shiro.authz.UnauthorizedException;
144
-
145
- void releaseUserCreationLockOnIp(String ip) throws UnauthorizedException;
146
-
147
- void releaseBearerTokenLockOnIp(String ip) throws UnauthorizedException;
148
-
149 139
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/UserManagementWriteServiceAsync.java
... ...
@@ -61,10 +61,6 @@ public interface UserManagementWriteServiceAsync extends UserManagementServiceAs
61 61
void updateRoleDefinition(RoleDefinitionDTO roleWithNewProperties, AsyncCallback<Void> callback);
62 62
63 63
void deleteUser(String username, AsyncCallback<SuccessInfo> callback);
64
-
65
- void unlockUser(String username, AsyncCallback<SuccessInfo> callback);
66
-
67
- void unlockUsers(Set<String> username, AsyncCallback<Set<SuccessInfo>> callback);
68 64
69 65
void deleteUsers(Set<String> usernames, AsyncCallback<Set<SuccessInfo>> callback);
70 66
... ...
@@ -125,8 +121,4 @@ public interface UserManagementWriteServiceAsync extends UserManagementServiceAs
125 121
void setCORSFilterConfigurationAllowedOrigins(ArrayList<String> allowedOrigins, AsyncCallback<Void> callback);
126 122
127 123
void fileTakedownNotice(TakedownNoticeRequestContext takedownNoticeRequestContext, AsyncCallback<Void> callback);
128
-
129
- void releaseUserCreationLockOnIp(String ip, AsyncCallback<Void> asyncCallback);
130
-
131
- void releaseBearerTokenLockOnIp(String ip, AsyncCallback<Void> asyncCallback);
132 124
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/AccessControlledButtonPanel.java
... ...
@@ -179,28 +179,6 @@ public class AccessControlledButtonPanel extends Composite {
179 179
return resolveButtonVisibility(permissionCheck, new Button(text, wrap(permissionCheck, callback)));
180 180
}
181 181
182
- /**
183
- * Adds an action button, appended with selection count, whose visibility depends on the provided {@link Supplier
184
- * permission check}.
185
- *
186
- * @param text
187
- * the {@link String text} to show on the button
188
- * @param permissionCheck
189
- * the {@link Supplier permission check} to decide if the action button is visible or not
190
- * @param callback
191
- * the {@link Command callback} to execute on button click, if permission is granted
192
- * @return the created {@link Button} instance
193
- */
194
- public <T extends Named> Button addCountingAction(final String text, final SetSelectionModel<T> selectionModel,
195
- final Supplier<Boolean> permissionCheck, final Command callback) {
196
- if (selectionModel == null) {
197
- throw new IllegalArgumentException("Selection model for a remove action must not be null");
198
- }
199
- final SelectedElementsCountingButton<T> button = new SelectedElementsCountingButton<T>(text,
200
- selectionModel, wrap(permissionCheck, callback));
201
- return resolveButtonVisibility(permissionCheck, button);
202
- }
203
-
204 182
private Button resolveButtonVisibility(final Supplier<Boolean> permissionCheck, final Button button) {
205 183
this.buttonToPermissions.put(button, permissionCheck);
206 184
button.getElement().getStyle().setMarginRight(5, Unit.PX);
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/component/DefaultActionsImagesBarCell.java
... ...
@@ -5,7 +5,6 @@ import java.util.Arrays;
5 5
import com.sap.sse.gwt.client.IconResources;
6 6
import com.sap.sse.gwt.client.celltable.ImagesBarCell;
7 7
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
8
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes.UserActions;
9 8
import com.sap.sse.security.ui.client.i18n.StringMessages;
10 9
11 10
public class DefaultActionsImagesBarCell extends ImagesBarCell {
... ...
@@ -15,7 +14,6 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
15 14
public static final String ACTION_CHANGE_OWNERSHIP = DefaultActions.CHANGE_OWNERSHIP.name();
16 15
public static final String ACTION_MIGRATE_GROUP_OWNERSHIP_HIERARCHY = "MIGRATE_GROUP_OWNERSHIP_HIERARCHY";
17 16
public static final String ACTION_CHANGE_ACL = DefaultActions.CHANGE_ACL.name();
18
- public static final String ACTION_MANAGE_LOCK = UserActions.MANAGE_LOCK.name();
19 17
20 18
protected final StringMessages stringMessages;
21 19
... ...
@@ -26,7 +24,7 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
26 24
@Override
27 25
protected Iterable<ImageSpec> getImageSpecs() {
28 26
return Arrays.asList(getUpdateImageSpec(), getDeleteImageSpec(), getChangeOwnershipImageSpec(),
29
- getChangeACLImageSpec(), getResetLockImageSpec());
27
+ getChangeACLImageSpec());
30 28
}
31 29
32 30
/**
... ...
@@ -67,12 +65,4 @@ public class DefaultActionsImagesBarCell extends ImagesBarCell {
67 65
IconResources.INSTANCE.changeACLIcon());
68 66
}
69 67
70
- /**
71
- * @return {@link ImageSpec} for {@link DefaultActions#CHANGE_ACL reset lock} action
72
- */
73
- protected ImageSpec getResetLockImageSpec() {
74
- return new ImageSpec(ACTION_MANAGE_LOCK, stringMessages.resetLock(),
75
- IconResources.INSTANCE.resetLockIcon());
76
- }
77
-
78 68
}
... ...
\ No newline at end of file
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/i18n/StringMessages.java
... ...
@@ -150,11 +150,7 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
150 150
String groups();
151 151
String group();
152 152
String errorDeletingUser(String username, String message);
153
- String doYouReallyWantToUnlockUser(String name);
154
- String doYouReallyWantToUnlockNUsers(int n);
155
- String unlockSucceededForUser(String username);
156
- String unlockFailedForUser(String username);
157
- String userIsAlreadyUnlocked();
153
+ String doYouReallyWantToRemoveUser(String name);
158 154
String errorTryingToUpdateUser(String username, String message);
159 155
String ownership();
160 156
String editObjectOwnership();
... ...
@@ -165,7 +161,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
165 161
String userNotFound(String username);
166 162
String usergroupNotFound(String userGroupName);
167 163
String actionChangeACL();
168
- String resetLock();
169 164
String editACLForObject(String objectName);
170 165
String acl();
171 166
String errorUpdatingAcl(String name);
... ...
@@ -231,7 +226,5 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
231 226
String lockedUntil();
232 227
String passwordAuthenticationCurrentlyLockedForUser();
233 228
String clientCurrentlyLockedForUserCreation();
234
- String unlockedSuccessfully();
235
- String failedToUnlock();
236 229
String optOutOfMarketingEmails();
237 230
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/i18n/StringMessages.properties
... ...
@@ -156,11 +156,7 @@ validated=Validated
156 156
groups=Groups
157 157
group=Group
158 158
errorDeletingUser=Error deleting user {0}: {1}
159
-doYouReallyWantToUnlockUser=Really allow locked user {0} to access SAP Sailing Analytics again?
160
-doYouReallyWantToUnlockNUsers=Really allow {0} users to access SAP Sailing Analytics again?
161
-unlockSucceededForUser=Unlock succeeded for user {0}.
162
-unlockFailedForUser=Unlock failed for user {0}.
163
-userIsAlreadyUnlocked=User is already unlocked.
159
+doYouReallyWantToRemoveUser=Really remove user {0}?
164 160
errorTryingToUpdateUser=Error trying to update user {0}: {1}
165 161
ownership=Ownership
166 162
editObjectOwnership=Edit object ownership
... ...
@@ -171,7 +167,6 @@ pleaseWaitUntilUserGroupNameIsResolved=Please wait until user group name is reso
171 167
userNotFound=User {0} not found
172 168
usergroupNotFound=User group {0} not found
173 169
actionChangeACL=Change ACL
174
-resetLock=Reset Lock
175 170
editACLForObject=Edit ACL for ''{0}''
176 171
acl=ACL
177 172
errorUpdatingAcl=Error updating ACL: {0}.
... ...
@@ -238,6 +233,4 @@ paymentFinished=Payment successful. Plan roles have been granted.
238 233
lockedUntil=Locked until
239 234
passwordAuthenticationCurrentlyLockedForUser=Password authentication is currently locked for this user due to too many failed login attempts. Please try again later.
240 235
clientCurrentlyLockedForUserCreation=Client is currently locked for user creation after too many user creations by the same client. Please try again later.
241
-unlockedSuccessfully=Unlocked successfully
242
-failedToUnlock=Failed to unlock
243 236
optOutOfMarketingEmails=Opt out of Marketing emails
... ...
\ No newline at end of file
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/i18n/StringMessages_de.properties
... ...
@@ -100,7 +100,6 @@ error=Es ist ein Fehler aufgetreten
100 100
refresh=Aktualisieren
101 101
preferredLanguage=Bevorzugte Sprache
102 102
cannotResetInvalidURL="Fehlerhafte Reseturl ..."
103
-cannotUploadVideosAndImagesTogether=Videos und Bilder können nicht gleichzeitig hochgeladen werden, bitte laden Sie sie separat hoch.
104 103
sharedSettingsLink=Link mit Settings
105 104
makeDefault=Als Voreinstellung
106 105
makeDefaultInProgress=In Bearbeitung...
... ...
@@ -155,11 +154,7 @@ validated=Geprüft
155 154
groups=Gruppen
156 155
group=Gruppe
157 156
errorDeletingUser=Fehler beim Löschen des Benutzers {0}: {1}
158
-doYouReallyWantToUnlockUser=Soll dem gesperrten Benutzer {0} der Zugriff auf SAP Sailing Analytics wirklich wieder gewährt werden?
159
-doYouReallyWantToUnlockNUsers=Soll {0} Benutzern wirklich wieder Zugriff auf SAP Sailing Analytics gewährt werden?
160
-unlockSucceededForUser=Entsperrung für Benutzer {0} erfolgreich.
161
-unlockFailedForUser=Entsperrung für Benutzer {0} fehlgeschlagen.
162
-userIsAlreadyUnlocked=Der Benutzer ist bereits entsperrt.
157
+doYouReallyWantToRemoveUser=Benutzer {0} wirklich löschen?
163 158
errorTryingToUpdateUser=Fehler beim Aktualisieren des Benutzers {0}: {1}
164 159
ownership=Besitzer
165 160
editObjectOwnership=Objekt-Besitzer bearbeiten
... ...
@@ -170,7 +165,6 @@ pleaseWaitUntilUserGroupNameIsResolved=Bitte warten, bis der Benutzergruppen-Nam
170 165
userNotFound=Benutzer {0} nicht gefunden
171 166
usergroupNotFound=Benutzergruppe {0} nicht gefunden
172 167
actionChangeACL=ACL ändern
173
-resetLock=Sperre zurücksetzen
174 168
editACLForObject=ACL für ''{0}'' ändern
175 169
acl=ACL
176 170
errorUpdatingAcl=Fehler beim Aktualisieren der ACL: {0}.
... ...
@@ -202,7 +196,6 @@ nullUserGroup=<Anonyme Usergruppe>
202 196
editRolesAndPermissionsForUser=Rollen und Berechtigungen für Benutzer {0} editieren
203 197
permissionType=Berechtigungstyp
204 198
couldNotLoadMarkTemplates=Markvorlagen konnten nicht geladen werden.
205
-transitive=Transitiv
206 199
failGeneratingHostedPageObject=Fehler beim Erzeugen der eingebetteten Seiten-Objekte, bitte nochmals versuchen
207 200
errorOpenCheckout=Fehler beim Öffnen des Bezahlformulars: {0}
208 201
errorSaveSubscription=Fehler beim Abspeichern des Abonnements: {0}
... ...
@@ -218,7 +211,6 @@ premiumFeatureListDescription=Vergleichen Sie alle Funktionen des FREE- oder PRE
218 211
selectSubscriptionPlan=Bitte wählen sie einen Abonnementplan aus.
219 212
features=Enthalten
220 213
premiumFeature=Premium-Feature
221
-premium=Prämie
222 214
price=Preis
223 215
pleaseSubscribeToUse=Erlaubnis verweigert! Möchten sie ein Abonement abschließen?
224 216
pleaseSubscribeToUseSpecific=Sie sind nicht berechtigt, die Funktion "{0}" zu verwenden! Möchten sie ein Abonement abschließen?
... ...
@@ -237,6 +229,4 @@ paymentFinished=Zahlung erfolgreich. Planrollen wurden verliehen.
237 229
lockedUntil=Gesperrt bis
238 230
passwordAuthenticationCurrentlyLockedForUser=Passwort-Authentifizierung ist für diesen Benutzer derzeit aufgrund zu vieler fehlgeschlagener Versuche gesperrt. Bitter später erneut versuchen.
239 231
clientCurrentlyLockedForUserCreation=Benutzererstellung für den aktuellen Client ist derzeit wegen zu vieler neuer Nutzer vom selben Client gesperrt. Bitte später erneut versuchen.
240
-unlockedSuccessfully=Erfolgreich entsperrt.
241
-failedToUnlock=Entsperren fehlgeschlagen
242 232
optOutOfMarketingEmails=Abmeldung von Marketing-E-Mails
... ...
\ No newline at end of file
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserManagementPanel.java
... ...
@@ -26,7 +26,6 @@ import com.sap.sse.gwt.client.celltable.RefreshableMultiSelectionModel;
26 26
import com.sap.sse.gwt.client.dialog.DataEntryDialog.DialogCallback;
27 27
import com.sap.sse.gwt.client.panels.LabeledAbstractFilterablePanel;
28 28
import com.sap.sse.security.shared.dto.UserDTO;
29
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes.UserActions;
30 29
import com.sap.sse.security.ui.client.UserManagementWriteServiceAsync;
31 30
import com.sap.sse.security.ui.client.UserService;
32 31
import com.sap.sse.security.ui.client.component.AccessControlledButtonPanel;
... ...
@@ -103,12 +102,6 @@ public class UserManagementPanel<TR extends CellTableWithCheckboxResources> exte
103 102
}
104 103
});
105 104
removeButton.ensureDebugId("DeleteUserButton");
106
- final boolean hasManageLockPermissionOnAnyUser = userService.hasCurrentUserAnyPermission(USER.getPermission(UserActions.MANAGE_LOCK), null);
107
- if (hasManageLockPermissionOnAnyUser) {
108
- final Button unlockButton = buttonPanel.addCountingAction("Unlock", userSelectionModel, () -> true,
109
- () -> onCountingUnlockButtonClick(stringMessages, userManagementWriteService, errorReporter));
110
- unlockButton.ensureDebugId("UnlockUserButton");
111
- }
112 105
ScrollPanel scrollPanel = new ScrollPanel(userList.asWidget());
113 106
LabeledAbstractFilterablePanel<UserDTO> filterBox = userList.getFilterField();
114 107
filterBox.getElement().setPropertyString("placeholder", stringMessages.filterUsers());
... ...
@@ -144,67 +137,6 @@ public class UserManagementPanel<TR extends CellTableWithCheckboxResources> exte
144 137
west.add(detailsPanel);
145 138
}
146 139
147
- private void onCountingUnlockButtonClick(final StringMessages stringMessages,
148
- final UserManagementWriteServiceAsync userManagementWriteService, final ErrorReporter errorReporter) {
149
- final Set<UserDTO> selectedUsers = userSelectionModel.getSelectedSet();
150
- final Set<String> selectedUsernames = new HashSet<String>();
151
- selectedUsers.forEach((u) -> selectedUsernames.add(u.getName()));
152
- final boolean didConfirm = Window.confirm(stringMessages.doYouReallyWantToUnlockNUsers(selectedUsers.size()));
153
- if (didConfirm) {
154
- // run api, collect results
155
- final Set<String> successUserNames = new HashSet<String>();
156
- final Set<String> failureUserNames = new HashSet<String>();
157
- userManagementWriteService.unlockUsers(selectedUsernames, new AsyncCallback<Set<SuccessInfo>>() {
158
- @Override
159
- public void onSuccess(Set<SuccessInfo> result) {
160
- for (SuccessInfo si : result) {
161
- final String username = si.getExtra();
162
- if (si.isSuccessful()) {
163
- successUserNames.add(username);
164
- } else {
165
- failureUserNames.add(username);
166
- }
167
- }
168
- // update locked until entries for successful unlocks
169
- final LabeledAbstractFilterablePanel<UserDTO> filterField = userList.getFilterField();
170
- final List<UserDTO> allUsersWithUpdatedEntries = new ArrayList<UserDTO>();
171
- for (UserDTO user : filterField.getAll()) {
172
- final boolean didSucceed = successUserNames.contains(user.getName());
173
- if (didSucceed) {
174
- allUsersWithUpdatedEntries.add(user.copyWithTimePoint(null));
175
- } else {
176
- allUsersWithUpdatedEntries.add(user);
177
- }
178
- }
179
- filterField.updateAll(allUsersWithUpdatedEntries);
180
- // create alert dialog
181
- String text = "";
182
- if (successUserNames.size() != 0) {
183
- text += stringMessages.unlockedSuccessfully() + ":\n";
184
- for (String name : successUserNames) {
185
- text += " • " + name + "\n";
186
- }
187
- text += "\n";
188
- }
189
- if (failureUserNames.size() != 0) {
190
- text += stringMessages.failedToUnlock() + ":\n";
191
- for (String name : failureUserNames) {
192
- text += " • " + name + "\n";
193
- }
194
- }
195
- if(!text.equals("")) {
196
- Window.alert(text);
197
- }
198
- }
199
-
200
- @Override
201
- public void onFailure(Throwable caught) {
202
- errorReporter.reportError(stringMessages.failedToUnlock() + ": " + caught.getMessage());
203
- }
204
- });
205
- }
206
- }
207
-
208 140
/** shows the edit dialog if the user exists */
209 141
private void showRolesAndPermissionsEditDialog(UserService userService,
210 142
final CellTableWithCheckboxResources tableResources, final ErrorReporter errorReporter) {
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/client/usermanagement/UserTableWrapper.java
... ...
@@ -14,7 +14,6 @@ import java.util.Comparator;
14 14
import java.util.HashMap;
15 15
import java.util.Iterator;
16 16
import java.util.List;
17
-import java.util.function.Consumer;
18 17
19 18
import com.google.gwt.cell.client.SafeHtmlCell;
20 19
import com.google.gwt.core.client.Callback;
... ...
@@ -32,8 +31,6 @@ import com.sap.sse.common.Util;
32 31
import com.sap.sse.common.util.NaturalComparator;
33 32
import com.sap.sse.gwt.client.DateAndTimeFormatterUtil;
34 33
import com.sap.sse.gwt.client.ErrorReporter;
35
-import com.sap.sse.gwt.client.Notification;
36
-import com.sap.sse.gwt.client.Notification.NotificationType;
37 34
import com.sap.sse.gwt.client.celltable.AbstractSortableTextColumn;
38 35
import com.sap.sse.gwt.client.celltable.CellTableWithCheckboxResources;
39 36
import com.sap.sse.gwt.client.celltable.EntityIdentityComparator;
... ...
@@ -48,7 +45,6 @@ import com.sap.sse.security.shared.dto.RoleWithSecurityDTO;
48 45
import com.sap.sse.security.shared.dto.StrippedUserGroupDTO;
49 46
import com.sap.sse.security.shared.dto.UserDTO;
50 47
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
51
-import com.sap.sse.security.shared.impl.SecuredSecurityTypes.UserActions;
52 48
import com.sap.sse.security.ui.client.EntryPointLinkFactory;
53 49
import com.sap.sse.security.ui.client.UserManagementServiceAsync;
54 50
import com.sap.sse.security.ui.client.UserManagementWriteServiceAsync;
... ...
@@ -166,53 +162,12 @@ extends TableWrapper<UserDTO, S, StringMessages, TR> {
166 162
user->user.getLockedUntil() != null && user.getLockedUntil().after(TimePoint.now()) ?
167 163
DateAndTimeFormatterUtil.dateTimeMedium.render(user.getLockedUntil().asDate()) : "",
168 164
userColumnListHandler);
169
- final AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> userActionColumn = composeUserActionColumn(
170
- stringMessages, errorReporter);
171
- filterField = new LabeledAbstractFilterablePanel<UserDTO>(new Label(stringMessages.filterUsers()),
172
- new ArrayList<UserDTO>(), dataProvider, stringMessages) {
173
- @Override
174
- public Iterable<String> getSearchableStrings(UserDTO t) {
175
- List<String> strings = new ArrayList<>();
176
- strings.add(t.getName());
177
- strings.add(t.getFullName());
178
- strings.add(t.getEmail());
179
- strings.add(t.getCompany());
180
- Util.addAll(Util.map(t.getRoles(), RoleWithSecurityDTO::getName), strings);
181
- Util.addAll(Util.map(t.getUserGroups(), StrippedUserGroupDTO::getName), strings);
182
- return strings;
183
- }
184
-
185
- @Override
186
- public AbstractCellTable<UserDTO> getCellTable() {
187
- return table;
188
- }
189
- };
190
- registerSelectionModelOnNewDataProvider(filterField.getAllListDataProvider());
191
- filterField.setUpdatePermissionFilterForCheckbox(user -> userService.hasPermission(user, DefaultActions.UPDATE));
192
- mainPanel.insert(filterField, 0);
193
- table.addColumnSortHandler(userColumnListHandler);
194
- table.addColumn(usernameColumn, getStringMessages().username());
195
- table.addColumn(fullNameColumn, stringMessages.name());
196
- table.addColumn(emailColumn, stringMessages.email());
197
- table.addColumn(emailValidatedColumn, stringMessages.validated());
198
- table.addColumn(companyColumn, stringMessages.company());
199
- table.addColumn(groupsColumn, stringMessages.groups());
200
- table.addColumn(rolesColumn, stringMessages.roles());
201
- table.addColumn(permissionsColumn, stringMessages.permissions());
202
- table.addColumn(lockedUntilColumn, stringMessages.lockedUntil());
203
- SecuredDTOOwnerColumn.configureOwnerColumns(table, userColumnListHandler, stringMessages);
204
- table.addColumn(userActionColumn, stringMessages.actions());
205
- table.ensureDebugId("UsersTable");
206
- }
207
-
208
- private AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> composeUserActionColumn(
209
- StringMessages stringMessages, ErrorReporter errorReporter) {
210 165
final HasPermissions type = SecuredSecurityTypes.USER;
211 166
final AccessControlledActionsColumn<UserDTO, DefaultActionsImagesBarCell> userActionColumn = create(
212 167
new DefaultActionsImagesBarCell(stringMessages), userService);
213 168
userActionColumn.addAction(ACTION_UPDATE, UPDATE, user -> editUser(user));
214 169
userActionColumn.addAction(ACTION_DELETE, DELETE, user -> {
215
- if (Window.confirm(stringMessages.doYouReallyWantToDeleteUser(user.getName()))) {
170
+ if (Window.confirm(stringMessages.doYouReallyWantToRemoveUser(user.getName()))) {
216 171
getUserManagementWriteService().deleteUser(user.getName(), new AsyncCallback<SuccessInfo>() {
217 172
@Override
218 173
public void onFailure(Throwable caught) {
... ...
@@ -237,53 +192,47 @@ extends TableWrapper<UserDTO, S, StringMessages, TR> {
237 192
final EditOwnershipDialog.DialogConfig<UserDTO> configOwnership = EditOwnershipDialog.create(
238 193
userService.getUserManagementWriteService(), type,
239 194
user -> refreshUserList((Callback<Iterable<UserDTO>, Throwable>) null), stringMessages);
240
- userActionColumn.addAction(ACTION_CHANGE_OWNERSHIP, CHANGE_OWNERSHIP, configOwnership::openOwnershipDialog);
241 195
final EditACLDialog.DialogConfig<UserDTO> configACL = EditACLDialog.create(
242 196
userService.getUserManagementWriteService(), type,
243 197
user -> user.getAccessControlList(), stringMessages);
198
+ userActionColumn.addAction(ACTION_CHANGE_OWNERSHIP, CHANGE_OWNERSHIP, configOwnership::openOwnershipDialog);
244 199
userActionColumn.addAction(DefaultActionsImagesBarCell.ACTION_CHANGE_ACL, DefaultActions.CHANGE_ACL,
245 200
u -> configACL.openDialog(u));
246
- userActionColumn.addAction(
247
- DefaultActionsImagesBarCell.ACTION_MANAGE_LOCK,
248
- UserActions.MANAGE_LOCK,
249
- onManageLockPressed(stringMessages, errorReporter)
250
- );
251
- return userActionColumn;
252
- }
253
-
254
- private Consumer<UserDTO> onManageLockPressed(StringMessages stringMessages, ErrorReporter errorReporter) {
255
- return selectedUser -> {
256
- final boolean isLocked = selectedUser.getLockedUntil().after(TimePoint.now());
257
- if (isLocked) {
258
- final String userName = selectedUser.getName();
259
- final boolean didConfirm = Window.confirm(stringMessages.doYouReallyWantToUnlockUser(userName));
260
- if (didConfirm) {
261
- getUserManagementWriteService().unlockUser(userName, new AsyncCallback<SuccessInfo>() {
262
- @Override
263
- public void onSuccess(SuccessInfo result) {
264
- Notification.notify(stringMessages.unlockSucceededForUser(userName), NotificationType.SUCCESS);
265
- final List<UserDTO> usersWithUpdatedEntry = new ArrayList<UserDTO>();
266
- for (UserDTO user : getAllUsers()) {
267
- if (user.getFullName() == selectedUser.getFullName()) {
268
- usersWithUpdatedEntry.add(user.copyWithTimePoint(null));
269
- } else {
270
- usersWithUpdatedEntry.add(user);
271
- }
272
- }
273
- filterField.updateAll(usersWithUpdatedEntry);
274
- }
201
+ filterField = new LabeledAbstractFilterablePanel<UserDTO>(new Label(stringMessages.filterUsers()),
202
+ new ArrayList<UserDTO>(), dataProvider, stringMessages) {
203
+ @Override
204
+ public Iterable<String> getSearchableStrings(UserDTO t) {
205
+ List<String> strings = new ArrayList<>();
206
+ strings.add(t.getName());
207
+ strings.add(t.getFullName());
208
+ strings.add(t.getEmail());
209
+ strings.add(t.getCompany());
210
+ Util.addAll(Util.map(t.getRoles(), RoleWithSecurityDTO::getName), strings);
211
+ Util.addAll(Util.map(t.getUserGroups(), StrippedUserGroupDTO::getName), strings);
212
+ return strings;
213
+ }
275 214
276
- @Override
277
- public void onFailure(Throwable caught) {
278
- Notification.notify(stringMessages.unlockFailedForUser(userName), NotificationType.ERROR);
279
- errorReporter.reportError(caught.getMessage());
280
- }
281
- });
282
- }
283
- } else {
284
- Notification.notify(stringMessages.userIsAlreadyUnlocked(), NotificationType.INFO);
215
+ @Override
216
+ public AbstractCellTable<UserDTO> getCellTable() {
217
+ return table;
285 218
}
286 219
};
220
+ registerSelectionModelOnNewDataProvider(filterField.getAllListDataProvider());
221
+ filterField.setUpdatePermissionFilterForCheckbox(user -> userService.hasPermission(user, DefaultActions.UPDATE));
222
+ mainPanel.insert(filterField, 0);
223
+ table.addColumnSortHandler(userColumnListHandler);
224
+ table.addColumn(usernameColumn, getStringMessages().username());
225
+ table.addColumn(fullNameColumn, stringMessages.name());
226
+ table.addColumn(emailColumn, stringMessages.email());
227
+ table.addColumn(emailValidatedColumn, stringMessages.validated());
228
+ table.addColumn(companyColumn, stringMessages.company());
229
+ table.addColumn(groupsColumn, stringMessages.groups());
230
+ table.addColumn(rolesColumn, stringMessages.roles());
231
+ table.addColumn(permissionsColumn, stringMessages.permissions());
232
+ table.addColumn(lockedUntilColumn, stringMessages.lockedUntil());
233
+ SecuredDTOOwnerColumn.configureOwnerColumns(table, userColumnListHandler, stringMessages);
234
+ table.addColumn(userActionColumn, stringMessages.actions());
235
+ table.ensureDebugId("UsersTable");
287 236
}
288 237
289 238
public Iterable<UserDTO> getAllUsers() {
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/SecurityDTOFactory.java
... ...
@@ -97,7 +97,7 @@ public class SecurityDTOFactory {
97 97
/* default tenant filled in later */ null,
98 98
getSecuredPermissions(filteredPermissions, user, securityService),
99 99
createStrippedUserGroupDTOsFromUserGroups(securityService.getUserGroupsOfUser(user),
100
- fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup), user.getTimedLock().getLockedUntil());
100
+ fromOriginalToStrippedDownUser, fromOriginalToStrippedDownUserGroup),
101 101
user.getLockingAndBanning().getLockedUntil());
102 102
userDTO.setDefaultTenantForCurrentServer(createStrippedUserGroupDTOFromUserGroup(
103 103
securityService.getDefaultTenantForCurrentUser(),
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementServiceImpl.java
... ...
@@ -26,7 +26,6 @@ import com.google.gwt.user.server.rpc.RemoteServiceServlet;
26 26
import com.sap.sse.ServerInfo;
27 27
import com.sap.sse.branding.BrandingConfigurationService;
28 28
import com.sap.sse.branding.shared.BrandingConfiguration;
29
-import com.sap.sse.common.TimedLock;
30 29
import com.sap.sse.common.Util;
31 30
import com.sap.sse.common.Util.Pair;
32 31
import com.sap.sse.common.Util.Triple;
... ...
@@ -37,7 +36,6 @@ import com.sap.sse.security.interfaces.Credential;
37 36
import com.sap.sse.security.shared.AccessControlListAnnotation;
38 37
import com.sap.sse.security.shared.HasPermissions;
39 38
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
40
-import com.sap.sse.security.shared.IPAddress;
41 39
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
42 40
import com.sap.sse.security.shared.TypeRelativeObjectIdentifier;
43 41
import com.sap.sse.security.shared.UnauthorizedException;
... ...
@@ -61,7 +59,6 @@ import com.sap.sse.security.shared.impl.UserGroup;
61 59
import com.sap.sse.security.ui.client.SerializationDummy;
62 60
import com.sap.sse.security.ui.client.UserManagementService;
63 61
import com.sap.sse.security.ui.oauth.client.CredentialDTO;
64
-import com.sap.sse.security.ui.shared.IpToTimedLockDTO;
65 62
import com.sap.sse.security.ui.shared.SecurityServiceSharingDTO;
66 63
import com.sap.sse.security.ui.shared.SuccessInfo;
67 64
import com.sap.sse.util.ServiceTrackerFactory;
... ...
@@ -438,25 +435,4 @@ public class UserManagementServiceImpl extends RemoteServiceServlet implements U
438 435
private BrandingConfigurationService getBrandingConfigurationService() {
439 436
return brandingConfigurationServiceTracker.getService();
440 437
}
441
-
442
- @Override
443
- public ArrayList<IpToTimedLockDTO> getClientIPBasedTimedLocksForUserCreation() throws UnauthorizedException {
444
- final HashMap<String, TimedLock> ipToLockMap = getSecurityService().getClientIPBasedTimedLocksForUserCreation();
445
- return filterIpToTimedLockTableByCurrentUserReadPermission(ipToLockMap);
446
- }
447
-
448
- private ArrayList<IpToTimedLockDTO> filterIpToTimedLockTableByCurrentUserReadPermission(
449
- final HashMap<String, TimedLock> ipToLockMap) {
450
- final SecurityService securityService = getSecurityService();
451
- return Util.mapToArrayList(
452
- Util.filter(ipToLockMap.entrySet(),
453
- e->securityService.hasCurrentUserReadPermission(new IPAddress(e.getKey()))),
454
- e->new IpToTimedLockDTO(e.getKey(), e.getValue()));
455
- }
456
-
457
- @Override
458
- public ArrayList<IpToTimedLockDTO> getClientIPBasedTimedLocksForBearerTokenAbuse() throws UnauthorizedException {
459
- final HashMap<String, TimedLock> ipToLockMap = getSecurityService().getClientIPBasedTimedLocksForBearerTokenAbuse();
460
- return filterIpToTimedLockTableByCurrentUserReadPermission(ipToLockMap);
461
- }
462 438
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/server/UserManagementWriteServiceImpl.java
... ...
@@ -23,7 +23,6 @@ import com.sap.sse.common.media.TakedownNoticeRequestContext;
23 23
import com.sap.sse.security.Action;
24 24
import com.sap.sse.security.SecurityService;
25 25
import com.sap.sse.security.shared.HasPermissions.DefaultActions;
26
-import com.sap.sse.security.shared.IPAddress;
27 26
import com.sap.sse.security.shared.PermissionChecker;
28 27
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
29 28
import com.sap.sse.security.shared.RoleDefinition;
... ...
@@ -375,38 +374,6 @@ public class UserManagementWriteServiceImpl extends UserManagementServiceImpl im
375 374
return new SuccessInfo(false, "Could not delete user.", /* redirectURL */ null, null);
376 375
}
377 376
}
378
-
379
- @Override
380
- public SuccessInfo unlockUser(String username) throws UnauthorizedException {
381
- User user = getSecurityService().getUserByName(username);
382
- if (user != null) {
383
- if (!getSecurityService().hasCurrentUserExplicitPermissions(user, UserActions.MANAGE_LOCK)) {
384
- logger.info("You are not permitted to manage locking on user " + username);
385
- return new SuccessInfo(false, "You are not permitted to manage locking on user " + username,
386
- /* redirectURL */ null, null, username);
387
- }
388
- try {
389
- getSecurityService().resetUserTimedLock(username);
390
- logger.info("Reset lock on user: " + username + ".");
391
- return new SuccessInfo(true, "Reset lock on user: " + username + ".", /* redirectURL */ null, null, username);
392
- } catch (UserManagementException e) {
393
- logger.info("Could not reset lock on user: " + username + ".");
394
- return new SuccessInfo(false, "Could not reset lock on user " + username, /* redirectURL */ null, null, username);
395
- }
396
- } else {
397
- logger.info("Could not reset lock on user: " + username + ".");
398
- return new SuccessInfo(false, "Could not reset lock on user " + username, /* redirectURL */ null, null, username);
399
- }
400
- }
401
-
402
- @Override
403
- public Set<SuccessInfo> unlockUsers(Set<String> usernames) throws UnauthorizedException {
404
- final Set<SuccessInfo> result = new HashSet<>();
405
- for (String username : usernames) {
406
- result.add(unlockUser(username));
407
- }
408
- return result;
409
- }
410 377
411 378
@Override
412 379
public Set<SuccessInfo> deleteUsers(Set<String> usernames) throws UnauthorizedException {
... ...
@@ -742,24 +709,4 @@ public class UserManagementWriteServiceImpl extends UserManagementServiceImpl im
742 709
public void fileTakedownNotice(TakedownNoticeRequestContext takedownNoticeRequestContext) throws MailException {
743 710
getSecurityService().fileTakedownNotice(takedownNoticeRequestContext);
744 711
}
745
-
746
- @Override
747
- public void releaseUserCreationLockOnIp(String ip) throws UnauthorizedException {
748
- final SecurityService securityService = getSecurityService();
749
- final WildcardPermission deletePermission = SecuredSecurityTypes.LOCKED_IP
750
- .getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
751
- // throws exception if not permitted
752
- SecurityUtils.getSubject().checkPermission(deletePermission.toString());
753
- securityService.releaseUserCreationLockOnIp(ip);
754
- }
755
-
756
- @Override
757
- public void releaseBearerTokenLockOnIp(String ip) throws UnauthorizedException {
758
- final SecurityService securityService = getSecurityService();
759
- final WildcardPermission deletePermission = SecuredSecurityTypes.LOCKED_IP
760
- .getPermissionForObject(DefaultActions.DELETE, new IPAddress(ip));
761
- // throws exception if not permitted
762
- SecurityUtils.getSubject().checkPermission(deletePermission.toString());
763
- securityService.releaseBearerTokenLockOnIp(ip);
764
- }
765 712
}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/IpToTimedLockDTO.java
... ...
@@ -1,28 +0,0 @@
1
-package com.sap.sse.security.ui.shared;
2
-
3
-import com.sap.sse.common.TimedLock;
4
-import com.sap.sse.common.Named;
5
-
6
-public class IpToTimedLockDTO implements Named {
7
- private static final long serialVersionUID = 7877190394556881643L;
8
- private final String ip;
9
- private final TimedLock timedLock;
10
-
11
- public IpToTimedLockDTO(final String ip, final TimedLock timedLock) {
12
- this.ip = ip;
13
- this.timedLock = timedLock;
14
- }
15
-
16
- @Override
17
- public String getName() {
18
- return "IpToTimedLockDTO";
19
- }
20
-
21
- public String getIp() {
22
- return ip;
23
- }
24
-
25
- public TimedLock getTimedLock() {
26
- return timedLock;
27
- }
28
-}
java/com.sap.sse.security.ui/src/main/java/com/sap/sse/security/ui/shared/SuccessInfo.java
... ...
@@ -15,7 +15,6 @@ public class SuccessInfo implements IsSerializable {
15 15
private String message;
16 16
private Triple<UserDTO, UserDTO, ServerInfoDTO> userDTO;
17 17
private String redirectURL;
18
- private String extra;
19 18
20 19
SuccessInfo() {} // for serializtion only
21 20
... ...
@@ -26,15 +25,6 @@ public class SuccessInfo implements IsSerializable {
26 25
this.redirectURL = redirectURL;
27 26
this.userDTO = userDTO;
28 27
}
29
-
30
- public SuccessInfo(boolean successful, String message, String redirectURL, Triple<UserDTO, UserDTO, ServerInfoDTO> userDTO, String extra) {
31
- super();
32
- this.successful = successful;
33
- this.message = message;
34
- this.redirectURL = redirectURL;
35
- this.userDTO = userDTO;
36
- this.extra = extra;
37
- }
38 28
39 29
public boolean isSuccessful() {
40 30
return successful;
... ...
@@ -47,12 +37,9 @@ public class SuccessInfo implements IsSerializable {
47 37
public Triple<UserDTO, UserDTO, ServerInfoDTO> getUserDTO() {
48 38
return userDTO;
49 39
}
50
-
40
+
51 41
public String getRedirectURL() {
52 42
return redirectURL;
53 43
}
54
-
55
- public String getExtra() {
56
- return extra;
57
- }
44
+
58 45
}
java/com.sap.sse.security.ui/src/main/resources/com/sap/sse/security/SSESecuritySerializers.gwt.xml
... ...
@@ -1,6 +1,5 @@
1 1
<?xml version="1.0" encoding="UTF-8"?>
2 2
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.7.0//EN" "http://gwtproject.org/doctype/2.7.0/gwt-module.dtd">
3 3
<module>
4
- <inherits name="com.sap.sse.SSECommon" />
5 4
<source path='shared'/>
6 5
</module>
java/com.sap.sse.security.ui/src/main/resources/com/sap/sse/security/ui/Login.gwt.xml
... ...
@@ -7,8 +7,6 @@
7 7
<inherits name="com.sap.sse.security.ui.SecurityLocalesAllPermutations" />
8 8
<inherits name="com.sap.sse.security.ui.LoginPanel"/>
9 9
<inherits name="com.sap.sse.landscape.aws.common.SSELandscapeAWSCommon" />
10
- <inherits name="com.sap.sse.gwt.SSESharedGWT" />
11
- <inherits name="com.sap.sse.branding.SSEBranding" />
12 10
13 11
<!-- Specify the app entry point class. -->
14 12
<entry-point class='com.sap.sse.security.ui.login.LoginEntryPoint'/>
java/com.sap.sse.security.ui/src/main/resources/com/sap/sse/security/ui/Register.gwt.xml
... ...
@@ -11,8 +11,6 @@
11 11
<inherits name="com.sap.sse.Security" />
12 12
<inherits name="com.sap.sse.security.ui.SecurityLocalesAllPermutations" />
13 13
<inherits name="com.sap.sse.security.SSESecuritySerializers" />
14
- <inherits name="com.sap.sse.gwt.SSESharedGWT" />
15
- <inherits name="com.sap.sse.branding.SSEBranding" />
16 14
<inherits name="com.sap.sse.landscape.aws.common.SSELandscapeAWSCommon" />
17 15
18 16
<super-source path="jre" />
java/com.sap.sse.security.ui/src/main/resources/shiro.ini
... ...
@@ -24,7 +24,7 @@ securityManager.sessionManager.sessionDAO = $sessionDAO
24 24
securityManager.sessionManager.globalSessionTimeout = 31536000000
25 25
cacheManager = com.sap.sse.security.SessionCacheManager
26 26
securityManager.cacheManager = $cacheManager
27
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
27
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
28 28
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
29 29
30 30
subjectDAO = com.sap.sse.security.NoSessionStorageForUnauthenticatedSessionsSessionDAO
java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/UserStoreImpl.java
... ...
@@ -14,7 +14,6 @@ import java.util.concurrent.ConcurrentHashMap;
14 14
import java.util.logging.Level;
15 15
import java.util.logging.Logger;
16 16
17
-import com.sap.sse.common.TimedLock;
18 17
import com.sap.sse.common.Util;
19 18
import com.sap.sse.common.Util.Pair;
20 19
import com.sap.sse.concurrent.LockUtil;
... ...
@@ -35,6 +34,7 @@ import com.sap.sse.security.shared.UserManagementException;
35 34
import com.sap.sse.security.shared.UserRole;
36 35
import com.sap.sse.security.shared.UserStoreManagementException;
37 36
import com.sap.sse.security.shared.WildcardPermission;
37
+import com.sap.sse.security.shared.impl.LockingAndBanning;
38 38
import com.sap.sse.security.shared.impl.Ownership;
39 39
import com.sap.sse.security.shared.impl.Role;
40 40
import com.sap.sse.security.shared.impl.User;
... ...
@@ -854,12 +854,12 @@ public class UserStoreImpl implements UserStore {
854 854
}
855 855
856 856
@Override
857
- public User createUser(String name, String email, TimedLock timedLock, Account... accounts)
857
+ public User createUser(String name, String email, LockingAndBanning lockingAndBanning, Account... accounts)
858 858
throws UserManagementException {
859 859
return LockUtil.executeWithWriteLockAndResultExpectException(usersLock, () -> {
860 860
checkUsernameUniqueness(name);
861 861
final Map<String, UserGroup> tenantsForServer = new ConcurrentHashMap<>();
862
- final User user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, timedLock, accounts);
862
+ final User user = new UserImpl(name, email, tenantsForServer, /* user group provider */ this, lockingAndBanning, accounts);
863 863
logger.info("Creating user: " + user + " with e-mail " + email);
864 864
addAndStoreUserInternal(user);
865 865
return user;
java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/DomainObjectFactoryImpl.java
... ...
@@ -20,9 +20,7 @@ import com.mongodb.client.MongoCollection;
20 20
import com.mongodb.client.MongoDatabase;
21 21
import com.sap.sse.common.Duration;
22 22
import com.sap.sse.common.TimePoint;
23
-import com.sap.sse.common.TimedLock;
24 23
import com.sap.sse.common.Util;
25
-import com.sap.sse.common.impl.TimedLockImpl;
26 24
import com.sap.sse.security.interfaces.Social;
27 25
import com.sap.sse.security.interfaces.UserImpl;
28 26
import com.sap.sse.security.interfaces.UserStore;
... ...
@@ -39,6 +37,8 @@ import com.sap.sse.security.shared.UserManagementException;
39 37
import com.sap.sse.security.shared.UsernamePasswordAccount;
40 38
import com.sap.sse.security.shared.WildcardPermission;
41 39
import com.sap.sse.security.shared.impl.AccessControlList;
40
+import com.sap.sse.security.shared.impl.LockingAndBanning;
41
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
42 42
import com.sap.sse.security.shared.impl.Ownership;
43 43
import com.sap.sse.security.shared.impl.QualifiedObjectIdentifierImpl;
44 44
import com.sap.sse.security.shared.impl.Role;
... ...
@@ -291,9 +291,9 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
291 291
final String validationSecret = (String) userDBObject.get(FieldNames.User.VALIDATION_SECRET.name());
292 292
final Long lockedUntilMillis = userDBObject.getLong(FieldNames.User.LOCKED_UNTIL_MILLIS.name());
293 293
final Long nextLockingDurationMillis = userDBObject.getLong(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name());
294
- final TimedLock timedLock = new TimedLockImpl(
294
+ final LockingAndBanning lockingAndBanning = new LockingAndBanningImpl(
295 295
lockedUntilMillis == null ? TimePoint.BeginningOfTime : TimePoint.of(lockedUntilMillis),
296
- nextLockingDurationMillis == null ? TimedLockImpl.DEFAULT_INITIAL_LOCKING_DELAY : Duration.ofMillis(nextLockingDurationMillis));
296
+ nextLockingDurationMillis == null ? LockingAndBanningImpl.DEFAULT_INITIAL_LOCKING_DELAY : Duration.ofMillis(nextLockingDurationMillis));
297 297
final Set<Role> roles = new HashSet<>();
298 298
final Set<String> permissions = new HashSet<>();
299 299
final List<?> rolesO = (List<?>) userDBObject.get(FieldNames.User.ROLE_IDS.name());
... ...
@@ -360,7 +360,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
360 360
Map<AccountType, Account> accounts = createAccountMapFromdDBObject(accountsMap);
361 361
User result = new UserImpl(username, email, fullName, company, locale,
362 362
emailValidated == null ? false : emailValidated, didOptOutOfMarketingEmails, passwordResetSecret,
363
- accounts.values(), userGroupProvider, timedLock);
363
+ validationSecret, defaultTenant, accounts.values(), userGroupProvider, lockingAndBanning);
364 364
for (final Role role : roles) {
365 365
result.addRole(role);
366 366
}
java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/MongoObjectFactoryImpl.java
... ...
@@ -16,7 +16,6 @@ import com.mongodb.client.MongoCollection;
16 16
import com.mongodb.client.MongoDatabase;
17 17
import com.mongodb.client.model.IndexOptions;
18 18
import com.mongodb.client.model.ReplaceOptions;
19
-import com.sap.sse.common.impl.TimedLockImpl;
20 19
import com.sap.sse.security.interfaces.Social;
21 20
import com.sap.sse.security.shared.AccessControlListAnnotation;
22 21
import com.sap.sse.security.shared.Account;
... ...
@@ -28,6 +27,7 @@ import com.sap.sse.security.shared.SocialUserAccount;
28 27
import com.sap.sse.security.shared.UsernamePasswordAccount;
29 28
import com.sap.sse.security.shared.WildcardPermission;
30 29
import com.sap.sse.security.shared.impl.AccessControlList;
30
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
31 31
import com.sap.sse.security.shared.impl.Ownership;
32 32
import com.sap.sse.security.shared.impl.Role;
33 33
import com.sap.sse.security.shared.impl.User;
... ...
@@ -217,13 +217,13 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
217 217
dbUser.put(FieldNames.User.PASSWORD_RESET_SECRET.name(), user.getPasswordResetSecret());
218 218
dbUser.put(FieldNames.User.VALIDATION_SECRET.name(), user.getValidationSecret());
219 219
dbUser.put(FieldNames.User.ACCOUNTS.name(), createAccountMapObject(user.getAllAccounts()));
220
- if (user.getTimedLock() instanceof TimedLockImpl) {
221
- final TimedLockImpl timedLock = ((TimedLockImpl) user.getTimedLock());
222
- dbUser.put(FieldNames.User.LOCKED_UNTIL_MILLIS.name(), timedLock.getLockedUntil().asMillis());
223
- dbUser.put(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name(), timedLock.getNextLockingDelay().asMillis());
220
+ if (user.getLockingAndBanning() instanceof LockingAndBanningImpl) {
221
+ final LockingAndBanningImpl lockingAndBanning = ((LockingAndBanningImpl) user.getLockingAndBanning());
222
+ dbUser.put(FieldNames.User.LOCKED_UNTIL_MILLIS.name(), lockingAndBanning.getLockedUntil().asMillis());
223
+ dbUser.put(FieldNames.User.NEXT_LOCKING_DURATION_MILLIS.name(), lockingAndBanning.getNextLockingDelay().asMillis());
224 224
} else {
225
- logger.warning("Expected user locking/banning to be of type "+TimedLockImpl.class.getSimpleName()
226
- +" but was of type "+user.getTimedLock().getClass().getSimpleName()+"; not storing to DB");
225
+ logger.warning("Expected user locking/banning to be of type "+LockingAndBanningImpl.class.getSimpleName()
226
+ +" but was of type "+user.getLockingAndBanning().getClass().getSimpleName()+"; not storing to DB");
227 227
}
228 228
BasicDBList dbRoles = new BasicDBList();
229 229
for (Role role : user.getRoles()) {
java/com.sap.sse.security.userstore.mongodb/src/com/sap/sse/security/userstore/mongodb/impl/UserProxy.java
... ...
@@ -4,13 +4,13 @@ import java.io.Serializable;
4 4
import java.util.Locale;
5 5
import java.util.Map;
6 6
7
-import com.sap.sse.common.TimedLock;
8 7
import com.sap.sse.security.shared.Account;
9 8
import com.sap.sse.security.shared.Account.AccountType;
10 9
import com.sap.sse.security.shared.HasPermissions;
11 10
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
12 11
import com.sap.sse.security.shared.UserGroupProvider;
13 12
import com.sap.sse.security.shared.WildcardPermission;
13
+import com.sap.sse.security.shared.impl.LockingAndBanning;
14 14
import com.sap.sse.security.shared.impl.Role;
15 15
import com.sap.sse.security.shared.impl.User;
16 16
import com.sap.sse.security.shared.impl.UserGroup;
... ...
@@ -242,7 +242,7 @@ public class UserProxy implements User {
242 242
}
243 243
244 244
@Override
245
- public TimedLock getTimedLock() {
245
+ public LockingAndBanning getLockingAndBanning() {
246 246
throw new UnsupportedOperationException();
247 247
}
248 248
java/com.sap.sse.security/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
java/com.sap.sse.security/src/com/sap/sse/security/AtLeastOneSuccessfulStrategyWithLockingAndBanning.java
... ...
@@ -0,0 +1,103 @@
1
+package com.sap.sse.security;
2
+
3
+import java.util.concurrent.ExecutionException;
4
+import java.util.concurrent.Future;
5
+import java.util.logging.Level;
6
+import java.util.logging.Logger;
7
+
8
+import org.apache.shiro.authc.AuthenticationException;
9
+import org.apache.shiro.authc.AuthenticationInfo;
10
+import org.apache.shiro.authc.AuthenticationToken;
11
+import org.apache.shiro.authc.IncorrectCredentialsException;
12
+import org.apache.shiro.authc.LockedAccountException;
13
+import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
14
+import org.apache.shiro.realm.Realm;
15
+
16
+import com.sap.sse.security.impl.Activator;
17
+import com.sap.sse.security.shared.impl.LockingAndBanning;
18
+import com.sap.sse.security.shared.impl.User;
19
+import com.sap.sse.util.ServiceTrackerFactory;
20
+
21
+public class AtLeastOneSuccessfulStrategyWithLockingAndBanning extends AtLeastOneSuccessfulStrategy {
22
+ private static final Logger logger = Logger.getLogger(AtLeastOneSuccessfulStrategyWithLockingAndBanning.class.getName());
23
+
24
+ private final Future<SecurityService> securityService;
25
+
26
+ public AtLeastOneSuccessfulStrategyWithLockingAndBanning() {
27
+ if (Activator.getContext() != null) {
28
+ securityService = ServiceTrackerFactory.createServiceFuture(Activator.getContext(), SecurityService.class);
29
+ } else {
30
+ securityService = null;
31
+ }
32
+ }
33
+
34
+ private SecurityService getSecurityService() {
35
+ SecurityService result;
36
+ try {
37
+ result = securityService == null ? null : securityService.get();
38
+ } catch (InterruptedException | ExecutionException e) {
39
+ logger.log(Level.SEVERE, "Error retrieving security service", e);
40
+ result = null;
41
+ }
42
+ return result;
43
+ }
44
+
45
+ @Override
46
+ public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo,
47
+ AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
48
+ if (token != null && token.getPrincipal() != null && realm instanceof UsernamePasswordRealm) {
49
+ final UsernamePasswordRealm upRealm = (UsernamePasswordRealm) realm;
50
+ final String username = token.getPrincipal().toString();
51
+ final User user = upRealm.getUserStore().getUserByName(username);
52
+ if (user != null) {
53
+ if (t != null) {
54
+ if (t instanceof IncorrectCredentialsException) {
55
+ logger.info("failed password authentication for user "+username);
56
+ final SecurityService mySecurityService = getSecurityService();
57
+ if (mySecurityService != null) {
58
+ final LockingAndBanning lockingAndBanning = mySecurityService.failedPasswordAuthentication(user);
59
+ if (lockingAndBanning != null) {
60
+ logger.info("User "+username+" locked for password authentication: "+lockingAndBanning);
61
+ }
62
+ } else {
63
+ logger.warning("Account locking due to failed password authentication for user "+username+" not possible; security service not found");
64
+ }
65
+ }
66
+ } else {
67
+ // no exception, so the authentication must have been successful
68
+ final SecurityService mySecurityService = getSecurityService();
69
+ if (mySecurityService != null) {
70
+ mySecurityService.successfulPasswordAuthentication(user);
71
+ }
72
+ }
73
+ }
74
+ } else if (token != null && realm instanceof BearerTokenRealm) {
75
+ final BearerAuthenticationToken bearerToken = (BearerAuthenticationToken) token;
76
+ if (singleRealmInfo == null || singleRealmInfo.getPrincipals().isEmpty()) {
77
+ if (t != null && t instanceof LockedAccountException) {
78
+ logger.fine(()->"Bearer token authentication from client IP "+bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent()+" currently locked");
79
+ } else {
80
+ // authentication failed
81
+ logger.info("failed bearer token authentication for client IP "+bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent());
82
+ final SecurityService mySecurityService = getSecurityService();
83
+ if (mySecurityService != null) {
84
+ final LockingAndBanning lockingAndBanning = mySecurityService.failedBearerTokenAuthentication(bearerToken.getClientIP());
85
+ if (lockingAndBanning != null) {
86
+ logger.info("Client IP "+bearerToken.getClientIP()+" locked for bearer token authentication: "+lockingAndBanning);
87
+ }
88
+ } else {
89
+ logger.warning("Client IP locking due to failed bearer token authentication for client IP "
90
+ +bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent()
91
+ +" not possible; security service not found");
92
+ }
93
+ }
94
+ } else { // valid authentication info means authentication was successful
95
+ final SecurityService mySecurityService = getSecurityService();
96
+ if (mySecurityService != null) {
97
+ mySecurityService.successfulBearerTokenAuthentication(bearerToken.getClientIP());
98
+ }
99
+ }
100
+ }
101
+ return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);
102
+ }
103
+}
java/com.sap.sse.security/src/com/sap/sse/security/AtLeastOneSuccessfulStrategyWithTimedLocks.java
... ...
@@ -1,103 +0,0 @@
1
-package com.sap.sse.security;
2
-
3
-import java.util.concurrent.ExecutionException;
4
-import java.util.concurrent.Future;
5
-import java.util.logging.Level;
6
-import java.util.logging.Logger;
7
-
8
-import org.apache.shiro.authc.AuthenticationException;
9
-import org.apache.shiro.authc.AuthenticationInfo;
10
-import org.apache.shiro.authc.AuthenticationToken;
11
-import org.apache.shiro.authc.IncorrectCredentialsException;
12
-import org.apache.shiro.authc.LockedAccountException;
13
-import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
14
-import org.apache.shiro.realm.Realm;
15
-
16
-import com.sap.sse.common.TimedLock;
17
-import com.sap.sse.security.impl.Activator;
18
-import com.sap.sse.security.shared.impl.User;
19
-import com.sap.sse.util.ServiceTrackerFactory;
20
-
21
-public class AtLeastOneSuccessfulStrategyWithTimedLocks extends AtLeastOneSuccessfulStrategy {
22
- private static final Logger logger = Logger.getLogger(AtLeastOneSuccessfulStrategyWithTimedLocks.class.getName());
23
-
24
- private final Future<SecurityService> securityService;
25
-
26
- public AtLeastOneSuccessfulStrategyWithTimedLocks() {
27
- if (Activator.getContext() != null) {
28
- securityService = ServiceTrackerFactory.createServiceFuture(Activator.getContext(), SecurityService.class);
29
- } else {
30
- securityService = null;
31
- }
32
- }
33
-
34
- private SecurityService getSecurityService() {
35
- SecurityService result;
36
- try {
37
- result = securityService == null ? null : securityService.get();
38
- } catch (InterruptedException | ExecutionException e) {
39
- logger.log(Level.SEVERE, "Error retrieving security service", e);
40
- result = null;
41
- }
42
- return result;
43
- }
44
-
45
- @Override
46
- public AuthenticationInfo afterAttempt(Realm realm, AuthenticationToken token, AuthenticationInfo singleRealmInfo,
47
- AuthenticationInfo aggregateInfo, Throwable t) throws AuthenticationException {
48
- if (token != null && token.getPrincipal() != null && realm instanceof UsernamePasswordRealm) {
49
- final UsernamePasswordRealm upRealm = (UsernamePasswordRealm) realm;
50
- final String username = token.getPrincipal().toString();
51
- final User user = upRealm.getUserStore().getUserByName(username);
52
- if (user != null) {
53
- if (t != null) {
54
- if (t instanceof IncorrectCredentialsException) {
55
- logger.info("failed password authentication for user "+username);
56
- final SecurityService mySecurityService = getSecurityService();
57
- if (mySecurityService != null) {
58
- final TimedLock timedLock = mySecurityService.failedPasswordAuthentication(user);
59
- if (timedLock != null) {
60
- logger.info("User "+username+" locked for password authentication: "+timedLock);
61
- }
62
- } else {
63
- logger.warning("Account locking due to failed password authentication for user "+username+" not possible; security service not found");
64
- }
65
- }
66
- } else {
67
- // no exception, so the authentication must have been successful
68
- final SecurityService mySecurityService = getSecurityService();
69
- if (mySecurityService != null) {
70
- mySecurityService.successfulPasswordAuthentication(user);
71
- }
72
- }
73
- }
74
- } else if (token != null && realm instanceof BearerTokenRealm) {
75
- final BearerAuthenticationToken bearerToken = (BearerAuthenticationToken) token;
76
- if (singleRealmInfo == null || singleRealmInfo.getPrincipals().isEmpty()) {
77
- if (t != null && t instanceof LockedAccountException) {
78
- logger.fine(()->"Bearer token authentication from client IP "+bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent()+" currently locked");
79
- } else {
80
- // authentication failed
81
- logger.info("failed bearer token authentication for client IP "+bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent());
82
- final SecurityService mySecurityService = getSecurityService();
83
- if (mySecurityService != null) {
84
- final TimedLock timedLock = mySecurityService.failedBearerTokenAuthentication(bearerToken.getClientIP());
85
- if (timedLock != null) {
86
- logger.info("Client IP "+bearerToken.getClientIP()+" locked for bearer token authentication: "+timedLock);
87
- }
88
- } else {
89
- logger.warning("Client IP locking due to failed bearer token authentication for client IP "
90
- +bearerToken.getClientIP()+" with user agent "+bearerToken.getUserAgent()
91
- +" not possible; security service not found");
92
- }
93
- }
94
- } else { // valid authentication info means authentication was successful
95
- final SecurityService mySecurityService = getSecurityService();
96
- if (mySecurityService != null) {
97
- mySecurityService.successfulBearerTokenAuthentication(bearerToken.getClientIP());
98
- }
99
- }
100
- }
101
- return super.afterAttempt(realm, token, singleRealmInfo, aggregateInfo, t);
102
- }
103
-}
java/com.sap.sse.security/src/com/sap/sse/security/OAuthRealm.java
... ...
@@ -33,7 +33,6 @@ import org.scribe.model.Verb;
33 33
import org.scribe.model.Verifier;
34 34
import org.scribe.oauth.OAuthService;
35 35
36
-import com.sap.sse.common.impl.TimedLockImpl;
37 36
import com.sap.sse.security.interfaces.Credential;
38 37
import com.sap.sse.security.interfaces.OAuthToken;
39 38
import com.sap.sse.security.interfaces.Social;
... ...
@@ -41,6 +40,7 @@ import com.sap.sse.security.interfaces.SocialSettingsKeys;
41 40
import com.sap.sse.security.shared.SocialUserAccount;
42 41
import com.sap.sse.security.shared.UserGroupManagementException;
43 42
import com.sap.sse.security.shared.UserManagementException;
43
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
44 44
import com.sap.sse.security.shared.impl.User;
45 45
import com.sap.sse.security.shared.impl.UserGroup;
46 46
... ...
@@ -189,7 +189,7 @@ public class OAuthRealm extends AbstractCompositeAuthorizingRealm {
189 189
try {
190 190
UserGroup tenant = getUserStore().createUserGroup(UUID.randomUUID(), socialname + SecurityService.TENANT_SUFFIX);
191 191
getAccessControlStore().setOwnership(tenant.getIdentifier(), user, tenant, tenant.getName());
192
- user = getUserStore().createUser(socialname, socialUser.getProperty(Social.EMAIL.name()), new TimedLockImpl(), socialUser);
192
+ user = getUserStore().createUser(socialname, socialUser.getProperty(Social.EMAIL.name()), new LockingAndBanningImpl(), socialUser);
193 193
tenant.add(user);
194 194
getUserStore().updateUserGroup(tenant);
195 195
} catch (UserManagementException | UserGroupManagementException e) {
java/com.sap.sse.security/src/com/sap/sse/security/SecurityService.java
... ...
@@ -2,7 +2,6 @@ package com.sap.sse.security;
2 2
3 3
import java.io.Serializable;
4 4
import java.math.BigDecimal;
5
-import java.util.HashMap;
6 5
import java.util.List;
7 6
import java.util.Locale;
8 7
import java.util.Map;
... ...
@@ -23,7 +22,6 @@ import org.apache.shiro.subject.Subject;
23 22
import org.osgi.framework.BundleContext;
24 23
25 24
import com.sap.sse.common.Duration;
26
-import com.sap.sse.common.TimedLock;
27 25
import com.sap.sse.common.Util;
28 26
import com.sap.sse.common.Util.Pair;
29 27
import com.sap.sse.common.http.HttpHeaderUtil;
... ...
@@ -55,6 +53,7 @@ import com.sap.sse.security.shared.UserManagementException;
55 53
import com.sap.sse.security.shared.WildcardPermission;
56 54
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
57 55
import com.sap.sse.security.shared.impl.AccessControlList;
56
+import com.sap.sse.security.shared.impl.LockingAndBanning;
58 57
import com.sap.sse.security.shared.impl.Ownership;
59 58
import com.sap.sse.security.shared.impl.Role;
60 59
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
... ...
@@ -179,16 +178,6 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
179 178
180 179
void deleteUserGroup(UserGroup userGroup) throws UserGroupManagementException;
181 180
182
- /**
183
- * Releases the lock applied on IP due to user creation abuse.
184
- */
185
- void releaseUserCreationLockOnIp(String ip);
186
-
187
- /**
188
- * Releases the lock applied on IP due to user creation abuse.
189
- */
190
- void releaseBearerTokenLockOnIp(String ip);
191
-
192 181
Iterable<User> getUserList();
193 182
194 183
User getUserByName(String username);
... ...
@@ -234,8 +223,6 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
234 223
235 224
void updateUserProperties(String username, String fullName, String company, Locale locale,
236 225
boolean didOptOutOfMarketingEmails) throws UserManagementException;
237
-
238
- void resetUserTimedLock(String username) throws UserManagementException;
239 226
240 227
void deleteUser(String username) throws UserManagementException;
241 228
... ...
@@ -888,7 +875,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
888 875
889 876
Pair<Boolean, Set<String>> getCORSFilterConfiguration(String serverName);
890 877
891
- TimedLock failedPasswordAuthentication(User user);
878
+ LockingAndBanning failedPasswordAuthentication(User user);
892 879
893 880
void successfulPasswordAuthentication(User user);
894 881
... ...
@@ -905,7 +892,7 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
905 892
* {@code userAgent}, the locking record including its last locking duration is expunged from the internal data
906 893
* structures, avoiding garbage piling up.
907 894
*/
908
- TimedLock failedBearerTokenAuthentication(String clientIP);
895
+ LockingAndBanning failedBearerTokenAuthentication(String clientIP);
909 896
910 897
/**
911 898
* Call this when the combination of {@code clientIP} and {@code userAgent} was not
... ...
@@ -920,15 +907,12 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
920 907
* Used in conjunction with {@link #failedBearerTokenAuthentication(String)} and
921 908
* {@link #successfulBearerTokenAuthentication(String)}. If and only if a locking state for the combination
922 909
* of {@code clientIP} and {@code userAgent} is known and still locked, {@code true} is returned. Unlocking
923
- * will happen by calling {@link #successfulBearerTokenAuthentication(String)} with an equal combination of
924
- * {@code clientIP} and {@code userAgent} or by calling {@link releaseBearerTokenLockOnIp(String)}. Invoking
925
- * {@link #failedBearerTokenAuthentication(String)} will establish (if not yet locked) or extend the locking
926
- * duration for the combination.
910
+ * will bappen by calling {@link #successfulBearerTokenAuthentication(String)} with an equal combination
911
+ * of {@code clientIP} and {@code userAgent}. Invoking {@link #failedBearerTokenAuthentication(String)}
912
+ * will establish (if not yet locked) or extend the locking duration for the combination.
927 913
*/
928 914
boolean isClientIPLockedForBearerTokenAuthentication(String clientIP);
929 915
930
- boolean isUserCreationLockedForClientIP(String clientIP);
931
-
932 916
void fileTakedownNotice(TakedownNoticeRequestContext takedownNoticeRequestContext) throws MailException;
933 917
934 918
/**
... ...
@@ -946,8 +930,4 @@ public interface SecurityService extends ReplicableWithObjectInputStream<Replica
946 930
*/
947 931
Iterable<User> getUsersToInformAboutReplicaSet(String serverName,
948 932
Optional<com.sap.sse.security.shared.HasPermissions.Action> alsoSendToAllUsersWithThisPermissionOnReplicaSet);
949
-
950
- HashMap<String, TimedLock> getClientIPBasedTimedLocksForUserCreation();
951
-
952
- HashMap<String, TimedLock> getClientIPBasedTimedLocksForBearerTokenAbuse();
953 933
}
java/com.sap.sse.security/src/com/sap/sse/security/UsernamePasswordRealm.java
... ...
@@ -50,8 +50,8 @@ public class UsernamePasswordRealm extends AbstractCompositeAuthorizingRealm {
50 50
logger.warning("Rejecting authentication attempt for non-existing user "+username);
51 51
return null;
52 52
}
53
- if (user.getTimedLock().isLocked()) {
54
- logger.warning("Rejected attempt to authenticate user "+username+" because it is locked: "+user.getTimedLock());
53
+ if (user.getLockingAndBanning().isAuthenticationLocked()) {
54
+ logger.warning("Rejected attempt to authenticate user "+username+" because it is locked: "+user.getLockingAndBanning());
55 55
throw new LockedAccountException("Password authentication for user "+username+" is currently locked");
56 56
}
57 57
final UsernamePasswordAccount upa = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD);
java/com.sap.sse.security/src/com/sap/sse/security/impl/ReplicableSecurityService.java
... ...
@@ -8,7 +8,6 @@ import java.util.UUID;
8 8
9 9
import org.apache.shiro.session.Session;
10 10
11
-import com.sap.sse.common.TimedLock;
12 11
import com.sap.sse.security.SecurityService;
13 12
import com.sap.sse.security.shared.Account;
14 13
import com.sap.sse.security.shared.QualifiedObjectIdentifier;
... ...
@@ -16,6 +15,7 @@ import com.sap.sse.security.shared.RoleDefinition;
16 15
import com.sap.sse.security.shared.UserGroupManagementException;
17 16
import com.sap.sse.security.shared.UserManagementException;
18 17
import com.sap.sse.security.shared.WildcardPermission;
18
+import com.sap.sse.security.shared.impl.LockingAndBanning;
19 19
import com.sap.sse.security.shared.impl.Ownership;
20 20
import com.sap.sse.security.shared.impl.User;
21 21
import com.sap.sse.security.shared.subscription.Subscription;
... ...
@@ -70,8 +70,6 @@ public interface ReplicableSecurityService extends SecurityService {
70 70
Void internalUpdateUserProperties(String username, String fullName, String company, Locale locale,
71 71
boolean didOptOutOfMarketingEmails);
72 72
73
- Void internalResetUserTimedLock(String username);
74
-
75 73
Boolean internalValidateEmail(String username, String validationSecret);
76 74
77 75
Void internalSetPreference(String username, String key, String value);
... ...
@@ -125,17 +123,13 @@ public interface ReplicableSecurityService extends SecurityService {
125 123
126 124
Void internalSetCORSFilterConfigurationAllowedOrigins(String serverName, String... allowedOrigins);
127 125
128
- TimedLock internalFailedPasswordAuthentication(String username);
126
+ LockingAndBanning internalFailedPasswordAuthentication(String username);
129 127
130 128
Boolean internalSuccessfulPasswordAuthentication(String username);
131 129
132 130
Boolean internalSuccessfulBearerTokenAuthentication(String clientIP);
133 131
134
- TimedLock internalFailedBearerTokenAuthentication(String clientIP);
135
-
136
- TimedLock internalRecordUserCreationFromClientIP(String clientIP);
137
-
138
- void internalReleaseUserCreationLockOnIp(String ip);
132
+ LockingAndBanning internalFailedBearerTokenAuthentication(String clientIP);
139 133
140
- void internalReleaseBearerTokenLockOnIp(String ip);
134
+ LockingAndBanning internalRecordUserCreationFromClientIP(String clientIP);
141 135
}
java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceImpl.java
... ...
@@ -95,11 +95,9 @@ import com.sap.sse.ServerInfo;
95 95
import com.sap.sse.branding.BrandingConfigurationService;
96 96
import com.sap.sse.common.Duration;
97 97
import com.sap.sse.common.TimePoint;
98
-import com.sap.sse.common.TimedLock;
99 98
import com.sap.sse.common.Util;
100 99
import com.sap.sse.common.Util.Pair;
101 100
import com.sap.sse.common.http.HttpHeaderUtil;
102
-import com.sap.sse.common.impl.TimedLockImpl;
103 101
import com.sap.sse.common.mail.MailException;
104 102
import com.sap.sse.common.media.TakedownNoticeRequestContext;
105 103
import com.sap.sse.concurrent.LockUtil;
... ...
@@ -142,15 +140,12 @@ import com.sap.sse.security.operations.DeleteRoleDefinitionOperation;
142 140
import com.sap.sse.security.operations.DeleteUserGroupOperation;
143 141
import com.sap.sse.security.operations.DeleteUserOperation;
144 142
import com.sap.sse.security.operations.PutRoleDefinitionToUserGroupOperation;
145
-import com.sap.sse.security.operations.ReleaseBearerTokenLockOnIpOperation;
146
-import com.sap.sse.security.operations.ReleaseUserCreationLockOnIpOperation;
147 143
import com.sap.sse.security.operations.RemoveAccessTokenOperation;
148 144
import com.sap.sse.security.operations.RemovePermissionForUserOperation;
149 145
import com.sap.sse.security.operations.RemoveRoleDefinitionFromUserGroupOperation;
150 146
import com.sap.sse.security.operations.RemoveRoleFromUserOperation;
151 147
import com.sap.sse.security.operations.RemoveUserFromUserGroupOperation;
152 148
import com.sap.sse.security.operations.ResetPasswordOperation;
153
-import com.sap.sse.security.operations.ResetUserLockOperation;
154 149
import com.sap.sse.security.operations.SecurityOperation;
155 150
import com.sap.sse.security.operations.SetAccessTokenOperation;
156 151
import com.sap.sse.security.operations.SetDefaultTenantForServerForUserOperation;
... ...
@@ -191,6 +186,8 @@ import com.sap.sse.security.shared.UsernamePasswordAccount;
191 186
import com.sap.sse.security.shared.WildcardPermission;
192 187
import com.sap.sse.security.shared.WithQualifiedObjectIdentifier;
193 188
import com.sap.sse.security.shared.impl.AccessControlList;
189
+import com.sap.sse.security.shared.impl.LockingAndBanning;
190
+import com.sap.sse.security.shared.impl.LockingAndBanningImpl;
194 191
import com.sap.sse.security.shared.impl.Ownership;
195 192
import com.sap.sse.security.shared.impl.PermissionAndRoleAssociation;
196 193
import com.sap.sse.security.shared.impl.Role;
... ...
@@ -284,7 +281,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
284 281
* @see #successfulBearerTokenAuthentication(String)
285 282
* @see #isClientIPLockedForBearerTokenAuthentication(String)
286 283
*/
287
- private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForBearerTokenAuthentication;
284
+ private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication;
288 285
private final static String CLIENT_IP_NULL_ESCAPE = UUID.randomUUID().toString();
289 286
290 287
/**
... ...
@@ -296,7 +293,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
296 293
* When entering values into this map, the method entering it is responsible for also scheduling a background
297 294
* task that a while after lock expiry the record is expunged again from the map to avoid garbage piling up.
298 295
*/
299
- private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation;
296
+ private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation;
300 297
301 298
private final Zxcvbn passwordValidator;
302 299
... ...
@@ -350,8 +347,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
350 347
throw new IllegalArgumentException("No HasPermissionsProvider defined");
351 348
}
352 349
logger.info("Initializing Security Service with user store " + userStore);
353
- this.clientIPBasedTimedLocksForBearerTokenAuthentication = new ConcurrentHashMap<>();
354
- this.clientIPBasedTimedLocksForUserCreation = new ConcurrentHashMap<>();
350
+ this.clientIPBasedLockingAndBanningForBearerTokenAuthentication = new ConcurrentHashMap<>();
351
+ this.clientIPBasedLockingAndBanningForUserCreation = new ConcurrentHashMap<>();
355 352
this.permissionChangeListeners = new PermissionChangeListeners(this);
356 353
this.sharedAcrossSubdomainsOf = sharedAcrossSubdomainsOf;
357 354
this.subscriptionPlanProvider = subscriptionPlanProvider;
... ...
@@ -1003,18 +1000,6 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1003 1000
}
1004 1001
1005 1002
@Override
1006
- public void releaseUserCreationLockOnIp(String ip) {
1007
- logger.info("Releasing timed lock for user creation at IP "+ip);
1008
- apply(new ReleaseUserCreationLockOnIpOperation(ip));
1009
- }
1010
-
1011
- @Override
1012
- public void releaseBearerTokenLockOnIp(String ip) {
1013
- logger.info("Releasing timed lock for bearer token abuse at IP "+ip);
1014
- apply(new ReleaseBearerTokenLockOnIpOperation(ip));
1015
- }
1016
-
1017
- @Override
1018 1003
public Void internalDeleteUserGroup(UUID groupId) throws UserGroupManagementException {
1019 1004
final UserGroup userGroup = getUserGroup(groupId);
1020 1005
if (userGroup == null) {
... ...
@@ -1120,16 +1105,6 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1120 1105
}
1121 1106
1122 1107
@Override
1123
- public HashMap<String,TimedLock> getClientIPBasedTimedLocksForUserCreation() {
1124
- return new HashMap<String, TimedLock>(clientIPBasedTimedLocksForUserCreation);
1125
- }
1126
-
1127
- @Override
1128
- public HashMap<String,TimedLock> getClientIPBasedTimedLocksForBearerTokenAbuse() {
1129
- return new HashMap<String, TimedLock>(clientIPBasedTimedLocksForBearerTokenAuthentication);
1130
- }
1131
-
1132
- @Override
1133 1108
public User createSimpleUser(final String username, final String email, String password, String fullName,
1134 1109
String company, Locale locale, final String validationBaseURL, UserGroup groupOwningUser,
1135 1110
String requestClientIP, boolean enforceStrongPassword) throws UserManagementException, MailException, UserGroupManagementException {
... ...
@@ -1185,29 +1160,22 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1185 1160
// synchronize to ensure that no two threads can enter values into the map concurrently;
1186 1161
// still the use of a ConcurrentMap is justified because there may be concurrent write access
1187 1162
// through replication
1188
- synchronized (clientIPBasedTimedLocksForUserCreation) {
1189
- final TimedLock timedLock = clientIPBasedTimedLocksForUserCreation.get(clientIP);
1190
- if (timedLock == null || !timedLock.isLocked()) {
1163
+ synchronized (clientIPBasedLockingAndBanningForUserCreation) {
1164
+ final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForUserCreation.get(clientIP);
1165
+ if (lockingAndBanning == null || !lockingAndBanning.isAuthenticationLocked()) {
1191 1166
apply(s->s.internalRecordUserCreationFromClientIP(clientIP));
1192 1167
} else {
1193
- timedLock.extendLockDuration();
1194
- throw new UserManagementException("Client IP "+clientIP+" locked for user creation: "+timedLock);
1168
+ throw new UserManagementException(UserManagementException.CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION);
1195 1169
}
1196 1170
}
1197 1171
}
1198 1172
1199 1173
@Override
1200
- public boolean isUserCreationLockedForClientIP(String clientIP) {
1201
- final TimedLock timedLock = clientIPBasedTimedLocksForUserCreation.get(escapeNullClientIP(clientIP));
1202
- return timedLock != null && timedLock.isLocked();
1203
- }
1204
-
1205
- @Override
1206
- public TimedLock internalRecordUserCreationFromClientIP(String clientIP) {
1207
- final TimedLock result = new TimedLockImpl(TimePoint.now().plus(DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION),
1174
+ public LockingAndBanning internalRecordUserCreationFromClientIP(String clientIP) {
1175
+ final LockingAndBanning result = new LockingAndBanningImpl(TimePoint.now().plus(DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION),
1208 1176
DEFAULT_CLIENT_IP_BASED_USER_CREATION_LOCKING_DURATION);
1209
- clientIPBasedTimedLocksForUserCreation.put(clientIP, result);
1210
- scheduleCleanUpTask(clientIP, result, clientIPBasedTimedLocksForUserCreation,
1177
+ clientIPBasedLockingAndBanningForUserCreation.put(clientIP, result);
1178
+ scheduleCleanUpTask(clientIP, result, clientIPBasedLockingAndBanningForUserCreation,
1211 1179
"client IPs locked for user creation");
1212 1180
return result;
1213 1181
}
... ...
@@ -1247,7 +1215,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1247 1215
1248 1216
@Override
1249 1217
public User internalCreateUser(String username, String email, Account... accounts) throws UserManagementException {
1250
- final User result = store.createUser(username, email, new TimedLockImpl(), accounts);
1218
+ final User result = store.createUser(username, email, new LockingAndBanningImpl(), accounts);
1251 1219
return result;
1252 1220
}
1253 1221
... ...
@@ -1310,29 +1278,12 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1310 1278
}
1311 1279
1312 1280
@Override
1313
- public void resetUserTimedLock(String username) throws UserManagementException {
1314
- final User user = store.getUserByName(username);
1315
- if (user == null) {
1316
- throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
1317
- }
1318
- apply(new ResetUserLockOperation(username, user.getTimedLock()));
1319
- }
1320
-
1321
- @Override
1322
- public Void internalResetUserTimedLock(String username) {
1323
- final User user = store.getUserByName(username);
1324
- user.getTimedLock().resetLock();
1325
- store.updateUser(user);
1326
- return null;
1327
- }
1328
-
1329
- @Override
1330 1281
public boolean checkPassword(String username, String password) throws UserManagementException {
1331 1282
final User user = store.getUserByName(username);
1332 1283
if (user == null) {
1333 1284
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
1334 1285
}
1335
- if (user.getTimedLock().isLocked()) {
1286
+ if (user.getLockingAndBanning().isAuthenticationLocked()) {
1336 1287
throw new UserManagementException(UserManagementException.PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER);
1337 1288
}
1338 1289
final UsernamePasswordAccount account = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD);
... ...
@@ -1348,23 +1299,23 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1348 1299
}
1349 1300
1350 1301
@Override
1351
- public TimedLock failedPasswordAuthentication(User user) {
1302
+ public LockingAndBanning failedPasswordAuthentication(User user) {
1352 1303
return apply(s->s.internalFailedPasswordAuthentication(user.getName()));
1353 1304
}
1354 1305
1355 1306
@Override
1356
- public TimedLock internalFailedPasswordAuthentication(String username) {
1307
+ public LockingAndBanning internalFailedPasswordAuthentication(String username) {
1357 1308
final User user = getUserByName(username);
1358
- final TimedLock timedLock;
1309
+ final LockingAndBanning lockingAndBanning;
1359 1310
if (user != null) {
1360
- timedLock = user.getTimedLock();
1361
- timedLock.extendLockDuration();
1311
+ lockingAndBanning = user.getLockingAndBanning();
1312
+ lockingAndBanning.failedPasswordAuthentication();
1362 1313
store.updateUser(user);
1363
- logger.info("failed password authentication for user "+username+"; locking: "+timedLock);
1314
+ logger.info("failed password authentication for user "+username+"; locking: "+lockingAndBanning);
1364 1315
} else {
1365
- timedLock = null;
1316
+ lockingAndBanning = null;
1366 1317
}
1367
- return timedLock;
1318
+ return lockingAndBanning;
1368 1319
}
1369 1320
1370 1321
@Override
... ...
@@ -1380,7 +1331,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1380 1331
final boolean changed;
1381 1332
final User user = getUserByName(username);
1382 1333
if (user != null) {
1383
- changed = user.getTimedLock().resetLock();
1334
+ changed = user.getLockingAndBanning().successfulPasswordAuthentication();
1384 1335
if (changed) {
1385 1336
store.updateUser(user);
1386 1337
}
... ...
@@ -1391,8 +1342,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1391 1342
}
1392 1343
1393 1344
@Override
1394
- public TimedLock failedBearerTokenAuthentication(String clientIP) {
1395
- final TimedLock result;
1345
+ public LockingAndBanning failedBearerTokenAuthentication(String clientIP) {
1346
+ final LockingAndBanning result;
1396 1347
final ReplicationService replicationService = getReplicationService();
1397 1348
if (replicationService == null || !replicationService.isReplicationStarting()) {
1398 1349
result = apply(s->s.internalFailedBearerTokenAuthentication(clientIP));
... ...
@@ -1404,22 +1355,22 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1404 1355
}
1405 1356
1406 1357
@Override
1407
- public TimedLock internalFailedBearerTokenAuthentication(String clientIP) {
1408
- final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.computeIfAbsent(escapeNullClientIP(clientIP), key->new TimedLockImpl());
1409
- timedLock.extendLockDuration();
1410
- logger.info("failed bearer token authentication from client IP "+clientIP+"; locking: "+timedLock);
1411
- scheduleCleanUpTask(clientIP, timedLock, clientIPBasedTimedLocksForBearerTokenAuthentication,
1358
+ public LockingAndBanning internalFailedBearerTokenAuthentication(String clientIP) {
1359
+ final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.computeIfAbsent(escapeNullClientIP(clientIP), key->new LockingAndBanningImpl());
1360
+ lockingAndBanning.failedPasswordAuthentication();
1361
+ logger.info("failed bearer token authentication from client IP "+clientIP+"; locking: "+lockingAndBanning);
1362
+ scheduleCleanUpTask(clientIP, lockingAndBanning, clientIPBasedLockingAndBanningForBearerTokenAuthentication,
1412 1363
"client IPs locked for bearer token authentication");
1413
- return timedLock;
1364
+ return lockingAndBanning;
1414 1365
}
1415 1366
1416 1367
/**
1417
- * Schedule a clean-up task to avoid leaking memory for the TimedLock objects; schedule it in two times the
1418
- * locking expiry of {@code timedLock}, but at least one hour, because if no authentication failure occurs
1419
- * for that IP/user agent combination, we will entirely remove the {@link TimedLock} from the map,
1368
+ * Schedule a clean-up task to avoid leaking memory for the LockingAndBanning objects; schedule it in two times the
1369
+ * locking expiry of {@code lockingAndBanning}, but at least one hour, because if no authentication failure occurs
1370
+ * for that IP/user agent combination, we will entirely remove the {@link LockingAndBanning} from the map,
1420 1371
* effectively resetting that IP to a short default locking duration again; this way, if during the double
1421 1372
* expiration time another failed attempt is registered, we can still grow the locking duration because we have kept
1422
- * the {@link TimedLock} object available for a bit longer. Furthermore, for authentication requests, the
1373
+ * the {@link LockingAndBanning} object available for a bit longer. Furthermore, for authentication requests, the
1423 1374
* responsible {@link Realm} will let authentication requests get to here only if not locked, so if we were to
1424 1375
* expunge entries immediately as they unlock, the locking duration could never grow.<p>
1425 1376
*
... ...
@@ -1427,16 +1378,16 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1427 1378
* expiry duration.
1428 1379
*/
1429 1380
private void scheduleCleanUpTask(final String clientIPOrNull,
1430
- final TimedLock timedLock,
1431
- final ConcurrentMap<String, TimedLock> mapToRemoveFrom,
1381
+ final LockingAndBanning lockingAndBanning,
1382
+ final ConcurrentMap<String, LockingAndBanning> mapToRemoveFrom,
1432 1383
final String nameOfMapForLog) {
1433 1384
final long millisUntilLockingExpiry = Math.max(
1434
- 2*ApproximateTime.approximateNow().until(timedLock.getLockedUntil()).asMillis(),
1385
+ 2*ApproximateTime.approximateNow().until(lockingAndBanning.getLockedUntil()).asMillis(),
1435 1386
Duration.ONE_HOUR.asMillis());
1436 1387
ThreadPoolUtil.INSTANCE.getDefaultBackgroundTaskThreadPoolExecutor().schedule(
1437 1388
()->{
1438
- final TimedLock lab = mapToRemoveFrom.get(escapeNullClientIP(clientIPOrNull));
1439
- if (lab != null && !lab.isLocked()) {
1389
+ final LockingAndBanning lab = mapToRemoveFrom.get(escapeNullClientIP(clientIPOrNull));
1390
+ if (lab != null && !lab.isAuthenticationLocked()) {
1440 1391
mapToRemoveFrom.remove(escapeNullClientIP(clientIPOrNull));
1441 1392
logger.info("Removed "+clientIPOrNull+" from "+nameOfMapForLog+"; "
1442 1393
+mapToRemoveFrom.size()
... ...
@@ -1461,9 +1412,9 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1461 1412
@Override
1462 1413
public Boolean internalSuccessfulBearerTokenAuthentication(String clientIP) {
1463 1414
final boolean changed;
1464
- final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.remove(escapeNullClientIP(clientIP));
1465
- if (timedLock != null) {
1466
- logger.info("Unlocked bearer token authentication from "+clientIP+"; last locking state was "+timedLock);
1415
+ final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.remove(escapeNullClientIP(clientIP));
1416
+ if (lockingAndBanning != null) {
1417
+ logger.info("Unlocked bearer token authentication from "+clientIP+"; last locking state was "+lockingAndBanning);
1467 1418
changed = true;
1468 1419
} else {
1469 1420
changed = false;
... ...
@@ -1473,8 +1424,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
1473 1424
1474 1425
@Override
1475 1426
public boolean isClientIPLockedForBearerTokenAuthentication(String clientIP) {
1476
- final TimedLock timedLock = clientIPBasedTimedLocksForBearerTokenAuthentication.get(escapeNullClientIP(clientIP));
1477
- return timedLock != null && timedLock.isLocked();
1427
+ final LockingAndBanning lockingAndBanning = clientIPBasedLockingAndBanningForBearerTokenAuthentication.get(escapeNullClientIP(clientIP));
1428
+ return lockingAndBanning != null && lockingAndBanning.isAuthenticationLocked();
1478 1429
}
1479 1430
1480 1431
@Override
... ...
@@ -2573,8 +2524,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
2573 2524
store.clear();
2574 2525
accessControlStore.clear();
2575 2526
corsFilterConfigurationsByReplicaSetName.clear();
2576
- clientIPBasedTimedLocksForBearerTokenAuthentication.clear();
2577
- clientIPBasedTimedLocksForUserCreation.clear();
2527
+ clientIPBasedLockingAndBanningForBearerTokenAuthentication.clear();
2528
+ clientIPBasedLockingAndBanningForUserCreation.clear();
2578 2529
}
2579 2530
2580 2531
@Override
... ...
@@ -2656,13 +2607,13 @@ implements ReplicableSecurityService, ClearStateTestSupport {
2656 2607
final SecurityServiceInitialLoadExtensionsDTO initialLoadExtensions = (SecurityServiceInitialLoadExtensionsDTO) is.readObject();
2657 2608
final ConcurrentMap<String, Pair<Boolean, Set<String>>> newCORSFilterConfigurations = initialLoadExtensions.getCorsFilterConfigurationsByReplicaSetName();
2658 2609
corsFilterConfigurationsByReplicaSetName.putAll(newCORSFilterConfigurations);
2659
- if (initialLoadExtensions.getClientIPBasedTimedLocksForBearerTokenAuthentication() != null) {
2610
+ if (initialLoadExtensions.getClientIPBasedLockingAndBanningForBearerTokenAuthentication() != null) {
2660 2611
// checking for null for backward compatibility; an older primary/master may not have known this field yet
2661
- clientIPBasedTimedLocksForBearerTokenAuthentication.putAll(initialLoadExtensions.getClientIPBasedTimedLocksForBearerTokenAuthentication());
2612
+ clientIPBasedLockingAndBanningForBearerTokenAuthentication.putAll(initialLoadExtensions.getClientIPBasedLockingAndBanningForBearerTokenAuthentication());
2662 2613
}
2663
- if (initialLoadExtensions.getClientIPBasedTimedLocksForUserCreation() != null) {
2614
+ if (initialLoadExtensions.getClientIPBasedLockingAndBanningForUserCreation() != null) {
2664 2615
// checking for null for backward compatibility; an older primary/master may not have known this field yet
2665
- clientIPBasedTimedLocksForUserCreation.putAll(initialLoadExtensions.getClientIPBasedTimedLocksForUserCreation());
2616
+ clientIPBasedLockingAndBanningForUserCreation.putAll(initialLoadExtensions.getClientIPBasedLockingAndBanningForUserCreation());
2666 2617
}
2667 2618
logger.info("Triggering SecurityInitializationCustomizers upon replication ...");
2668 2619
customizers.forEach(c -> c.customizeSecurityService(this));
... ...
@@ -2678,8 +2629,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
2678 2629
objectOutputStream.writeObject(baseUrlForCrossDomainStorage);
2679 2630
objectOutputStream.writeObject(new SecurityServiceInitialLoadExtensionsDTO(
2680 2631
corsFilterConfigurationsByReplicaSetName,
2681
- clientIPBasedTimedLocksForBearerTokenAuthentication,
2682
- clientIPBasedTimedLocksForUserCreation));
2632
+ clientIPBasedLockingAndBanningForBearerTokenAuthentication,
2633
+ clientIPBasedLockingAndBanningForUserCreation));
2683 2634
}
2684 2635
2685 2636
@Override
... ...
@@ -2986,8 +2937,8 @@ implements ReplicableSecurityService, ClearStateTestSupport {
2986 2937
// See com.sap.sse.security.impl.Activator.clearState(), moved due to required reinitialisation sequence for
2987 2938
// permission-vertical
2988 2939
public void clearState() throws Exception {
2989
- clientIPBasedTimedLocksForBearerTokenAuthentication.clear();
2990
- clientIPBasedTimedLocksForUserCreation.clear();
2940
+ clientIPBasedLockingAndBanningForBearerTokenAuthentication.clear();
2941
+ clientIPBasedLockingAndBanningForUserCreation.clear();
2991 2942
}
2992 2943
2993 2944
@Override
... ...
@@ -3551,18 +3502,4 @@ implements ReplicableSecurityService, ClearStateTestSupport {
3551 3502
.forEach(usersToSendMailTo::add));
3552 3503
return usersToSendMailTo;
3553 3504
}
3554
-
3555
- @Override
3556
- public void internalReleaseUserCreationLockOnIp(String ip) {
3557
- if(clientIPBasedTimedLocksForUserCreation.containsKey(ip)) {
3558
- clientIPBasedTimedLocksForUserCreation.remove(ip);
3559
- }
3560
- }
3561
-
3562
- @Override
3563
- public void internalReleaseBearerTokenLockOnIp(String ip) {
3564
- if(clientIPBasedTimedLocksForBearerTokenAuthentication.containsKey(ip)) {
3565
- clientIPBasedTimedLocksForBearerTokenAuthentication.remove(ip);
3566
- }
3567
- }
3568 3505
}
java/com.sap.sse.security/src/com/sap/sse/security/impl/SecurityServiceInitialLoadExtensionsDTO.java
... ...
@@ -6,17 +6,17 @@ import java.io.Serializable;
6 6
import java.util.Set;
7 7
import java.util.concurrent.ConcurrentMap;
8 8
9
-import com.sap.sse.common.TimedLock;
10 9
import com.sap.sse.common.Util.Pair;
11 10
import com.sap.sse.replication.Replicable;
12 11
import com.sap.sse.security.SecurityService;
12
+import com.sap.sse.security.shared.impl.LockingAndBanning;
13 13
14 14
/**
15 15
* Starting with the CORS filter configurations, this and future extensions of the {@link SecurityService}'s
16 16
* initial load format can be added to this DTO type. The benefit, compared to adding new content with
17 17
* explicit {@link ObjectOutputStream#writeObject(Object)} and {@link ObjectInputStream#readObject()} calls,
18 18
* is that there is a certain built-in backward compatibility when a replica with a new version and additional
19
- * fields expected in the initial load tries to replicate from an older version where those fields don't exist
19
+ * fields expected in the initial load tries to replica from an older version where those fields don't exist
20 20
* yet in this type. Then, those additional fields will come out as {@code null} on the replica, and the replica
21 21
* at least has a chance to continue with a useful initialization of those data structures instead of having
22 22
* the replication of {@link SecurityService} and all subsequent {@link Replicable}s fail due to incompatible
... ...
@@ -30,30 +30,29 @@ public class SecurityServiceInitialLoadExtensionsDTO implements Serializable {
30 30
31 31
private final ConcurrentMap<String, Pair<Boolean, Set<String>>> corsFilterConfigurationsByReplicaSetName;
32 32
33
- private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForBearerTokenAuthentication;
33
+ private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication;
34 34
35
- private final ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation;
35
+ private final ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation;
36 36
37 37
public SecurityServiceInitialLoadExtensionsDTO(
38 38
ConcurrentMap<String, Pair<Boolean, Set<String>>> corsFilterConfigurationsByReplicaSetName,
39
- ConcurrentMap<String, TimedLock> clientIPBasedTimedLockForBearerTokenAuthentication,
40
- ConcurrentMap<String, TimedLock> clientIPBasedTimedLocksForUserCreation) {
39
+ ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForBearerTokenAuthentication,
40
+ ConcurrentMap<String, LockingAndBanning> clientIPBasedLockingAndBanningForUserCreation) {
41 41
super();
42 42
this.corsFilterConfigurationsByReplicaSetName = corsFilterConfigurationsByReplicaSetName;
43
- this.clientIPBasedTimedLocksForBearerTokenAuthentication = clientIPBasedTimedLockForBearerTokenAuthentication;
44
- this.clientIPBasedTimedLocksForUserCreation = clientIPBasedTimedLocksForUserCreation;
43
+ this.clientIPBasedLockingAndBanningForBearerTokenAuthentication = clientIPBasedLockingAndBanningForBearerTokenAuthentication;
44
+ this.clientIPBasedLockingAndBanningForUserCreation = clientIPBasedLockingAndBanningForUserCreation;
45 45
}
46
-
47 46
48 47
ConcurrentMap<String, Pair<Boolean, Set<String>>> getCorsFilterConfigurationsByReplicaSetName() {
49 48
return corsFilterConfigurationsByReplicaSetName;
50 49
}
51 50
52
- ConcurrentMap<String, TimedLock> getClientIPBasedTimedLocksForBearerTokenAuthentication() {
53
- return clientIPBasedTimedLocksForBearerTokenAuthentication;
51
+ ConcurrentMap<String, LockingAndBanning> getClientIPBasedLockingAndBanningForBearerTokenAuthentication() {
52
+ return clientIPBasedLockingAndBanningForBearerTokenAuthentication;
54 53
}
55 54
56
- ConcurrentMap<String, TimedLock> getClientIPBasedTimedLocksForUserCreation() {
57
- return clientIPBasedTimedLocksForUserCreation;
55
+ ConcurrentMap<String, LockingAndBanning> getClientIPBasedLockingAndBanningForUserCreation() {
56
+ return clientIPBasedLockingAndBanningForUserCreation;
58 57
}
59 58
}
java/com.sap.sse.security/src/com/sap/sse/security/operations/ReleaseBearerTokenLockOnIpOperation.java
... ...
@@ -1,18 +0,0 @@
1
-package com.sap.sse.security.operations;
2
-
3
-import com.sap.sse.security.impl.ReplicableSecurityService;
4
-
5
-public class ReleaseBearerTokenLockOnIpOperation implements SecurityOperation<Void> {
6
- private static final long serialVersionUID = 5839571828359473821L;
7
- protected final String ip;
8
-
9
- public ReleaseBearerTokenLockOnIpOperation(final String ip) {
10
- this.ip = ip;
11
- }
12
-
13
- @Override
14
- public Void internalApplyTo(ReplicableSecurityService toState) throws Exception {
15
- toState.internalReleaseBearerTokenLockOnIp(ip);
16
- return null;
17
- }
18
-}
java/com.sap.sse.security/src/com/sap/sse/security/operations/ReleaseUserCreationLockOnIpOperation.java
... ...
@@ -1,18 +0,0 @@
1
-package com.sap.sse.security.operations;
2
-
3
-import com.sap.sse.security.impl.ReplicableSecurityService;
4
-
5
-public class ReleaseUserCreationLockOnIpOperation implements SecurityOperation<Void> {
6
- private static final long serialVersionUID = 8729427754960969395L;
7
- protected final String ip;
8
-
9
- public ReleaseUserCreationLockOnIpOperation(final String ip) {
10
- this.ip = ip;
11
- }
12
-
13
- @Override
14
- public Void internalApplyTo(ReplicableSecurityService toState) throws Exception {
15
- toState.internalReleaseUserCreationLockOnIp(ip);
16
- return null;
17
- }
18
-}
java/com.sap.sse.security/src/com/sap/sse/security/operations/ResetUserLockOperation.java
... ...
@@ -1,22 +0,0 @@
1
-package com.sap.sse.security.operations;
2
-
3
-import com.sap.sse.common.TimedLock;
4
-import com.sap.sse.security.impl.ReplicableSecurityService;
5
-
6
-public class ResetUserLockOperation implements SecurityOperation<Void> {
7
- private static final long serialVersionUID = -6267523788529623080L;
8
- protected final TimedLock timedLock;
9
- protected final String username;
10
-
11
- public ResetUserLockOperation(String username, TimedLock timedLock) {
12
- this.username = username;
13
- this.timedLock = timedLock;
14
- }
15
-
16
- @Override
17
- public Void internalApplyTo(ReplicableSecurityService toState) throws Exception {
18
- toState.internalResetUserTimedLock(username);
19
- return null;
20
- }
21
-
22
-}
java/com.sap.sse.threadmanager/resources/shiro.ini
... ...
@@ -26,7 +26,7 @@ securityManager.subjectDAO = $subjectDAO
26 26
securityManager.sessionManager.globalSessionTimeout = 31536000000
27 27
cacheManager = com.sap.sse.security.SessionCacheManager
28 28
securityManager.cacheManager = $cacheManager
29
-authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithTimedLocks
29
+authenticationStrategy = com.sap.sse.security.AtLeastOneSuccessfulStrategyWithLockingAndBanning
30 30
securityManager.authenticator.authenticationStrategy = $authenticationStrategy
31 31
32 32
# Support for anonymous user permissions
scripts/assume_unchanged_for_mac.sh
... ...
@@ -1,25 +0,0 @@
1
-#!/bin/bash
2
-
3
-# Description:
4
-# This script finds all *.prefs and *.launch files tracked by Git
5
-# and sets them to "assume-unchanged", so local changes won't show
6
-# up in 'git status' or be accidentally committed.
7
-
8
-# Find and apply the assume-unchanged flag
9
-echo "Scanning for tracked *.prefs and *.launch files..."
10
-
11
-files=$(git ls-files | grep -E '\.prefs$|\.launch$')
12
-
13
-if [ -z "$files" ]; then
14
- echo "No .prefs or .launch files found in the tracked file list."
15
- exit 0
16
-fi
17
-
18
-echo "$files" | while read -r file; do
19
- git update-index --assume-unchanged "$file"
20
- echo "Marked as assume-unchanged: $file"
21
-done
22
-
23
-echo ""
24
-echo "Git will now ignore local changes to these files (but they will still update from upstream if you clear this flag before pulling)."
25
-
wiki/howto/onboarding.md
... ...
@@ -10,9 +10,7 @@ First of all, make sure you've looked at [http://www.amazon.de/Patterns-Elements
10 10
11 11
1. Git Account
12 12
13
- - The primary Git repository for the project is hosted on Github (see [https://github.com/SAP/sailing-analytics](https://github.com/SAP/sailing-analytics)). To clone, use ``git@github.com:SAP/sailing-analytics.git``.
14
- - If you are on Windows, keep in mind you may run into the following problem. By default, the filesystem in Windows enforces a 260 character limit on paths. The longest path length for a file in this project, if the drive name is included, is 263 characters. A possible solution is to pass a single character name for the project folder in the git clone command, and clone the project on drive root, which may bring the longest file path down to compatible length. Alternatively, Windows 10 and 11 offer settings to enable a much much longer maximum file path that requires additional configuration. You may check that out at your own will.
15
- - To gain write access you have to become member of the [sailing-analytics-team](https://github.com/orgs/SAP/teams/sailing-analytics-team) organization. For that you need to [link your Github user to the Github SAP organization](https://wiki.one.int.sap/wiki/display/ospodocs/Self-Service+for+Joining+an+SAP+GitHub+Organization). For that to work, your Github account needs to have your @sap.com e-mail address assigned and verified. We still have a shadow repository around that, e.g., powers our Wiki at [https://wiki.sapsailing.com](https://wiki.sapsailing.com) and which lives at ``ssh://trac@sapsailing.com/home/trac/git``.
13
+ - The primary Git repository for the project is hosted on Github (see [https://github.com/SAP/sailing-analytics](https://github.com/SAP/sailing-analytics)). To clone, use ``git@github.com:SAP/sailing-analytics.git``. To gain write access you have to become member of the [sailing-analytics-team](https://github.com/orgs/SAP/teams/sailing-analytics-team) organization. For that you need to [link your Github user to the Github SAP organization](https://wiki.one.int.sap/wiki/display/ospodocs/Self-Service+for+Joining+an+SAP+GitHub+Organization). For that to work, your Github account needs to have your @sap.com e-mail address assigned and verified. We still have a shadow repository around that, e.g., powers our Wiki at [https://wiki.sapsailing.com](https://wiki.sapsailing.com) and which lives at ``ssh://trac@sapsailing.com/home/trac/git``.
16 14
17 15
- In case you'd like to get access to the external git at `ssh://trac@sapsailing.com/home/trac/git` please send your SSH public key to one of the project maintainers, requesting git access. Make sure to NOT generate the key using Putty. Putty keys don't work reliably under Linux and on Windows/Cygwin environments. Use ssh-keygen in a Cygwin or Linux or MacOS/X environment instead. For further instructions for generating an ssh-key see [GitHub](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).
18 16
Note: If you want to use the ssh-key in the context of our solution, it can be an RSA or ED25519 format. Example for creating a key: `ssh-keygen -t ed25519 -b 512 -C "test@test.com"`. Make sure to set a non-empty password for your key.
... ...
@@ -191,9 +189,6 @@ If git is not in the Path system environment variable, the gradle build will not
191 189
### Build for deployment
192 190
Open a shell (preferrably a git bash or a cygwin bash), cd to the git workspace's root folder and issue "./configuration/buildAndUpdateProduct.sh build". This should build the software and run all the tests. If you want to avoid the tests being executed, use the -t option. If you only want to build one GWT permutation (Chrome/English), use the -b option. When inside the SAP VPN, add the -p option for proxy use. Run the build script without arguments to get usage hints.
193 191
194
-### Development Environment
195
-Read [[here|wiki/info/landscape/development-environment]] and importantly for [[pushing to main|https://wiki.sapsailing.com/wiki/info/landscape/development-environment.md#git-bugzilla-and-our-branches]].
196
-
197 192
### Steps to consider for using other GWT modules
198 193
199 194
1. For Eclipse Build
wiki/info/landscape/development-environment.md
... ...
@@ -18,7 +18,7 @@ Everything else should follow the pattern
18 18
- when the workflow has finished, it triggers your Hudson job which collects the [build and test results](https://hudson.sapsailing.com/job/bug12345)
19 19
- be verbose and document your changes, progress, hold-ups and problems on your Bugzilla issue
20 20
- when build is "green," suggest your branch for review; so far we do this informally by assigning the Bugzilla issue to the reviewer and in a comment asking for review; in the future, we may want to use Github Pull Requests for this
21
-- after your branch has been merged into ``main``, disable your Hudson build job for your branch, comment about the merge in Bugzilla and resolve the Bugzilla item, usually as "FIXED".
21
+- after your branch has been merged into ``main``, disable your Hudson build job for your branch
22 22
- the ``main`` branch will then build a new release that you can roll out into the production landscape
23 23
- in case of changes to i18n-related message properties files, merge ``main`` into ``translation`` which triggers the translation process; the completed translations will arrive as pushes to the ``translations`` branch, triggering another ``release`` workflow, and---if successful---an automated merge into ``main`` with the corresponding build/release process happens, based on the [translation Hudson job](https://hudson.sapsailing.com/job/translation/configure)'s special logic
24 24
- a successful ``main`` build (still on Java 8) will lead to an automatic merge into one or more branches for newer Java releases (such as ``docker-24``) with the corresponding build/release process