Merge branch 'bug6151' into main

This commit is contained in:
Axel Uhl
2025-07-11 18:10:01 +02:00
10 changed files with 44 additions and 27 deletions
@@ -24,7 +24,7 @@
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console 12001 -clean"/> <stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog -console 12001 -clean"/>
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:ThreadPriorityPolicy=2 -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -Dpolardata.source.url=https://www.sapsailing.com -Dwindestimation.source.url=https://www.sapsailing.com -Drestore.tracked.races=true -Dorg.eclipse.jetty.server.Request.maxFormContentSize=50000000 -DAnniversaryRaceDeterminator.enabled=true -Djava.naming.factory.url.pkgs=org.eclipse.jetty.jndi -Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory -Dorg.eclipse.jetty.annotations.maxWait=120 -Dchargebee.site=${CHARGEBEE_SITE} -Dchargebee.apikey=${CHARGEBEE_API_KEY} -Dmanage2sail.accesstoken=${MANAGE2SAIL_ACCESS_TOKEN} -Dsubscriptions.disableMailVerificationRequirement=true -Dgoogle.maps.authenticationparams=${GOOGLE_MAPS_AUTHENTICATION_PARAMS} -Dgwt.rpc.version=9 -Dwindestimation.source.bearertoken=${WIND_ESTIMATION_MODEL_BEARER_TOKEN} -Dpolardata.source.bearertoken=${POLAR_DATA_BEARER_TOKEN} -Dcom.sap.sse.debranding=false -Digtimi.riot.port=6000 -Digtimi.base.url=http://127.0.0.1:8888 -Dsap.aicore.credentials='${SAP_AICORE_CREDENTIALS}' -Dsap.sailing.aiagent.modelname=gpt-4o -Dgeonames.org.usernames=&quot;${GEONAMES_ORG_USERNAMES}&quot;"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea -Declipse.ignoreApp=true -Dosgi.noShutdown=true -Dfile.encoding=cp1252 -Dexpedition.udp.port=5010 -Xmx6000m -XX:ThreadPriorityPolicy=2 -XX:+UseG1GC -Djetty.home=${project_loc:com.sap.sailing.server}/../target/configuration/jetty -Djava.util.logging.config.file=${project_loc:com.sap.sailing.server}/../target/configuration/logging_debug.properties -Dkiwo.results=${project_loc:com.sap.sailing.kiworesultimport.test}/resources -Dpersistentcompetitors.clear=false -Dpolardata.source.url=https://www.sapsailing.com -Dwindestimation.source.url=https://www.sapsailing.com -Drestore.tracked.races=false -Dorg.eclipse.jetty.server.Request.maxFormContentSize=50000000 -DAnniversaryRaceDeterminator.enabled=true -Djava.naming.factory.url.pkgs=org.eclipse.jetty.jndi -Djava.naming.factory.initial=org.eclipse.jetty.jndi.InitialContextFactory -Dorg.eclipse.jetty.annotations.maxWait=120 -Dchargebee.site=${CHARGEBEE_SITE} -Dchargebee.apikey=${CHARGEBEE_API_KEY} -Dmanage2sail.accesstoken=${MANAGE2SAIL_ACCESS_TOKEN} -Dsubscriptions.disableMailVerificationRequirement=true -Dgoogle.maps.authenticationparams=${GOOGLE_MAPS_AUTHENTICATION_PARAMS} -Dgwt.rpc.version=9 -Dwindestimation.source.bearertoken=${WIND_ESTIMATION_MODEL_BEARER_TOKEN} -Dpolardata.source.bearertoken=${POLAR_DATA_BEARER_TOKEN} -Dcom.sap.sse.debranding=false -Digtimi.riot.port=6000 -Digtimi.base.url=http://127.0.0.1:8888 -Dsap.aicore.credentials='${SAP_AICORE_CREDENTIALS}' -Dsap.sailing.aiagent.modelname=gpt-4o -Dgeonames.org.usernames=&quot;${GEONAMES_ORG_USERNAMES}&quot;"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/> <stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/>
<stringAttribute key="pde.version" value="3.3"/> <stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="profilingTraceType-ALLOCATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%INCREASE_COUNT%CTX_KEY%8192%CTX_ENTRY%KEY_MIN_SIZE%CTX_KEY%32%CTX_ENTRY%KEY_MAX_SIZE%CTX_KEY%65536%CTX_ENTRY%KEY_INC_LINE_NRS%CTX_KEY%true%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%CLASS_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ADAPTIVE%CTX_KEY%false%CTX_ENTRY%"/> <stringAttribute key="profilingTraceType-ALLOCATION_TRACE" value="KEY_APPLICATION_FILTER%CTX_KEY%*%CTX_ENTRY%INCREASE_COUNT%CTX_KEY%8192%CTX_ENTRY%KEY_MIN_SIZE%CTX_KEY%32%CTX_ENTRY%KEY_MAX_SIZE%CTX_KEY%65536%CTX_ENTRY%KEY_INC_LINE_NRS%CTX_KEY%true%CTX_ENTRY%KEY_SESSION_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ENABLEMENT%CTX_KEY%false%CTX_ENTRY%CLASS_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_USER_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_REQUEST_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_TENANT_FILTER%CTX_KEY%*%CTX_ENTRY%KEY_ADAPTIVE%CTX_KEY%false%CTX_ENTRY%"/>
@@ -14,6 +14,8 @@ public class UserManagementException extends UserStoreManagementException implem
public static final String USERNAME_DOES_NOT_MEET_REQUIREMENTS = "Username does not meet requirements"; public static final String USERNAME_DOES_NOT_MEET_REQUIREMENTS = "Username does not meet requirements";
public static final String CANNOT_RESET_PASSWORD_WITHOUT_VALIDATED_EMAIL = "Cannot reset password without validated e-mail address"; public static final String CANNOT_RESET_PASSWORD_WITHOUT_VALIDATED_EMAIL = "Cannot reset password without validated e-mail address";
public static final String USER_DOESNT_HAVE_PERMISSION = "The user does not have the required permission"; public static final String USER_DOESNT_HAVE_PERMISSION = "The user does not have the required permission";
public static final String CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION = "Client currently locked for user creation";
public static final String PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER = "Password authentication currently locked for user";
private final String message; private final String message;
@@ -127,6 +127,8 @@ public class AuthenticationManagerImpl implements AuthenticationManager {
if (caught instanceof UserManagementException) { if (caught instanceof UserManagementException) {
if (Util.hasLength(caught.getMessage()) && caught.getMessage().equals(USER_ALREADY_EXISTS)) { if (Util.hasLength(caught.getMessage()) && caught.getMessage().equals(USER_ALREADY_EXISTS)) {
view.setErrorMessage(i18n.userAlreadyExists(name)); view.setErrorMessage(i18n.userAlreadyExists(name));
} else if (Util.hasLength(caught.getMessage()) && caught.getMessage().equals(UserManagementException.CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION)) {
view.setErrorMessage(i18n.clientCurrentlyLockedForUserCreation());
} else { } else {
Notification.notify(i18n.errorCreatingUser(name, caught.getMessage()==null?"":caught.getMessage()), NotificationType.ERROR); Notification.notify(i18n.errorCreatingUser(name, caught.getMessage()==null?"":caught.getMessage()), NotificationType.ERROR);
} }
@@ -224,4 +224,6 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages {
String paymentUnfinished(); String paymentUnfinished();
String paymentFinished(); String paymentFinished();
String lockedUntil(); String lockedUntil();
String passwordAuthenticationCurrentlyLockedForUser();
String clientCurrentlyLockedForUserCreation();
} }
@@ -230,4 +230,6 @@ takeMeToSubscriptions=Go to subscription plans
errorPollingCheckoutResults=Could not retrieve payment status. errorPollingCheckoutResults=Could not retrieve payment status.
paymentUnfinished=Waiting for payment to process. paymentUnfinished=Waiting for payment to process.
paymentFinished=Payment successful. Plan roles have been granted. paymentFinished=Payment successful. Plan roles have been granted.
lockedUntil=Locked until lockedUntil=Locked until
passwordAuthenticationCurrentlyLockedForUser=Password authentication is currently locked for this user due to too many failed login attempts. Please try again later.
clientCurrentlyLockedForUserCreation=Client is currently locked for user creation after too many user creations by the same client. Please try again later.
@@ -226,4 +226,6 @@ takeMeToSubscriptions=Zur Abbonementübersicht
errorPollingCheckoutResults=Der Zahlungsstatus konnte nicht abgerufen werden. errorPollingCheckoutResults=Der Zahlungsstatus konnte nicht abgerufen werden.
paymentUnfinished=Warte auf Zahlungsbestätigung. paymentUnfinished=Warte auf Zahlungsbestätigung.
paymentFinished=Zahlung erfolgreich. Planrollen wurden verliehen. paymentFinished=Zahlung erfolgreich. Planrollen wurden verliehen.
lockedUntil=Gesperrt bis lockedUntil=Gesperrt bis
passwordAuthenticationCurrentlyLockedForUser=Passwort-Authentifizierung ist für diesen Benutzer derzeit aufgrund zu vieler fehlgeschlagener Versuche gesperrt. Bitter später erneut versuchen.
clientCurrentlyLockedForUserCreation=Benutzererstellung für den aktuellen Client ist derzeit wegen zu vieler neuer Nutzer vom selben Client gesperrt. Bitte später erneut versuchen.
@@ -179,6 +179,8 @@ public class EditProfileEntryPoint implements EntryPoint {
Notification.notify(stringMessages.passwordDoesNotMeetRequirements(), NotificationType.ERROR); Notification.notify(stringMessages.passwordDoesNotMeetRequirements(), NotificationType.ERROR);
} else if (UserManagementException.INVALID_CREDENTIALS.equals(message)) { } else if (UserManagementException.INVALID_CREDENTIALS.equals(message)) {
Notification.notify(stringMessages.invalidCredentials(), NotificationType.ERROR); Notification.notify(stringMessages.invalidCredentials(), NotificationType.ERROR);
} else if (UserManagementException.PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER.equals(message)) {
Notification.notify(stringMessages.passwordAuthenticationCurrentlyLockedForUser(), NotificationType.ERROR);
} else { } else {
Notification.notify(stringMessages.errorChangingPassword(caught.getMessage()), NotificationType.ERROR); Notification.notify(stringMessages.errorChangingPassword(caught.getMessage()), NotificationType.ERROR);
} }
@@ -94,29 +94,32 @@ public class RegisterView extends Composite {
/* fullName */ null, /* company */ null, LocaleInfo.getCurrentLocale().getLocaleName(), /* fullName */ null, /* company */ null, LocaleInfo.getCurrentLocale().getLocaleName(),
EntryPointLinkFactory.createEmailValidationLink(new HashMap<String, String>()), EntryPointLinkFactory.createEmailValidationLink(new HashMap<String, String>()),
new AsyncCallback<UserDTO>() { new AsyncCallback<UserDTO>() {
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
final String message = caught.getMessage(); final String message = caught.getMessage();
if (caught instanceof UserManagementException) { if (caught instanceof UserManagementException) {
if (Util.hasLength(message) && message.equals(USER_ALREADY_EXISTS)) { if (Util.hasLength(message) && message.equals(USER_ALREADY_EXISTS)) {
Notification.notify(stringMessages.userAlreadyExists(usernameTextBox.getText()), NotificationType.ERROR); Notification.notify(stringMessages.userAlreadyExists(usernameTextBox.getText()), NotificationType.ERROR);
} else { } else if (Util.hasLength(message) && message.equals(UserManagementException.CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION)) {
Notification.notify(stringMessages.errorCreatingUser(usernameTextBox.getText(), message==null?"":message), NotificationType.ERROR); Notification.notify(stringMessages.clientCurrentlyLockedForUserCreation(), NotificationType.ERROR);
} else {
Notification.notify(stringMessages.errorCreatingUser(usernameTextBox.getText(),
message == null ? "" : message), NotificationType.ERROR);
}
} else {
Notification.notify(stringMessages.errorCreatingUser(usernameTextBox.getText(), message), NotificationType.ERROR);
}
}
@Override
public void onSuccess(UserDTO result) {
if (result != null) {
Notification.notify(stringMessages.signedUpSuccessfully(result.getName()), NotificationType.SUCCESS);
closeWindow();
} else {
Notification.notify(stringMessages.unknownErrorCreatingUser(usernameTextBox.getText()), NotificationType.ERROR);
}
} }
} else {
Notification.notify(stringMessages.errorCreatingUser(usernameTextBox.getText(), message), NotificationType.ERROR);
}
}
@Override
public void onSuccess(UserDTO result) {
if (result != null) {
Notification.notify(stringMessages.signedUpSuccessfully(result.getName()), NotificationType.SUCCESS);
closeWindow();
} else {
Notification.notify(stringMessages.unknownErrorCreatingUser(usernameTextBox.getText()), NotificationType.ERROR);
}
}
}); });
} }
@@ -103,6 +103,8 @@ public class UserDetailsPresenter implements AbstractUserDetails.Presenter {
Notification.notify(i18n_sec.passwordDoesNotMeetRequirements(), NotificationType.ERROR); Notification.notify(i18n_sec.passwordDoesNotMeetRequirements(), NotificationType.ERROR);
} else if (UserManagementException.INVALID_CREDENTIALS.equals(message)) { } else if (UserManagementException.INVALID_CREDENTIALS.equals(message)) {
Notification.notify(i18n_sec.invalidCredentials(), NotificationType.ERROR); Notification.notify(i18n_sec.invalidCredentials(), NotificationType.ERROR);
} else if (UserManagementException.PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER.equals(message)) {
Notification.notify(i18n_sec.passwordAuthenticationCurrentlyLockedForUser(), NotificationType.ERROR);
} else { } else {
Notification.notify(i18n_sec.errorChangingPassword(caught.getMessage()), NotificationType.ERROR); Notification.notify(i18n_sec.errorChangingPassword(caught.getMessage()), NotificationType.ERROR);
} }
@@ -1152,7 +1152,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
if (lockingAndBanning == null || !lockingAndBanning.isAuthenticationLocked()) { if (lockingAndBanning == null || !lockingAndBanning.isAuthenticationLocked()) {
apply(s->s.internalRecordUserCreationFromClientIP(clientIP)); apply(s->s.internalRecordUserCreationFromClientIP(clientIP));
} else { } else {
throw new UserManagementException("Client IP "+clientIP+" locked for user creation: "+lockingAndBanning); throw new UserManagementException(UserManagementException.CLIENT_CURRENTLY_LOCKED_FOR_USER_CREATION);
} }
} }
} }
@@ -1267,7 +1267,7 @@ implements ReplicableSecurityService, ClearStateTestSupport {
throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST); throw new UserManagementException(UserManagementException.USER_DOES_NOT_EXIST);
} }
if (user.getLockingAndBanning().isAuthenticationLocked()) { if (user.getLockingAndBanning().isAuthenticationLocked()) {
throw new UserManagementException("Password authentication is locked for user "+username); throw new UserManagementException(UserManagementException.PASSWORD_AUTHENTICATION_CURRENTLY_LOCKED_FOR_USER);
} }
final UsernamePasswordAccount account = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD); final UsernamePasswordAccount account = (UsernamePasswordAccount) user.getAccount(AccountType.USERNAME_PASSWORD);
String hashedOldPassword = hashPassword(password, account.getSalt()); String hashedOldPassword = hashPassword(password, account.getSalt());