mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:26:51 +00:00
Merge pull request #2494 from hongwei1/develop
bugfix/tweaked the password regex
This commit is contained in:
commit
db86568d61
@ -519,7 +519,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
|
||||
case Some(STATIC) => {
|
||||
val cacheValueFromRedis = Caching.getStaticResourceDocCache(cacheKey)
|
||||
|
||||
val dynamicDocs: Box[JValue] =
|
||||
val staticDocs: Box[JValue] =
|
||||
if (cacheValueFromRedis.isDefined) {
|
||||
Full(json.parse(cacheValueFromRedis.get))
|
||||
} else {
|
||||
@ -530,12 +530,12 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
|
||||
Full(resourceDocJsonJValue)
|
||||
}
|
||||
|
||||
Future(dynamicDocs.map(successJsonResponse(_)))
|
||||
Future(staticDocs.map(successJsonResponse(_)))
|
||||
}
|
||||
case _ => {
|
||||
val cacheValueFromRedis = Caching.getAllResourceDocCache(cacheKey)
|
||||
|
||||
val dynamicDocs: Box[JValue] =
|
||||
val bothStaticAndDyamicDocs: Box[JValue] =
|
||||
if (cacheValueFromRedis.isDefined) {
|
||||
Full(json.parse(cacheValueFromRedis.get))
|
||||
} else {
|
||||
@ -546,7 +546,7 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
|
||||
Full(resourceDocJsonJValue)
|
||||
}
|
||||
|
||||
Future(dynamicDocs.map(successJsonResponse(_)))
|
||||
Future(bothStaticAndDyamicDocs.map(successJsonResponse(_)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -715,13 +715,11 @@ trait ResourceDocsAPIMethods extends MdcLoggable with APIMethods220 with APIMeth
|
||||
swaggerJValue <- NewStyle.function.tryons(s"$UnknownError Can not convert internal swagger file.", 400, cc.callContext) {
|
||||
val cacheValueFromRedis = Caching.getStaticSwaggerDocCache(cacheKey)
|
||||
|
||||
val dynamicDocs: JValue =
|
||||
if (cacheValueFromRedis.isDefined) {
|
||||
json.parse(cacheValueFromRedis.get)
|
||||
} else {
|
||||
convertResourceDocsToSwaggerJvalueAndSetCache(cacheKey, requestedApiVersionString, resourceDocsJsonFiltered)
|
||||
}
|
||||
dynamicDocs
|
||||
if (cacheValueFromRedis.isDefined) {
|
||||
json.parse(cacheValueFromRedis.get)
|
||||
} else {
|
||||
convertResourceDocsToSwaggerJvalueAndSetCache(cacheKey, requestedApiVersionString, resourceDocsJsonFiltered)
|
||||
}
|
||||
}
|
||||
} yield {
|
||||
(swaggerJValue, HttpCode.`200`(cc.callContext))
|
||||
|
||||
@ -784,16 +784,24 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
* (?=.*\d) //should contain at least one digit
|
||||
* (?=.*[a-z]) //should contain at least one lower case
|
||||
* (?=.*[A-Z]) //should contain at least one upper case
|
||||
* (?=.*[!"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~]) //should contain at least one special character
|
||||
* ([A-Za-z0-9!"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~]{10,16}) //should contain 10 to 16 valid characters
|
||||
* (?=.*[!\"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~\[\]]) //should contain at least one special character
|
||||
* ([A-Za-z0-9!\"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~\[\]]{10,16}) //should contain 10 to 16 valid characters
|
||||
**/
|
||||
val regex =
|
||||
"""^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~])([A-Za-z0-9!"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~]{10,16})$""".r
|
||||
password match {
|
||||
case password if(password.length > 16 && password.length <= 512 && basicPasswordValidation(password) ==SILENCE_IS_GOLDEN) => true
|
||||
case regex(password) if(basicPasswordValidation(password) ==SILENCE_IS_GOLDEN) => true
|
||||
case _ => false
|
||||
"""^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!\"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~\[\]])([A-Za-z0-9!\"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~\[\]]{10,16})$""".r
|
||||
|
||||
// first check `basicPasswordValidation`
|
||||
if (basicPasswordValidation(password) != SILENCE_IS_GOLDEN) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 2nd: check the password length between 10 and 512
|
||||
if (password.length > 16 && password.length <= 512) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 3rd: check the regular expression
|
||||
regex.pattern.matcher(password).matches()
|
||||
}
|
||||
|
||||
/** only A-Z, a-z, 0-9,-,_,. =, & and max length <= 2048 */
|
||||
@ -847,12 +855,17 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
|
||||
/** also support space now */
|
||||
def basicPasswordValidation(value:String): String ={
|
||||
val valueLength = value.length
|
||||
val regex = """^([A-Za-z0-9!"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~ ]+)$""".r
|
||||
value match {
|
||||
case regex(e) if(valueLength <= 512) => SILENCE_IS_GOLDEN
|
||||
case regex(e) if(valueLength > 512) => ErrorMessages.InvalidValueLength
|
||||
case _ => ErrorMessages.InvalidValueCharacters
|
||||
val regex = """^([A-Za-z0-9!\"#$%&'\(\)*+,-./:;<=>?@\\[\\\\]^_\\`{|}~ \[\]]+)$""".r
|
||||
|
||||
if (!regex.pattern.matcher(value).matches()) {
|
||||
return ErrorMessages.InvalidValueCharacters
|
||||
}
|
||||
|
||||
if (valueLength > 512) {
|
||||
return ErrorMessages.InvalidValueLength
|
||||
}
|
||||
|
||||
SILENCE_IS_GOLDEN
|
||||
}
|
||||
|
||||
/** only A-Z, a-z, 0-9, -, _, ., @, and max length <= 512 */
|
||||
|
||||
@ -37,6 +37,7 @@ import code.api.util._
|
||||
import code.setup.PropsReset
|
||||
import code.util.Helper.SILENCE_IS_GOLDEN
|
||||
import com.openbankproject.commons.model.UserAuthContextCommons
|
||||
import com.github.dwickern.macros.NameOf.nameOf
|
||||
import net.liftweb.common.{Box, Empty, Full}
|
||||
import net.liftweb.http.provider.HTTPParam
|
||||
import net.liftweb.json.{JValue, parse}
|
||||
@ -838,6 +839,65 @@ class APIUtilTest extends FeatureSpec with Matchers with GivenWhenThen with Prop
|
||||
actualValue6 contains (InvalidValueLength) shouldBe (true)
|
||||
|
||||
}
|
||||
|
||||
scenario(s"Test the ${nameOf(APIUtil.basicPasswordValidation _)} method") {
|
||||
val firefoxStrongPasswordProposal = "9YF]gZnXzAENM+]"
|
||||
|
||||
basicPasswordValidation(firefoxStrongPasswordProposal) shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("Abc!123 xyz") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("SuperStrong#123") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("Hello World!") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation(" ") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN allow space so far
|
||||
|
||||
basicPasswordValidation("short💥") shouldBe (InvalidValueCharacters) // ❌ ErrorMessages.InvalidValueCharacters
|
||||
basicPasswordValidation("a" * 513) shouldBe (InvalidValueLength) // ❌ ErrorMessages.InvalidValueLength
|
||||
|
||||
}
|
||||
|
||||
scenario(s"Test the ${nameOf(APIUtil.fullPasswordValidation _)} method") {
|
||||
val firefoxStrongPasswordProposal = "9YF]gZnXzAENM+]"
|
||||
|
||||
fullPasswordValidation(firefoxStrongPasswordProposal) // ✅ true
|
||||
fullPasswordValidation("Abc!123xyz") // ✅ true
|
||||
fullPasswordValidation("SuperStrong#123") // ✅ true
|
||||
fullPasswordValidation("Abcdefg!1") // ✅ true
|
||||
fullPasswordValidation("short1!") // ❌ false(too short)
|
||||
fullPasswordValidation("alllowercase123!") // ❌ false(no capital letter)
|
||||
fullPasswordValidation("ALLUPPERCASE123!") // ❌ false(no smaller case letter)
|
||||
fullPasswordValidation("NoSpecialChar123") // ❌ false(not special character)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
feature(s"test ${nameOf(APIUtil.basicPasswordValidation _)} and ${nameOf(APIUtil.fullPasswordValidation _)}") {
|
||||
|
||||
scenario(s"Test the ${nameOf(APIUtil.basicPasswordValidation _)} method") {
|
||||
val firefoxStrongPasswordProposal = "9YF]gZnXzAENM+]"
|
||||
|
||||
basicPasswordValidation(firefoxStrongPasswordProposal) shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("Abc!123 xyz") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("SuperStrong#123") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation("Hello World!") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN
|
||||
basicPasswordValidation(" ") shouldBe (SILENCE_IS_GOLDEN) // ✅ SILENCE_IS_GOLDEN allow space so far
|
||||
|
||||
basicPasswordValidation("short💥") shouldBe (InvalidValueCharacters) // ❌ ErrorMessages.InvalidValueCharacters
|
||||
basicPasswordValidation("a" * 513) shouldBe (InvalidValueLength) // ❌ ErrorMessages.InvalidValueLength
|
||||
|
||||
}
|
||||
|
||||
scenario(s"Test the ${nameOf(APIUtil.fullPasswordValidation _)} method") {
|
||||
val firefoxStrongPasswordProposal = "9YF]gZnXzAENM+]"
|
||||
|
||||
fullPasswordValidation(firefoxStrongPasswordProposal) // ✅ true
|
||||
fullPasswordValidation("Abc!123xyz") // ✅ true
|
||||
fullPasswordValidation("SuperStrong#123") // ✅ true
|
||||
fullPasswordValidation("Abcdefg!1") // ✅ true
|
||||
fullPasswordValidation("short1!") // ❌ false(too short)
|
||||
fullPasswordValidation("alllowercase123!") // ❌ false(no capital letter)
|
||||
fullPasswordValidation("ALLUPPERCASE123!") // ❌ false(no smaller case letter)
|
||||
fullPasswordValidation("NoSpecialChar123") // ❌ false(not special character)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user