Authenticate with external accounts using OIDC

After successful authentication at the provider, an account is
automatically created at docspell and the user is logged in.
This commit is contained in:
eikek
2021-09-05 21:39:09 +02:00
parent 7edb96a297
commit f8362329a9
13 changed files with 382 additions and 75 deletions

View File

@ -6,12 +6,10 @@
package docspell.oidc
import cats.data.OptionT
import cats.data.{Kleisli, OptionT}
import cats.effect._
import cats.implicits._
import docspell.common._
import org.http4s.HttpRoutes
import org.http4s._
import org.http4s.client.Client
@ -22,7 +20,16 @@ import org.log4s.getLogger
object CodeFlowRoutes {
private[this] val log4sLogger = getLogger
def apply[F[_]: Async, A](
def apply[F[_]: Async](
enabled: Boolean,
onUserInfo: OnUserInfo[F],
config: CodeFlowConfig[F],
client: Client[F]
): HttpRoutes[F] =
if (enabled) route[F](onUserInfo, config, client)
else Kleisli(_ => OptionT.pure(Response.notFound[F]))
def route[F[_]: Async](
onUserInfo: OnUserInfo[F],
config: CodeFlowConfig[F],
client: Client[F]

View File

@ -20,21 +20,26 @@ object UserInfoDecoder {
findSomeId("preferred_username")
/** Looks recursively in the JSON for the first attribute with name `key` and returns
* its value (expecting an Ident).
* its value.
*/
def findSomeId(key: String): Decoder[Ident] =
def findSomeString(key: String): Decoder[String] =
Decoder.instance { cursor =>
cursor.value
.findAllByKey(key)
.find(_.isString)
.flatMap(_.asString)
.toRight(s"No value found in JSON for key '$key'")
.flatMap(normalizeUid)
.left
.map(msg => DecodingFailure(msg, Nil))
}
private def normalizeUid(uid: String): Either[String, Ident] =
/** Looks recursively in the JSON for the first attribute with name `key` and returns
* its value (expecting an Ident).
*/
def findSomeId(key: String): Decoder[Ident] =
findSomeString(key).emap(normalizeUid)
def normalizeUid(uid: String): Either[String, Ident] =
Ident(uid.filter(Ident.chars.contains))
.flatMap(id =>
if (id.nonEmpty) Right(id) else Left(s"Id '$uid' empty after normalizing!'")