aboutsummaryrefslogblamecommitdiff
path: root/src/main/scala/xyz/driver/pdsuicommon/domain/User.scala
blob: f75f3919f92e8aa159a49655381bf4430fd7418c (plain) (tree)
1
2
3
4
5
6
7
8
9
                                     
 

                                 
                                                 
 


                                              
 


                                         
                                       
                                                            

                                                       
                                                                










                                                                                                                 

















                                                               











                                                                         






                                                                                                      


                                                                                    


















                                                                                               
                                                                            

   




                                                                       

































































                                                                                                              
 
package xyz.driver.pdsuicommon.domain

import java.math.BigInteger
import java.security.SecureRandom
import java.time.{Instant, LocalDateTime, ZoneId}

import xyz.driver.pdsuicommon.logging._
import xyz.driver.pdsuicommon.domain.User.Role
import xyz.driver.pdsuicommon.utils.Utils

final case class User(id: StringId[User],
                      email: Email,
                      name: String,
                      roles: Set[Role],
                      latestActivity: Option[LocalDateTime],
                      deleted: Option[LocalDateTime]) {

  def this(driverUser: xyz.driver.entities.users.AuthUserInfo) {
    this(
      id = StringId[xyz.driver.pdsuicommon.domain.User](driverUser.id.value),
      email = Email(driverUser.email.toString),
      name = driverUser.name.toString,
      roles = driverUser.roles.flatMap(User.mapRoles),
      latestActivity =
        driverUser.lastLoginTime.map(t => Instant.ofEpochMilli(t.millis).atZone(ZoneId.of("Z")).toLocalDateTime),
      deleted = Option.empty[LocalDateTime]
    )
  }
}

object User {

  sealed trait Role extends Product with Serializable {

    /**
      * Bit representation of this role
      */
    def bit: Int

    def is(that: Role): Boolean = this == that

    def oneOf(roles: Role*): Boolean = roles.contains(this)

    def oneOf(roles: Set[Role]): Boolean = roles.contains(this)
  }

  object Role extends PhiLogging {
    case object RecordAdmin            extends Role { val bit = 1 << 0  }
    case object RecordCleaner          extends Role { val bit = 1 << 1  }
    case object RecordOrganizer        extends Role { val bit = 1 << 2  }
    case object DocumentExtractor      extends Role { val bit = 1 << 3  }
    case object TrialSummarizer        extends Role { val bit = 1 << 4  }
    case object CriteriaCurator        extends Role { val bit = 1 << 5  }
    case object TrialAdmin             extends Role { val bit = 1 << 6  }
    case object EligibilityVerifier    extends Role { val bit = 1 << 7  }
    case object TreatmentMatchingAdmin extends Role { val bit = 1 << 8  }
    case object RoutesCurator          extends Role { val bit = 1 << 9  }
    case object SystemUser             extends Role { val bit = 1 << 10 }
    case object ResearchOncologist     extends Role { val bit = 1 << 11 }

    val RepRoles = Set[Role](RecordAdmin, RecordCleaner, RecordOrganizer, DocumentExtractor)

    val TcRoles = Set[Role](TrialSummarizer, CriteriaCurator, TrialAdmin)

    val TreatmentMatchingRoles = Set[Role](RoutesCurator, EligibilityVerifier, TreatmentMatchingAdmin)

    val PepRoles = Set[Role](ResearchOncologist)

    val All = RepRoles ++ TcRoles ++ TreatmentMatchingRoles ++ PepRoles + SystemUser

    def apply(bitMask: Int): Role = {
      def extractRole(role: Role): Set[Role] =
        if ((bitMask & role.bit) != 0) Set(role) else Set.empty[Role]

      val roles = All.flatMap(extractRole)
      roles.size match {
        case 1 => roles.head
        case _ =>
          logger.error(phi"Can't convert a bit mask ${Unsafe(bitMask)} to any role")
          throw new IllegalArgumentException()
      }
    }

    implicit def toPhiString(x: Role): PhiString = Unsafe(Utils.getClassSimpleName(x.getClass))
  }

  implicit def toPhiString(x: User): PhiString = {
    import x._
    phi"User(id=$id, roles=${Unsafe(roles.map(_.toString).mkString(", "))})"
  }

  // SecureRandom is thread-safe, see the implementation
  private val random = new SecureRandom()

  def createPassword: String = new BigInteger(240, random).toString(32)

  def mapRoles(coreRole: xyz.driver.core.auth.Role): Set[xyz.driver.pdsuicommon.domain.User.Role] = {
    coreRole match {
      case xyz.driver.entities.auth.AdministratorRole =>
        Set(
          xyz.driver.pdsuicommon.domain.User.Role.SystemUser,
          xyz.driver.pdsuicommon.domain.User.Role.RecordAdmin,
          xyz.driver.pdsuicommon.domain.User.Role.TrialAdmin,
          xyz.driver.pdsuicommon.domain.User.Role.TreatmentMatchingAdmin
        )
      case xyz.driver.entities.auth.RecordAdmin =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.RecordAdmin)
      case xyz.driver.entities.auth.RecordCleaner =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.RecordCleaner)
      case xyz.driver.entities.auth.RecordOrganizer =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.RecordOrganizer)
      case xyz.driver.entities.auth.DocumentExtractor =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.DocumentExtractor)
      case xyz.driver.entities.auth.TrialSummarizer =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.TrialSummarizer)
      case xyz.driver.entities.auth.CriteriaCurator =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.CriteriaCurator)
      case xyz.driver.entities.auth.TrialAdmin =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.TrialAdmin)
      case xyz.driver.entities.auth.EligibilityVerifier =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.EligibilityVerifier)
      case xyz.driver.entities.auth.TreatmentMatchingAdmin =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.TreatmentMatchingAdmin)
      case xyz.driver.entities.auth.RoutesCurator =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.RoutesCurator)
      case xyz.driver.entities.auth.ResearchOncologist =>
        Set(xyz.driver.pdsuicommon.domain.User.Role.ResearchOncologist)
      case _ =>
        Set.empty[xyz.driver.pdsuicommon.domain.User.Role]
    }
  }

  def mapRolesToDriver(pdsuiRole: xyz.driver.pdsuicommon.domain.User.Role): Set[xyz.driver.core.auth.Role] = {
    pdsuiRole match {
      case xyz.driver.pdsuicommon.domain.User.Role.SystemUser =>
        Set(xyz.driver.entities.auth.AdministratorRole)
      case xyz.driver.pdsuicommon.domain.User.Role.RecordAdmin =>
        Set(xyz.driver.entities.auth.RecordAdmin)
      case xyz.driver.pdsuicommon.domain.User.Role.RecordCleaner =>
        Set(xyz.driver.entities.auth.RecordCleaner)
      case xyz.driver.pdsuicommon.domain.User.Role.RecordOrganizer =>
        Set(xyz.driver.entities.auth.RecordOrganizer)
      case xyz.driver.pdsuicommon.domain.User.Role.DocumentExtractor =>
        Set(xyz.driver.entities.auth.DocumentExtractor)
      case xyz.driver.pdsuicommon.domain.User.Role.TrialSummarizer =>
        Set(xyz.driver.entities.auth.TrialSummarizer)
      case xyz.driver.pdsuicommon.domain.User.Role.CriteriaCurator =>
        Set(xyz.driver.entities.auth.CriteriaCurator)
      case xyz.driver.pdsuicommon.domain.User.Role.TrialAdmin =>
        Set(xyz.driver.entities.auth.TrialAdmin)
      case xyz.driver.pdsuicommon.domain.User.Role.EligibilityVerifier =>
        Set(xyz.driver.entities.auth.EligibilityVerifier)
      case xyz.driver.pdsuicommon.domain.User.Role.TreatmentMatchingAdmin =>
        Set(xyz.driver.entities.auth.TreatmentMatchingAdmin)
      case xyz.driver.pdsuicommon.domain.User.Role.RoutesCurator =>
        Set(xyz.driver.entities.auth.RoutesCurator)
      case xyz.driver.pdsuicommon.domain.User.Role.ResearchOncologist =>
        Set(xyz.driver.entities.auth.ResearchOncologist)
      case _ =>
        Set.empty[xyz.driver.core.auth.Role]
    }
  }
}