Skip to content

Instantly share code, notes, and snippets.

View Algiras's full-sized avatar

Algimantas Krasauskas Algiras

  • Vilnius, Lithuania
View GitHub Profile
case class UsernamePasswordCredentials(username: String, password: String)
case class UserStore(
identityStore: IdentityStore[IO, UserId, User],
checkPassword: UsernamePasswordCredentials => IO[Option[User]]
)
val httpApp = authenticator
.map(
SecuredRequestHandler(_).liftService(privateRoutes) <+> routes
).map(_.orNotFound)
def run(args: List[String]): IO[ExitCode] =
httpApp.flatMap(server(_))
val privateRoutes = TSecAuthService[User, TSecBearerToken[UserId], IO] {
case GET -> Root / "safe-resource" asAuthed user => Ok(s"Hello ${user.username}")
}
val authenticator = for {
users <- Ref.of[IO, Map[UserId, User]](Map.empty)
tokens <- Ref.of[IO, Map[SecureRandomId, TSecBearerToken[UserId]]](Map.empty)
} yield BearerTokenAuthenticator[IO, UserId, User](
userStore(users),
tokenStore(tokens),
TSecTokenSettings(
expiryDuration = 10.minutes,
maxIdle = None
))
def tokenStore(ref: Ref[IO, Map[SecureRandomId, TSecBearerToken[UserId]]]) =
new BackingStore[IO, SecureRandomId, TSecBearerToken[UserId]] {
override def put(elem: TSecBearerToken[UserId]) =
ref.modify(store => (store + (elem.id -> elem), elem))
override def update(elem: TSecBearerToken[UserId]) = put(elem)
override def delete(id: SecureRandomId) = ref.modify(store => (store - id, ()))
override def get(id: SecureRandomId) = OptionT(ref.get.map(_.get(id)))
}
type UserId = FUUID @@ UserIdTag // shapeless.tag.@@
case class User(id: UserId,
username: String,
password: PasswordHash[BCrypt])
def userStore(users: Ref[IO, Map[UserId, User]]) =
new IdentityStore[IO, UserId, User] {
override def get(id: UserId) = OptionT(users.get.map(_.get(id)))
}
object AppServer extends IOApp {
val routes = HttpRoutes.of[IO] {
case GET -> Root / "non-safe-resource" => Ok()
}
val httpApp = routes.orNotFound
val server = BlazeServerBuilder[IO]
.bindHttp()
.withHttpApp(_)
.serve
.compile
@Algiras
Algiras / ContravariantReader.scala
Created October 11, 2019 10:14
ContravariantReader.scala
case class Reader[-From, +To](fn: From => To) {
def map[B](fn2: To => B): Reader[From, B] = Reader(fn.andThen(fn2))
def flatMap[From1 <: From, B](fn2: To => Reader[From1, B]): Reader[From1, B] =
Reader[From1, B](r => fn2(fn(r)).fn(r))
}
trait A { def nr: Int}
trait B { def str: String}
object FizzBuzzResult {
def fizzBuzzToString(fbz: FizzBuzz): String = fbz match {
case Buzz => "buzz"
case Fizz => "fizz"
case FizzAndBuzz => "fizzbuzz"
case number: Other[_] => number.nr.toString()
}
def apply[N <: Nat](implicit res: FizzBuzzResult[N]): String =
res.result.map(fizzBuzzToString).reverse.mkString("\n")
trait NatToFizzBuzz[N <: Nat] {
type Out <: FizzBuzz
val value: Out
}
sealed trait NatToFizzBuzzInstances1 {
type Aux[N <: Nat, O <: FizzBuzz] = NatToFizzBuzz[N] { type Out = O }
implicit def other[N <: Nat](implicit toInt: ToInt[N]): Aux[N, Other[N]] = new NatToFizzBuzz[N] {