From c3b1035eaf5231766df4697ada02c4eb04564b0d Mon Sep 17 00:00:00 2001
From: Shinsuke Sugaya <shinsuke@apache.org>
Date: Sat, 28 Dec 2019 19:12:25 +0900
Subject: [PATCH] fix #2350 add fe:maskEmail

---
 .../codelibs/fess/taglib/FessFunctions.java   | 10 +++++++
 src/main/webapp/WEB-INF/fe.tld                |  8 ++++++
 .../fess/taglib/FessFunctionsTest.java        | 27 +++++++++++++++++++
 3 files changed, 45 insertions(+)

diff --git a/src/main/java/org/codelibs/fess/taglib/FessFunctions.java b/src/main/java/org/codelibs/fess/taglib/FessFunctions.java
index b663d008d..a609a0747 100644
--- a/src/main/java/org/codelibs/fess/taglib/FessFunctions.java
+++ b/src/main/java/org/codelibs/fess/taglib/FessFunctions.java
@@ -74,6 +74,9 @@ public class FessFunctions {
 
     private static final String PDF_DATE = "pdf_date";
 
+    private static final Pattern EMAIL_ADDRESS_PATTERN = Pattern.compile("[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}",
+            Pattern.CASE_INSENSITIVE);
+
     private static LoadingCache<String, Long> resourceHashCache = CacheBuilder.newBuilder().maximumSize(1000)
             .expireAfterWrite(10, TimeUnit.MINUTES).build(new CacheLoader<String, Long>() {
                 @Override
@@ -419,4 +422,11 @@ public class FessFunctions {
                 .map(user -> user.hasRoles(roles) || user.hasRoles(ComponentUtil.getFessConfig().getAuthenticationAdminRolesAsArray()))
                 .orElse(false);
     }
+
+    public static String maskEmail(final String value) {
+        if (value == null) {
+            return StringUtil.EMPTY;
+        }
+        return EMAIL_ADDRESS_PATTERN.matcher(value).replaceAll("******@****.***");
+    }
 }
diff --git a/src/main/webapp/WEB-INF/fe.tld b/src/main/webapp/WEB-INF/fe.tld
index 561a57848..e8c7bb659 100644
--- a/src/main/webapp/WEB-INF/fe.tld
+++ b/src/main/webapp/WEB-INF/fe.tld
@@ -258,6 +258,14 @@
     <example>${fe:formatCode("L", "prettyprint", doc.mimetype, doc.content_description)}</example>
   </function>
 
+  <function>
+    <description>Mask e-mail address.</description>
+    <name>maskEmail</name>
+    <function-class>org.codelibs.fess.taglib.FessFunctions</function-class>
+    <function-signature>java.lang.String maskEmail(java.lang.String)</function-signature>
+    <example>${fe:maskEmail(doc.content_description)}</example>
+  </function>
+
   <function>
     <description>Get a message from properties files.</description>
     <name>message</name>
diff --git a/src/test/java/org/codelibs/fess/taglib/FessFunctionsTest.java b/src/test/java/org/codelibs/fess/taglib/FessFunctionsTest.java
index be5a45afd..acc01d3f0 100644
--- a/src/test/java/org/codelibs/fess/taglib/FessFunctionsTest.java
+++ b/src/test/java/org/codelibs/fess/taglib/FessFunctionsTest.java
@@ -115,6 +115,33 @@ public class FessFunctionsTest extends UnitFessTestCase {
         code = "aaa\nL10:\nL11:ccc";
         value = FessFunctions.formatCode("L", "prettyprint", "text/plain", code);
         assertEquals("<pre class=\"prettyprint linenums:10\">\nccc</pre>", value);
+    }
+
+    public void test_maskEmail() {
+        String value;
+
+        value = FessFunctions.maskEmail(null);
+        assertEquals("", value);
+
+        value = FessFunctions.maskEmail("");
+        assertEquals("", value);
+
+        value = FessFunctions.maskEmail("aaa bbb ccc");
+        assertEquals("aaa bbb ccc", value);
+
+        value = FessFunctions.maskEmail("aaa@bbb.ccc");
+        assertEquals("******@****.***", value);
+
+        value = FessFunctions.maskEmail("111.aaa@bbb.ccc");
+        assertEquals("******@****.***", value);
+
+        value = FessFunctions.maskEmail("111 aaa+@bbb.ccc 222");
+        assertEquals("111 ******@****.*** 222", value);
+
+        value = FessFunctions.maskEmail("あaaa@bbb.ccc1");
+        assertEquals("あ******@****.***1", value);
 
+        value = FessFunctions.maskEmail("<aaa@bbb.ccc>");
+        assertEquals("<******@****.***>", value);
     }
 }
-- 
GitLab