From 350f0bd10e65c3d60dfab546d3a375ff3990a614 Mon Sep 17 00:00:00 2001 From: vlad Date: Wed, 3 Aug 2016 19:58:45 -0700 Subject: Finer grained permission-control --- src/main/scala/com/drivergrp/core/auth.scala | 76 +++++++++++++++++++++------- 1 file changed, 59 insertions(+), 17 deletions(-) (limited to 'src/main/scala/com/drivergrp/core/auth.scala') diff --git a/src/main/scala/com/drivergrp/core/auth.scala b/src/main/scala/com/drivergrp/core/auth.scala index 8722d6a..eed40ef 100644 --- a/src/main/scala/com/drivergrp/core/auth.scala +++ b/src/main/scala/com/drivergrp/core/auth.scala @@ -2,7 +2,16 @@ package com.drivergrp.core object auth { - trait Permission + sealed trait Permission + case object CanSeeUser extends Permission + case object CanSeeAssay extends Permission + case object CanSeeReport extends Permission + case object CanCreateReport extends Permission + case object CanEditReport extends Permission + case object CanEditReviewingReport extends Permission + case object CanSignOutReport extends Permission + case object CanShareReportWithPatient extends Permission + case object CanAssignRoles extends Permission trait Role { val id: Id[Role] @@ -11,6 +20,43 @@ object auth { def hasPermission(permission: Permission): Boolean = false } + case object ObserverRole extends Role { + val id = Id(1L) + val name = Name("observer") + + override def hasPermission(permission: Permission): Boolean = + Set[Permission](CanSeeUser, CanSeeAssay, CanSeeReport).contains(permission) + } + + 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 hasPermission(permission: Permission): Boolean = + Set[Permission](CanSeeUser, CanSeeAssay, CanSeeReport, CanEditReport).contains(permission) + } + + case object PathologistRole extends Role { + val id = Id(4L) + val name = Name("pathologist") + + override def hasPermission(permission: Permission): Boolean = + Set[Permission](CanSeeUser, CanSeeAssay, CanSeeReport, CanEditReport, CanSignOutReport, CanEditReviewingReport) + .contains(permission) + } + + case object AdministratorRole extends Role { + val id = Id(5L) + val name = Name("administrator") + + override def hasPermission(permission: Permission): Boolean = true + } + trait User { def id: Id[User] def roles: Set[Role] @@ -22,31 +68,27 @@ object auth { final case class AuthToken(value: Base64[Macaroon]) + def extractUser(authToken: AuthToken): User = { + new User() { + override def id: Id[User] = Id[User](1L) + override def roles: Set[Role] = Set(PathologistRole) + } + + // TODO: or reject(ValidationRejection(s"Wasn't able to extract user for the token provided")) if none + } + object directives { import akka.http.scaladsl.server._ import Directives._ val AuthenticationTokenHeader = "WWW-Authenticate" - type UserExtractor = AuthToken => Option[User] - - def authorize(role: Role)(implicit userExtractor: UserExtractor): Directive1[Id[User]] = { + def authorize(permission: Permission): Directive1[AuthToken] = { headerValueByName(AuthenticationTokenHeader).flatMap { tokenValue => val token = AuthToken(Base64[Macaroon](tokenValue)) - userExtractor(token) match { - case Some(user) => - if (user.roles.contains(role)) provide(user.id: Id[User]) - 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))) + if (extractUser(token).roles.exists(_.hasPermission(permission))) provide(token) + else reject(ValidationRejection(s"User does not have the required permission $permission")) } } } -- cgit v1.2.3