sql injections fixes
This commit is contained in:
+3
-2
@@ -242,10 +242,11 @@ public class ProvisioningEntriesReadPlatformServiceImpl implements ProvisioningE
|
||||
@Override
|
||||
public ProvisioningEntryData retrieveProvisioningEntryData(String date) {
|
||||
ProvisioningEntryDataMapper mapper1 = new ProvisioningEntryDataMapper();
|
||||
final String sql1 = "select " + mapper1.getSchema() + " where entry.created_date like " + "'" + date + "%'";
|
||||
date = date+"%";
|
||||
final String sql1 = "select " + mapper1.getSchema() + " where entry.created_date like ? ";
|
||||
ProvisioningEntryData data = null;
|
||||
try {
|
||||
data = this.jdbcTemplate.queryForObject(sql1, mapper1, new Object[] {});
|
||||
data = this.jdbcTemplate.queryForObject(sql1, mapper1, new Object[] {date});
|
||||
} catch (EmptyResultDataAccessException e) {
|
||||
|
||||
}
|
||||
|
||||
+16
-10
@@ -41,6 +41,7 @@ import org.apache.fineract.infrastructure.core.service.Page;
|
||||
import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
@@ -91,6 +92,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
private final PaginationParametersDataValidator paginationParametersDataValidator;
|
||||
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
|
||||
private final DepositProductReadPlatformService depositProductReadPlatformService;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
@@ -99,7 +101,8 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
final LoanProductReadPlatformService loanProductReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
|
||||
final PaginationParametersDataValidator paginationParametersDataValidator,
|
||||
final SavingsProductReadPlatformService savingsProductReadPlatformService,
|
||||
final DepositProductReadPlatformService depositProductReadPlatformService) {
|
||||
final DepositProductReadPlatformService depositProductReadPlatformService,
|
||||
final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
@@ -111,6 +114,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
this.paginationParametersDataValidator = paginationParametersDataValidator;
|
||||
this.savingsProductReadPlatformService = savingsProductReadPlatformService;
|
||||
this.depositProductReadPlatformService = depositProductReadPlatformService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
private static final class AuditMapper implements RowMapper<AuditData> {
|
||||
@@ -190,7 +194,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
}
|
||||
|
||||
updatedExtraCriteria += " order by aud.id DESC limit " + PaginationParameters.getCheckedLimit(null);
|
||||
return retrieveEntries("audit", updatedExtraCriteria, includeJson);
|
||||
return retrieveEntries("audit", updatedExtraCriteria, includeJson, StringUtils.isNotBlank(extraCriteria));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -203,7 +207,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
String updatedExtraCriteria = "";
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
updatedExtraCriteria = " where (" + extraCriteria + ")";
|
||||
updatedExtraCriteria = " where (" + extraCriteria + ")";
|
||||
}
|
||||
|
||||
final AuditMapper rm = new AuditMapper();
|
||||
@@ -211,7 +215,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(rm.schema(includeJson, hierarchy));
|
||||
sqlBuilder.append(' ').append(updatedExtraCriteria);
|
||||
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), extraCriteria);
|
||||
if (parameters.isOrderByRequested()) {
|
||||
sqlBuilder.append(' ').append(parameters.orderBySql());
|
||||
} else {
|
||||
@@ -240,10 +244,10 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
updatedExtraCriteria += " group by aud.id order by aud.id";
|
||||
|
||||
return retrieveEntries("makerchecker", updatedExtraCriteria, includeJson);
|
||||
return retrieveEntries("makerchecker", updatedExtraCriteria, includeJson, StringUtils.isNotBlank(extraCriteria));
|
||||
}
|
||||
|
||||
public Collection<AuditData> retrieveEntries(final String useType, final String extraCriteria, final boolean includeJson) {
|
||||
public Collection<AuditData> retrieveEntries(final String useType, final String extraCriteria, final boolean includeJson, boolean isExtraCritereaIncluded) {
|
||||
|
||||
if (!(useType.equals("audit") || useType.equals("makerchecker"))) { throw new PlatformDataIntegrityException(
|
||||
"error.msg.invalid.auditSearchTemplate.useType", "Invalid Audit Search Template UseType: " + useType); }
|
||||
@@ -253,7 +257,7 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
final AuditMapper rm = new AuditMapper();
|
||||
String sql = "select " + rm.schema(includeJson, hierarchy);
|
||||
|
||||
|
||||
Boolean isLimitedChecker = false;
|
||||
if (useType.equals("makerchecker")) {
|
||||
if (currentUser.hasNotPermissionForAnyOf("ALL_FUNCTIONS", "CHECKER_SUPER_USER")) {
|
||||
@@ -267,7 +271,9 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
+ " join m_appuser_role ur on ur.role_id = r.id and ur.appuser_id = " + currentUser.getId();
|
||||
}
|
||||
sql += extraCriteria;
|
||||
|
||||
if(isExtraCritereaIncluded){
|
||||
this.columnValidator.validateSqlInjection(sql, extraCriteria);
|
||||
}
|
||||
logger.info("sql: " + sql);
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
@@ -281,9 +287,9 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
|
||||
|
||||
final AuditMapper rm = new AuditMapper();
|
||||
|
||||
final String sql = "select " + rm.schema(true, hierarchy) + " where aud.id = " + auditId;
|
||||
final String sql = "select " + rm.schema(true, hierarchy) + " where aud.id = ? ";
|
||||
|
||||
final AuditData auditResult = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
|
||||
final AuditData auditResult = this.jdbcTemplate.queryForObject(sql, rm, new Object[] {auditId});
|
||||
|
||||
return replaceIdsOnAuditData(auditResult);
|
||||
}
|
||||
|
||||
+8
-5
@@ -86,17 +86,20 @@ public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatat
|
||||
if (status != null || entity != null || productId != null) {
|
||||
sqlBuilder.append(" where ");
|
||||
}
|
||||
|
||||
List<Object> paramList = new ArrayList<>();
|
||||
if (status != null) {
|
||||
sqlBuilder.append(" status_enum = " + status);
|
||||
sqlBuilder.append(" status_enum = ? ");
|
||||
paramList.add(status);
|
||||
}
|
||||
|
||||
if (entity != null) {
|
||||
sqlBuilder.append(" and t.application_table_name = '" + entity + "'");
|
||||
sqlBuilder.append(" and t.application_table_name = ? ");
|
||||
paramList.add(entity);
|
||||
}
|
||||
|
||||
if (productId != null) {
|
||||
sqlBuilder.append(" and t.product_id = " + productId);
|
||||
sqlBuilder.append(" and t.product_id = ? ");
|
||||
paramList.add(productId);
|
||||
}
|
||||
if (searchParameters.isLimited()) {
|
||||
sqlBuilder.append(" limit ").append(searchParameters.getLimit());
|
||||
@@ -105,7 +108,7 @@ public class EntityDatatableChecksReadPlatformServiceImpl implements EntityDatat
|
||||
}
|
||||
}
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sqlBuilder.toString(), new Object[] {},
|
||||
return this.paginationHelper.fetchPage(jdbcTemplate, sqlCountRows, sqlBuilder.toString(),paramList.toArray(),
|
||||
entityDataTableChecksMapper);
|
||||
|
||||
}
|
||||
|
||||
+10
-2
@@ -49,6 +49,7 @@ import org.apache.fineract.infrastructure.dataqueries.exception.DatatableEntryRe
|
||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
|
||||
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableSystemErrorException;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.LocalDateTime;
|
||||
@@ -134,6 +135,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
if (appTable == null) {
|
||||
andClause = "";
|
||||
} else {
|
||||
SQLInjectionValidator.validateSQLInput(appTable);
|
||||
andClause = " and application_table_name = '" + appTable + "'";
|
||||
}
|
||||
|
||||
@@ -164,6 +166,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
public DatatableData retrieveDatatable(final String datatable) {
|
||||
|
||||
// PERMITTED datatables
|
||||
SQLInjectionValidator.validateSQLInput(datatable);
|
||||
final String sql = "select application_table_name, registered_table_name" + " from x_registered_table " + " where exists"
|
||||
+ " (select 'f'" + " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id"
|
||||
+ " left join m_role_permission rp on rp.role_id = r.id" + " left join m_permission p on p.id = rp.permission_id"
|
||||
@@ -1161,7 +1164,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
// id only used for reading a specific entry in a one to many datatable
|
||||
// (when updating)
|
||||
if (id == null) {
|
||||
sql = sql + "select * from `" + dataTableName + "` where " + getFKField(appTable) + " = " + appTableId;
|
||||
String whereClause = getFKField(appTable) + " = " + appTableId;
|
||||
SQLInjectionValidator.validateSQLInput(whereClause);
|
||||
sql = sql + "select * from `" + dataTableName + "` where " + whereClause;
|
||||
} else {
|
||||
sql = sql + "select * from `" + dataTableName + "` where id = " + id;
|
||||
}
|
||||
@@ -1185,7 +1190,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
// id only used for reading a specific entry in a one to many datatable
|
||||
// (when updating)
|
||||
if (id == null) {
|
||||
sql = sql + "select * from `" + dataTableName + "` where " + getFKField(appTable) + " = " + appTableId;
|
||||
String whereClause = getFKField(appTable) + " = " + appTableId;
|
||||
SQLInjectionValidator.validateSQLInput(whereClause);
|
||||
sql = sql + "select * from `" + dataTableName + "` where " + whereClause;
|
||||
} else {
|
||||
sql = sql + "select * from `" + dataTableName + "` where id = " + id;
|
||||
}
|
||||
@@ -1333,6 +1340,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
|
||||
}
|
||||
|
||||
private String queryForApplicationTableName(final String datatable) {
|
||||
SQLInjectionValidator.validateSQLInput(datatable);
|
||||
final String sql = "SELECT application_table_name FROM x_registered_table where registered_table_name = '" + datatable + "'";
|
||||
|
||||
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* Licensed to the Apache ftware Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.security.utils;
|
||||
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ColumnValidator {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Autowired
|
||||
public ColumnValidator(final RoutingDataSource dataSource) {
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
}
|
||||
|
||||
private void validateColumn(Map<String, Set<String>> tableColumnMap) {
|
||||
try {
|
||||
DatabaseMetaData dbMetaData = this.jdbcTemplate.getDataSource()
|
||||
.getConnection().getMetaData();
|
||||
ResultSet resultSet = null;
|
||||
for (HashMap.Entry<String, Set<String>> entry : tableColumnMap
|
||||
.entrySet()) {
|
||||
Set<String> columns = entry.getValue();
|
||||
resultSet = dbMetaData.getColumns(null, null, entry.getKey(),
|
||||
null);
|
||||
Set<String> tableColumns = getTableColumns(resultSet);
|
||||
if (columns.size() > 0 && tableColumns.size() == 0) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
for (String requestedColumn : columns) {
|
||||
if (!tableColumns.contains(requestedColumn)) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> getTableColumns(final ResultSet rs) {
|
||||
Set<String> columns = new HashSet<>();
|
||||
try {
|
||||
while (rs.next()) {
|
||||
columns.add(rs.getString("column_name"));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void validateSqlInjection(String schema, String condition) {
|
||||
SQLInjectionValidator.validateSQLInput(condition);
|
||||
List<String> operator = new ArrayList<>(Arrays.asList("=", ">", "<",
|
||||
"> =", "< =", "! =", "!=", ">=", "<="));
|
||||
condition = condition.trim().replace("( ", "(").replace(" )", ")")
|
||||
.toLowerCase();
|
||||
for (String op : operator) {
|
||||
condition = replaceAll(condition, op).replaceAll(" +", " ");
|
||||
}
|
||||
Set<String> operands = getOperand(condition);
|
||||
schema = schema.trim().replaceAll(" +", " ").toLowerCase();
|
||||
Map<String, Set<String>> tableColumnAliasMap = getTableColumnAliasMap(operands);
|
||||
Map<String, Set<String>> tableColumnMap = getTableColumnMap(schema,
|
||||
tableColumnAliasMap);
|
||||
validateColumn(tableColumnMap);
|
||||
}
|
||||
|
||||
private static Map<String, Set<String>> getTableColumnMap(String schema,
|
||||
Map<String, Set<String>> tableColumnAliasMap) {
|
||||
Map<String, Set<String>> tableColumnMap = new HashMap<>();
|
||||
schema = schema.substring(schema.indexOf("from"));
|
||||
for (String alias : tableColumnAliasMap.keySet()) {
|
||||
int index = schema.indexOf(" " + alias + " ");
|
||||
if (index > -1) {
|
||||
int startPos = 0;
|
||||
startPos = schema.substring(0, index - 1).lastIndexOf(' ',
|
||||
index);
|
||||
Set<String> columns = tableColumnAliasMap.get(alias);
|
||||
tableColumnMap.put(schema.substring(startPos, index).trim(),
|
||||
columns);
|
||||
} else {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
return tableColumnMap;
|
||||
}
|
||||
|
||||
private static Map<String, Set<String>> getTableColumnAliasMap(
|
||||
Set<String> operands) {
|
||||
Map<String, Set<String>> tableColumnMap = new HashMap<>();
|
||||
for (String operand : operands) {
|
||||
String[] tableColumn = operand.split("\\.");
|
||||
if (tableColumn.length == 2) {
|
||||
if (tableColumnMap.containsKey(tableColumn[0])) {
|
||||
Set<String> columns = tableColumnMap.get(tableColumn[0]);
|
||||
columns.add(tableColumn[1]);
|
||||
} else {
|
||||
Set<String> columns = new HashSet<>();
|
||||
columns.add(tableColumn[1]);
|
||||
tableColumnMap.put(tableColumn[0], columns);
|
||||
}
|
||||
} else {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
return tableColumnMap;
|
||||
}
|
||||
|
||||
private static Set<String> getOperand(String condition) {
|
||||
Set<String> operandList = new HashSet<>();
|
||||
List<String> operatorList = new ArrayList<>(Arrays.asList("!=", "=",
|
||||
">", "<", " like ", " between ", " in ", " in(", " is ",
|
||||
" is not ", " equals ", " not equals "));
|
||||
for (String op : operatorList) {
|
||||
int startIndex = 0;
|
||||
do {
|
||||
int index = condition.indexOf(op, startIndex);
|
||||
if (index > -1) {
|
||||
char currentChar = condition.charAt(index - 1);
|
||||
if (op.equals("=")) {
|
||||
if (!((currentChar + "").equals("!")
|
||||
|| (currentChar + "").equals(">") || (currentChar + "")
|
||||
.equals("<"))) {
|
||||
operandList.add(getOperand(condition, index,
|
||||
currentChar));
|
||||
}
|
||||
} else {
|
||||
operandList.add(getOperand(condition, index,
|
||||
currentChar));
|
||||
}
|
||||
|
||||
startIndex = index + op.length();
|
||||
}
|
||||
|
||||
} while (condition.indexOf(op, startIndex) > -1);
|
||||
}
|
||||
return operandList;
|
||||
}
|
||||
|
||||
private static String getOperand(String condition, int index,
|
||||
char currentChar) {
|
||||
int startPos = 0;
|
||||
if ((currentChar + "").equals(" ")) {
|
||||
startPos = condition.substring(0, index - 1)
|
||||
.lastIndexOf(' ', index);
|
||||
} else {
|
||||
startPos = condition.substring(0, index).lastIndexOf(' ', index);
|
||||
}
|
||||
String a = condition.substring(startPos == -1 ? 0 : startPos, index);
|
||||
return a.trim().replace("(", "").replace(")", "");
|
||||
}
|
||||
|
||||
private static String replaceAll(String condition, String op) {
|
||||
int startIndex = 0;
|
||||
do {
|
||||
int index = condition.indexOf(op, startIndex);
|
||||
if (index > -1) {
|
||||
if (op.equals("=")) {
|
||||
if (!((condition.charAt(index - 1) + "").equals("!")
|
||||
|| (condition.charAt(index - 1) + "").equals(">") || (condition
|
||||
.charAt(index - 1) + "").equals("<"))) {
|
||||
condition = condition.replace(op, " " + op + " ");
|
||||
return condition;
|
||||
}
|
||||
startIndex = index + 2 + op.length();
|
||||
|
||||
} else if (op.equals("< =") || op.equals("> =")
|
||||
|| op.equals("! =")) {
|
||||
condition = condition.replace(op, op.replace(" ", ""));
|
||||
return condition;
|
||||
} else {
|
||||
condition = condition.replace(op, " " + op + " ");
|
||||
return condition;
|
||||
}
|
||||
} else {
|
||||
return condition;
|
||||
}
|
||||
|
||||
} while (condition.indexOf(op, startIndex) > -1);
|
||||
return condition;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.security.utils;
|
||||
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
|
||||
|
||||
public class SQLInjectionException extends PlatformApiDataValidationException {
|
||||
|
||||
public SQLInjectionException() {
|
||||
super("error.msg.found.sql.injection", "Unexpected SQL Commands found", null);
|
||||
}
|
||||
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.infrastructure.security.utils;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SQLInjectionValidator {
|
||||
|
||||
private final static String[] DDL_COMMANDS = { "create", "drop", "alter", "truncate", "comment" };
|
||||
|
||||
private final static String[] DML_COMMANDS = { "select", "insert", "update", "delete", "merge", "upsert", "call" };
|
||||
|
||||
private final static String[] COMMENTS = { "--", "({", "/*", "#" };
|
||||
|
||||
private final static String SQL_PATTERN = "[a-zA-Z_=,'!><.?\"`% ()0-9]*";
|
||||
|
||||
public final static void validateSQLInput(final String sqlSearch) {
|
||||
String lowerCaseSQL = sqlSearch.toLowerCase();
|
||||
for (String ddl : DDL_COMMANDS) {
|
||||
if (lowerCaseSQL.contains(ddl)) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
|
||||
for (String dml : DML_COMMANDS) {
|
||||
if (lowerCaseSQL.contains(dml)) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
|
||||
for (String comments : COMMENTS) {
|
||||
if (lowerCaseSQL.contains(comments)) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
|
||||
//Removing the space before and after '=' operator
|
||||
//String s = " \" OR 1 = 1"; For the cases like this
|
||||
boolean injectionFound = false;
|
||||
String inputSqlString = lowerCaseSQL;
|
||||
while (inputSqlString.indexOf(" =") > 0) { //Don't remove space before = operator
|
||||
inputSqlString = inputSqlString.replaceAll(" =", "=");
|
||||
}
|
||||
|
||||
while (inputSqlString.indexOf("= ") > 0) { //Don't remove space after = operator
|
||||
inputSqlString = inputSqlString.replaceAll("= ", "=");
|
||||
}
|
||||
|
||||
StringTokenizer tokenizer = new StringTokenizer(inputSqlString, " ");
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken().trim();
|
||||
if (token.equals("'")) {
|
||||
if (tokenizer.hasMoreElements()) {
|
||||
String nextToken = tokenizer.nextToken().trim();
|
||||
if (!nextToken.equals("'")) {
|
||||
injectionFound = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
injectionFound = true;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if (token.equals("\"")) {
|
||||
if (tokenizer.hasMoreElements()) {
|
||||
String nextToken = tokenizer.nextToken().trim();
|
||||
if (!nextToken.equals("\"")) {
|
||||
injectionFound = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
injectionFound = true;
|
||||
break ;
|
||||
}
|
||||
} else if (token.indexOf('=') > 0) {
|
||||
StringTokenizer operatorToken = new StringTokenizer(token, "=");
|
||||
String operand = operatorToken.nextToken().trim();
|
||||
if (!operatorToken.hasMoreTokens()) {
|
||||
injectionFound = true;
|
||||
break;
|
||||
}
|
||||
String value = operatorToken.nextToken().trim();
|
||||
if (operand.equals(value)) {
|
||||
injectionFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (injectionFound) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
|
||||
Pattern pattern = Pattern.compile(SQL_PATTERN);
|
||||
Matcher matcher = pattern.matcher(sqlSearch);
|
||||
if (!matcher.matches()) {
|
||||
throw new SQLInjectionException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
-5
@@ -31,6 +31,7 @@ import org.apache.fineract.infrastructure.dataqueries.data.ResultsetColumnHeader
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.GenericDataService;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.ReadWriteNonCoreDataService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.infrastructure.survey.data.ClientScoresOverview;
|
||||
import org.apache.fineract.infrastructure.survey.data.LikelihoodStatus;
|
||||
import org.apache.fineract.infrastructure.survey.data.SurveyDataTableData;
|
||||
@@ -96,6 +97,7 @@ public class ReadSurveyServiceImpl implements ReadSurveyService {
|
||||
|
||||
@Override
|
||||
public SurveyDataTableData retrieveSurvey(String surveyName) {
|
||||
SQLInjectionValidator.validateSQLInput(surveyName);
|
||||
final String sql = "select cf.enabled, application_table_name, registered_table_name" + " from x_registered_table "
|
||||
+ " left join c_configuration cf on x_registered_table.registered_table_name = cf.name " + " where exists" + " (select 'f'"
|
||||
+ " from m_appuser_role ur " + " join m_role r on r.id = ur.role_id"
|
||||
@@ -125,13 +127,13 @@ public class ReadSurveyServiceImpl implements ReadSurveyService {
|
||||
@Override
|
||||
public List<ClientScoresOverview> retrieveClientSurveyScoreOverview(String surveyName, Long clientId) {
|
||||
|
||||
final String sql = "SELECT tz.id, lkh.name, lkh.code, poverty_line, tz.date, tz.score FROM " + surveyName + " tz"
|
||||
+ " JOIN ppi_likelihoods_ppi lkp on lkp.ppi_name = '" + surveyName + "' AND enabled = '" + LikelihoodStatus.ENABLED
|
||||
+ "' JOIN ppi_scores sc on score_from <= tz.score AND score_to >=tz.score"
|
||||
final String sql = "SELECT tz.id, lkh.name, lkh.code, poverty_line, tz.date, tz.score FROM ? tz"
|
||||
+ " JOIN ppi_likelihoods_ppi lkp on lkp.ppi_name = ? AND enabled = ? "
|
||||
+ " JOIN ppi_scores sc on score_from <= tz.score AND score_to >=tz.score"
|
||||
+ " JOIN ppi_poverty_line pvl on pvl.likelihood_ppi_id = lkp.id AND pvl.score_id = sc.id"
|
||||
+ " JOIN ppi_likelihoods lkh on lkh.id = lkp.likelihood_id " + " WHERE client_id = " + clientId;
|
||||
+ " JOIN ppi_likelihoods lkh on lkh.id = lkp.likelihood_id " + " WHERE client_id = ? ";
|
||||
|
||||
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql);
|
||||
final SqlRowSet rs = this.jdbcTemplate.queryForRowSet(sql, new Object[] { surveyName, surveyName, LikelihoodStatus.ENABLED, clientId });
|
||||
|
||||
List<ClientScoresOverview> scoresOverviews = new ArrayList<>();
|
||||
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ public class MixTaxonomyReadPlatformServiceImpl implements MixTaxonomyReadPlatfo
|
||||
|
||||
@Override
|
||||
public MixTaxonomyData retrieveOne(final Long id) {
|
||||
final String sql = "select " + this.mixTaxonomyMapper.schema() + " where tx.id =" + id;
|
||||
return this.jdbcTemplate.queryForObject(sql, this.mixTaxonomyMapper);
|
||||
final String sql = "select " + this.mixTaxonomyMapper.schema() + " where tx.id = ? ";
|
||||
return this.jdbcTemplate.queryForObject(sql, this.mixTaxonomyMapper, new Object[] { id });
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -58,15 +58,15 @@ public class NamespaceReadPlatformServiceImpl implements NamespaceReadPlatformSe
|
||||
|
||||
@Override
|
||||
public NamespaceData retrieveNamespaceById(final Long id) {
|
||||
final String sql = this.namespaceMapper.schema() + " where id=" + id;
|
||||
final String sql = this.namespaceMapper.schema() + " where id= ? ";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, this.namespaceMapper);
|
||||
return this.jdbcTemplate.queryForObject(sql, this.namespaceMapper, new Object[] { id });
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceData retrieveNamespaceByPrefix(final String prefix) {
|
||||
final String sql = this.namespaceMapper.schema() + " where prefix='" + prefix + "'";
|
||||
final String sql = this.namespaceMapper.schema() + " where prefix = ? ";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, this.namespaceMapper);
|
||||
return this.jdbcTemplate.queryForObject(sql, this.namespaceMapper, new Object[] { prefix });
|
||||
}
|
||||
}
|
||||
+42
-25
@@ -30,6 +30,8 @@ import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
import org.apache.fineract.organisation.staff.exception.StaffNotFoundException;
|
||||
import org.apache.fineract.portfolio.client.domain.ClientStatus;
|
||||
@@ -49,11 +51,14 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
private final PlatformSecurityContext context;
|
||||
private final StaffLookupMapper lookupMapper = new StaffLookupMapper();
|
||||
private final StaffInOfficeHierarchyMapper staffInOfficeHierarchyMapper = new StaffInOfficeHierarchyMapper();
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) {
|
||||
public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
private static final class StaffMapper implements RowMapper<StaffData> {
|
||||
@@ -157,20 +162,20 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
|
||||
@Override
|
||||
public Collection<StaffData> retrieveAllLoanOfficersInOfficeById(final Long officeId) {
|
||||
return retrieveAllStaff(" office_id=" + officeId + " and is_loan_officer=1");
|
||||
return retrieveAllStaff(" office_id = ? and is_loan_officer=1", officeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<StaffData> retrieveAllStaffForDropdown(final Long officeId) {
|
||||
|
||||
//adding the Authorization criteria so that a user cannot see an employee who does not belong to his office or a sub office for his office.
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy();
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy()+"%";
|
||||
|
||||
final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId);
|
||||
|
||||
final String sql = "select " + this.lookupMapper.schema() + " where s.office_id = ? and s.is_active=1 and o.hierarchy like '"+ hierarchy+ "%'";
|
||||
final String sql = "select " + this.lookupMapper.schema() + " where s.office_id = ? and s.is_active=1 and o.hierarchy like ? ";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { defaultOfficeId });
|
||||
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { defaultOfficeId, hierarchy });
|
||||
}
|
||||
|
||||
private Long defaultToUsersOfficeIfNull(final Long officeId) {
|
||||
@@ -185,14 +190,14 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
public StaffData retrieveStaff(final Long staffId) {
|
||||
|
||||
//adding the Authorization criteria so that a user cannot see an employee who does not belong to his office or a sub office for his office.
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy();
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy()+ "%";
|
||||
|
||||
|
||||
try {
|
||||
final StaffMapper rm = new StaffMapper();
|
||||
final String sql = "select " + rm.schema() + " where s.id = ? and o.hierarchy like '"+ hierarchy+ "%'" ;
|
||||
final String sql = "select " + rm.schema() + " where s.id = ? and o.hierarchy like ? " ;
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { staffId });
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { staffId, hierarchy });
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new StaffNotFoundException(staffId);
|
||||
}
|
||||
@@ -202,18 +207,22 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
public Collection<StaffData> retrieveAllStaff(final String sqlSearch, final Long officeId, final boolean loanOfficersOnly,
|
||||
final String status) {
|
||||
final String extraCriteria = getStaffCriteria(sqlSearch, officeId, loanOfficersOnly, status);
|
||||
return retrieveAllStaff(extraCriteria);
|
||||
return retrieveAllStaff(extraCriteria, officeId);
|
||||
}
|
||||
|
||||
private Collection<StaffData> retrieveAllStaff(final String extraCriteria) {
|
||||
|
||||
private Collection<StaffData> retrieveAllStaff(final String extraCriteria, Long officeId) {
|
||||
|
||||
final StaffMapper rm = new StaffMapper();
|
||||
String sql = "select " + rm.schema();
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sql += " where " + extraCriteria;
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy()+"%";
|
||||
if (StringUtils.isNotBlank(extraCriteria)){
|
||||
sql += " where " + extraCriteria;
|
||||
}
|
||||
sql = sql + " order by s.lastname";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
if(officeId==null){
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {hierarchy });
|
||||
}
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {officeId, hierarchy });
|
||||
}
|
||||
|
||||
private String getStaffCriteria(final String sqlSearch, final Long officeId, final boolean loanOfficersOnly, final String status) {
|
||||
@@ -222,9 +231,11 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
|
||||
if (sqlSearch != null) {
|
||||
extraCriteria.append(" and (").append(sqlSearch).append(")");
|
||||
final StaffMapper rm = new StaffMapper();
|
||||
this.columnValidator.validateSqlInjection(rm.schema(), sqlSearch);
|
||||
}
|
||||
if (officeId != null) {
|
||||
extraCriteria.append(" and office_id = ").append(officeId).append(" ");
|
||||
extraCriteria.append(" and s.office_id = ? ");
|
||||
}
|
||||
if (loanOfficersOnly) {
|
||||
extraCriteria.append(" and s.is_loan_officer is true ");
|
||||
@@ -232,21 +243,21 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
// Passing status parameter to get ACTIVE (By Default), INACTIVE or ALL
|
||||
// (Both active and Inactive) employees
|
||||
if (status.equalsIgnoreCase("active")) {
|
||||
extraCriteria.append(" and is_active = 1 ");
|
||||
extraCriteria.append(" and s.is_active = 1 ");
|
||||
} else if (status.equalsIgnoreCase("inActive")) {
|
||||
extraCriteria.append(" and is_active = 0 ");
|
||||
extraCriteria.append(" and s.is_active = 0 ");
|
||||
} else if (status.equalsIgnoreCase("all")) {} else {
|
||||
throw new UnrecognizedQueryParamException("status", status, new Object[] { "all", "active", "inactive" });
|
||||
}
|
||||
|
||||
//adding the Authorization criteria so that a user cannot see an employee who does not belong to his office or a sub office for his office.
|
||||
final String hierarchy = this.context.authenticatedUser().getOffice().getHierarchy();
|
||||
extraCriteria.append(" and o.hierarchy like '"+ hierarchy+ "%' ");
|
||||
|
||||
extraCriteria.append(" and o.hierarchy like ? ");
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria.toString())) {
|
||||
extraCriteria.delete(0, 4);
|
||||
}
|
||||
|
||||
|
||||
// remove begin four letter including a space from the string.
|
||||
return extraCriteria.toString();
|
||||
}
|
||||
@@ -265,15 +276,21 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
|
||||
|
||||
String sql = "select c.display_name as client, g.display_name as grp,l.loan_officer_id as loan, s.field_officer_id as sav"+
|
||||
" from m_staff staff "+
|
||||
" left outer join m_client c on staff.id = c.staff_id AND c.status_enum < "+ ClientStatus.CLOSED.getValue() +
|
||||
" left outer join m_client c on staff.id = c.staff_id AND c.status_enum < ? "+
|
||||
" left outer join m_group g on staff.id = g.staff_id " +
|
||||
" left outer join m_loan l on staff.id = l.loan_officer_id and l.loan_status_id < " + LoanStatus.WITHDRAWN_BY_CLIENT.getValue() +
|
||||
" left outer join m_savings_account s on c.staff_id = s.field_officer_id and s.status_enum < "+ SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT.getValue() +
|
||||
" where staff.id = " + staffId +
|
||||
" left outer join m_loan l on staff.id = l.loan_officer_id and l.loan_status_id < ? " +
|
||||
" left outer join m_savings_account s on c.staff_id = s.field_officer_id and s.status_enum < ? "+
|
||||
" where staff.id = ? "+
|
||||
" group by staff.id";
|
||||
|
||||
|
||||
List<Map<String, Object>> result = this.jdbcTemplate.queryForList(sql);
|
||||
List<Map<String, Object>> result = this.jdbcTemplate.queryForList(
|
||||
sql,
|
||||
new Object[] {
|
||||
ClientStatus.CLOSED.getValue(),
|
||||
LoanStatus.WITHDRAWN_BY_CLIENT.getValue(),
|
||||
SavingsAccountStatusType.WITHDRAWN_BY_APPLICANT
|
||||
.getValue(), staffId });
|
||||
if (result != null) {
|
||||
for (Map<String, Object> map : result) {
|
||||
if (map.get("client") != null) {
|
||||
|
||||
+17
-6
@@ -33,6 +33,7 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.service.CurrencyReadPlatformService;
|
||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||
@@ -70,16 +71,18 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
private final StaffReadPlatformService staffReadPlatformService;
|
||||
private final CurrencyReadPlatformService currencyReadPlatformService;
|
||||
private final PaginationHelper<CashierTransactionData> paginationHelper = new PaginationHelper<>();
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public TellerManagementReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
final OfficeReadPlatformService officeReadPlatformService, StaffReadPlatformService staffReadPlatformService,
|
||||
final CurrencyReadPlatformService currencyReadPlatformService) {
|
||||
final CurrencyReadPlatformService currencyReadPlatformService, final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
this.staffReadPlatformService = staffReadPlatformService;
|
||||
this.currencyReadPlatformService = currencyReadPlatformService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
private static final class TellerMapper implements RowMapper<TellerData> {
|
||||
@@ -223,11 +226,11 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
|
||||
@Override
|
||||
public Collection<TellerData> retrieveAllTellers(final String sqlSearch, final Long officeId, final String status) {
|
||||
final String extraCriteria = getTellerCriteria(sqlSearch, officeId, status);
|
||||
return retrieveAllTeller(extraCriteria);
|
||||
final String extraCriteria = getTellerCriteria(sqlSearch, officeId, status);
|
||||
return retrieveAllTeller(extraCriteria, officeId);
|
||||
}
|
||||
|
||||
private Collection<TellerData> retrieveAllTeller(final String extraCriteria) {
|
||||
private Collection<TellerData> retrieveAllTeller(final String extraCriteria, final Long officeId) {
|
||||
|
||||
final TellerMapper tm = new TellerMapper();
|
||||
String sql = "select " + tm.schema();
|
||||
@@ -235,6 +238,9 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
sql += " where " + extraCriteria;
|
||||
}
|
||||
sql = sql + " order by t.teller_name";
|
||||
if(officeId!=null){
|
||||
return this.jdbcTemplate.query(sql, tm, new Object[] {officeId});
|
||||
}
|
||||
return this.jdbcTemplate.query(sql, tm, new Object[] {});
|
||||
}
|
||||
|
||||
@@ -244,9 +250,11 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
|
||||
if (sqlSearch != null) {
|
||||
extraCriteria.append(" and (").append(sqlSearch).append(")");
|
||||
final TellerMapper tm = new TellerMapper();
|
||||
this.columnValidator.validateSqlInjection(tm.schema(), sqlSearch);
|
||||
}
|
||||
if (officeId != null) {
|
||||
extraCriteria.append(" and office_id = ").append(officeId).append(" ");
|
||||
extraCriteria.append(" and office_id = ? ");
|
||||
}
|
||||
// Passing status parameter to get ACTIVE (By Default), INACTIVE or ALL
|
||||
// (Both active and Inactive) employees
|
||||
@@ -278,7 +286,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
|
||||
@Override
|
||||
public Collection<CashierData> retrieveCashiersForTellers(final String sqlSearch, final Long tellerId) {
|
||||
final String extraCriteria = getTellerCriteria(sqlSearch, tellerId);
|
||||
final String extraCriteria = getTellerCriteria(sqlSearch, tellerId);
|
||||
return fetchCashiers(extraCriteria);
|
||||
}
|
||||
|
||||
@@ -288,6 +296,9 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
|
||||
if (sqlSearch != null) {
|
||||
extraCriteria.append(" and (").append(sqlSearch).append(")");
|
||||
final CashierMapper cm = new CashierMapper();
|
||||
this.columnValidator.validateSqlInjection(cm.schema(), sqlSearch);
|
||||
|
||||
}
|
||||
if (tellerId != null) {
|
||||
extraCriteria.append(" and teller_id = ").append(tellerId).append(" ");
|
||||
|
||||
+7
-1
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData;
|
||||
import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData;
|
||||
@@ -56,13 +57,16 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final ClientReadPlatformService clientReadPlatformService;
|
||||
private final GroupReadPlatformService groupReadPlatformService;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public AccountDetailsReadPlatformServiceJpaRepositoryImpl(final ClientReadPlatformService clientReadPlatformService,
|
||||
final RoutingDataSource dataSource, final GroupReadPlatformService groupReadPlatformService) {
|
||||
final RoutingDataSource dataSource, final GroupReadPlatformService groupReadPlatformService,
|
||||
final ColumnValidator columnValidator) {
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.groupReadPlatformService = groupReadPlatformService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,6 +123,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
||||
private List<LoanAccountSummaryData> retrieveLoanAccountDetails(final String loanwhereClause, final Object[] inputs) {
|
||||
final LoanAccountSummaryDataMapper rm = new LoanAccountSummaryDataMapper();
|
||||
final String sql = "select " + rm.loanAccountSummarySchema() + loanwhereClause;
|
||||
this.columnValidator.validateSqlInjection(rm.loanAccountSummarySchema(), loanwhereClause);
|
||||
return this.jdbcTemplate.query(sql, rm, inputs);
|
||||
}
|
||||
|
||||
@@ -129,6 +134,7 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou
|
||||
private List<SavingsAccountSummaryData> retrieveAccountDetails(final String savingswhereClause, final Object[] inputs) {
|
||||
final SavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new SavingsAccountSummaryDataMapper();
|
||||
final String savingsSql = "select " + savingsAccountSummaryDataMapper.schema() + savingswhereClause;
|
||||
this.columnValidator.validateSqlInjection(savingsAccountSummaryDataMapper.schema() , savingswhereClause);
|
||||
return this.jdbcTemplate.query(savingsSql, savingsAccountSummaryDataMapper, inputs);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -102,13 +102,13 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService
|
||||
public Collection<ChargeData> retrieveAllChargesForCurrency(String currencyCode) {
|
||||
final ChargeMapper rm = new ChargeMapper();
|
||||
|
||||
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.currency_code='" + currencyCode + "' ";
|
||||
String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.currency_code= ? ";
|
||||
|
||||
sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled();
|
||||
|
||||
sql += " order by c.name ";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {currencyCode});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+28
-20
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.client.service;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -41,6 +42,7 @@ import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
@@ -86,6 +88,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
private final AddressReadPlatformService addressReadPlatformService;
|
||||
private final ConfigurationReadPlatformService configurationReadPlatformService;
|
||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
@@ -94,7 +97,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
final SavingsProductReadPlatformService savingsProductReadPlatformService,
|
||||
final AddressReadPlatformService addressReadPlatformService,
|
||||
final ConfigurationReadPlatformService configurationReadPlatformService,
|
||||
final EntityDatatableChecksReadService entityDatatableChecksReadService) {
|
||||
final EntityDatatableChecksReadService entityDatatableChecksReadService,
|
||||
final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.officeReadPlatformService = officeReadPlatformService;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
@@ -104,6 +108,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
this.addressReadPlatformService=addressReadPlatformService;
|
||||
this.configurationReadPlatformService=configurationReadPlatformService;
|
||||
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,6 +170,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Transactional(readOnly=true)
|
||||
public Page<ClientData> retrieveAll(final SearchParameters searchParameters) {
|
||||
|
||||
final String userOfficeHierarchy = this.context.officeHierarchy();
|
||||
@@ -175,7 +181,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
// this.context.validateAccessRights(searchParameters.getHierarchy());
|
||||
// underHierarchySearchString = searchParameters.getHierarchy() + "%";
|
||||
// }
|
||||
|
||||
List<Object> paramList = new ArrayList<>(Arrays.asList(underHierarchySearchString, underHierarchySearchString));
|
||||
final StringBuilder sqlBuilder = new StringBuilder(200);
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(this.clientMapper.schema());
|
||||
@@ -183,10 +189,11 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
if(searchParameters.isSelfUser()){
|
||||
sqlBuilder.append(" and c.id in (select umap.client_id from m_selfservice_user_client_mapping as umap where umap.appuser_id = ? ) ");
|
||||
paramList.add(appUserID);
|
||||
}
|
||||
|
||||
final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
|
||||
|
||||
final String extraCriteria = buildSqlStringFromClientCriteria(this.clientMapper.schema(), searchParameters, paramList);
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sqlBuilder.append(" and (").append(extraCriteria).append(")");
|
||||
}
|
||||
@@ -207,14 +214,10 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
}
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
Object[] params = new Object[] {underHierarchySearchString, underHierarchySearchString };
|
||||
if(searchParameters.isSelfUser()){
|
||||
params = new Object[] {underHierarchySearchString, underHierarchySearchString, appUserID };
|
||||
}
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), params, this.clientMapper);
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(), paramList.toArray(), this.clientMapper);
|
||||
}
|
||||
|
||||
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
|
||||
private String buildSqlStringFromClientCriteria(String schemaSql, final SearchParameters searchParameters, List<Object> paramList) {
|
||||
|
||||
String sqlSearch = searchParameters.getSqlSearch();
|
||||
final Long officeId = searchParameters.getOfficeId();
|
||||
@@ -228,32 +231,38 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
sqlSearch = sqlSearch.replaceAll(" display_name ", " c.display_name ");
|
||||
sqlSearch = sqlSearch.replaceAll("display_name ", "c.display_name ");
|
||||
extraCriteria = " and (" + sqlSearch + ")";
|
||||
this.columnValidator.validateSqlInjection(schemaSql, sqlSearch);
|
||||
}
|
||||
|
||||
if (officeId != null) {
|
||||
extraCriteria += " and c.office_id = " + officeId;
|
||||
extraCriteria += " and c.office_id = ? ";
|
||||
paramList.add(officeId);
|
||||
}
|
||||
|
||||
if (externalId != null) {
|
||||
extraCriteria += " and c.external_id like " + ApiParameterHelper.sqlEncodeString(externalId);
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(externalId));
|
||||
extraCriteria += " and c.external_id like ? " ;
|
||||
}
|
||||
|
||||
if (displayName != null) {
|
||||
//extraCriteria += " and concat(ifnull(c.firstname, ''), if(c.firstname > '',' ', '') , ifnull(c.lastname, '')) like "
|
||||
extraCriteria += " and c.display_name like "
|
||||
+ ApiParameterHelper.sqlEncodeString("%" + displayName + "%");
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(ApiParameterHelper.sqlEncodeString("%" + displayName + "%")));
|
||||
extraCriteria += " and c.display_name like ? ";
|
||||
}
|
||||
|
||||
if (firstname != null) {
|
||||
extraCriteria += " and c.firstname like " + ApiParameterHelper.sqlEncodeString(firstname);
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(firstname));
|
||||
extraCriteria += " and c.firstname like ? " ;
|
||||
}
|
||||
|
||||
if (lastname != null) {
|
||||
extraCriteria += " and c.lastname like " + ApiParameterHelper.sqlEncodeString(lastname);
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(lastname));
|
||||
extraCriteria += " and c.lastname like ? ";
|
||||
}
|
||||
|
||||
if (searchParameters.isScopedByOfficeHierarchy()) {
|
||||
extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(searchParameters.getHierarchy() + "%");
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(searchParameters.getHierarchy() + "%"));
|
||||
extraCriteria += " and o.hierarchy like ? ";
|
||||
}
|
||||
|
||||
if(searchParameters.isOrphansOnly()){
|
||||
@@ -263,7 +272,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
extraCriteria = extraCriteria.substring(4);
|
||||
}
|
||||
|
||||
return extraCriteria;
|
||||
}
|
||||
|
||||
@@ -297,8 +305,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sql += " and (" + extraCriteria + ")";
|
||||
}
|
||||
|
||||
this.columnValidator.validateSqlInjection(sql, extraCriteria);
|
||||
}
|
||||
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] {});
|
||||
}
|
||||
|
||||
|
||||
+29
-15
@@ -47,6 +47,8 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
@@ -90,6 +92,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final CalendarReadPlatformService calendarReadPlatformService;
|
||||
private final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
// data mappers
|
||||
private final CenterDataMapper centerMapper = new CenterDataMapper();
|
||||
@@ -104,7 +107,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
|
||||
final StaffReadPlatformService staffReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService,
|
||||
final PaginationParametersDataValidator paginationParametersDataValidator, final ConfigurationDomainService configurationDomainService,
|
||||
final CalendarReadPlatformService calendarReadPlatformService) {
|
||||
final CalendarReadPlatformService calendarReadPlatformService, final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
@@ -114,41 +117,48 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
this.paginationParametersDataValidator = paginationParametersDataValidator;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.calendarReadPlatformService = calendarReadPlatformService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
// 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where
|
||||
// clause is ambiguous
|
||||
// caused by the same name of columns in m_office and m_group tables
|
||||
private String getCenterExtraCriteria(final SearchParameters searchCriteria) {
|
||||
private String getCenterExtraCriteria(String schemaSl, List<Object> paramList,final SearchParameters searchCriteria) {
|
||||
|
||||
StringBuffer extraCriteria = new StringBuffer(200);
|
||||
extraCriteria.append(" and g.level_id = " + GroupTypes.CENTER.getId());
|
||||
|
||||
String sqlQueryCriteria = searchCriteria.getSqlSearch();
|
||||
if (StringUtils.isNotBlank(sqlQueryCriteria)) {
|
||||
SQLInjectionValidator.validateSQLInput(sqlQueryCriteria);
|
||||
sqlQueryCriteria = sqlQueryCriteria.replaceAll(" display_name ", " g.display_name ");
|
||||
sqlQueryCriteria = sqlQueryCriteria.replaceAll("display_name ", "g.display_name ");
|
||||
extraCriteria.append(" and (").append(sqlQueryCriteria).append(") ");
|
||||
this.columnValidator.validateSqlInjection(schemaSl, sqlQueryCriteria);
|
||||
}
|
||||
|
||||
final Long officeId = searchCriteria.getOfficeId();
|
||||
if (officeId != null) {
|
||||
extraCriteria.append(" and g.office_id = ").append(officeId);
|
||||
extraCriteria.append(" and g.office_id = ? ");
|
||||
paramList.add(officeId);
|
||||
}
|
||||
|
||||
final String externalId = searchCriteria.getExternalId();
|
||||
if (externalId != null) {
|
||||
extraCriteria.append(" and g.external_id = ").append(ApiParameterHelper.sqlEncodeString(externalId));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(externalId));
|
||||
extraCriteria.append(" and g.external_id = ? ");
|
||||
}
|
||||
|
||||
final String name = searchCriteria.getName();
|
||||
if (name != null) {
|
||||
extraCriteria.append(" and g.display_name like ").append(ApiParameterHelper.sqlEncodeString(name + "%"));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(name + "%"));
|
||||
extraCriteria.append(" and g.display_name like ? ");
|
||||
}
|
||||
|
||||
final String hierarchy = searchCriteria.getHierarchy();
|
||||
if (hierarchy != null) {
|
||||
extraCriteria.append(" and o.hierarchy like ").append(ApiParameterHelper.sqlEncodeString(hierarchy + "%"));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(hierarchy + "%"));
|
||||
extraCriteria.append(" and o.hierarchy like ? ");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria.toString())) {
|
||||
@@ -157,7 +167,8 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
|
||||
final Long staffId = searchCriteria.getStaffId();
|
||||
if (staffId != null) {
|
||||
extraCriteria.append(" and g.staff_id = ").append(staffId);
|
||||
paramList.add(staffId);
|
||||
extraCriteria.append(" and g.staff_id = ? ");
|
||||
}
|
||||
|
||||
return extraCriteria.toString();
|
||||
@@ -372,9 +383,10 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(this.centerMapper.schema());
|
||||
sqlBuilder.append(" where o.hierarchy like ?");
|
||||
|
||||
final String extraCriteria = getCenterExtraCriteria(searchParameters);
|
||||
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(hierarchySearchString));
|
||||
final String extraCriteria = getCenterExtraCriteria(this.centerMapper.schema(), paramList, searchParameters);
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), extraCriteria);
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sqlBuilder.append(" and (").append(extraCriteria).append(")");
|
||||
}
|
||||
@@ -392,7 +404,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
|
||||
new Object[] { hierarchySearchString }, this.centerMapper);
|
||||
paramList.toArray(), this.centerMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -407,9 +419,11 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
sqlBuilder.append("select ");
|
||||
sqlBuilder.append(this.centerMapper.schema());
|
||||
sqlBuilder.append(" where o.hierarchy like ?");
|
||||
|
||||
final String extraCriteria = getCenterExtraCriteria(searchParameters);
|
||||
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(hierarchySearchString));
|
||||
|
||||
final String extraCriteria = getCenterExtraCriteria(this.centerMapper.schema(), paramList, searchParameters);
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), extraCriteria);
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sqlBuilder.append(" and (").append(extraCriteria).append(")");
|
||||
}
|
||||
@@ -425,7 +439,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
|
||||
}
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sqlBuilder.toString(), this.centerMapper, new Object[] { hierarchySearchString });
|
||||
return this.jdbcTemplate.query(sqlBuilder.toString(), this.centerMapper, paramList.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+30
-16
@@ -39,6 +39,8 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.organisation.office.data.OfficeData;
|
||||
import org.apache.fineract.organisation.office.service.OfficeReadPlatformService;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
@@ -70,6 +72,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
private final AllGroupTypesDataMapper allGroupTypesDataMapper = new AllGroupTypesDataMapper();
|
||||
private final PaginationHelper<GroupGeneralData> paginationHelper = new PaginationHelper<>();
|
||||
private final PaginationParametersDataValidator paginationParametersDataValidator;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
private final static Set<String> supportedOrderByValues = new HashSet<>(Arrays.asList("id", "name", "officeId", "officeName"));
|
||||
|
||||
@@ -78,7 +81,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
final CenterReadPlatformService centerReadPlatformService,
|
||||
final OfficeReadPlatformService officeReadPlatformService, final StaffReadPlatformService staffReadPlatformService,
|
||||
final CodeValueReadPlatformService codeValueReadPlatformService,
|
||||
final PaginationParametersDataValidator paginationParametersDataValidator) {
|
||||
final PaginationParametersDataValidator paginationParametersDataValidator,
|
||||
final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.centerReadPlatformService = centerReadPlatformService;
|
||||
@@ -86,6 +90,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
this.staffReadPlatformService = staffReadPlatformService;
|
||||
this.codeValueReadPlatformService = codeValueReadPlatformService;
|
||||
this.paginationParametersDataValidator = paginationParametersDataValidator;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,9 +152,10 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
sqlBuilder.append("select SQL_CALC_FOUND_ROWS ");
|
||||
sqlBuilder.append(this.allGroupTypesDataMapper.schema());
|
||||
sqlBuilder.append(" where o.hierarchy like ?");
|
||||
|
||||
final String extraCriteria = getGroupExtraCriteria(searchParameters);
|
||||
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(hierarchySearchString));
|
||||
final String extraCriteria = getGroupExtraCriteria(this.allGroupTypesDataMapper.schema(), paramList, searchParameters);
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), extraCriteria);
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sqlBuilder.append(" and (").append(extraCriteria).append(")");
|
||||
}
|
||||
@@ -167,7 +173,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
|
||||
final String sqlCountRows = "SELECT FOUND_ROWS()";
|
||||
return this.paginationHelper.fetchPage(this.jdbcTemplate, sqlCountRows, sqlBuilder.toString(),
|
||||
new Object[] { hierarchySearchString }, this.allGroupTypesDataMapper);
|
||||
paramList.toArray(), this.allGroupTypesDataMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,9 +186,9 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
sqlBuilder.append("select ");
|
||||
sqlBuilder.append(this.allGroupTypesDataMapper.schema());
|
||||
sqlBuilder.append(" where o.hierarchy like ?");
|
||||
|
||||
final String extraCriteria = getGroupExtraCriteria(searchParameters);
|
||||
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(hierarchySearchString));
|
||||
final String extraCriteria = getGroupExtraCriteria(this.allGroupTypesDataMapper.schema(), paramList, searchParameters);
|
||||
if (StringUtils.isNotBlank(extraCriteria)) {
|
||||
sqlBuilder.append(" and (").append(extraCriteria).append(")");
|
||||
}
|
||||
@@ -195,45 +201,52 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
sqlBuilder.append(parameters.limitSql());
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sqlBuilder.toString(), this.allGroupTypesDataMapper, new Object[] { hierarchySearchString });
|
||||
return this.jdbcTemplate.query(sqlBuilder.toString(), this.allGroupTypesDataMapper, paramList.toArray());
|
||||
}
|
||||
|
||||
// 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where
|
||||
// clause is ambiguous
|
||||
// caused by the same name of columns in m_office and m_group tables
|
||||
private String getGroupExtraCriteria(final SearchParameters searchCriteria) {
|
||||
private String getGroupExtraCriteria(String schemaSql, List<Object> paramList, final SearchParameters searchCriteria) {
|
||||
|
||||
StringBuffer extraCriteria = new StringBuffer(200);
|
||||
extraCriteria.append(" and g.level_Id = ").append(GroupTypes.GROUP.getId());
|
||||
String sqlSearch = searchCriteria.getSqlSearch();
|
||||
if (sqlSearch != null) {
|
||||
SQLInjectionValidator.validateSQLInput(sqlSearch);
|
||||
sqlSearch = sqlSearch.replaceAll(" display_name ", " g.display_name ");
|
||||
sqlSearch = sqlSearch.replaceAll("display_name ", "g.display_name ");
|
||||
extraCriteria.append(" and ( ").append(sqlSearch).append(") ");
|
||||
this.columnValidator.validateSqlInjection(schemaSql, sqlSearch);
|
||||
}
|
||||
|
||||
final Long officeId = searchCriteria.getOfficeId();
|
||||
if (officeId != null) {
|
||||
extraCriteria.append(" and g.office_id = ").append(officeId);
|
||||
paramList.add(officeId);
|
||||
extraCriteria.append(" and g.office_id = ? ");
|
||||
}
|
||||
|
||||
final String externalId = searchCriteria.getExternalId();
|
||||
if (externalId != null) {
|
||||
extraCriteria.append(" and g.external_id = ").append(ApiParameterHelper.sqlEncodeString(externalId));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(externalId));
|
||||
extraCriteria.append(" and g.external_id = ? ");
|
||||
}
|
||||
|
||||
final String name = searchCriteria.getName();
|
||||
if (name != null) {
|
||||
extraCriteria.append(" and g.display_name like ").append(ApiParameterHelper.sqlEncodeString("%" + name + "%"));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString("%" + name + "%"));
|
||||
extraCriteria.append(" and g.display_name like ? ");
|
||||
}
|
||||
|
||||
final String hierarchy = searchCriteria.getHierarchy();
|
||||
if (hierarchy != null) {
|
||||
extraCriteria.append(" and o.hierarchy like ").append(ApiParameterHelper.sqlEncodeString(hierarchy + "%"));
|
||||
paramList.add(ApiParameterHelper.sqlEncodeString(hierarchy + "%"));
|
||||
extraCriteria.append(" and o.hierarchy like ? ");
|
||||
}
|
||||
|
||||
if (searchCriteria.isStaffIdPassed()) {
|
||||
extraCriteria.append(" and g.staff_id = ").append(searchCriteria.getStaffId());
|
||||
paramList.add(searchCriteria.getStaffId());
|
||||
extraCriteria.append(" and g.staff_id = ? ");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(extraCriteria.toString())) {
|
||||
@@ -242,7 +255,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
|
||||
|
||||
final Long staffId = searchCriteria.getStaffId();
|
||||
if (staffId != null) {
|
||||
extraCriteria.append(" and g.staff_id = ").append(staffId);
|
||||
paramList.add(staffId);
|
||||
extraCriteria.append(" and g.staff_id = ? ");
|
||||
}
|
||||
|
||||
if(searchCriteria.isOrphansOnly()){
|
||||
|
||||
+7
-1
@@ -44,6 +44,8 @@ import org.apache.fineract.infrastructure.core.service.PaginationHelper;
|
||||
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.core.service.SearchParameters;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.apache.fineract.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||
@@ -153,6 +155,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
private final LoanUtilService loanUtilService;
|
||||
private final ConfigurationDomainService configurationDomainService;
|
||||
private final AccountDetailsReadPlatformService accountDetailsReadPlatformService;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public LoanReadPlatformServiceImpl(final PlatformSecurityContext context, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||
@@ -166,7 +169,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
final FloatingRatesReadPlatformService floatingRatesReadPlatformService, final LoanUtilService loanUtilService,
|
||||
final ConfigurationDomainService configurationDomainService,
|
||||
final AccountDetailsReadPlatformService accountDetailsReadPlatformService,
|
||||
final LoanRepositoryWrapper loanRepositoryWrapper) {
|
||||
final LoanRepositoryWrapper loanRepositoryWrapper, final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.loanRepositoryWrapper = loanRepositoryWrapper ;
|
||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||
@@ -187,6 +190,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
this.loanUtilService = loanUtilService;
|
||||
this.configurationDomainService = configurationDomainService;
|
||||
this.accountDetailsReadPlatformService = accountDetailsReadPlatformService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -281,7 +285,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
|
||||
String sqlQueryCriteria = searchParameters.getSqlSearch();
|
||||
if (StringUtils.isNotBlank(sqlQueryCriteria)) {
|
||||
SQLInjectionValidator.validateSQLInput(sqlQueryCriteria);
|
||||
sqlQueryCriteria = sqlQueryCriteria.replaceAll("accountNo", "l.account_no");
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), sqlQueryCriteria);
|
||||
sqlBuilder.append(" and (").append(sqlQueryCriteria).append(")");
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -32,6 +32,7 @@ import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
|
||||
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType;
|
||||
import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAccessUtil;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.SQLInjectionValidator;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.portfolio.charge.data.ChargeData;
|
||||
import org.apache.fineract.portfolio.charge.service.ChargeReadPlatformService;
|
||||
@@ -121,7 +122,8 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
String sql = "select " + rm.schema();
|
||||
|
||||
if ((inClause != null) && (!(inClause.trim().isEmpty()))) {
|
||||
sql += " where lp.id in ( " + inClause + " ) ";
|
||||
sql += " where lp.id in ("+inClause+") ";
|
||||
SQLInjectionValidator.validateSQLInput(inClause);
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
@@ -534,17 +536,17 @@ public class LoanProductReadPlatformServiceImpl implements LoanProductReadPlatfo
|
||||
|
||||
final LoanProductMapper rm = new LoanProductMapper(null, null);
|
||||
|
||||
String sql = "select " + rm.loanProductSchema() + " where lp.currency_code='" + currencyCode + "'";
|
||||
String sql = "select " + rm.loanProductSchema() + " where lp.currency_code= ? ";
|
||||
|
||||
// Check if branch specific products are enabled. If yes, fetch only
|
||||
// products mapped to current user's office
|
||||
String inClause = fineractEntityAccessUtil
|
||||
.getSQLWhereClauseForProductIDsForUserOffice_ifGlobalConfigEnabled(FineractEntityType.LOAN_PRODUCT);
|
||||
if ((inClause != null) && (!(inClause.trim().isEmpty()))) {
|
||||
sql += " and id in ( " + inClause + " ) ";
|
||||
sql += " and id in (" + inClause + ") ";
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {});
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] {currencyCode});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-1
@@ -82,7 +82,8 @@ public class MeetingReadPlatformServiceImpl implements MeetingReadPlatformServic
|
||||
final MeetingDataMapper rm = new MeetingDataMapper();
|
||||
String sql = rm.schema() + " where ci.entity_id = ? and ci.entity_type_enum = ? ";
|
||||
if (limit != null && limit > 0) {
|
||||
sql = sql + " order by m.meeting_date desc " + " limit " + limit;
|
||||
sql = sql + " order by m.meeting_date desc " + " limit ? ";
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { entityId, entityTypeId, limit });
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { entityId, entityTypeId });
|
||||
|
||||
+17
-8
@@ -20,7 +20,10 @@ package org.apache.fineract.portfolio.note.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
@@ -86,14 +89,16 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
final NoteType noteType = NoteType.fromInt(noteTypeId);
|
||||
try {
|
||||
final NoteMapper rm = new NoteMapper();
|
||||
String conditionSql = getResourceCondition(noteType);
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(noteId, resourceId));
|
||||
String conditionSql = getResourceCondition(noteType, paramList);
|
||||
if (StringUtils.isNotBlank(conditionSql)) {
|
||||
conditionSql = " and " + conditionSql;
|
||||
}
|
||||
|
||||
final String sql = rm.schema() + " where n.id = ? " + conditionSql + " order by n.created_date DESC";
|
||||
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { noteId, resourceId });
|
||||
return this.jdbcTemplate.queryForObject(sql, rm, paramList.toArray());
|
||||
} catch (final EmptyResultDataAccessException e) {
|
||||
throw new NoteNotFoundException(noteId, resourceId, noteType.name().toLowerCase());
|
||||
}
|
||||
@@ -103,22 +108,26 @@ public class NoteReadPlatformServiceImpl implements NoteReadPlatformService {
|
||||
public Collection<NoteData> retrieveNotesByResource(final Long resourceId, final Integer noteTypeId) {
|
||||
final NoteType noteType = NoteType.fromInt(noteTypeId);
|
||||
final NoteMapper rm = new NoteMapper();
|
||||
final String conditionSql = getResourceCondition(noteType);
|
||||
List<Object> paramList = new ArrayList<>(
|
||||
Arrays.asList(resourceId));
|
||||
final String conditionSql = getResourceCondition(noteType, paramList);
|
||||
|
||||
final String sql = rm.schema() + " where " + conditionSql + " order by n.created_date DESC";
|
||||
|
||||
return this.jdbcTemplate.query(sql, rm, new Object[] { resourceId });
|
||||
return this.jdbcTemplate.query(sql, rm, paramList.toArray());
|
||||
}
|
||||
|
||||
public static String getResourceCondition(final NoteType noteType) {
|
||||
public static String getResourceCondition(final NoteType noteType, List<Object> paramList) {
|
||||
String conditionSql = "";
|
||||
switch (noteType) {
|
||||
case CLIENT:
|
||||
conditionSql = " n.client_id = ? and note_type_enum = " + NoteType.CLIENT.getValue();
|
||||
paramList.add(NoteType.CLIENT.getValue());
|
||||
conditionSql = " n.client_id = ? and note_type_enum = ?";
|
||||
break;
|
||||
case LOAN:
|
||||
conditionSql = " n.loan_id = ? and ( n.note_type_enum = " + NoteType.LOAN.getValue() + " or n.note_type_enum = "
|
||||
+ NoteType.LOAN_TRANSACTION.getValue() + " )";
|
||||
paramList.add(NoteType.LOAN.getValue());
|
||||
paramList.add(NoteType.LOAN_TRANSACTION.getValue());
|
||||
conditionSql = " n.loan_id = ? and ( n.note_type_enum = ? or n.note_type_enum = ? )";
|
||||
break;
|
||||
case LOAN_TRANSACTION:
|
||||
conditionSql = " n.loan_transaction_id = ? ";
|
||||
|
||||
+6
-7
@@ -241,21 +241,20 @@ public class SavingsAccountChargeReadPlatformServiceImpl implements SavingsAccou
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountAnnualFeeData> retrieveChargesWithAnnualFeeDue() {
|
||||
final String sql = "select " + this.chargeDueMapper.schema() + " where sac.charge_due_date is not null and sac.charge_time_enum = "
|
||||
+ ChargeTimeType.ANNUAL_FEE.getValue() + " and sac.charge_due_date <= NOW() and sa.status_enum = "
|
||||
+ SavingsAccountStatusType.ACTIVE.getValue();
|
||||
final String sql = "select " + this.chargeDueMapper.schema() + " where sac.charge_due_date is not null and sac.charge_time_enum = ? "
|
||||
+ " and sac.charge_due_date <= NOW() and sa.status_enum = ? ";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.chargeDueMapper, new Object[] {});
|
||||
return this.jdbcTemplate.query(sql, this.chargeDueMapper, new Object[] {ChargeTimeType.ANNUAL_FEE.getValue(), SavingsAccountStatusType.ACTIVE.getValue()});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<SavingsAccountAnnualFeeData> retrieveChargesWithDue() {
|
||||
final String sql = "select "
|
||||
+ this.chargeDueMapper.schema()
|
||||
+ " where sac.charge_due_date is not null and sac.charge_due_date <= NOW() and sac.waived = 0 and sac.is_paid_derived=0 and sac.is_active=1 and sa.status_enum = "
|
||||
+ SavingsAccountStatusType.ACTIVE.getValue() + " order by sac.charge_due_date ";
|
||||
+ " where sac.charge_due_date is not null and sac.charge_due_date <= NOW() and sac.waived = 0 and sac.is_paid_derived=0 and sac.is_active=1 and sa.status_enum = ? "
|
||||
+ " order by sac.charge_due_date ";
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.chargeDueMapper, new Object[] {});
|
||||
return this.jdbcTemplate.query(sql, this.chargeDueMapper, new Object[] {SavingsAccountStatusType.ACTIVE.getValue()});
|
||||
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -39,6 +39,7 @@ import org.apache.fineract.infrastructure.dataqueries.data.EntityTables;
|
||||
import org.apache.fineract.infrastructure.dataqueries.data.StatusEnum;
|
||||
import org.apache.fineract.infrastructure.dataqueries.service.EntityDatatableChecksReadService;
|
||||
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
|
||||
import org.apache.fineract.infrastructure.security.utils.ColumnValidator;
|
||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||
import org.apache.fineract.organisation.staff.data.StaffData;
|
||||
import org.apache.fineract.organisation.staff.service.StaffReadPlatformService;
|
||||
@@ -106,6 +107,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
private final PaginationHelper<SavingsAccountData> paginationHelper = new PaginationHelper<>();
|
||||
|
||||
private final EntityDatatableChecksReadService entityDatatableChecksReadService;
|
||||
private final ColumnValidator columnValidator;
|
||||
|
||||
@Autowired
|
||||
public SavingsAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
|
||||
@@ -113,7 +115,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
final SavingsProductReadPlatformService savingProductReadPlatformService,
|
||||
final StaffReadPlatformService staffReadPlatformService, final SavingsDropdownReadPlatformService dropdownReadPlatformService,
|
||||
final ChargeReadPlatformService chargeReadPlatformService,
|
||||
final EntityDatatableChecksReadService entityDatatableChecksReadService) {
|
||||
final EntityDatatableChecksReadService entityDatatableChecksReadService, final ColumnValidator columnValidator) {
|
||||
this.context = context;
|
||||
this.jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
this.clientReadPlatformService = clientReadPlatformService;
|
||||
@@ -127,6 +129,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
// this.annualFeeMapper = new SavingsAccountAnnualFeeMapper();
|
||||
this.chargeReadPlatformService = chargeReadPlatformService;
|
||||
this.entityDatatableChecksReadService = entityDatatableChecksReadService;
|
||||
this.columnValidator = columnValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,6 +182,7 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead
|
||||
String sqlQueryCriteria = searchParameters.getSqlSearch();
|
||||
if (StringUtils.isNotBlank(sqlQueryCriteria)) {
|
||||
sqlQueryCriteria = sqlQueryCriteria.replaceAll("accountNo", "sa.account_no");
|
||||
this.columnValidator.validateSqlInjection(sqlBuilder.toString(), sqlQueryCriteria);
|
||||
sqlBuilder.append(" and (").append(sqlQueryCriteria).append(")");
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -278,7 +278,7 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
|
||||
this.context.authenticatedUser();
|
||||
|
||||
String sql = "select " + this.savingsProductRowMapper.schema() + " where sp.currency_code='" + currencyCode + "'";
|
||||
String sql = "select " + this.savingsProductRowMapper.schema() + " where sp.currency_code= ? ";
|
||||
|
||||
// Check if branch specific products are enabled. If yes, fetch only
|
||||
// products mapped to current user's office
|
||||
@@ -288,6 +288,6 @@ public class SavingsProductReadPlatformServiceImpl implements SavingsProductRead
|
||||
sql += " and id in ( " + inClause + " ) ";
|
||||
}
|
||||
|
||||
return this.jdbcTemplate.query(sql, this.savingsProductRowMapper);
|
||||
return this.jdbcTemplate.query(sql, this.savingsProductRowMapper, new Object[] {currencyCode});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user