From a9e70401de5995896a49344c14f3718c76bc1b6a Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Sat, 28 Dec 2019 12:38:11 +0100 Subject: [PATCH] Update dependencies --- .../scala/docspell/common/LenientUri.scala | 122 +++++++++++------- .../restserver/routes/Authenticate.scala | 6 +- .../postgresql/V1.0.0__initial_database.sql | 1 - project/Dependencies.scala | 28 ++-- project/build.properties | 2 +- project/plugins.sbt | 4 +- 6 files changed, 92 insertions(+), 71 deletions(-) diff --git a/modules/common/src/main/scala/docspell/common/LenientUri.scala b/modules/common/src/main/scala/docspell/common/LenientUri.scala index 840ca9f2..7a249f58 100644 --- a/modules/common/src/main/scala/docspell/common/LenientUri.scala +++ b/modules/common/src/main/scala/docspell/common/LenientUri.scala @@ -8,51 +8,78 @@ import cats.data.NonEmptyList import cats.effect.{Blocker, ContextShift, Sync} import docspell.common.LenientUri.Path import io.circe.{Decoder, Encoder} +import java.net.URLEncoder import scodec.bits.ByteVector +import cats.effect.Resource +import java.net.HttpURLConnection /** A URI. * * It is not compliant to rfc3986, but covers most use cases in a convenient way. */ -case class LenientUri(scheme: NonEmptyList[String] - , authority: Option[String] - , path: LenientUri.Path - , query: Option[String] - , fragment: Option[String]) { +case class LenientUri( + scheme: NonEmptyList[String], + authority: Option[String], + path: LenientUri.Path, + query: Option[String], + fragment: Option[String] +) { def /(segment: String): LenientUri = copy(path = path / segment) - def ++ (np: Path): LenientUri = + def ++(np: Path): LenientUri = copy(path = np.segments.foldLeft(path)(_ / _)) - def ++ (np: String): LenientUri = { + def ++(np: String): LenientUri = { val rel = LenientUri.stripLeading(np, '/') ++(LenientUri.unsafe(s"a:$rel").path) } + def withQuery(name: String, value: String): LenientUri = + withQueryPlain(name, URLEncoder.encode(value, "UTF-8")) + + def withQueryPlain(name: String, value: String): LenientUri = + copy(query = query.map(q => q + "&" + name + "=" + value).orElse(Option(s"$name=$value"))) + + def withFragment(f: String): LenientUri = + copy(fragment = Some(f)) + def toJavaUrl: Either[String, URL] = Either.catchNonFatal(new URL(asString)).left.map(_.getMessage) - def readURL[F[_]: Sync : ContextShift](chunkSize: Int, blocker: Blocker): Stream[F, Byte] = - Stream.emit(Either.catchNonFatal(new URL(asString))). - covary[F]. - rethrow. - flatMap(url => fs2.io.readInputStream(Sync[F].delay(url.openStream()), chunkSize, blocker, true)) + def open[F[_]: Sync]: Either[String, Resource[F, HttpURLConnection]] = + toJavaUrl.map { url => + Resource + .make(Sync[F].delay(url.openConnection().asInstanceOf[HttpURLConnection]))( + conn => Sync[F].delay(conn.disconnect()) + ) + } + + def readURL[F[_]: Sync: ContextShift](chunkSize: Int, blocker: Blocker): Stream[F, Byte] = + Stream + .emit(Either.catchNonFatal(new URL(asString))) + .covary[F] + .rethrow + .flatMap( + url => fs2.io.readInputStream(Sync[F].delay(url.openStream()), chunkSize, blocker, true) + ) def host: Option[String] = - authority. - map(a => a.indexOf(':') match { - case -1 => a - case n => a.substring(0, n) - }) + authority.map( + a => + a.indexOf(':') match { + case -1 => a + case n => a.substring(0, n) + } + ) def asString: String = { val schemePart = scheme.toList.mkString(":") - val authPart = authority.map(a => s"//$a").getOrElse("") - val pathPart = path.asString - val queryPart = query.map(q => s"?$q").getOrElse("") - val fragPart = fragment.map(f => s"#$f").getOrElse("") + val authPart = authority.map(a => s"//$a").getOrElse("") + val pathPart = path.asString + val queryPart = query.map(q => s"?$q").getOrElse("") + val fragPart = fragment.map(f => s"#$f").getOrElse("") s"$schemePart:$authPart$pathPart$queryPart$fragPart" } } @@ -68,30 +95,30 @@ object LenientUri { } case object RootPath extends Path { val segments = Nil - val isRoot = true - val isEmpty = false + val isRoot = true + val isEmpty = false def /(seg: String): Path = NonEmptyPath(NonEmptyList.of(seg)) def asString = "/" } case object EmptyPath extends Path { val segments = Nil - val isRoot = false - val isEmpty = true + val isRoot = false + val isEmpty = true def /(seg: String): Path = NonEmptyPath(NonEmptyList.of(seg)) def asString = "" } case class NonEmptyPath(segs: NonEmptyList[String]) extends Path { def segments = segs.toList - val isEmpty = false - val isRoot = false + val isEmpty = false + val isRoot = false def /(seg: String): Path = copy(segs = segs.append(seg)) def asString = segs.head match { - case "." => segments.map(percentEncode).mkString("/") + case "." => segments.map(percentEncode).mkString("/") case ".." => segments.map(percentEncode).mkString("/") - case _ => "/" + segments.map(percentEncode).mkString("/") + case _ => "/" + segments.map(percentEncode).mkString("/") } } @@ -104,11 +131,12 @@ object LenientUri { def parse(str: String): Either[String, LenientUri] = { def makePath(str: String): Path = str.trim match { case "/" => RootPath - case "" => EmptyPath - case _ => NonEmptyList.fromList(stripLeading(str, '/').split('/').toList.map(percentDecode)) match { - case Some(nl) => NonEmptyPath(nl) - case None => sys.error(s"Invalid url: $str") - } + case "" => EmptyPath + case _ => + NonEmptyList.fromList(stripLeading(str, '/').split('/').toList.map(percentDecode)) match { + case Some(nl) => NonEmptyPath(nl) + case None => sys.error(s"Invalid url: $str") + } } def makeNonEmpty(str: String): Option[String] = @@ -128,9 +156,13 @@ object LenientUri { case n => pqf.indexOf('#', n) match { case -1 => - (makePath(pqf.substring(0, n)), makeNonEmpty(pqf.substring(n+1)), None) + (makePath(pqf.substring(0, n)), makeNonEmpty(pqf.substring(n + 1)), None) case k => - (makePath(pqf.substring(0, n)), makeNonEmpty(pqf.substring(n+1, k)), makeNonEmpty(pqf.substring(k+1))) + ( + makePath(pqf.substring(0, n)), + makeNonEmpty(pqf.substring(n + 1, k)), + makeNonEmpty(pqf.substring(k + 1)) + ) } } @@ -140,7 +172,7 @@ object LenientUri { val scheme = makeScheme(p0) val (auth, pathQF) = p1.indexOf('/') match { case -1 => (Some(p1), "") - case n => (Some(p1.substring(0, n)), p1.substring(n)) + case n => (Some(p1.substring(0, n)), p1.substring(n)) } val (path, query, frag) = splitPathQF(pathQF) scheme match { @@ -155,7 +187,7 @@ object LenientUri { case -1 => Left(s"No scheme found: $str") case n => - val scheme = makeScheme(p0.substring(0, n)) + val scheme = makeScheme(p0.substring(0, n)) val (path, query, frag) = splitPathQF(p0.substring(n + 1)) scheme match { case None => @@ -167,16 +199,13 @@ object LenientUri { } } - private[this] val delims: Set[Char] = ",/?:@&=+$# %".toSet + private[this] val delims: Set[Char] = ",/?:@&$# %".toSet private def percent(s: String): String = - "%" + ByteVector.encodeUtf8(s). - fold(throw _, identity). - toHex + "%" + ByteVector.encodeUtf8(s).fold(throw _, identity).toHex def percentEncode(s: String): String = - s.flatMap(c => - if (delims.contains(c)) percent(c.toString) else c.toString) + s.flatMap(c => if (delims.contains(c)) percent(c.toString) else c.toString) def percentDecode(s: String): String = if (!s.contains("%")) s @@ -188,13 +217,14 @@ object LenientUri { else if (c == '%') ("%", res) else (acc, res :+ c.toByte) } - ._2.decodeUtf8.fold(throw _, identity) + ._2 + .decodeUtf8 + .fold(throw _, identity) private def stripLeading(s: String, c: Char): String = if (s.length > 0 && s.charAt(0) == c) s.substring(1) else s - implicit val encodeLenientUri: Encoder[LenientUri] = Encoder.encodeString.contramap(_.asString) diff --git a/modules/restserver/src/main/scala/docspell/restserver/routes/Authenticate.scala b/modules/restserver/src/main/scala/docspell/restserver/routes/Authenticate.scala index 9d958ce0..e07de9d0 100644 --- a/modules/restserver/src/main/scala/docspell/restserver/routes/Authenticate.scala +++ b/modules/restserver/src/main/scala/docspell/restserver/routes/Authenticate.scala @@ -26,7 +26,7 @@ object Authenticate { val authUser = getUser[F](S.loginSession(cfg)) val onFailure: AuthedRoutes[String, F] = - Kleisli(req => OptionT.liftF(Forbidden(req.authInfo))) + Kleisli(req => OptionT.liftF(Forbidden(req.context))) val middleware: AuthMiddleware[F, AuthToken] = AuthMiddleware(authUser, onFailure) @@ -41,12 +41,12 @@ object Authenticate { val authUser = getUser[F](S.loginSession(cfg)) val onFailure: AuthedRoutes[String, F] = - Kleisli(req => OptionT.liftF(Forbidden(req.authInfo))) + Kleisli(req => OptionT.liftF(Forbidden(req.context))) val middleware: AuthMiddleware[F, AuthToken] = AuthMiddleware(authUser, onFailure) - middleware(AuthedRoutes(authReq => f(authReq.authInfo).run(authReq.req))) + middleware(AuthedRoutes(authReq => f(authReq.context).run(authReq.req))) } private def getUser[F[_]: Effect](auth: String => F[Login.Result]): Kleisli[F, Request[F], Either[String, AuthToken]] = diff --git a/modules/store/src/main/resources/db/migration/postgresql/V1.0.0__initial_database.sql b/modules/store/src/main/resources/db/migration/postgresql/V1.0.0__initial_database.sql index 504a7229..480d875c 100644 --- a/modules/store/src/main/resources/db/migration/postgresql/V1.0.0__initial_database.sql +++ b/modules/store/src/main/resources/db/migration/postgresql/V1.0.0__initial_database.sql @@ -1,4 +1,3 @@ - CREATE TABLE "filemeta" ( "id" varchar(254) not null primary key, "timestamp" varchar(40) not null, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index bd53d0c2..e10a49e2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,26 +6,24 @@ object Dependencies { val BcryptVersion = "0.4" val BetterMonadicForVersion = "0.3.1" - val BitpeaceVersion = "0.4.0" + val BitpeaceVersion = "0.4.1" val CirceVersion = "0.12.3" - val DoobieVersion = "0.8.6" + val DoobieVersion = "0.8.7" val FastparseVersion = "2.1.3" - val FlywayVersion = "6.0.8" + val FlywayVersion = "6.1.3" val Fs2Version = "2.1.0" val H2Version = "1.4.200" - val Http4sVersion = "0.21.0-M5" + val Http4sVersion = "0.21.0-M6" val KindProjectorVersion = "0.10.3" val Log4sVersion = "1.8.2" val LogbackVersion = "1.2.3" - val MariaDbVersion = "2.5.1" + val MariaDbVersion = "2.5.2" val MiniTestVersion = "2.7.0" - val PostgresVersion = "42.2.8" - val PureConfigVersion = "0.12.1" - val SqliteVersion = "3.28.0" + val PostgresVersion = "42.2.9" + val PureConfigVersion = "0.12.2" + val SqliteVersion = "3.30.1" val StanfordNlpVersion = "3.9.2" - val TikaVersion = "1.22" - val javaxMailVersion = "1.6.2" - val dnsJavaVersion = "2.1.9" + val TikaVersion = "1.23" val YamuscaVersion = "0.6.1" val stanfordNlpCore = Seq( @@ -130,12 +128,6 @@ object Dependencies { "org.flywaydb" % "flyway-core" % FlywayVersion ) - val javaxMail = Seq( - "javax.mail" % "javax.mail-api" % javaxMailVersion, - "com.sun.mail" % "javax.mail" % javaxMailVersion, - "dnsjava" % "dnsjava" % dnsJavaVersion intransitive() - ) - val yamusca = Seq( "com.github.eikek" %% "yamusca-core" % YamuscaVersion ) @@ -151,7 +143,7 @@ object Dependencies { val betterMonadicFor = "com.olegpy" %% "better-monadic-for" % BetterMonadicForVersion val webjars = Seq( - "swagger-ui" -> "3.24.0", + "swagger-ui" -> "3.24.3", "Semantic-UI" -> "2.4.1", "jquery" -> "3.4.1" ).map({case (a, v) => "org.webjars" % a % v }) diff --git a/project/build.properties b/project/build.properties index 6adcdc75..00b48d97 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.3 +sbt.version=1.3.6 diff --git a/project/plugins.sbt b/project/plugins.sbt index aae3bb7f..c6ff1545 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,6 +2,6 @@ addSbtPlugin("com.github.eikek" % "sbt-openapi-schema" % "0.5.0") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.4.1") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1-M3") +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.5.2") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1") addSbtPlugin("com.47deg" % "sbt-microsites" % "0.9.2")