Skip to content

Commit 983066b

Browse files
committed
FINERACT-1873: Template request fix for 1.7.x
1 parent 71b73db commit 983066b

File tree

5 files changed

+78
-11
lines changed

5 files changed

+78
-11
lines changed

fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/FineractProperties.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.fineract.infrastructure.core.config;
2121

22+
import java.util.List;
2223
import lombok.Getter;
2324
import lombok.Setter;
2425
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -34,6 +35,8 @@ public class FineractProperties {
3435

3536
private FineractModeProperties mode;
3637

38+
private FineractTemplateProperties template;
39+
3740
@Getter
3841
@Setter
3942
public static class FineractTenantProperties {
@@ -61,4 +64,12 @@ public boolean isReadOnlyMode() {
6164
return readEnabled && !writeEnabled && !batchEnabled;
6265
}
6366
}
67+
68+
@Getter
69+
@Setter
70+
public static class FineractTemplateProperties {
71+
72+
private boolean regexWhitelistEnabled;
73+
private List<String> regexWhitelist;
74+
}
6475
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.template.exception;
20+
21+
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
22+
23+
public class TemplateForbiddenException extends AbstractPlatformResourceNotFoundException {
24+
25+
public TemplateForbiddenException(final String url) {
26+
super("error.msg.template.url.forbidden", "Template with url " + url + " not allowed");
27+
}
28+
}

fineract-provider/src/main/java/org/apache/fineract/template/service/TemplateMergeService.java

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,23 @@
3838
import java.security.NoSuchAlgorithmException;
3939
import java.util.HashMap;
4040
import java.util.Map;
41+
import java.util.regex.Matcher;
42+
import java.util.regex.Pattern;
43+
import lombok.RequiredArgsConstructor;
44+
import lombok.extern.slf4j.Slf4j;
45+
import org.apache.fineract.infrastructure.core.config.FineractProperties;
4146
import org.apache.fineract.template.domain.Template;
4247
import org.apache.fineract.template.domain.TemplateFunctions;
43-
import org.slf4j.Logger;
44-
import org.slf4j.LoggerFactory;
48+
import org.apache.fineract.template.exception.TemplateForbiddenException;
4549
import org.springframework.security.core.context.SecurityContextHolder;
4650
import org.springframework.stereotype.Service;
4751

52+
@Slf4j
53+
@RequiredArgsConstructor
4854
@Service
4955
public class TemplateMergeService {
5056

51-
private static final Logger LOG = LoggerFactory.getLogger(TemplateMergeService.class);
52-
53-
// private final FromJsonHelper fromApiJsonHelper;
57+
private final FineractProperties fineractProperties;
5458
private Map<String, Object> scopes;
5559
private String authToken;
5660

@@ -92,7 +96,7 @@ private Map<String, Object> getCompiledMapFromMappers(final Map<String, String>
9296
try {
9397
this.scopes.put(entry.getKey(), getMapFromUrl(url));
9498
} catch (final IOException e) {
95-
LOG.error("getCompiledMapFromMappers() failed", e);
99+
log.error("getCompiledMapFromMappers() failed", e);
96100
}
97101
}
98102
}
@@ -114,6 +118,26 @@ private Map<String, Object> getMapFromUrl(final String url) throws IOException {
114118
}
115119

116120
private HttpURLConnection getConnection(final String url) {
121+
if (fineractProperties.getTemplate() != null && fineractProperties.getTemplate().isRegexWhitelistEnabled()) {
122+
boolean whitelisted = false;
123+
124+
if (fineractProperties.getTemplate().getRegexWhitelist() != null
125+
&& !fineractProperties.getTemplate().getRegexWhitelist().isEmpty()) {
126+
for (String urlPattern : fineractProperties.getTemplate().getRegexWhitelist()) {
127+
Pattern pattern = Pattern.compile(urlPattern);
128+
Matcher matcher = pattern.matcher(url);
129+
if (matcher.matches()) {
130+
whitelisted = true;
131+
break;
132+
}
133+
}
134+
}
135+
136+
if (!whitelisted) {
137+
throw new TemplateForbiddenException(url);
138+
}
139+
}
140+
117141
if (this.authToken == null) {
118142
final String name = SecurityContextHolder.getContext().getAuthentication().getName();
119143
final String password = SecurityContextHolder.getContext().getAuthentication().getCredentials().toString();
@@ -138,7 +162,7 @@ protected PasswordAuthentication getPasswordAuthentication() {
138162
connection.setDoInput(true);
139163

140164
} catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
141-
LOG.error("getConnection() failed, return null", e);
165+
log.error("getConnection() failed, return null", e);
142166
}
143167

144168
return connection;
@@ -158,13 +182,13 @@ private static String getStringFromInputStream(final InputStream is) {
158182
}
159183

160184
} catch (final IOException e) {
161-
LOG.error("getStringFromInputStream() failed", e);
185+
log.error("getStringFromInputStream() failed", e);
162186
} finally {
163187
if (br != null) {
164188
try {
165189
br.close();
166190
} catch (final IOException e) {
167-
LOG.error("Problem occurred in getStringFromInputStream function", e);
191+
log.error("Problem occurred in getStringFromInputStream function", e);
168192
}
169193
}
170194
}

fineract-provider/src/main/resources/application.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ fineract.content.regex-whitelist=${FINERACT_CONTENT_REGEX_WHITELIST:.*\\.pdf$,.*
4444
fineract.content.mime-whitelist-enabled=${FINERACT_CONTENT_MIME_WHITELIST_ENABLED:true}
4545
fineract.content.mime-whitelist=${FINERACT_CONTENT_MIME_WHITELIST:application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,image/jpeg,image/png}
4646

47+
fineract.template.regex-whitelist-enabled=${FINERACT_TEMPLATE_REGEX_WHITELIST_ENABLED:true}
48+
fineract.template.regex-whitelist=${FINERACT_TEMPLATE_REGEX_WHITELIST:}
49+
4750
management.health.jms.enabled=false
4851

4952
# FINERACT 1296

fineract-provider/src/test/java/org/apache/fineract/template/service/TemplateServiceStepDefinitions.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@
3434
import org.apache.commons.io.IOUtils;
3535
import org.apache.fineract.template.domain.Template;
3636
import org.apache.fineract.template.domain.TemplateMapper;
37+
import org.springframework.beans.factory.annotation.Autowired;
3738

3839
public class TemplateServiceStepDefinitions implements En {
3940

40-
private TemplateMergeService tms = new TemplateMergeService();
41-
41+
@Autowired
42+
private TemplateMergeService tms;
4243
private String template;
4344

4445
private Map<String, Object> data;

0 commit comments

Comments
 (0)