This is an automated email from the ASF dual-hosted git repository. rabbah pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push: new 9839e82 Make AuthKey parsing leaner. (#3371) 9839e82 is described below commit 9839e82be79c6f19d6f857445aa7140a5cbd6f88 Author: Markus Thömmes <markusthoem...@me.com> AuthorDate: Tue Mar 6 12:54:50 2018 +0100 Make AuthKey parsing leaner. (#3371) Like in the case of ActivationIds, for AuthKeys we do not care if the user really gives us a UUID. For the system internal it doesn't matter. --- .../src/main/scala/whisk/core/entity/AuthKey.scala | 51 +++++++--------------- .../src/main/scala/whisk/core/entity/Secret.scala | 28 +++++------- .../src/main/scala/whisk/core/entity/UUID.scala | 47 ++++++-------------- .../scala/whisk/core/entity/test/SchemaTests.scala | 2 +- 4 files changed, 41 insertions(+), 87 deletions(-) diff --git a/common/scala/src/main/scala/whisk/core/entity/AuthKey.scala b/common/scala/src/main/scala/whisk/core/entity/AuthKey.scala index 55aa96b..bd1a24c 100644 --- a/common/scala/src/main/scala/whisk/core/entity/AuthKey.scala +++ b/common/scala/src/main/scala/whisk/core/entity/AuthKey.scala @@ -17,12 +17,8 @@ package whisk.core.entity -import scala.util.Try - -import spray.json.JsString -import spray.json.JsValue -import spray.json.RootJsonFormat -import spray.json.deserializationError +import spray.json._ +import spray.json.DefaultJsonProtocol._ /** * Authentication key, consisting of a UUID and Secret. @@ -31,14 +27,14 @@ import spray.json.deserializationError * The constructor is private so that argument requirements are checked and normalized * before creating a new instance. * - * @param (uuid, key) the uuid and key, assured to be non-null because both types are values + * @param k (uuid, key) the uuid and key, assured to be non-null because both types are values */ protected[core] class AuthKey private (private val k: (UUID, Secret)) extends AnyVal { - def uuid = k._1 - def key = k._2 + def uuid: UUID = k._1 + def key: Secret = k._2 def revoke = new AuthKey(uuid, Secret()) - def compact = s"$uuid:$key" - override def toString = uuid.toString + def compact: String = s"$uuid:$key" + override def toString: String = uuid.toString } protected[core] object AuthKey { @@ -64,37 +60,22 @@ protected[core] object AuthKey { * the first two hence "k:v*" produces ("k","v"). * * @param str the string containing uuid and key separated by colon - * @return AuthKey if argument is properly formated + * @return AuthKey if argument is properly formatted * @throws IllegalArgumentException if argument is not well formed */ @throws[IllegalArgumentException] protected[core] def apply(str: String): AuthKey = { - val (k, v) = split(str) - new AuthKey(UUID(k), Secret(v)) - } + val (uuid, secret) = str.split(':').toList match { + case k :: v :: _ => (k, v) + case k :: Nil => (k, "") + case Nil => ("", "") + } - /** - * Makes a tuple from a string where the values are separated by a colon. - * If the string contains more than one colon, all values are ignored except for - * the first two hence "k:v*" produces the tuple ("k","v") and "::*" produces ("",""). - * - * @param string to create pair from - * @return (key, value) where both are null, value is null, or neither is null - */ - private def split(str: String): (String, String) = { - val parts = if (str != null && str.nonEmpty) str.split(":") else Array[String]() - val k = if (parts.size >= 1) parts(0).trim else null - val v = if (parts.size == 2) parts(1).trim else null - (k, v) + new AuthKey(UUID(uuid.trim), Secret(secret.trim)) } - protected[core] implicit val serdes = new RootJsonFormat[AuthKey] { + protected[core] implicit val serdes: RootJsonFormat[AuthKey] = new RootJsonFormat[AuthKey] { def write(k: AuthKey) = JsString(k.compact) - - def read(value: JsValue) = - Try { - val JsString(s) = value - AuthKey(s) - } getOrElse deserializationError("authorization key malformed") + def read(value: JsValue) = AuthKey(value.convertTo[String]) } } diff --git a/common/scala/src/main/scala/whisk/core/entity/Secret.scala b/common/scala/src/main/scala/whisk/core/entity/Secret.scala index db902ae..aac4e7f 100644 --- a/common/scala/src/main/scala/whisk/core/entity/Secret.scala +++ b/common/scala/src/main/scala/whisk/core/entity/Secret.scala @@ -17,11 +17,8 @@ package whisk.core.entity -import scala.util.Try -import spray.json.JsValue -import spray.json.RootJsonFormat -import spray.json.JsString -import spray.json.deserializationError +import spray.json._ +import spray.json.DefaultJsonProtocol._ /** * Secret, a cryptographic string such as a key used for authentication. @@ -33,12 +30,12 @@ import spray.json.deserializationError * @param key the secret key, required not null or empty */ protected[core] class Secret private (val key: String) extends AnyVal { - protected[core] def asString = toString - protected[entity] def toJson = JsString(toString) - override def toString = key + protected[core] def asString: String = toString + protected[entity] def toJson: JsString = JsString(toString) + override def toString: String = key } -protected[core] object Secret extends ArgNormalizer[Secret] { +protected[core] object Secret { /** Minimum secret length */ private val MIN_LENGTH = 64 @@ -54,7 +51,7 @@ protected[core] object Secret extends ArgNormalizer[Secret] { * @throws IllegalArgumentException is argument is not a valid Secret */ @throws[IllegalArgumentException] - override protected[entity] def factory(str: String): Secret = { + protected[core] def apply(str: String): Secret = { require(str.length >= MIN_LENGTH, s"secret must be at least $MIN_LENGTH characters") require(str.length <= MAX_LENGTH, s"secret must be at most $MAX_LENGTH characters") new Secret(str) @@ -69,14 +66,9 @@ protected[core] object Secret extends ArgNormalizer[Secret] { Secret(rand.alphanumeric.take(MIN_LENGTH).mkString) } - implicit val serdes = new RootJsonFormat[Secret] { - def write(s: Secret) = s.toJson - - def read(value: JsValue) = - Try { - val JsString(s) = value - Secret(s) - } getOrElse deserializationError("secret malformed") + implicit val serdes: RootJsonFormat[Secret] = new RootJsonFormat[Secret] { + def write(s: Secret): JsValue = s.toJson + def read(value: JsValue): Secret = Secret(value.convertTo[String]) } private val rand = new scala.util.Random(new java.security.SecureRandom()) diff --git a/common/scala/src/main/scala/whisk/core/entity/UUID.scala b/common/scala/src/main/scala/whisk/core/entity/UUID.scala index 3518077..cce8e29 100644 --- a/common/scala/src/main/scala/whisk/core/entity/UUID.scala +++ b/common/scala/src/main/scala/whisk/core/entity/UUID.scala @@ -21,57 +21,38 @@ import java.security.SecureRandom import com.fasterxml.uuid.Generators -import scala.util.Try -import spray.json.JsString -import spray.json.JsValue -import spray.json.RootJsonFormat -import spray.json.deserializationError +import spray.json._ +import spray.json.DefaultJsonProtocol._ /** - * Wrapper for java.util.UUID. + * Represents a user's username and/or a namespace identifier (generally looks like UUIDs) * * It is a value type (hence == is .equals, immutable and cannot be assigned null). * The constructor is private so that argument requirements are checked and normalized * before creating a new instance. * - * @param uuid the uuid, required not null + * @param asString the uuid in string representation */ -protected[core] class UUID private (private val uuid: java.util.UUID) extends AnyVal { - protected[core] def asString = toString - protected[core] def snippet = toString.substring(0, 8) - protected[entity] def toJson = JsString(toString) - override def toString = uuid.toString +protected[core] class UUID private (val asString: String) extends AnyVal { + protected[core] def snippet: String = asString.substring(0, 8) + protected[entity] def toJson: JsString = JsString(asString) + override def toString: String = asString } -protected[core] object UUID extends ArgNormalizer[UUID] { - - /** - * Creates a UUID from a string. The string must be a valid UUID. - * - * @param str the uuid as string - * @return UUID instance - * @throws IllegalArgumentException is argument is not a valid UUID - */ - @throws[IllegalArgumentException] - override protected[entity] def factory(str: String): UUID = { - new UUID(java.util.UUID.fromString(str)) - } +protected[core] object UUID { /** * Generates a random UUID using java.util.UUID factory. * * @return new UUID */ - protected[core] def apply(): UUID = new UUID(UUIDs.randomUUID()) + protected[core] def apply(): UUID = new UUID(UUIDs.randomUUID().toString) - implicit val serdes = new RootJsonFormat[UUID] { - def write(u: UUID) = u.toJson + protected[core] def apply(str: String): UUID = new UUID(str) - def read(value: JsValue) = - Try { - val JsString(u) = value - UUID(u) - } getOrElse deserializationError("uuid malformed") + implicit val serdes: RootJsonFormat[UUID] = new RootJsonFormat[UUID] { + def write(u: UUID): JsValue = u.toJson + def read(value: JsValue): UUID = new UUID(value.convertTo[String]) } } diff --git a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala index daf8998..cbf49c8 100644 --- a/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala +++ b/tests/src/test/scala/whisk/core/entity/test/SchemaTests.scala @@ -56,7 +56,7 @@ class SchemaTests extends FlatSpec with BeforeAndAfter with ExecHelpers with Mat } it should "reject malformed ids" in { - Seq(null, "", " ", ":", " : ", " :", ": ", "a:b").foreach { i => + Seq("", " ", ":", " : ", " :", ": ", "a:b").foreach { i => an[IllegalArgumentException] should be thrownBy AuthKey(i) } } -- To stop receiving notification emails like this one, please contact rab...@apache.org.