All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lucuma.core.model.User.scala Maven / Gradle / Ivy

There is a newer version: 0.108.0
Show newest version
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model

import cats.ApplicativeError
import cats.Eq
import cats.implicits.*
import lucuma.core.util.WithGid
import lucuma.refined.*

/** A user has [at least] an identity and a role. */
sealed trait User extends Product with Serializable {

  def id: User.Id
  def role: Role

  /**
   * A name to display in interfaces. This is never empty, and respects users' formatting
   * preferences as specified in their ORCID record.
   */
  def displayName: String

  /** Verity that this user has access greater than or equal to `access`. */
  final def verifyAccess[F[_]](
    access:      Access
  )(using ev: ApplicativeError[F, Throwable]): F[Unit] =
    ev.raiseError(
      AccessControlException(displayName, id, role, access)
    ).whenA(role.access < access)

}

object User extends WithGid('u'.refined) {
  given Eq[User] = Eq.instance {
    case (a: GuestUser, b: GuestUser)       => a === b
    case (a: ServiceUser, b: ServiceUser)   => a === b
    case (a: StandardUser, b: StandardUser) => a === b
    case _                                  => false
  }

}

/** Guest users have the weakest `Role` and no identifying information. */
final case class GuestUser(id: User.Id) extends User {
  val role        = GuestRole
  val displayName = "Guest User"
}

object GuestUser {
  given Eq[GuestUser] = Eq.by(_.id)
}

/** Service users have the strongest `Role` and represent services themselves. */
final case class ServiceUser(id: User.Id, name: String) extends User {
  val role        = ServiceRole(name)
  val displayName = s"Service User ($name)"
}

object ServiceUser {
  given Eq[ServiceUser] = Eq.by(x => (x.id, x.name))
}

/**
 * Standard users are authenticated and have a current role and ORCID profile, as well as a set of
 * other roles they can assume.
 */
final case class StandardUser(
  id:         User.Id,
  role:       StandardRole,
  otherRoles: List[StandardRole],
  profile:    OrcidProfile
) extends User {
  val displayName = profile.displayName
}

object StandardUser {
  given Eq[StandardUser] =
    Eq.by(x => (x.id, x.role, x.otherRoles, x.profile))
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy