From 6f3170d80abe231f7edfd6ce64aa8e11b3520119 Mon Sep 17 00:00:00 2001 From: Jacopo Cappellato Date: Mon, 11 May 2026 10:02:58 +0200 Subject: [PATCH 1/2] Fixed: Implement permission checks for ENTITY_MAINT in EntitySQLProcessor and ProgramExport --- .../webtools/entity/EntitySQLProcessor.groovy | 104 ++--- .../webtools/entity/ProgramExport.groovy | 408 +++++++++--------- 2 files changed, 258 insertions(+), 254 deletions(-) diff --git a/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/EntitySQLProcessor.groovy b/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/EntitySQLProcessor.groovy index 289edf4cb61..fb10dff32d1 100644 --- a/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/EntitySQLProcessor.groovy +++ b/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/EntitySQLProcessor.groovy @@ -24,66 +24,68 @@ import java.sql.ResultSetMetaData import org.apache.ofbiz.entity.jdbc.SQLProcessor import org.apache.ofbiz.entity.model.ModelGroupReader -String sqlCommand = context.request.getParameter('sqlCommand') // (see OFBIZ-6567) +if (security.hasPermission('ENTITY_MAINT', session)) { + String sqlCommand = context.request.getParameter('sqlCommand') // (see OFBIZ-6567) -String resultMessage = '' -List columns = [] -List> records = [] -ModelGroupReader mgr = delegator.getModelGroupReader() -List> groups = [] -mgr.getGroupNames(delegator.getDelegatorName()).each { String group -> - groups.add(0, ['group': group]) //use for list-option in widget drop-down -} - -if (sqlCommand && selGroup) { - try (SQLProcessor du = new SQLProcessor(delegator, delegator.getGroupHelperInfo(selGroup))) { - if (sqlCommand.toUpperCase().startsWith('SELECT')) { - try (ResultSet rs = du.executeQuery(sqlCommand)) { - ResultSetMetaData rsmd = rs.getMetaData() + String resultMessage = '' + List columns = [] + List> records = [] + ModelGroupReader mgr = delegator.getModelGroupReader() + List> groups = [] + mgr.getGroupNames(delegator.getDelegatorName()).each { String group -> + groups.add(0, ['group': group]) //use for list-option in widget drop-down + } - int numberOfColumns = rsmd.getColumnCount() - for (int i = 1; i <= numberOfColumns; i++) { - columns.add(rsmd.getColumnLabel(i)) - } + if (sqlCommand && selGroup) { + try (SQLProcessor du = new SQLProcessor(delegator, delegator.getGroupHelperInfo(selGroup))) { + if (sqlCommand.toUpperCase().startsWith('SELECT')) { + try (ResultSet rs = du.executeQuery(sqlCommand)) { + ResultSetMetaData rsmd = rs.getMetaData() - boolean rowLimitReached = false - while (rs.next()) { - if (records.size() >= rowLimit) { - rowLimitReached = true - break + int numberOfColumns = rsmd.getColumnCount() + for (int i = 1; i <= numberOfColumns; i++) { + columns.add(rsmd.getColumnLabel(i)) } - List record = [] - for (int i = 1; i <= numberOfColumns; i++) { - record.add(rs.getObject(i)) + boolean rowLimitReached = false + while (rs.next()) { + if (records.size() >= rowLimit) { + rowLimitReached = true + break + } + + List record = [] + for (int i = 1; i <= numberOfColumns; i++) { + record.add(rs.getObject(i)) + } + records.add(record) } - records.add(record) + + resultMessage = "Returned ${rowLimitReached ? '' : 'top'} ${records.size() as String} rows." + } + } else { + if (sqlCommand.toUpperCase().contains('SYSCS_UTIL.SYSCS_EXPORT_TABLE') + || sqlCommand.toUpperCase().contains('JSP')) { + context.resultMessage = 'Not executed for security reason' + context.groups = groups + context.columns = columns + context.records = records + context.sqlCommand = sqlCommand + return } - resultMessage = "Returned ${rowLimitReached ? '' : 'top'} ${records.size() as String} rows." - } - } else { - if (sqlCommand.toUpperCase().contains('SYSCS_UTIL.SYSCS_EXPORT_TABLE') - || sqlCommand.toUpperCase().contains('JSP')) { - context.resultMessage = 'Not executed for security reason' - context.groups = groups - context.columns = columns - context.records = records - context.sqlCommand = sqlCommand - return + du.prepareStatement(sqlCommand) + numOfAffectedRows = du.executeUpdate() + resultMessage = "Affected $numOfAffectedRows rows." } - - du.prepareStatement(sqlCommand) - numOfAffectedRows = du.executeUpdate() - resultMessage = "Affected $numOfAffectedRows rows." + } catch (Exception exc) { + resultMessage = exc.getMessage() } - } catch (Exception exc) { - resultMessage = exc.getMessage() } -} -context.groups = groups -context.resultMessage = resultMessage -context.columns = columns -context.records = records -context.sqlCommand = sqlCommand // (see OFBIZ-6567) + context.groups = groups + context.resultMessage = resultMessage + context.columns = columns + context.records = records + context.sqlCommand = sqlCommand // (see OFBIZ-6567) +} diff --git a/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/ProgramExport.groovy b/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/ProgramExport.groovy index 693d3692e6c..7e8e405fd0b 100644 --- a/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/ProgramExport.groovy +++ b/framework/webtools/src/main/groovy/org/apache/ofbiz/webtools/entity/ProgramExport.groovy @@ -36,216 +36,218 @@ import org.codehaus.groovy.control.MultipleCompilationErrorsException import org.codehaus.groovy.control.customizers.ImportCustomizer import org.codehaus.groovy.control.customizers.SecureASTCustomizer -String groovyProgram = null -recordValues = [] -errMsgList = [] - -if (parameters.groovyProgram) { - groovyProgram = parameters.groovyProgram -} else { - groovyProgram = ''' -// Use the List variable recordValues to fill it with GenericValue maps. -// full groovy syntax is available -// Use full EntityQuery syntax instead of just the from method - -import org.apache.ofbiz.entity.util.EntityFindOptions - -// example: - -// find the first three record in the product entity (if any) -EntityFindOptions findOptions = new EntityFindOptions() -findOptions.setMaxRows(3) - -List products = delegator.findList(\'Product\', null, null, null, findOptions, false) -if (products != null) { - recordValues.addAll(products) -} - -// Get the last record created from the Product entity -condition = EntityCondition.makeCondition(\'productId\', EntityOperator.NOT_EQUAL, null) -product = EntityQuery.use(delegator).from(\'Product\').where(condition).orderBy(\'-productId\').queryFirst() -if (product) { - recordValues << product -} - -''' - parameters.groovyProgram = groovyProgram -} +if (security.hasPermission('ENTITY_MAINT', session)) { + String groovyProgram = null + recordValues = [] + errMsgList = [] + + if (parameters.groovyProgram) { + groovyProgram = parameters.groovyProgram + } else { + groovyProgram = ''' + // Use the List variable recordValues to fill it with GenericValue maps. + // full groovy syntax is available + // Use full EntityQuery syntax instead of just the from method + + import org.apache.ofbiz.entity.util.EntityFindOptions + + // example: + + // find the first three record in the product entity (if any) + EntityFindOptions findOptions = new EntityFindOptions() + findOptions.setMaxRows(3) + + List products = delegator.findList(\'Product\', null, null, null, findOptions, false) + if (products != null) { + recordValues.addAll(products) + } -// Dangerous Pattern Detection -// (?s) flag for multi-line/dotall matching to prevent whitespace bypass -List dangerousPatterns = [ - // Process & Command Execution + Runtime Variants - /(?s)Runtime\s*\.\s*getRuntime\s*\(\s*\)/, - /(?s)['"]java\.lang\.Runtime['"]\.class/, - /(?s)Runtime\.class\.getDeclaredMethod/, - /(?s)getRuntime\s*\(\s*\)\.exec/, - /(?s)ProcessBuilder/, - /(?s)\.\s*execute\s*\(/, - /(?s)System\s*\.\s*exit/, - // Reflection & ClassLoading - /(?s)Class\s*\.\s*forName/, - /(?s)\.newInstance\s*\(/, - /(?s)\.getDeclaredMethod/, - /(?s)\.getDeclaredField/, - /(?s)\.getMethod\s*\(/, - /(?s)\.getField\s*\(/, - /(?s)\.invoke\s*\(/, - /(?s)\.loadClass\s*\(/, - /(?s)\.getClassLoader\s*\(/, - /(?s)java\s*\.\s*lang\s*\.\s*reflect/, - /(?s)URLClassLoader/, - /(?s)GroovyClassLoader/, - /(?s)ScriptEngineManager/, - /(?s)javax\s*\.\s*script/, - /(?s)sun\s*\.\s*misc\s*\.\s*Unsafe/, - // Eval/GroovyShell Blocking - /(?s)Eval\s*\.\s*me/, - /(?s)Eval\s*\.\s*x/, - /(?s)Eval\s*\.\s*xy/, - /(?s)Eval\s*\.\s*xyz/, - /(?s)GroovyShell/, - /(?s)\.evaluate\s*\(/, - // File System Operations - /(?s)java\s*\.\s*io\s*\.\s*File\s*\(/, - /(?s)new\s+File\s*\(/, - /(?s)Files\s*\.\s*readAllBytes/, - /(?s)Paths\s*\.\s*get/, - /(?s)\.toFile\s*\(/, - /(?s)\.getResourceAsStream\s*\(/, - /(?s)\.getText\s*\(/, - /(?s)\.bytes\b/, - // Network Operations - /(?s)Socket\s*\(/, - /(?s)ServerSocket/, - /(?s)DatagramSocket/, - /(?s)InetSocketAddress/, - /(?s)InetAddress/, - /(?s)java\s*\.\s*net\s*\./, - /(?s)URL\s*\(/, - /(?s)NetworkInterface/, - /(?s)\.openConnection\s*\(/, - /(?s)\.connect\s*\(/, - // OFBiz Multitenancy Bypass - /(?s)DelegatorFactory/ -] - -for (String pattern : dangerousPatterns) { - if (groovyProgram =~ pattern) { - request.setAttribute('_ERROR_MESSAGE_', "Script contains prohibited pattern: ${pattern}") - return + // Get the last record created from the Product entity + condition = EntityCondition.makeCondition(\'productId\', EntityOperator.NOT_EQUAL, null) + product = EntityQuery.use(delegator).from(\'Product\').where(condition).orderBy(\'-productId\').queryFirst() + if (product) { + recordValues << product } -} -// Groovy Sandbox with SecureASTCustomizer -SecureASTCustomizer secureCustomizer = new SecureASTCustomizer() -secureCustomizer.with { - // Import whitelist - only safe OFBiz entity classes - setImportsWhitelist([ - 'org.apache.ofbiz.entity.GenericValue', - 'org.apache.ofbiz.entity.model.ModelEntity', - 'org.apache.ofbiz.entity.condition.EntityCondition', - 'org.apache.ofbiz.entity.condition.EntityOperator', - 'org.apache.ofbiz.entity.util.EntityQuery', - 'org.apache.ofbiz.entity.util.EntityFindOptions', - 'java.util.List', - 'java.util.Map', - 'java.util.Set' - ]) - setStarImportsWhitelist([]) - setStaticImportsWhitelist([]) - setStaticStarImportsWhitelist([]) - setIndirectImportCheckEnabled(false) - // Constant types whitelist - setConstantTypesClassesWhiteList([ - Object, String, Integer, Long, Float, Double, Boolean, - Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Boolean.TYPE, - BigDecimal, BigInteger, - Date, java.sql.Date, java.sql.Timestamp, - Range, IntRange, - GenericValue, ModelEntity, - EntityCondition, EntityOperator, - EntityQuery, EntityFindOptions, - List, Map, Set - ]) - // Token and statement restrictions - setTokensBlacklist([KEYWORD_PACKAGE, KEYWORD_IMPORT]) - setStatementsBlacklist([ - WhileStatement, ForStatement, - SwitchStatement - ]) - setExpressionsBlacklist([MethodPointerExpression]) - // Receiver whitelist - only safe OFBiz entity operations - setReceiversWhiteList([ - 'java.lang.Object', - 'org.apache.ofbiz.entity.Delegator', - 'org.apache.ofbiz.entity.util.EntityQuery', - 'org.apache.ofbiz.entity.util.EntityFindOptions', - 'org.apache.ofbiz.entity.GenericValue', - 'org.apache.ofbiz.entity.condition.EntityCondition', - 'org.apache.ofbiz.entity.condition.EntityOperator', - 'org.apache.ofbiz.entity.model.ModelEntity', - 'java.util.List', 'java.util.Map', 'java.util.Set', - 'java.lang.String', 'java.lang.Integer', - 'java.lang.Long', 'java.lang.Boolean', - 'java.util.Date', 'java.sql.Date', 'java.sql.Timestamp', - 'java.math.BigDecimal', 'java.math.BigInteger', - 'groovy.lang.Range', 'groovy.lang.IntRange' - ]) - setClosuresAllowed(true) - setMethodDefinitionAllowed(false) -} + ''' + parameters.groovyProgram = groovyProgram + } -// Add imports for script. -ImportCustomizer importCustomizer = new ImportCustomizer() -importCustomizer.addImport('org.apache.ofbiz.entity.GenericValue') -importCustomizer.addImport('org.apache.ofbiz.entity.model.ModelEntity') -importCustomizer.addImport('org.apache.ofbiz.entity.condition.EntityCondition') -importCustomizer.addImport('org.apache.ofbiz.entity.condition.EntityOperator') -importCustomizer.addImport('org.apache.ofbiz.entity.util.EntityQuery') - -// AST TRANSFORMATION BLOCKING - Disable Grape/Grab -CompilerConfiguration configuration = new CompilerConfiguration() -try { - Class grabTransform = Thread.currentThread().contextClassLoader - .loadClass('org.codehaus.groovy.transform.GrabAnnotationTransformation') - configuration.setDisabledGlobalASTTransformations( - [grabTransform.name] as Set) -} catch (ClassNotFoundException ignored) { -} -configuration.addCompilationCustomizers(importCustomizer) -configuration.addCompilationCustomizers(secureCustomizer) + // Dangerous Pattern Detection + // (?s) flag for multi-line/dotall matching to prevent whitespace bypass + List dangerousPatterns = [ + // Process & Command Execution + Runtime Variants + /(?s)Runtime\s*\.\s*getRuntime\s*\(\s*\)/, + /(?s)['"]java\.lang\.Runtime['"]\.class/, + /(?s)Runtime\.class\.getDeclaredMethod/, + /(?s)getRuntime\s*\(\s*\)\.exec/, + /(?s)ProcessBuilder/, + /(?s)\.\s*execute\s*\(/, + /(?s)System\s*\.\s*exit/, + // Reflection & ClassLoading + /(?s)Class\s*\.\s*forName/, + /(?s)\.newInstance\s*\(/, + /(?s)\.getDeclaredMethod/, + /(?s)\.getDeclaredField/, + /(?s)\.getMethod\s*\(/, + /(?s)\.getField\s*\(/, + /(?s)\.invoke\s*\(/, + /(?s)\.loadClass\s*\(/, + /(?s)\.getClassLoader\s*\(/, + /(?s)java\s*\.\s*lang\s*\.\s*reflect/, + /(?s)URLClassLoader/, + /(?s)GroovyClassLoader/, + /(?s)ScriptEngineManager/, + /(?s)javax\s*\.\s*script/, + /(?s)sun\s*\.\s*misc\s*\.\s*Unsafe/, + // Eval/GroovyShell Blocking + /(?s)Eval\s*\.\s*me/, + /(?s)Eval\s*\.\s*x/, + /(?s)Eval\s*\.\s*xy/, + /(?s)Eval\s*\.\s*xyz/, + /(?s)GroovyShell/, + /(?s)\.evaluate\s*\(/, + // File System Operations + /(?s)java\s*\.\s*io\s*\.\s*File\s*\(/, + /(?s)new\s+File\s*\(/, + /(?s)Files\s*\.\s*readAllBytes/, + /(?s)Paths\s*\.\s*get/, + /(?s)\.toFile\s*\(/, + /(?s)\.getResourceAsStream\s*\(/, + /(?s)\.getText\s*\(/, + /(?s)\.bytes\b/, + // Network Operations + /(?s)Socket\s*\(/, + /(?s)ServerSocket/, + /(?s)DatagramSocket/, + /(?s)InetSocketAddress/, + /(?s)InetAddress/, + /(?s)java\s*\.\s*net\s*\./, + /(?s)URL\s*\(/, + /(?s)NetworkInterface/, + /(?s)\.openConnection\s*\(/, + /(?s)\.connect\s*\(/, + // OFBiz Multitenancy Bypass + /(?s)DelegatorFactory/ + ] + + for (String pattern : dangerousPatterns) { + if (groovyProgram =~ pattern) { + request.setAttribute('_ERROR_MESSAGE_', "Script contains prohibited pattern: ${pattern}") + return + } + } -Binding binding = new Binding() -binding.setVariable('delegator', delegator) -binding.setVariable('recordValues', recordValues) + // Groovy Sandbox with SecureASTCustomizer + SecureASTCustomizer secureCustomizer = new SecureASTCustomizer() + secureCustomizer.with { + // Import whitelist - only safe OFBiz entity classes + setImportsWhitelist([ + 'org.apache.ofbiz.entity.GenericValue', + 'org.apache.ofbiz.entity.model.ModelEntity', + 'org.apache.ofbiz.entity.condition.EntityCondition', + 'org.apache.ofbiz.entity.condition.EntityOperator', + 'org.apache.ofbiz.entity.util.EntityQuery', + 'org.apache.ofbiz.entity.util.EntityFindOptions', + 'java.util.List', + 'java.util.Map', + 'java.util.Set' + ]) + setStarImportsWhitelist([]) + setStaticImportsWhitelist([]) + setStaticStarImportsWhitelist([]) + setIndirectImportCheckEnabled(false) + // Constant types whitelist + setConstantTypesClassesWhiteList([ + Object, String, Integer, Long, Float, Double, Boolean, + Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Boolean.TYPE, + BigDecimal, BigInteger, + Date, java.sql.Date, java.sql.Timestamp, + Range, IntRange, + GenericValue, ModelEntity, + EntityCondition, EntityOperator, + EntityQuery, EntityFindOptions, + List, Map, Set + ]) + // Token and statement restrictions + setTokensBlacklist([KEYWORD_PACKAGE, KEYWORD_IMPORT]) + setStatementsBlacklist([ + WhileStatement, ForStatement, + SwitchStatement + ]) + setExpressionsBlacklist([MethodPointerExpression]) + // Receiver whitelist - only safe OFBiz entity operations + setReceiversWhiteList([ + 'java.lang.Object', + 'org.apache.ofbiz.entity.Delegator', + 'org.apache.ofbiz.entity.util.EntityQuery', + 'org.apache.ofbiz.entity.util.EntityFindOptions', + 'org.apache.ofbiz.entity.GenericValue', + 'org.apache.ofbiz.entity.condition.EntityCondition', + 'org.apache.ofbiz.entity.condition.EntityOperator', + 'org.apache.ofbiz.entity.model.ModelEntity', + 'java.util.List', 'java.util.Map', 'java.util.Set', + 'java.lang.String', 'java.lang.Integer', + 'java.lang.Long', 'java.lang.Boolean', + 'java.util.Date', 'java.sql.Date', 'java.sql.Timestamp', + 'java.math.BigDecimal', 'java.math.BigInteger', + 'groovy.lang.Range', 'groovy.lang.IntRange' + ]) + setClosuresAllowed(true) + setMethodDefinitionAllowed(false) + } -ClassLoader loader = Thread.currentThread().getContextClassLoader() -GroovyShell shell = new GroovyShell(loader, binding, configuration) + // Add imports for script. + ImportCustomizer importCustomizer = new ImportCustomizer() + importCustomizer.addImport('org.apache.ofbiz.entity.GenericValue') + importCustomizer.addImport('org.apache.ofbiz.entity.model.ModelEntity') + importCustomizer.addImport('org.apache.ofbiz.entity.condition.EntityCondition') + importCustomizer.addImport('org.apache.ofbiz.entity.condition.EntityOperator') + importCustomizer.addImport('org.apache.ofbiz.entity.util.EntityQuery') -/* codenarc-disable ReturnNullFromCatchBlock */ -if (groovyProgram) { + // AST TRANSFORMATION BLOCKING - Disable Grape/Grab + CompilerConfiguration configuration = new CompilerConfiguration() try { - shell.parse(groovyProgram) - shell.evaluate(groovyProgram) - recordValues = shell.getVariable('recordValues') - xmlDoc = GenericValue.makeXmlDocument(recordValues) - context.put('xmlDoc', xmlDoc) - } catch (MultipleCompilationErrorsException e) { - request.setAttribute('_ERROR_MESSAGE_', e) - return - } catch (MissingPropertyException e) { - request.setAttribute('_ERROR_MESSAGE_', e) - return - } catch (IllegalArgumentException e) { - request.setAttribute('_ERROR_MESSAGE_', e) - return - } catch (SecurityException e) { - request.setAttribute('_ERROR_MESSAGE_', 'Security violation: ' + e.message) - return - } catch (Exception e) { - request.setAttribute('_ERROR_MESSAGE_', e) - return + Class grabTransform = Thread.currentThread().contextClassLoader + .loadClass('org.codehaus.groovy.transform.GrabAnnotationTransformation') + configuration.setDisabledGlobalASTTransformations( + [grabTransform.name] as Set) + } catch (ClassNotFoundException ignored) { + } + configuration.addCompilationCustomizers(importCustomizer) + configuration.addCompilationCustomizers(secureCustomizer) + + Binding binding = new Binding() + binding.setVariable('delegator', delegator) + binding.setVariable('recordValues', recordValues) + + ClassLoader loader = Thread.currentThread().getContextClassLoader() + GroovyShell shell = new GroovyShell(loader, binding, configuration) + + /* codenarc-disable ReturnNullFromCatchBlock */ + if (groovyProgram) { + try { + shell.parse(groovyProgram) + shell.evaluate(groovyProgram) + recordValues = shell.getVariable('recordValues') + xmlDoc = GenericValue.makeXmlDocument(recordValues) + context.put('xmlDoc', xmlDoc) + } catch (MultipleCompilationErrorsException e) { + request.setAttribute('_ERROR_MESSAGE_', e) + return + } catch (MissingPropertyException e) { + request.setAttribute('_ERROR_MESSAGE_', e) + return + } catch (IllegalArgumentException e) { + request.setAttribute('_ERROR_MESSAGE_', e) + return + } catch (SecurityException e) { + request.setAttribute('_ERROR_MESSAGE_', 'Security violation: ' + e.message) + return + } catch (Exception e) { + request.setAttribute('_ERROR_MESSAGE_', e) + return + } } + /* codenarc-enable ReturnNullFromCatchBlock */ } -/* codenarc-enable ReturnNullFromCatchBlock */ From 170109e3c9165e4d7be87fed4e907daf4c41b92b Mon Sep 17 00:00:00 2001 From: Jacopo Cappellato Date: Tue, 12 May 2026 12:48:53 +0200 Subject: [PATCH 2/2] Fixed: Remove unnecessary requirePasswordChange parameter from ChangePassword forms and adjust login workflow accordingly --- .../apache/ofbiz/webapp/control/LoginWorker.java | 14 +++++++------- themes/common-theme/template/ChangePassword.ftl | 1 - themes/helveticus/template/ChangePassword.ftl | 1 - themes/rainbowstone/template/ChangePassword.ftl | 1 - 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java index 5f8a15eccdc..4f0326a63f7 100644 --- a/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java +++ b/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/LoginWorker.java @@ -444,10 +444,9 @@ public static String login(HttpServletRequest request, HttpServletResponse respo if (UtilValidate.isEmpty(password) && UtilValidate.isEmpty(token)) { unpwErrMsgList.add(UtilProperties.getMessage(RESOURCE, "loginevents.password_was_empty_reenter", UtilHttp.getLocale(request))); } - boolean requirePasswordChange = "Y".equals(request.getParameter("requirePasswordChange")); if (!unpwErrMsgList.isEmpty()) { request.setAttribute("_ERROR_MESSAGE_LIST_", unpwErrMsgList); - return requirePasswordChange ? "requirePasswordChange" : "error"; + return "error"; } boolean setupNewDelegatorEtc = false; @@ -535,8 +534,9 @@ public static String login(HttpServletRequest request, HttpServletResponse respo if (ModelService.RESPOND_SUCCESS.equals(result.get(ModelService.RESPONSE_MESSAGE))) { GenericValue userLogin = (GenericValue) result.get("userLogin"); - - if (requirePasswordChange) { + if (userLogin != null && "Y".equals(userLogin.getString("requirePasswordChange")) + && UtilValidate.isNotEmpty(request.getParameter("newPassword")) + && UtilValidate.isNotEmpty(request.getParameter("newPasswordVerify"))) { Map inMap = UtilMisc.toMap( "login.username", username, "login.password", password, @@ -554,7 +554,7 @@ public static String login(HttpServletRequest request, HttpServletResponse respo String errMsg = UtilProperties.getMessage(RESOURCE, "loginevents.following_error_occurred_during_login", messageMap, UtilHttp.getLocale(request)); request.setAttribute("_ERROR_MESSAGE_", errMsg); - return "requirePasswordChange"; + return "error"; } if (ServiceUtil.isError(resultPasswordChange)) { String errorMessage = (String) resultPasswordChange.get(ModelService.ERROR_MESSAGE); @@ -565,7 +565,7 @@ public static String login(HttpServletRequest request, HttpServletResponse respo request.setAttribute("_ERROR_MESSAGE_", errMsg); } request.setAttribute("_ERROR_MESSAGE_LIST_", resultPasswordChange.get(ModelService.ERROR_MESSAGE_LIST)); - return "requirePasswordChange"; + return "error"; } else { try { userLogin.refresh(); @@ -575,7 +575,7 @@ public static String login(HttpServletRequest request, HttpServletResponse respo String errMsg = UtilProperties.getMessage(RESOURCE, "loginevents.following_error_occurred_during_login", messageMap, UtilHttp.getLocale(request)); request.setAttribute("_ERROR_MESSAGE_", errMsg); - return "requirePasswordChange"; + return "error"; } } } diff --git a/themes/common-theme/template/ChangePassword.ftl b/themes/common-theme/template/ChangePassword.ftl index 5c11996dd53..5a99d0baa45 100644 --- a/themes/common-theme/template/ChangePassword.ftl +++ b/themes/common-theme/template/ChangePassword.ftl @@ -29,7 +29,6 @@ under the License.
- diff --git a/themes/helveticus/template/ChangePassword.ftl b/themes/helveticus/template/ChangePassword.ftl index 9a0426c77c0..11dc9c90ee8 100644 --- a/themes/helveticus/template/ChangePassword.ftl +++ b/themes/helveticus/template/ChangePassword.ftl @@ -29,7 +29,6 @@ under the License.
- diff --git a/themes/rainbowstone/template/ChangePassword.ftl b/themes/rainbowstone/template/ChangePassword.ftl index 9a0426c77c0..11dc9c90ee8 100644 --- a/themes/rainbowstone/template/ChangePassword.ftl +++ b/themes/rainbowstone/template/ChangePassword.ftl @@ -29,7 +29,6 @@ under the License.
-