FINERACT-1894: Template request fix

This commit is contained in:
Aleksandar Vidakovic
2023-02-21 07:27:52 +01:00
committed by Aleksandar Vidakovic
parent 34e8b046a2
commit d27d9f343d
5 changed files with 75 additions and 9 deletions
@@ -52,6 +52,8 @@ public class FineractProperties {
private FineractJobProperties job;
private FineractTemplateProperties template;
@Getter
@Setter
public static class FineractTenantProperties {
@@ -234,4 +236,12 @@ public class FineractProperties {
private int stuckRetryThreshold;
}
@Getter
@Setter
public static class FineractTemplateProperties {
private boolean regexWhitelistEnabled;
private List<String> regexWhitelist;
}
}
@@ -0,0 +1,28 @@
/**
* 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.template.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
public class TemplateForbiddenException extends AbstractPlatformResourceNotFoundException {
public TemplateForbiddenException(final String url) {
super("error.msg.template.url.forbidden", "Template with url " + url + " not allowed");
}
}
@@ -38,20 +38,24 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.config.FineractProperties;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.template.domain.Template;
import org.apache.fineract.template.domain.TemplateFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.fineract.template.exception.TemplateForbiddenException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
public class TemplateMergeService {
private static final Logger LOG = LoggerFactory.getLogger(TemplateMergeService.class);
// private final FromJsonHelper fromApiJsonHelper;
private final FineractProperties fineractProperties;
// TODO Replace this with appropriate alternative available in Guava
private static String getStringFromInputStream(final InputStream is) {
@@ -64,7 +68,7 @@ public class TemplateMergeService {
sb.append(line);
}
} catch (final IOException e) {
LOG.error("getStringFromInputStream() failed", e);
log.error("getStringFromInputStream() failed", e);
}
return sb.toString();
@@ -102,7 +106,7 @@ public class TemplateMergeService {
try {
scopes.put(entry.getKey(), getMapFromUrl(url));
} catch (final IOException e) {
LOG.error("getCompiledMapFromMappers() failed", e);
log.error("getCompiledMapFromMappers() failed", e);
}
}
}
@@ -124,6 +128,26 @@ public class TemplateMergeService {
}
private HttpURLConnection getConnection(final String url) {
if (fineractProperties.getTemplate() != null && fineractProperties.getTemplate().isRegexWhitelistEnabled()) {
boolean whitelisted = false;
if (fineractProperties.getTemplate().getRegexWhitelist() != null
&& !fineractProperties.getTemplate().getRegexWhitelist().isEmpty()) {
for (String urlPattern : fineractProperties.getTemplate().getRegexWhitelist()) {
Pattern pattern = Pattern.compile(urlPattern);
Matcher matcher = pattern.matcher(url);
if (matcher.matches()) {
whitelisted = true;
break;
}
}
}
if (!whitelisted) {
throw new TemplateForbiddenException(url);
}
}
String authToken = ThreadLocalContextUtil.getAuthToken();
if (authToken == null) {
final String name = SecurityContextHolder.getContext().getAuthentication().getName();
@@ -149,7 +173,7 @@ public class TemplateMergeService {
connection.setDoInput(true);
} catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
LOG.error("getConnection() failed, return null", e);
log.error("getConnection() failed, return null", e);
}
return connection;
@@ -88,6 +88,8 @@ fineract.content.s3.bucketName=${FINERACT_CONTENT_S3_BUCKET_NAME:}
fineract.content.s3.accessKey=${FINERACT_CONTENT_S3_ACCESS_KEY:}
fineract.content.s3.secretKey=${FINERACT_CONTENT_S3_SECRET_KEY:}
fineract.template.regex-whitelist-enabled=${FINERACT_TEMPLATE_REGEX_WHITELIST_ENABLED:true}
fineract.template.regex-whitelist=${FINERACT_TEMPLATE_REGEX_WHITELIST:}
fineract.report.export.s3.bucket=${FINERACT_REPORT_EXPORT_S3_BUCKET_NAME:}
fineract.report.export.s3.enabled=${FINERACT_REPORT_EXPORT_S3_ENABLED:false}
@@ -34,10 +34,12 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.fineract.template.domain.Template;
import org.apache.fineract.template.domain.TemplateMapper;
import org.springframework.beans.factory.annotation.Autowired;
public class TemplateServiceStepDefinitions implements En {
private TemplateMergeService tms = new TemplateMergeService();
@Autowired
private TemplateMergeService tms;
private String template;