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

controllers.AnonymousRequest.scala Maven / Gradle / Ivy

The newest version!
package controllers

import com.gilt.apidoc.models.{ Membership, Organization, User, Visibility }
import models.MainTemplate
import core.Role
import play.api.mvc._
import play.api.mvc.Results.Redirect
import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._
import play.api.Play.current
import java.util.UUID

class AnonymousRequest[A](
  resources: RequestResources,
  val request: Request[A]
) extends WrappedRequest[A](request) {

  val user = resources.user
  val org = resources.org
  val isAdmin = resources.isAdmin
  val isMember = resources.isMember

  lazy val api = Authenticated.api(user)

  def mainTemplate(title: String): MainTemplate = {
    MainTemplate(
      title = title,
      user = user,
      org = org,
      isOrgMember = isMember,
      isOrgAdmin = isAdmin
    )
  }

  def requireAdmin() {
    resources.requireAdmin()
  }

  def requireOrg() {
    resources.requireOrg()
  }
}

class AnonymousOrgRequest[A](
  anon: AnonymousRequest[A]
) extends WrappedRequest[A](anon.request) {

  val user = anon.user
  val org = anon.org.get
  val isAdmin = anon.isAdmin
  val isMember = anon.isMember

  lazy val api = anon.api

  def mainTemplate(title: String = org.name): MainTemplate = anon.mainTemplate(title)

  def requireAdmin() {
    anon.requireAdmin()
  }

}


case class RequestResources(
  user: Option[User],
  org: Option[Organization],
  memberships: Seq[Membership]
) {
  require(
    memberships.isEmpty || (!org.isEmpty || !user.isEmpty),
    "memberships must be empty if there is no organization or no user"
  )

  val isAdmin = !memberships.find(_.role == Role.Admin.key).isEmpty
  val isMember = isAdmin || !memberships.find(_.role == Role.Member.key).isEmpty

  def requireUser() {
    require(!user.isEmpty, "Action requires an authenticated user")
  }

  def requireOrg() {
    require(!org.isEmpty, "Action requires an org")
  }

  def requireAdmin() {
    requireUser()
    requireOrg()
    require(isAdmin, s"Action requires admin role. User[${user.get.guid}] is not an admin of Org[${org.get.key}]")
  }

  def requireMember() {
    requireUser()
    requireOrg()
    require(isMember, s"Action requires member role. User[${user.get.guid}] is not a member of Org[${org.get.key}]")
  }

}

object AnonymousRequest {

  import scala.concurrent.ExecutionContext.Implicits.global

  def resources(requestPath: String, userGuid: Option[String]): RequestResources = {
    val user = userGuid.flatMap { guid =>
      Await.result(Authenticated.api().Users.getByGuid(UUID.fromString(guid)), 5000.millis)
    }

    val org = requestPath.split("/").drop(1).headOption.flatMap { possibleOrgKey =>
      Await.result(Authenticated.api(user).Organizations.getByKey(possibleOrgKey), 1000.millis).headOption
    }

    val memberships = if (user.isEmpty || org.isEmpty) {
      Seq.empty
    } else {
      Await.result(Authenticated.api(user).Memberships.get(orgKey = Some(org.get.key), userGuid = Some(user.get.guid)), 1000.millis)
    }

    RequestResources(
      user = user,
      org = org,
      memberships = memberships
    )
  }

}

object Anonymous extends ActionBuilder[AnonymousRequest] {

  import scala.concurrent.ExecutionContext.Implicits.global

  def invokeBlock[A](request: Request[A], block: (AnonymousRequest[A]) => Future[Result]) = {
    val resources = AnonymousRequest.resources(request.path, request.session.get("user_guid"))
    block(new AnonymousRequest(resources, request))
  }
}

object AnonymousOrg extends ActionBuilder[AnonymousOrgRequest] {

  import scala.concurrent.ExecutionContext.Implicits.global

  def invokeBlock[A](request: Request[A], block: (AnonymousOrgRequest[A]) => Future[Result]) = {
    val resources = AnonymousRequest.resources(request.path, request.session.get("user_guid"))
    if (resources.org.isEmpty) {
      Future.successful(Redirect("/").flashing("warning" -> "Org not found or access denied"))
    } else {
      val anon = new AnonymousRequest(resources, request)
      val anonRequest = new AnonymousOrgRequest(anon)

      if (resources.isMember) {
        block(anonRequest)
      } else if (resources.org.get.metadata.flatMap(_.visibility) == Some(Visibility.Public)) {
        block(anonRequest)
      } else {
        Future.successful(Redirect("/").flashing("warning" -> "Org not found or access denied"))
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy