blob: 84d943d4edec2969ae3902e805570756b996cb33 (
plain) (
tree)
|
|
package com.drivergrp.core
object auth {
final case class FullName[+T](firstName: Name[T], middleName: Name[T], lastName: Name[T])
final case class Email(username: String, domain: String) {
override def toString = username + "@" + domain
}
trait Role {
val id: Id[Role]
val name: Name[Role]
def canEditReport: Boolean = false
def canSignOffReport: Boolean = false
def canAssignRoles: Boolean = false
}
case object ObserverRole extends Role {
val id = Id(1L)
val name = Name("observer")
}
case object PatientRole extends Role {
val id = Id(2L)
val name = Name("patient")
}
case object CuratorRole extends Role {
val id = Id(3L)
val name = Name("curator")
override def canEditReport: Boolean = true
}
case object PathologistRole extends Role {
val id = Id(4L)
val name = Name("pathologist")
override def canEditReport: Boolean = true
override def canSignOffReport: Boolean = true
}
case object AdministratorRole extends Role {
val id = Id(5L)
val name = Name("administrator")
override def canEditReport: Boolean = true
override def canSignOffReport: Boolean = true
override def canAssignRoles: Boolean = true
}
final case class Avatar(id: Id[Avatar], name: Name[Avatar])
final case class User(id: Id[User], name: FullName[User], email: Email, avatar: Option[Avatar], roles: Set[Role])
val TestUser = User(Id[User](1L),
FullName[User](Name("James"), Name("Dewey"), Name("Watson")),
Email("j.watson", "uchicago.edu"),
Some(Avatar(Id[Avatar](1L), Name[Avatar]("Coolface"))),
Set(PathologistRole))
final case class Macaroon(value: String)
final case class Base64[T](value: String)
final case class AuthToken(value: Base64[Macaroon])
object directives {
import akka.http.scaladsl.server._
import Directives._
val AuthenticationTokenHeader = "WWW-Authenticate"
def authorize(role: Role): Directive1[Id[User]] = {
headerValueByName(AuthenticationTokenHeader).flatMap { tokenValue =>
val token = AuthToken(Base64[Macaroon](tokenValue))
extractUser(token) match {
case Some(user) =>
if (user.roles.contains(role)) provide(user.id)
else reject(ValidationRejection(s"User does not have the required ${role.name} role"))
case None =>
reject(ValidationRejection(s"Wasn't able to extract user for the token provided"))
}
}
}
def extractToken: Directive1[AuthToken] = {
headerValueByName(AuthenticationTokenHeader).flatMap { token =>
provide(AuthToken(Base64[Macaroon](token)))
}
}
def extractUser(authToken: AuthToken): Option[User] = {
Some(TestUser)
}
}
}
|