Skip to content

Commit 7a2af15

Browse files
authored
Merge pull request #139 from vijayabraj/master
SensitiveLogger for Java SDK
2 parents 91911da + 89aaf18 commit 7a2af15

File tree

9 files changed

+261
-5
lines changed

9 files changed

+261
-5
lines changed

pom.xml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<groupId>net.authorize</groupId>
1010
<artifactId>anet-java-sdk</artifactId>
1111
<packaging>jar</packaging>
12-
<version>1.9.7-SNAPSHOT</version>
12+
<version>1.9.8-SNAPSHOT</version>
1313
<name>Authorize.Net Java SDK</name>
1414
<description>Authorize.Net SDK includes standard payments, recurring billing, and customer profiles.</description>
1515
<url>http://developer.authorize.net</url>
@@ -81,6 +81,11 @@
8181
<version>1.3</version>
8282
<scope>test</scope>
8383
</dependency>
84+
<dependency>
85+
<groupId>com.google.code.gson</groupId>
86+
<artifactId>gson</artifactId>
87+
<version>2.3.1</version>
88+
</dependency>
8489
</dependencies>
8590
<properties>
8691
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -145,16 +150,23 @@
145150
</plugin>
146151
</plugins>
147152
<resources>
153+
<resource>
154+
<directory>resources</directory>
155+
<filtering>true</filtering>
156+
<includes>
157+
<include>**/AuthorizedNetSensitiveTagsConfig.json</include>
158+
</includes>
159+
</resource>
148160
<resource>
149161
<directory>resources</directory>
150162
<filtering>false</filtering>
151163
<includes>
152-
<include>*</include>
164+
<include>**/*.*</include>
153165
</includes>
154166
<excludes>
155167
<exclude>log4j.properties</exclude>
156168
</excludes>
157-
</resource>
169+
</resource>
158170
</resources>
159171
</build>
160172
</project>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"sensitiveTags": [
3+
{
4+
"tagName": "cardCode",
5+
"pattern": "",
6+
"replacement": "xxx",
7+
"disableMask": false
8+
},
9+
{
10+
"tagName": "cardNumber",
11+
"pattern": "(\\p{N}+)(\\p{N}{4})",
12+
"replacement": "xxxx-$2",
13+
"disableMask": false
14+
},
15+
{
16+
"tagName": "expirationDate",
17+
"pattern": "",
18+
"replacement": "xxx",
19+
"disableMask": false
20+
},
21+
{
22+
"tagName": "accountNumber",
23+
"pattern": "(\\p{N}+)(\\p{N}{4})",
24+
"replacement": "xxxx-$2",
25+
"disableMask": false
26+
},
27+
{
28+
"tagName": "nameOnAccount",
29+
"pattern": "",
30+
"replacement": "xxx",
31+
"disableMask": false
32+
},
33+
{
34+
"tagName": "transactionKey",
35+
"pattern": "",
36+
"replacement": "xxx",
37+
"disableMask": false
38+
}
39+
],
40+
"sensitiveStringRegexes": [
41+
"4\\p{N}{3}([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
42+
"4\\p{N}{3}([\\ \\-]?)(?:\\p{N}{4}\\1){2}\\p{N}(?:\\p{N}{3})?",
43+
"5[1-5]\\p{N}{2}([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
44+
"6(?:011|22(?:1(?=[\\ \\-]?(?:2[6-9]|[3-9]))|[2-8]|9(?=[\\ \\-]?(?:[01]|2[0-5])))|4[4-9]\\p{N}|5\\p{N}\\p{N})([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
45+
"35(?:2[89]|[3-8]\\p{N})([\\ \\-]?)\\p{N}{4}\\1\\p{N}{4}\\1\\p{N}{4}",
46+
"3[47]\\p{N}\\p{N}([\\ \\-]?)\\p{N}{6}\\1\\p{N}{5}"
47+
]
48+
}
49+

resources/project.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
project.basedir=${basedir}

src/main/java/net/authorize/util/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ public final class Constants {
3535
public static final String HTTP_READ_TIME_OUT = "http.ReadTimeout";
3636
public static final int HTTP_READ_TIME_OUT_DEFAULT_VALUE = 30000;
3737

38-
public static final String CLIENT_ID = "sdk-java-1.9.6";
38+
public static final String CLIENT_ID = "sdk-java-1.9.7";
3939
}

src/main/java/net/authorize/util/HttpUtility.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ static HttpPost createPostRequest(Environment env, ANetApiRequest request) throw
6868

6969
if(null != request) {
7070
postUrl = new URI(env.getXmlBaseUrl() + "/xml/v1/request.api");
71-
logger.debug(String.format("MerchantInfo->LoginId/TransactionKey: '%s':'%s'", request.getMerchantAuthentication().getName(), request.getMerchantAuthentication().getTransactionKey() ));
7271
logger.debug(String.format("Posting request to Url: '%s'", postUrl));
7372
httpPost = new HttpPost(postUrl);
7473
httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package net.authorize.util;
2+
3+
public class SensitiveDataConfigType {
4+
5+
public SensitiveTag[] sensitiveTags;
6+
7+
public SensitiveTag[] getSensitiveTags() {
8+
return sensitiveTags;
9+
}
10+
11+
public void setSensitiveTags(SensitiveTag[] sensitiveTags) {
12+
this.sensitiveTags = sensitiveTags;
13+
}
14+
15+
public String[] getSensitiveStringRegexes() {
16+
return sensitiveStringRegexes;
17+
}
18+
19+
public void setSensitiveStringRegexes(String[] sensitiveStringRegexes) {
20+
this.sensitiveStringRegexes = sensitiveStringRegexes;
21+
}
22+
23+
public String[] sensitiveStringRegexes;
24+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package net.authorize.util;
2+
3+
import java.io.BufferedReader;
4+
import java.io.FileNotFoundException;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.io.InputStreamReader;
8+
import java.io.UnsupportedEncodingException;
9+
import java.util.regex.Pattern;
10+
11+
import org.apache.log4j.PatternLayout;
12+
import org.apache.log4j.spi.LoggingEvent;
13+
import org.apache.log4j.Logger;
14+
15+
import com.google.gson.Gson;
16+
import com.google.gson.GsonBuilder;
17+
18+
public class SensitiveFilterLayout extends PatternLayout{
19+
20+
private static Pattern[] cardPatterns;
21+
22+
private static Pattern[] tagPatterns;
23+
private static String[] tagReplacements;
24+
private static Gson gson;
25+
26+
public SensitiveFilterLayout() throws UnsupportedEncodingException, FileNotFoundException, IOException {
27+
GsonBuilder gsonBuilder = new GsonBuilder();
28+
gsonBuilder.registerTypeAdapter(SensitiveDataConfigType.class, new SensitiveTagsDeserializer());
29+
gson = gsonBuilder.create();
30+
31+
InputStream in = getClass().getResourceAsStream("/AuthorizedNetSensitiveTagsConfig.json");
32+
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
33+
SensitiveDataConfigType configType = gson.fromJson(reader, SensitiveDataConfigType.class);
34+
cardPatterns = new Pattern[configType.sensitiveStringRegexes.length];
35+
36+
for(int i = 0; i < configType.sensitiveStringRegexes.length; i++) {
37+
cardPatterns[i] = Pattern.compile(configType.sensitiveStringRegexes[i]);
38+
}
39+
40+
int noOfSensitiveTags = configType.sensitiveTags.length;
41+
tagPatterns = new Pattern[noOfSensitiveTags];
42+
tagReplacements = new String[noOfSensitiveTags];
43+
44+
for(int j=0; j<noOfSensitiveTags; j++) {
45+
String tagName = configType.sensitiveTags[j].tagName;
46+
String pattern = configType.sensitiveTags[j].pattern;
47+
String replacement = configType.sensitiveTags[j].replacement;
48+
49+
if(pattern != null && !pattern.isEmpty())
50+
tagPatterns[j] = Pattern.compile("<"+tagName+">"+pattern+"</"+tagName+">");
51+
else
52+
tagPatterns[j] = Pattern.compile("<"+tagName+">"+".+"+"</"+tagName+">");
53+
tagReplacements[j] = "<"+tagName+">"+replacement+"</"+tagName+">";
54+
}
55+
if(reader!=null)
56+
reader.close();
57+
}
58+
59+
@Override
60+
public String format(LoggingEvent event) {
61+
if(event.getMessage() instanceof String) {
62+
String message = event.getRenderedMessage();
63+
String maskXmlMessage = SensitiveFilterLayout.maskSensitiveXmlString(message);
64+
String maskCardNumber = SensitiveFilterLayout.maskCreditCards(maskXmlMessage);
65+
66+
Throwable throwable = event.getThrowableInformation() != null ? event.getThrowableInformation().getThrowable() : null;
67+
LoggingEvent maskedEvent = new LoggingEvent(event.fqnOfCategoryClass, Logger.getLogger(event.getLoggerName()), event.timeStamp, event.getLevel(), maskCardNumber, throwable);
68+
return super.format(maskedEvent);
69+
}
70+
return null;
71+
}
72+
73+
public static String maskCreditCards(String str) {
74+
for (int i = 0; i < cardPatterns.length; i++) {
75+
str = cardPatterns[i].matcher(str).replaceAll("XXXX");
76+
}
77+
return str;
78+
}
79+
80+
public static String maskSensitiveXmlString(String str) {
81+
for (int i = 0; i < tagPatterns.length; i++) {
82+
str = tagPatterns[i].matcher(str).replaceAll(tagReplacements[i]);
83+
}
84+
return str;
85+
}
86+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package net.authorize.util;
2+
3+
public class SensitiveTag {
4+
5+
public String tagName;
6+
public String getTagName() {
7+
return tagName;
8+
}
9+
10+
public void setTagName(String tagName) {
11+
this.tagName = tagName;
12+
}
13+
14+
public String getPattern() {
15+
return pattern;
16+
}
17+
18+
public void setPattern(String pattern) {
19+
this.pattern = pattern;
20+
}
21+
22+
public String getReplacement() {
23+
return replacement;
24+
}
25+
26+
public void setReplacement(String replacement) {
27+
this.replacement = replacement;
28+
}
29+
30+
public boolean isDisableMask() {
31+
return disableMask;
32+
}
33+
34+
public void setDisableMask(boolean disableMask) {
35+
this.disableMask = disableMask;
36+
}
37+
38+
public String pattern;
39+
public String replacement;
40+
public boolean disableMask;
41+
42+
public SensitiveTag(String tagName, String pattern, String replacement, boolean disableMask) {
43+
44+
this.tagName = tagName;
45+
this.pattern = pattern;
46+
this.replacement = replacement;
47+
this.disableMask = disableMask;
48+
}
49+
}
50+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.authorize.util;
2+
3+
import java.lang.reflect.Type;
4+
5+
import com.google.gson.JsonArray;
6+
import com.google.gson.JsonDeserializationContext;
7+
import com.google.gson.JsonDeserializer;
8+
import com.google.gson.JsonElement;
9+
import com.google.gson.JsonObject;
10+
import com.google.gson.JsonParseException;
11+
12+
public class SensitiveTagsDeserializer implements JsonDeserializer<SensitiveDataConfigType>{
13+
14+
public SensitiveDataConfigType deserialize(JsonElement arg0, Type arg1, JsonDeserializationContext arg2)
15+
throws JsonParseException {
16+
final JsonObject jsonObject = arg0.getAsJsonObject();
17+
18+
final JsonArray jsonSensitiveRegexesArray = jsonObject.get("sensitiveStringRegexes").getAsJsonArray();
19+
20+
final String[] stringRegexes = new String[jsonSensitiveRegexesArray.size()];
21+
22+
for (int j=0; j<stringRegexes.length; j++) {
23+
final JsonElement jsonStringRegex = jsonSensitiveRegexesArray.get(j);
24+
stringRegexes[j] = jsonStringRegex.getAsString();
25+
}
26+
27+
SensitiveTag[] sensitiveTags = arg2.deserialize(jsonObject.get("sensitiveTags"), SensitiveTag[].class);
28+
29+
final SensitiveDataConfigType configType = new SensitiveDataConfigType();
30+
configType.setSensitiveTags(sensitiveTags);
31+
configType.setSensitiveStringRegexes(stringRegexes);
32+
33+
return configType;
34+
}
35+
}

0 commit comments

Comments
 (0)