Update dependencies

This commit is contained in:
Eike Kettner 2019-12-28 12:38:11 +01:00
parent 07a23b9611
commit a9e70401de
6 changed files with 92 additions and 71 deletions

View File

@ -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)

View File

@ -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]] =

View File

@ -1,4 +1,3 @@
CREATE TABLE "filemeta" (
"id" varchar(254) not null primary key,
"timestamp" varchar(40) not null,

View File

@ -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 })

View File

@ -1 +1 @@
sbt.version=1.3.3
sbt.version=1.3.6

View File

@ -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")