diff --git a/jvm/src/main/scala/cs214/webapp/server/web/decorators.scala b/jvm/src/main/scala/cs214/webapp/server/web/decorators.scala index 9149e340fac37782f2759bcdf22b1d331611b761..4b057556231157d605b0e8c2d660fa0d9793951a 100644 --- a/jvm/src/main/scala/cs214/webapp/server/web/decorators.scala +++ b/jvm/src/main/scala/cs214/webapp/server/web/decorators.scala @@ -23,23 +23,21 @@ object decorators: cask.Response(f"Invalid or missing 'Origin' header: must match the Host", 403) class adminAuth(expectedAdminKeyOpt: Option[String]) extends cask.router.Decorator[cask.Response[JsonData], cask.Response[JsonData], Any]: - private val expectedAuthOpt: Option[String] = expectedAdminKeyOpt.map { key => - s"Basic ${Base64.getEncoder.encodeToString(s"$key:".getBytes("UTF-8"))}" - } + private val expectedAuthOpt: Option[String] = expectedAdminKeyOpt.map: + key => s"Basic ${Base64.getEncoder.encodeToString(s"$key:".getBytes("UTF-8"))}" + private val expectedAuthBytesOpt: Option[Array[Byte]] = expectedAuthOpt.map(_.getBytes("UTF-8")) - override def wrapFunction(request: cask.Request, delegate: Delegate) = val authHeaderOpt: Option[String] = request.headers.get("authorization").flatMap(_.headOption) val authHeaderBytesOpt: Option[Array[Byte]] = authHeaderOpt.map(_.getBytes("UTF-8")) // Perform the check using constant time comparison - val authorized = (expectedAuthBytesOpt, authHeaderBytesOpt) match { + val authorized = (expectedAuthBytesOpt, authHeaderBytesOpt) match case (Some(expectedBytes), Some(actualBytes)) => MessageDigest.isEqual(actualBytes, expectedBytes) case _ => // Either expected key wasn't configured OR header was missing/malformed false - } if (authorized){ delegate(Map()) } else { @@ -49,5 +47,4 @@ object decorators: statusCode = 401, headers = Seq("WWW-Authenticate" -> "Basic realm=\"Admin API\"") ) - } - \ No newline at end of file + } \ No newline at end of file