1 /*
2  *  Make.org Core API
3  *  Copyright (C) 2018 Make.org
4  *
5  * This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 package org.make.api.technical.security
21 
22 import java.security.MessageDigest
23 import java.util.Base64
24 
25 import grizzled.slf4j.Logging
26 import org.make.core.DateHelper
27 
28 object SecurityHelper extends Logging {
29 
30   val HASH_SEPARATOR: String = "-"
31 
32   @Deprecated
33 //  This hash method is used for backward compatibility only. Use `defaultHash` instead.
34   def sha256(value: String): String =
35     MessageDigest.getInstance("SHA-256").digest(value.getBytes("UTF-8")).map("%02x".format(_)).mkString
36 
37   def defaultHash(value: String): String =
38     MessageDigest.getInstance("SHA-512").digest(value.getBytes("UTF-8")).map("%02x".format(_)).mkString
39 
40   def base64Encode(value: String): String =
41     Base64.getEncoder.encodeToString(value.getBytes("UTF-8"))
42 
43   def base64Decode(value: String): String =
44     new String(Base64.getDecoder.decode(value), "UTF-8")
45 
46   def generateHash(value: String, salt: String): String =
47     defaultHash(s"${defaultHash(value)}$salt")
48 
49   def createSecureHash(value: String, salt: String): String = {
50     val date = DateHelper.now().toString
51 
52     s"${base64Encode(date)}$HASH_SEPARATOR${generateHash(s"$value$date", salt)}"
53   }
54 
55   def validateSecureHash(hash: String, value: String, salt: String): Boolean = {
56     hash.split(HASH_SEPARATOR) match {
57       case Array(base64Date, hashedValue) =>
58         val deprecatedCheck = sha256(s"${sha256(s"$value")}${base64Decode(base64Date)}$salt") == hashedValue
59         if (deprecatedCheck) {
60           logger.warn(s"Use of deprecated hash function (sha256) on value $value")
61         }
62         generateHash(s"$value${base64Decode(base64Date)}", salt) == hashedValue || deprecatedCheck
63       case _ => false
64     }
65   }
66 
67   def anonymizeEmail(email: String): String = {
68     val emailDomainName = email.takeRight(email.length - email.lastIndexOf("@"))
69     val emailLocalPart = email.substring(0, email.lastIndexOf("@"))
70     s"${emailLocalPart.head}${"*" * (emailLocalPart.length - 2)}${emailLocalPart.last}$emailDomainName"
71   }
72 }
Line Stmt Id Pos Tree Symbol Tests Code
30 247 981 - 984 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest,org.make.api.userhistory.userhistorytest "-"
35 325 1175 - 1198 Apply java.lang.String.getBytes org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest value.getBytes("UTF-8")
35 20 1131 - 1221 ApplyToImplicitArgs scala.collection.ArrayOps.map org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest scala.Predef.byteArrayOps(java.security.MessageDigest.getInstance("SHA-256").digest(value.getBytes("UTF-8"))).map[String](((x$1: Byte) => scala.Predef.augmentString("%02x").format(x$1)))((ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))
35 223 1131 - 1230 Select scala.collection.IterableOnceOps.mkString org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest scala.Predef.wrapRefArray[String](scala.Predef.byteArrayOps(java.security.MessageDigest.getInstance("SHA-256").digest(value.getBytes("UTF-8"))).map[String](((x$1: Byte) => scala.Predef.augmentString("%02x").format(x$1)))((ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))).mkString
35 205 1131 - 1199 Apply java.security.MessageDigest.digest org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest java.security.MessageDigest.getInstance("SHA-256").digest(value.getBytes("UTF-8"))
35 109 1157 - 1166 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest "SHA-256"
35 76 1204 - 1220 Apply scala.collection.StringOps.format org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest scala.Predef.augmentString("%02x").format(x$1)
38 101 1305 - 1314 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.crmservicecomponenttest,org.make.api.userhistory.userhistorytest "SHA-512"
38 122 1352 - 1368 Apply scala.collection.StringOps.format org.make.api.technical.security.securityhelpertest,org.make.api.userhistory.userhistorytest,org.make.api.technical.crm.crmservicecomponenttest scala.Predef.augmentString("%02x").format(x$2)
38 183 1279 - 1347 Apply java.security.MessageDigest.digest org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.crmservicecomponenttest,org.make.api.userhistory.userhistorytest java.security.MessageDigest.getInstance("SHA-512").digest(value.getBytes("UTF-8"))
38 308 1323 - 1346 Apply java.lang.String.getBytes org.make.api.technical.security.securityhelpertest,org.make.api.userhistory.userhistorytest,org.make.api.technical.crm.crmservicecomponenttest value.getBytes("UTF-8")
38 320 1279 - 1369 ApplyToImplicitArgs scala.collection.ArrayOps.map org.make.api.technical.security.securityhelpertest,org.make.api.userhistory.userhistorytest,org.make.api.technical.crm.crmservicecomponenttest scala.Predef.byteArrayOps(java.security.MessageDigest.getInstance("SHA-512").digest(value.getBytes("UTF-8"))).map[String](((x$2: Byte) => scala.Predef.augmentString("%02x").format(x$2)))((ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))
38 206 1279 - 1378 Select scala.collection.IterableOnceOps.mkString org.make.api.technical.security.securityhelpertest,org.make.api.userhistory.userhistorytest,org.make.api.technical.crm.crmservicecomponenttest scala.Predef.wrapRefArray[String](scala.Predef.byteArrayOps(java.security.MessageDigest.getInstance("SHA-512").digest(value.getBytes("UTF-8"))).map[String](((x$2: Byte) => scala.Predef.augmentString("%02x").format(x$2)))((ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String]))).mkString
41 16 1428 - 1485 Apply java.util.Base64.Encoder.encodeToString org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest java.util.Base64.getEncoder().encodeToString(value.getBytes("UTF-8"))
41 70 1461 - 1484 Apply java.lang.String.getBytes org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest value.getBytes("UTF-8")
44 95 1579 - 1586 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest "UTF-8"
44 297 1535 - 1587 Apply java.lang.String.<init> org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest new scala.Predef.String(java.util.Base64.getDecoder().decode(value), "UTF-8")
44 224 1546 - 1577 Apply java.util.Base64.Decoder.decode org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest java.util.Base64.getDecoder().decode(value)
47 177 1651 - 1693 Apply org.make.api.technical.security.SecurityHelper.defaultHash org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.crmservicecomponenttest,org.make.api.userhistory.userhistorytest SecurityHelper.this.defaultHash(("".+(SecurityHelper.this.defaultHash(value)).+(salt): String))
50 106 1774 - 1799 Apply java.time.ZonedDateTime.toString org.make.api.widget.widgetservicetest org.make.core.DateHelper.now().toString()
56 321 1983 - 1997 Select org.make.api.technical.security.SecurityHelper.HASH_SEPARATOR org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest SecurityHelper.this.HASH_SEPARATOR
56 201 1972 - 1998 Apply java.lang.String.split org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest hash.split(SecurityHelper.this.HASH_SEPARATOR)
58 71 2082 - 2160 Apply java.lang.Object.== org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest SecurityHelper.this.sha256(("".+(SecurityHelper.this.sha256(("".+(value): String))).+(SecurityHelper.this.base64Decode(base64Date)).+(salt): String)).==(hashedValue)
59 89 2169 - 2169 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest ()
59 293 2169 - 2169 Block <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest ()
60 11 2202 - 2274 Apply grizzled.slf4j.Logger.warn org.make.api.technical.security.securityhelpertest SecurityHelper.this.logger.warn(("Use of deprecated hash function (sha256) on value ".+(value): String))
60 213 2202 - 2274 Block grizzled.slf4j.Logger.warn org.make.api.technical.security.securityhelpertest SecurityHelper.this.logger.warn(("Use of deprecated hash function (sha256) on value ".+(value): String))
62 179 2293 - 2383 Apply scala.Boolean.|| org.make.api.technical.security.securityhelpertest,org.make.api.widget.widgetservicetest,org.make.api.technical.security.securityapitest SecurityHelper.this.generateHash(("".+(value).+(SecurityHelper.this.base64Decode(base64Date)): String), salt).==(hashedValue).||(deprecatedCheck)
63 108 2400 - 2405 Literal <nosymbol> org.make.api.technical.security.securityapitest false
68 313 2522 - 2544 Apply java.lang.String.lastIndexOf org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest email.lastIndexOf("@")
68 65 2491 - 2545 Apply scala.collection.StringOps.takeRight org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest scala.Predef.augmentString(email).takeRight(email.length().-(email.lastIndexOf("@")))
68 204 2507 - 2544 Apply scala.Int.- org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest email.length().-(email.lastIndexOf("@"))
69 86 2571 - 2613 Apply java.lang.String.substring org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest email.substring(0, email.lastIndexOf("@"))
69 271 2587 - 2588 Literal <nosymbol> org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest 0
69 215 2590 - 2612 Apply java.lang.String.lastIndexOf org.make.api.technical.security.securityhelpertest,org.make.api.technical.crm.sendmessagestest,org.make.api.technical.crm.crmservicecomponenttest email.lastIndexOf("@")